@wrongstack/tools 0.309.1 → 0.310.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.
Files changed (57) hide show
  1. package/dist/_regex.d.ts +6 -34
  2. package/dist/bash.js +3 -3
  3. package/dist/builtin.js +3011 -1677
  4. package/dist/codebase-index/binary-frame.d.ts +57 -8
  5. package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +6 -0
  6. package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +6 -0
  7. package/dist/codebase-index/codebase-search-tool.d.ts +15 -5
  8. package/dist/codebase-index/index-service.d.ts +3 -19
  9. package/dist/codebase-index/index.js +2735 -1415
  10. package/dist/codebase-index/indexer.d.ts +3 -0
  11. package/dist/codebase-index/parser-batch.d.ts +53 -0
  12. package/dist/codebase-index/parser-dispatch.d.ts +32 -0
  13. package/dist/codebase-index/parser-output.d.ts +14 -0
  14. package/dist/codebase-index/parser-worker-pool.d.ts +57 -4
  15. package/dist/codebase-index/parser-worker-script.d.ts +5 -2
  16. package/dist/codebase-index/parser-worker-script.js +4042 -0
  17. package/dist/codebase-index/project-server-cache.d.ts +16 -0
  18. package/dist/codebase-index/project-server-client.d.ts +2 -2
  19. package/dist/codebase-index/project-server-query-cache.d.ts +88 -0
  20. package/dist/codebase-index/project-server.js +2846 -1308
  21. package/dist/codebase-index/py-parser.d.ts +5 -0
  22. package/dist/codebase-index/schema.d.ts +14 -1
  23. package/dist/codebase-index/sqlite-runtime.d.ts +2 -2
  24. package/dist/codebase-index/tree-sitter/queries.d.ts +30 -3
  25. package/dist/codebase-index/tree-sitter/visitor.d.ts +2 -1
  26. package/dist/codebase-index/vector-search.d.ts +12 -0
  27. package/dist/codebase-index/wal-maintenance.d.ts +58 -0
  28. package/dist/codebase-index/worker-protocol/contracts.d.ts +44 -0
  29. package/dist/codebase-index/worker-protocol.d.ts +17 -1
  30. package/dist/codebase-index/worker.js +2300 -1020
  31. package/dist/codebase-index/writer-admin.d.ts +11 -0
  32. package/dist/codebase-index/writer-helpers.d.ts +31 -1
  33. package/dist/codebase-index/writer-mutations.d.ts +0 -6
  34. package/dist/codebase-index/writer-schema.d.ts +2 -2
  35. package/dist/codebase-index/writer.d.ts +15 -0
  36. package/dist/edit.js +2511 -1203
  37. package/dist/exec.js +5 -3
  38. package/dist/grep.js +5 -124
  39. package/dist/index.js +3007 -1736
  40. package/dist/json.js +5 -124
  41. package/dist/kanban.js +130 -0
  42. package/dist/logs.js +5 -121
  43. package/dist/pack.js +3011 -1677
  44. package/dist/patch.js +2524 -1216
  45. package/dist/plan.js +106 -0
  46. package/dist/read.js +2506 -1198
  47. package/dist/replace.js +2487 -1295
  48. package/dist/search.js +6 -2
  49. package/dist/session-kanban.js +24 -16
  50. package/dist/task.js +106 -0
  51. package/dist/todo.js +106 -0
  52. package/dist/tool-tier.d.ts +11 -0
  53. package/dist/tool-tier.js +3019 -1677
  54. package/dist/tree.js +14 -3
  55. package/dist/win32.js +3 -3
  56. package/dist/write.js +2513 -1205
  57. package/package.json +5 -4
@@ -21,4 +21,9 @@ export declare function parseSymbols(opts: {
21
21
  lang: SymbolLang;
22
22
  }): Promise<FileSymbols>;
23
23
  export { detectLang } from './languages.js';
24
+ /**
25
+ * The resolved Python binary (or null when no runtime is available).
26
+ * Shared with the P3.8 batch parser so both paths run the same interpreter.
27
+ */
28
+ export declare function resolvePythonBinary(): Promise<string | null>;
24
29
  //# sourceMappingURL=py-parser.d.ts.map
@@ -75,6 +75,13 @@ export interface SearchResult {
75
75
  }
76
76
  /** Result of a full reindex. */
