@wrongstack/tools 0.302.2 → 0.305.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.d.ts +6 -0
- package/dist/builtin.js +3213 -686
- package/dist/codebase-index/binary-frame.d.ts +43 -0
- package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +1 -0
- package/dist/codebase-index/codebase-index-tool.d.ts +6 -0
- package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +1 -0
- package/dist/codebase-index/content-hash.d.ts +66 -0
- package/dist/codebase-index/index.js +1597 -153
- package/dist/codebase-index/indexer.d.ts +6 -0
- package/dist/codebase-index/parser-worker-pool.d.ts +63 -0
- package/dist/codebase-index/parser-worker-script.d.ts +42 -0
- package/dist/codebase-index/project-server-protocol.d.ts +2 -0
- package/dist/codebase-index/project-server.js +1483 -104
- package/dist/codebase-index/schema.d.ts +18 -0
- package/dist/codebase-index/tree-sitter/queries.d.ts +48 -0
- package/dist/codebase-index/tree-sitter/util.d.ts +31 -0
- package/dist/codebase-index/tree-sitter/visitor.d.ts +47 -0
- package/dist/codebase-index/tree-sitter-parser.d.ts +58 -0
- package/dist/codebase-index/vector-search.d.ts +62 -0
- package/dist/codebase-index/worker-protocol.d.ts +2 -0
- package/dist/codebase-index/worker.js +1452 -73
- package/dist/codebase-index/writer-bulk-insert.d.ts +5 -0
- package/dist/codebase-index/writer-graph-reader.d.ts +39 -0
- package/dist/codebase-index/writer-schema.d.ts +9 -2
- package/dist/codebase-index/writer.d.ts +36 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3258 -727
- package/dist/kanban-contract-actions.d.ts +7 -0
- package/dist/kanban-task-inputs.d.ts +16 -2
- package/dist/kanban-tool-schema.d.ts +2 -2
- package/dist/kanban-tool-types.d.ts +39 -2
- package/dist/kanban.js +580 -193
- package/dist/pack.js +3212 -686
- package/dist/plan.d.ts +4 -1
- package/dist/plan.js +2701 -18
- package/dist/read.js +1559 -103
- package/dist/session-kanban.d.ts +94 -1
- package/dist/session-kanban.js +308 -44
- package/dist/task.d.ts +5 -4
- package/dist/task.js +2825 -138
- package/dist/todo.d.ts +10 -1
- package/dist/todo.js +2474 -30
- package/dist/tool-tier.js +3212 -686
- package/package.json +8 -4
|
@@ -38,6 +38,13 @@ export interface FileMeta {
|
|
|
38
38
|
mtimeMs: number;
|
|
39
39
|
symbolCount: number;
|
|
40
40
|
lastIndexed: number;
|
|
41
|
+
/**
|
|
42
|
+
* xxHash64 of the file's UTF-8 bytes (Phase 2). `undefined` for callers
|
|
43
|
+
* that don't compute it; the writer stores an empty string in that case.
|
|
44
|
+
* The indexer compares this against the current file's hash to skip
|
|
45
|
+
* re-parsing when content is byte-identical despite an mtime change.
|
|
46
|
+
*/
|
|
47
|
+
contentHash?: string | undefined;
|
|
41
48
|
}
|
|
42
49
|
/** Statistics about the index. */
|
|
43
50
|
export interface IndexStats {
|
|
@@ -69,6 +76,17 @@ export interface SearchResult {
|
|
|
69
76
|
/** Result of a full reindex. */
|
|
70
77
|
export interface IndexResult {
|
|
71
78
|
filesIndexed: number;
|
|
79
|
+
/** Outcome detail for this run. Optional for compatibility with older project daemons. */
|
|
80
|
+
fileOutcomes?: {
|
|
81
|
+
/** Files parsed and committed with one or more symbols. */
|
|
82
|
+
parsed: number;
|
|
83
|
+
/** Files reused from trusted metadata or an unchanged content hash. */
|
|
84
|
+
skipped: number;
|
|
85
|
+
/** Files successfully represented in the index with zero symbols. */
|
|
86
|
+
empty: number;
|
|
87
|
+
/** Files that could not be read, parsed, or committed. */
|
|
88
|
+
failed: number;
|
|
89
|
+
} | undefined;
|
|
72
90
|
symbolsIndexed: number;
|
|
73
91
|
langStats: Record<SymbolLang, number>;
|
|
74
92
|
durationMs: number;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language tree-sitter node-mapping queries.
|
|
3
|
+
*
|
|
4
|
+
* The Day 2-3 skeleton defines the *declaration-kind* surface for each
|
|
5
|
+
* language: which tree-sitter node types map to which `SymbolKind`, and how
|
|
6
|
+
* to extract the symbol's name from that node. Ref/import/heritage emission
|
|
7
|
+
* (calls, type references, extends/implements, include paths) lands on Day 4
|
|
8
|
+
* alongside the C-family tests, where real AST fixtures prove the mapping.
|
|
9
|
+
*
|
|
10
|
+
* Why no tree-sitter queries (the `.scm` query language)?
|
|
11
|
+
* The universal visitor (`visitor.ts`) walks the tree by node-type rather
|
|
12
|
+
* than running a `.scm` query. A query-based approach would be faster at
|
|
13
|
+
* very large scale but adds a second AST traversal pattern and a separate
|
|
14
|
+
* grammar file per language. Direct traversal keeps the code shape aligned
|
|
15
|
+
* with `ts-parser.ts` and `py-parser.ts` — one recursion, one witness list.
|
|
16
|
+
*
|
|
17
|
+
* Each language only needs to fill in the few fields that differ from the
|
|
18
|
+
* default (see {@link DEFAULT_QUERIES}). The block form in `LANG_QUERIES`
|
|
19
|
+
* documents the full set of fields exhaustively so the next reader can see
|
|
20
|
+
* at a glance what a language can override.
|
|
21
|
+
*/
|
|
22
|
+
import type { SymbolKind, SymbolLang } from '../schema.js';
|
|
23
|
+
/**
|
|
24
|
+
* Declarations worth indexing for a language.
|
|
25
|
+
*
|
|
26
|
+
* `declKinds` — map of `tree-sitter node.type` → `SymbolKind`.
|
|
27
|
+
* `nameField` — node field name that carries the identifier; defaults
|
|
28
|
+
* to `'name'`. Some grammars expose a `declarator` field
|
|
29
|
+
* that wraps a `pointer_declarator` or `function_declarator`.
|
|
30
|
+
* `nameExtractor` — optional escape hatch for languages (e.g. Elixir)
|
|
31
|
+
* whose declaration shape doesn't have a clean `name` field.
|
|
32
|
+
* `scopeNodes` — node types that push a new scope onto the visitor's
|
|
33
|
+
* stack. Class/struct/namespace/interface/impl/module.
|
|
34
|
+
* `skipNamedChildren` — when true, the visitor does not recurse into
|
|
35
|
+
* named children of a declaration node. Set for languages
|
|
36
|
+
* where the parent itself is the only indexable unit
|
|
37
|
+
* (rare; default false).
|
|
38
|
+
*/
|
|
39
|
+
export interface NodeQueries {
|
|
40
|
+
declKinds: Record<string, SymbolKind>;
|
|
41
|
+
nameField?: Partial<Record<string, string>>;
|
|
42
|
+
nameExtractor?: (node: import('web-tree-sitter').Node) => string | null;
|
|
43
|
+
scopeNodes?: ReadonlySet<string>;
|
|
44
|
+
skipNamedChildren?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Resolve the queries for a language, falling back to the default. */
|
|
47
|
+
export declare function getQueries(lang: SymbolLang): NodeQueries;
|
|
48
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the tree-sitter extractor.
|
|
3
|
+
*
|
|
4
|
+
* Newline-offset binary search is the same pattern `generic-parser.ts` and
|
|
5
|
+
* `import-extractor.ts` use: precompute the offset of every `\n` once per
|
|
6
|
+
* file, then resolve match→line in O(log n) instead of O(n). Tree-sitter
|
|
7
|
+
* gives us `{ row, column }` directly, but we need the same conversion for
|
|
8
|
+
* identifiers that we extract from arbitrary child nodes whose byte offset
|
|
9
|
+
* we have to translate into 1-based line + 0-based col ourselves.
|
|
10
|
+
*/
|
|
11
|
+
/** 1-based {line, col} for a byte offset, using binary search over newline offsets. */
|
|
12
|
+
export declare function lineColAt(offsets: readonly number[], index: number): {
|
|
13
|
+
line: number;
|
|
14
|
+
col: number;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Precompute newline offsets once per file. The cost is a single O(n) scan
|
|
18
|
+
* of the buffer; subsequent lookups (typically dozens to hundreds per file)
|
|
19
|
+
* are O(log n) instead of O(n).
|
|
20
|
+
*/
|
|
21
|
+
export declare function newlineOffsets(content: string): number[];
|
|
22
|
+
/**
|
|
23
|
+
* Cap the source the visitor walks, mirroring `GENERIC_MAX_FILE_CHARS` in
|
|
24
|
+
* `generic-parser.ts`. Files larger than this get sliced; the rest is dropped
|
|
25
|
+
* from the index. Mirrors the safety net that the regex extractor already
|
|
26
|
+
* applies — without it, a multi-MB blob can blow the AST heap.
|
|
27
|
+
*/
|
|
28
|
+
export declare const TREE_SITTER_MAX_FILE_CHARS: number;
|
|
29
|
+
/** Soft cap on symbols per file (matches `GENERIC_MAX_SYMBOLS_DEFAULT`). */
|
|
30
|
+
export declare const TREE_SITTER_MAX_SYMBOLS = 500;
|
|
31
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Tree-Sitter AST visitor.
|
|
3
|
+
*
|
|
4
|
+
* Walks a parsed syntax tree, applying the per-language {@link NodeQueries}
|
|
5
|
+
* table, and produces an indexed symbol list. Ref emission (calls, type
|
|
6
|
+
* references, imports, heritage) is intentionally out of scope here — it
|
|
7
|
+
* ships on Day 4 alongside the C-family tests, where per-language fixtures
|
|
8
|
+
* can verify each `callType` mapping.
|
|
9
|
+
*
|
|
10
|
+
* The visitor is O(n) over named children: each node is visited at most
|
|
11
|
+
* once, and the scope stack is push/pop in O(1). The cost on a 50k-file
|
|
12
|
+
* monorepo is dominated by `Parser.parse(content)` itself, which tree-sitter
|
|
13
|
+
* implements as a single-pass GLR parse in WASM.
|
|
14
|
+
*
|
|
15
|
+
* Two design rules that shaped this module:
|
|
16
|
+
*
|
|
17
|
+
* 1. **Recursive scope tracking, not parent-chain walks.** `ts-parser.ts`
|
|
18
|
+
* pushed scope parts onto an array and trimmed on return; we mirror
|
|
19
|
+
* that. The cost is O(depth) push/pop instead of O(depth × symbols)
|
|
20
|
+
* parent walks — for a 200-symbol file at depth 5, that's 1000 fewer
|
|
21
|
+
* `parent` lookups.
|
|
22
|
+
*
|
|
23
|
+
* 2. **Identifier extraction has two shapes.** Most languages give you a
|
|
24
|
+
* `name` field on the declaration node; a handful (C declarators,
|
|
25
|
+
* Elixir calls) don't. The visitor tries `queries.nameExtractor` first,
|
|
26
|
+
* then falls back to `queries.nameField[type] ?? 'name'`, then gives
|
|
27
|
+
* up — emitting no symbol for that node rather than fabricating one.
|
|
28
|
+
*/
|
|
29
|
+
import type { Tree } from 'web-tree-sitter';
|
|
30
|
+
import type { Symbol as IndexSymbol, SymbolLang } from '../schema.js';
|
|
31
|
+
import type { NodeQueries } from './queries.js';
|
|
32
|
+
/** Result of walking one parsed file. */
|
|
33
|
+
export interface VisitResult {
|
|
34
|
+
symbols: IndexSymbol[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Walk a parsed tree and emit symbols.
|
|
38
|
+
*
|
|
39
|
+
* `tree` — the parsed syntax tree.
|
|
40
|
+
* `content` — original source text. Used to derive `signature` (the
|
|
41
|
+
* declaration node's slice of the source) and `docComment`.
|
|
42
|
+
* `file` — absolute path, threaded into every emitted symbol.
|
|
43
|
+
* `lang` — the language the tree was parsed under.
|
|
44
|
+
* `queries` — per-language node-mapping table.
|
|
45
|
+
*/
|
|
46
|
+
export declare function visitTree(tree: Tree, content: string, file: string, lang: SymbolLang, queries: NodeQueries): VisitResult;
|
|
47
|
+
//# sourceMappingURL=visitor.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-Sitter WASM Universal AST Extractor (Phase 1).
|
|
3
|
+
*
|
|
4
|
+
* Replaces regex heuristics in `generic-parser.ts` for languages with a
|
|
5
|
+
* pre-compiled tree-sitter grammar: C, C++, Java, C#, PHP, Ruby, Swift,
|
|
6
|
+
* Kotlin, Elixir, Shell (bash), plus Go/Python/Rust as opt-in WASM paths
|
|
7
|
+
* (default behavior still uses the existing first-class parsers).
|
|
8
|
+
*
|
|
9
|
+
* The runtime contract matches {@link parseGeneric}: callers receive a
|
|
10
|
+
* {@link FileSymbols} record. Symbol ids are always 0 — the caller assigns
|
|
11
|
+
* them during bulk insertion. Refs carry `fromId: 0` and are deduplicated
|
|
12
|
+
* downstream by `parser-dispatch.ts#withRelations`.
|
|
13
|
+
*
|
|
14
|
+
* Design notes:
|
|
15
|
+
* - Grammar WASM files live alongside the runtime in `wasm/<lang>/`.
|
|
16
|
+
* Vendoring them in-tree makes builds deterministic; no fetch-on-first-run.
|
|
17
|
+
* - The {@link web-tree-sitter} runtime is initialized once per process.
|
|
18
|
+
* `Language.load(wasmPath)` resolves on the first parse of each language
|
|
19
|
+
* and is memoized — every subsequent parse reuses the same Language object.
|
|
20
|
+
* - On any failure (grammar file missing, runtime not installed, parse error
|
|
21
|
+
* with no recoverable symbols) this module returns an empty `symbols[]`
|
|
22
|
+
* rather than throwing — matching the existing parsers' "never drops a
|
|
23
|
+
* file from the index" contract.
|
|
24
|
+
*/
|
|
25
|
+
import type { FileSymbols, SymbolLang } from './schema.js';
|
|
26
|
+
/** True when this lang has a tree-sitter grammar available right now. */
|
|
27
|
+
export declare function isTreeSitterSupported(lang: SymbolLang): boolean;
|
|
28
|
+
/** Visible for tests: the absolute path to a vendored grammar WASM. */
|
|
29
|
+
export declare function getGrammarWasmPath(lang: SymbolLang): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Async entry point mirroring {@link parseGeneric}. Used by
|
|
32
|
+
* `parser-dispatch.ts` via dynamic import. Returns an empty `symbols[]`
|
|
33
|
+
* on any failure rather than throwing — the dispatch layer falls back to
|
|
34
|
+
* `generic-parser` for regex coverage when this returns zero symbols.
|
|
35
|
+
*
|
|
36
|
+
* Symbol emission is *not* implemented in this file yet — this Day-1
|
|
37
|
+
* scaffold only proves grammar loading and parsing work end-to-end.
|
|
38
|
+
* Day 2-3 introduces the universal visitor (`tree-sitter/visitor.ts`)
|
|
39
|
+
* and per-language query tables (`tree-sitter/queries.ts`).
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseSymbols(opts: {
|
|
42
|
+
file: string;
|
|
43
|
+
content: string;
|
|
44
|
+
lang: SymbolLang;
|
|
45
|
+
}): Promise<FileSymbols>;
|
|
46
|
+
/**
|
|
47
|
+
* Internal helper used by AST-shape inspectors and tests. Loads and caches
|
|
48
|
+
* the tree-sitter `Language` for a given {@link SymbolLang} without parsing.
|
|
49
|
+
* Not part of the public parser API — the indexer should always go through
|
|
50
|
+
* {@link parseSymbols}.
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadTreeSitterLanguage(lang: SymbolLang): Promise<import('web-tree-sitter').Language>;
|
|
53
|
+
/** Test-only helper: parse and return the root node type. Throws on failure. */
|
|
54
|
+
export declare function __smokeRootType(opts: {
|
|
55
|
+
content: string;
|
|
56
|
+
lang: SymbolLang;
|
|
57
|
+
}): Promise<string>;
|
|
58
|
+
//# sourceMappingURL=tree-sitter-parser.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 3: Hybrid Search Engine — vector embedding layer + RRF fusion.
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - **Symbol embeddings**: a lightweight character n-gram TF-IDF representation
|
|
6
|
+
* of each symbol's text (name + signature + doc comment), producing a fixed
|
|
7
|
+
* 384-dimensional float32 vector. No native deps (no ONNX runtime). Designed
|
|
8
|
+
* to be swapped for a real transformer embedding model in a future phase
|
|
9
|
+
* without changing the storage or fusion interface.
|
|
10
|
+
* - **Cosine similarity**: ranks symbols by vector proximity to a query vector.
|
|
11
|
+
* - **Reciprocal Rank Fusion (RRF)**: merges the ranked lists from BM25/FTS5
|
|
12
|
+
* trigram search and vector search into a single result set.
|
|
13
|
+
*
|
|
14
|
+
* The RRF formula (k=60, following the original Cormack et al. 2009 paper):
|
|
15
|
+
* RRF_Score(d) = 1/(k + Rank_BM25(d)) + 1/(k + Rank_Vector(d))
|
|
16
|
+
* where a missing rank from either source is treated as infinity (contributes 0).
|
|
17
|
+
*/
|
|
18
|
+
/** The constant k in the RRF formula — the standard value from the literature. */
|
|
19
|
+
export declare const RRF_K = 60;
|
|
20
|
+
/** Fixed vector dimensionality. 384 matches the proposal's spec. */
|
|
21
|
+
export declare const VECTOR_DIMENSIONS = 384;
|
|
22
|
+
/**
|
|
23
|
+
* Compute a fixed-dimensional embedding of a text string using character
|
|
24
|
+
* n-gram hashing (the "hashing trick").
|
|
25
|
+
*
|
|
26
|
+
* Each n-gram is hashed to a bucket in [0, VECTOR_DIMENSIONS). The bucket's
|
|
27
|
+
* float32 value is incremented by the n-gram's term frequency. After all
|
|
28
|
+
* n-grams are counted, the vector is L2-normalized so cosine similarity
|
|
29
|
+
* reduces to a dot product.
|
|
30
|
+
*
|
|
31
|
+
* This is NOT a semantic embedding — it captures **lexical similarity**
|
|
32
|
+
* (shared substrings). A real embedding model would be dropped in here
|
|
33
|
+
* without changing the storage or fusion interface.
|
|
34
|
+
*/
|
|
35
|
+
export declare function embedText(text: string): Float32Array;
|
|
36
|
+
/** Cosine similarity between two L2-normalized vectors (reduces to dot product). */
|
|
37
|
+
export declare function cosineSimilarity(a: Float32Array, b: Float32Array): number;
|
|
38
|
+
/** Serialize a Float32Array to a Buffer for SQLite BLOB storage. */
|
|
39
|
+
export declare function encodeVector(vec: Float32Array): Buffer;
|
|
40
|
+
/** Deserialize a BLOB from SQLite back to a Float32Array. */
|
|
41
|
+
export declare function decodeVector(buf: Buffer | Uint8Array): Float32Array;
|
|
42
|
+
/**
|
|
43
|
+
* Rank map: symbolId → rank (0-based). Lower rank = more relevant.
|
|
44
|
+
* Built from a search result list (already sorted by relevance).
|
|
45
|
+
*/
|
|
46
|
+
export type RankMap = Map<number, number>;
|
|
47
|
+
/** Build a RankMap from a sorted result list. */
|
|
48
|
+
export declare function buildRankMap(sortedIds: number[]): RankMap;
|
|
49
|
+
/**
|
|
50
|
+
* Reciprocal Rank Fusion — merge two ranked lists into a single fused ranking.
|
|
51
|
+
*
|
|
52
|
+
* Each symbol's RRF score is the sum of 1/(k + rank) from each source.
|
|
53
|
+
* Symbols only in one list still contribute 1/(k + rank) from that source.
|
|
54
|
+
* Symbols in neither list are absent from the output.
|
|
55
|
+
*
|
|
56
|
+
* @param bm25Ranks - rank map from BM25/FTS5 trigram search
|
|
57
|
+
* @param vectorRanks - rank map from vector similarity search
|
|
58
|
+
* @param k - the RRF constant (default 60, per Cormack et al.)
|
|
59
|
+
* @returns sorted [symbolId, rrfScore] pairs, descending by score
|
|
60
|
+
*/
|
|
61
|
+
export declare function reciprocalRankFusion(bm25Ranks: RankMap, vectorRanks: RankMap, k?: number): Array<[number, number]>;
|
|
62
|
+
//# sourceMappingURL=vector-search.d.ts.map
|
|
@@ -38,6 +38,8 @@ export interface CallRefsOpArgs extends StatsOpArgs {
|
|
|
38
38
|
symbol: string;
|
|
39
39
|
file?: string | undefined;
|
|
40
40
|
limit?: number | undefined;
|
|
41
|
+
/** When true, follow the call graph transitively (callers-of-callers / callees-of-callees) via recursive CTE. */
|
|
42
|
+
transitive?: boolean | undefined;
|
|
41
43
|
}
|
|
42
44
|
export interface SearchOpResult {
|
|
43
45
|
results: SearchResult[];
|