77
77
  export interface IndexResult {
78
+ /**
79
+ * Files actually parsed and committed with one or more symbols this run
80
+ * (P5.15: exactly `fileOutcomes.parsed`). Skipped (mtime/hash-unchanged),
81
+ * empty, and failed files are reported separately in `fileOutcomes` —
82
+ * historically they inflated this number, misreading incremental runs as
83
+ * doing full work.
84
+ */
78
85
  filesIndexed: number;
79
86
  /** Outcome detail for this run. Optional for compatibility with older project daemons. */
80
87
  fileOutcomes?: {
@@ -201,6 +208,12 @@ export interface GraphEdge {
201
208
  export interface CodeMapGraph {
202
209
  nodes: GraphNode[];
203
210
  edges: GraphEdge[];
211
+ /**
212
+ * True when the project server served a previous generation's cached
213
+ * answer while a refresh was publishing (stale-read serving). Never set
214
+ * by the worker/inline path, which refuses reads during a refresh.
215
+ */
216
+ stale?: boolean | undefined;
204
217
  }
205
- export declare const SCHEMA_VERSION = 4;
218
+ export declare const SCHEMA_VERSION = 5;
206
219
  //# sourceMappingURL=schema.d.ts.map
@@ -1,8 +1,8 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
2
  /**
3
- * Load `node:sqlite`'s `DatabaseSync` lazily. Keeping this off writer.ts top
3
+ * Load the active runtime's synchronous SQLite implementation lazily. Keeping this off writer.ts top
4
4
  * level lets codebase-index tools register at CLI boot without eagerly loading
5
- * SQLite. Runtimes without `node:sqlite` fail only when the index is used.
5
+ * SQLite. Runtimes without `node:sqlite` or `bun:sqlite` fail only when the index is used.
6
6
  */
7
7
  export declare function loadDatabaseSync(): typeof DatabaseSync;
8
8
  export declare function runSqliteWithRetry<T>(fn: () => T): T;
@@ -4,8 +4,8 @@
4
4
  * The Day 2-3 skeleton defines the *declaration-kind* surface for each
5
5
  * language: which tree-sitter node types map to which `SymbolKind`, and how
6
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.
7
+ * (calls, type references, extends/implements, include paths) landed with
8
+ * P3.9, where real AST fixtures proved the mapping.
9
9
  *
10
10
  * Why no tree-sitter queries (the `.scm` query language)?
11
11
  * The universal visitor (`visitor.ts`) walks the tree by node-type rather
@@ -19,7 +19,7 @@
19
19
  * documents the full set of fields exhaustively so the next reader can see
20
20
  * at a glance what a language can override.
21
21
  */
22
- import type { SymbolKind, SymbolLang } from '../schema.js';
22
+ import type { CallType, SymbolKind, SymbolLang } from '../schema.js';
23
23
  /**
24
24
  * Declarations worth indexing for a language.
25
25
  *
@@ -35,6 +35,10 @@ import type { SymbolKind, SymbolLang } from '../schema.js';
35
35
  * named children of a declaration node. Set for languages
36
36
  * where the parent itself is the only indexable unit
37
37
  * (rare; default false).
38
+ * `refRules` — P3.9: node types that emit cross-references (calls,
39
+ * imports, heritage). Absent for languages whose grammar
40
+ * would turn the rule into noise (Elixir's `call` covers
41
+ * operators; shell has no symbol calls).
38
42
  */
39
43
  export interface NodeQueries {
40
44
  declKinds: Record<string, SymbolKind>;
@@ -42,6 +46,29 @@ export interface NodeQueries {
42
46
  nameExtractor?: (node: import('web-tree-sitter').Node) => string | null;
43
47
  scopeNodes?: ReadonlySet<string>;
44
48
  skipNamedChildren?: boolean;
49
+ refRules?: Partial<Record<string, RefRule>>;
50
+ }
51
+ /** One ref a refRule wants emitted. `callType` defaults to the rule's. */
52
+ export interface RefEmission {
53
+ toName: string;
54
+ callType?: CallType;
55
+ module?: string;
56
+ }
57
+ /**
58
+ * How to turn one tree-sitter node into refs.
59
+ *
60
+ * `callType` — the ref kind this rule emits.
61
+ * `field` — field carrying the callee/target (e.g. `'function'`).
62
+ * Default when no extractor: leaf-name of that field.
63
+ * `nameExtractor` — full control (multi-ref nodes like heritage lists,
64
+ * imports whose module must be derived from the node
65
+ * text, Ruby `require` calls). Return `null`/`[]` to
66
+ * emit nothing for this node.
67
+ */
68
+ export interface RefRule {
69
+ callType: CallType;
70
+ field?: string;
71
+ nameExtractor?: (node: import('web-tree-sitter').Node) => ReadonlyArray<RefEmission> | null;
45
72
  }
46
73
  /** Resolve the queries for a language, falling back to the default. */
47
74
  export declare function getQueries(lang: SymbolLang): NodeQueries;
@@ -27,11 +27,12 @@
27
27
  * up — emitting no symbol for that node rather than fabricating one.
28
28
  */
29
29
  import type { Tree } from 'web-tree-sitter';
30
- import type { Symbol as IndexSymbol, SymbolLang } from '../schema.js';
30
+ import type { Symbol as IndexSymbol, Ref, SymbolLang } from '../schema.js';
31
31
  import type { NodeQueries } from './queries.js';
32
32
  /** Result of walking one parsed file. */
33
33
  export interface VisitResult {
34
34
  symbols: IndexSymbol[];
35
+ refs: Ref[];
35
36
  }
36
37
  /**
37
38
  * Walk a parsed tree and emit symbols.
@@ -17,6 +17,18 @@
17
17
  */
18
18
  /** The constant k in the RRF formula — the standard value from the literature. */
19
19
  export declare const RRF_K = 60;
20
+ /**
21
+ * P4.11: opt-in gate for the vector embedding layer. Default OFF.
22
+ *
23
+ * The 384-dim char-trigram embedding is lexical similarity — it duplicates
24
+ * what the FTS5 trigram tokenizer already provides — while costing ~1.5 KB
25
+ * of BLOB per symbol on every insert and an embedText() pass per symbol even
26
+ * when the table is unavailable. With the gate off, ranking is BM25/FTS-only
27
+ * (identical result set; the vector layer only re-ordered FTS candidates).
28
+ * Set WRONGSTACK_INDEX_VECTORS=1 to restore the hybrid RRF path; a force
29
+ * reindex repopulates the table for pre-existing symbols.
30
+ */
31
+ export declare function vectorEmbeddingEnabled(): boolean;
20
32
  /** Fixed vector dimensionality. 384 matches the proposal's spec. */
21
33
  export declare const VECTOR_DIMENSIONS = 384;
22
34
  /**
@@ -0,0 +1,58 @@
1
+ /**
2
+ * P4.14: idle-time WAL maintenance for the detached project-server daemon.
3
+ *
4
+ * `wal_autocheckpoint=1000` is PASSIVE and only attempts a checkpoint after a
5
+ * COMMIT. A daemon whose clients keep issuing searches (long-running WAL
6
+ * readers) can hold WAL snapshots indefinitely: the autocheckpointer sees
7
+ * busy=1 every time and the WAL grows without bound until a reader gap or
8
+ * shutdown. Nothing re-fires once writes stop — a COMMIT is what arms it.
9
+ *
10
+ * This scheduler gives the daemon its own maintenance heartbeat:
11
+ * - every completed write run arms a sliding idle timer;
12
+ * - when it fires (no further writes slid it), it checkpoints the WAL
13
+ * (probe-first; never blocks on readers) and periodically runs
14
+ * `PRAGMA optimize` so the query planner's statistics stay current.
15
+ *
16
+ * All timers are unref'd — they must never keep the daemon alive past its
17
+ * idle-exit, and firing is harmless at any point because checkpointWal is
18
+ * best-effort.
19
+ */
20
+ export interface WalMaintenanceOptions {
21
+ /** Idle window after a write completion before maintenance fires. */
22
+ idleMs?: number | undefined;
23
+ /** Run `optimize()` once every N maintenance fires. Default: 8. */
24
+ optimizeEvery?: number | undefined;
25
+ /** Clock for tests. */
26
+ setTimeoutFn?: typeof setTimeout | undefined;
27
+ /** Clear for tests. */
28
+ clearTimeoutFn?: typeof clearTimeout | undefined;
29
+ }
30
+ export interface WalMaintenanceHooks {
31
+ /** Returns true when a checkpoint completed (WAL reset). */
32
+ checkpoint: () => boolean;
33
+ /** Recompute statistics. */
34
+ optimize: () => void;
35
+ }
36
+ export declare class WalMaintenance {
37
+ private readonly hooks;
38
+ private timer;
39
+ private fireCount;
40
+ private disposed;
41
+ private readonly idleMs;
42
+ private readonly optimizeEvery;
43
+ private readonly setTimeoutFn;
44
+ private readonly clearTimeoutFn;
45
+ constructor(hooks: WalMaintenanceHooks, options?: WalMaintenanceOptions);
46
+ /**
47
+ * Arm (or re-arm) the idle timer. Call after every completed write run —
48
+ * bursty incremental writes keep sliding the window so maintenance runs
49
+ * once after the burst settles, not per write.
50
+ */
51
+ notifyWriteCompleted(): void;
52
+ private fire;
53
+ /** True when an idle fire is pending (test visibility). */
54
+ get armed(): boolean;
55
+ /** Stop all maintenance. Idempotent; safe to call on every shutdown path. */
56
+ dispose(): void;
57
+ }
58
+ //# sourceMappingURL=wal-maintenance.d.ts.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Leaf contract types shared by `index-service.ts` and `worker-protocol.ts`.
3
+ *
4
+ * Lives separately from `index-service.ts` so the worker protocol can import
5
+ * these types type-only without depending on the implementation side, and
6
+ * so the runtime side can re-export them for downstream consumers that already
7
+ * reference them via the old path. Breaks the long-standing type-level SCC
8
+ * ARCH-CYCLE-TYPE-28 where `index-service.ts` and `worker-protocol.ts` were
9
+ * mutually importing contract types.
10
+ *
11
+ * This module MUST contain no runtime imports.
12
+ */
13
+ import type { CallSite } from '../schema.js';
14
+ /** Result of an incoming calls query. */
15
+ export interface IncomingCallsResult {
16
+ calls: CallSite[];
17
+ symbolFound: boolean;
18
+ /** True when `file` was scoped but the name is ambiguous (other files define it too). */
19
+ ambiguous: boolean;
20
+ /** Total matching call sites before the limit was applied. */
21
+ totalMatches: number;
22
+ /**
23
+ * True when the project server served a previous generation's cached
24
+ * answer while a refresh was publishing (stale-read serving). Never set by
25
+ * the worker/inline path, which refuses reads during a refresh instead.
26
+ */
27
+ stale?: boolean | undefined;
28
+ }
29
+ /** Result of an outgoing calls query. */
30
+ export interface OutgoingCallsResult {
31
+ calls: CallSite[];
32
+ symbolFound: boolean;
33
+ /** Number of refs whose target could not be resolved (to_id IS NULL). */
34
+ unresolvedCount: number;
35
+ /** Total matching call sites before the limit was applied. */
36
+ totalMatches: number;
37
+ /**
38
+ * True when the project server served a previous generation's cached
39
+ * answer while a refresh was publishing (stale-read serving). Never set by
40
+ * the worker/inline path, which refuses reads during a refresh instead.
41
+ */
42
+ stale?: boolean | undefined;
43
+ }
44
+ //# sourceMappingURL=contracts.d.ts.map
@@ -4,8 +4,8 @@
4
4
  * Plain structured-cloneable shapes only — no class instances, no functions.
5
5
  * Errors cross the boundary as strings and are re-wrapped by the host.
6
6
  */
7
+ import type { IncomingCallsResult, OutgoingCallsResult } from './worker-protocol/contracts.js';
7
8
  import type { CodeMapGraph, IndexResult, IndexStats, SearchResult } from './schema.js';
8
- import type { IncomingCallsResult, OutgoingCallsResult } from './index-service.js';
9
9
  export interface IndexOpArgs {
10
10
  projectRoot: string;
11
11
  indexDir?: string | undefined;
@@ -44,6 +44,22 @@ export interface CallRefsOpArgs extends StatsOpArgs {
44
44
  export interface SearchOpResult {
45
45
  results: SearchResult[];
46
46
  total: number;
47
+ /**
48
+ * P2.5: present only on zero-hit responses. Minimal summary (files indexed,
49
+ * last_indexed) so the search tool can distinguish "index exists but nothing
50
+ * matched" from "no persisted index at all" without a separate stats round
51
+ * trip over IPC.
52
+ */
53
+ indexSummary?: {
54
+ totalFiles: number;
55
+ lastIndexed: number | null;
56
+ } | undefined;
57
+ /**
58
+ * True when the project server served a previous generation's cached
59
+ * answer while a refresh was publishing (stale-read serving). Never set by
60
+ * the worker/inline path, which refuses reads during a refresh instead.
61
+ */
62
+ stale?: boolean | undefined;
47
63
  }
48
64
  /** Map of op name → { args, result } so host and worker stay in lockstep. */
49
65
  export interface OpShapes {