@wrongstack/tools 0.317.0 → 0.317.2

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 (109) hide show
  1. package/dist/_spawn-stream.d.ts +1 -1
  2. package/dist/audit.d.ts +37 -2
  3. package/dist/audit.js +4 -4
  4. package/dist/bash.js +1 -1
  5. package/dist/batch-tool-use.js +1 -1
  6. package/dist/browser/index.js +1 -1
  7. package/dist/browser/tools.d.ts +16 -1
  8. package/dist/builtin.js +43 -43
  9. package/dist/{chunk-SDLVH5RZ.js → chunk-3QQSBUXR.js} +6 -5
  10. package/dist/{chunk-K3WNSHUF.js → chunk-45JPRMC2.js} +62 -36
  11. package/dist/{chunk-EJWSCQ6D.js → chunk-4AEZIFOW.js} +6 -5
  12. package/dist/{chunk-PQKK5JH7.js → chunk-4E42D7UF.js} +2 -2
  13. package/dist/{chunk-JRJJX3L5.js → chunk-5WNDJHT6.js} +3 -2
  14. package/dist/{chunk-7EY5DCRO.js → chunk-5ZYEGP2P.js} +4 -4
  15. package/dist/{chunk-HPEO4EA7.js → chunk-6RR5VX6U.js} +35 -17
  16. package/dist/{chunk-QDQY7NQ2.js → chunk-A2PX7M7A.js} +5 -5
  17. package/dist/{chunk-JQRIR762.js → chunk-AK2K4KHR.js} +27 -19
  18. package/dist/{chunk-P7FYFZ6M.js → chunk-BANPF4LY.js} +11 -7
  19. package/dist/{chunk-RGISBZBD.js → chunk-CPSAF2AU.js} +3 -2
  20. package/dist/{chunk-BSLVR56S.js → chunk-CPVLVQYT.js} +6 -5
  21. package/dist/{chunk-VJNHFZ7J.js → chunk-CVALEVGA.js} +6 -5
  22. package/dist/{chunk-PY2IOS7C.js → chunk-CWALNI6K.js} +5 -5
  23. package/dist/{chunk-LIJQMYYX.js → chunk-ELFFQ4RU.js} +7 -3
  24. package/dist/{chunk-JNNVRHMV.js → chunk-FJEQZHZN.js} +8 -8
  25. package/dist/{chunk-S5CCLZL3.js → chunk-FRN7TIAA.js} +2 -2
  26. package/dist/{chunk-PCHQ6YRR.js → chunk-FYDKHXN7.js} +2 -2
  27. package/dist/{chunk-NKJW5GFO.js → chunk-H6AWAZ2Y.js} +3 -3
  28. package/dist/{chunk-IVWV2UM6.js → chunk-HTYEO67J.js} +6 -5
  29. package/dist/{chunk-UNSKG6DC.js → chunk-ICAXDRP6.js} +10 -15
  30. package/dist/{chunk-IYK7XGDZ.js → chunk-JJQB6R7Y.js} +7 -7
  31. package/dist/{chunk-LWKUTMD5.js → chunk-MRZOVQ5D.js} +6 -5
  32. package/dist/{chunk-YGG6X57C.js → chunk-NKX4SJ5R.js} +12 -9
  33. package/dist/{chunk-U4D5S3VQ.js → chunk-NWZ6XGBJ.js} +2 -1
  34. package/dist/{chunk-UKU2ZX4C.js → chunk-P7ZQ2FAJ.js} +27 -17
  35. package/dist/{chunk-4I4LWFOO.js → chunk-PQTONQ4P.js} +16 -11
  36. package/dist/{chunk-XGHMUZ77.js → chunk-RMB76PDS.js} +3 -3
  37. package/dist/{chunk-5OAOKALG.js → chunk-RUOMW2I6.js} +4 -3
  38. package/dist/{chunk-553IQUMO.js → chunk-S2JRYDYG.js} +7 -6
  39. package/dist/{chunk-OUBDL3WH.js → chunk-SOG7XIRF.js} +11 -8
  40. package/dist/{chunk-U6DZWHBA.js → chunk-TDLZIDCY.js} +9 -7
  41. package/dist/{chunk-TRDX25UH.js → chunk-TFEGJDH5.js} +293 -86
  42. package/dist/{chunk-AHHDWNXC.js → chunk-TKA4VEX2.js} +2 -2
  43. package/dist/{chunk-5H4GSJAI.js → chunk-UE3UBMCP.js} +7 -6
  44. package/dist/{chunk-IXMNTNW5.js → chunk-UKGMDCXT.js} +4 -3
  45. package/dist/{chunk-VGBUDLW4.js → chunk-UOXX4SQZ.js} +7 -6
  46. package/dist/{chunk-T2F4S7U4.js → chunk-WI3VDXHD.js} +18 -8
  47. package/dist/{chunk-O4MBV4AX.js → chunk-WJYXMB2R.js} +6 -5
  48. package/dist/{chunk-U4VAATKP.js → chunk-WXJY3BKV.js} +16 -6
  49. package/dist/{chunk-DR7JOQTC.js → chunk-X5K3U6GI.js} +3 -3
  50. package/dist/{chunk-DSEANA2W.js → chunk-XVGB6KYU.js} +37 -36
  51. package/dist/{chunk-TEBQ4VPZ.js → chunk-YOHO4DVT.js} +6 -5
  52. package/dist/{chunk-RXISBFR5.js → chunk-ZE6KLBUO.js} +5 -4
  53. package/dist/{chunk-22B7GE5T.js → chunk-ZHH3BEWU.js} +13 -12
  54. package/dist/codebase-index/bm25.d.ts +14 -1
  55. package/dist/codebase-index/index.js +8 -8
  56. package/dist/codebase-index/json-parser.d.ts +4 -0
  57. package/dist/codebase-index/parser-worker-script.js +2 -2
  58. package/dist/codebase-index/project-server.js +48 -9
  59. package/dist/codebase-index/worker.js +4 -4
  60. package/dist/codebase-index/writer-bulk-insert.d.ts +0 -1
  61. package/dist/codebase-index/writer-schema.d.ts +1 -1
  62. package/dist/codebase-index/writer.d.ts +38 -0
  63. package/dist/diff.js +1 -1
  64. package/dist/e2e.d.ts +40 -1
  65. package/dist/e2e.js +1 -1
  66. package/dist/edit.js +7 -7
  67. package/dist/exec.js +1 -1
  68. package/dist/fetch.js +1 -1
  69. package/dist/format.d.ts +42 -2
  70. package/dist/format.js +4 -4
  71. package/dist/git.d.ts +70 -1
  72. package/dist/git.js +1 -1
  73. package/dist/glob.js +3 -3
  74. package/dist/{go-parser-JXYKJHRC.js → go-parser-IKHW67WE.js} +2 -2
  75. package/dist/grep.js +3 -3
  76. package/dist/index.js +45 -45
  77. package/dist/install.d.ts +51 -2
  78. package/dist/install.js +4 -4
  79. package/dist/{json-parser-IBHZ4BZC.js → json-parser-2EOVP5MR.js} +81 -15
  80. package/dist/kanban.d.ts +19 -1
  81. package/dist/kanban.js +2 -2
  82. package/dist/languages/index.js +2 -2
  83. package/dist/{legacy-bridge-7M6QLUQN.js → legacy-bridge-SFNXIRAP.js} +4 -4
  84. package/dist/lint.js +4 -4
  85. package/dist/logs.js +1 -1
  86. package/dist/outdated.d.ts +25 -1
  87. package/dist/outdated.js +1 -1
  88. package/dist/pack.js +44 -44
  89. package/dist/{parser-dispatch-QH4XPGG6.js → parser-dispatch-X62UWXJS.js} +3 -3
  90. package/dist/patch.js +7 -7
  91. package/dist/plan.js +4 -4
  92. package/dist/{py-parser-IS4HKYMF.js → py-parser-TDXSQZBC.js} +2 -2
  93. package/dist/read.js +7 -7
  94. package/dist/replace.js +7 -7
  95. package/dist/{rs-parser-XHUUO2KZ.js → rs-parser-GIWPUA3T.js} +2 -2
  96. package/dist/scaffold.js +1 -1
  97. package/dist/search.js +1 -1
  98. package/dist/session-kanban.js +1 -1
  99. package/dist/task.js +4 -4
  100. package/dist/test.js +4 -4
  101. package/dist/todo.js +3 -3
  102. package/dist/tool-diff.js +1 -1
  103. package/dist/tool-tier.js +45 -45
  104. package/dist/tool-use.js +1 -1
  105. package/dist/{ts-parser-RCTYKSVI.js → ts-parser-7W26YB26.js} +2 -2
  106. package/dist/typecheck.js +4 -4
  107. package/dist/write.js +7 -7
  108. package/dist/{yaml-parser-4SAXV3PL.js → yaml-parser-RGBXEZE4.js} +2 -2
  109. package/package.json +5 -5
@@ -18,9 +18,9 @@ import {
18
18
  polyglotInvariantEngine,
19
19
  replaceSymbolInFile,
20
20
  runDeadCodeScan
21
- } from "../chunk-JQRIR762.js";
21
+ } from "../chunk-AK2K4KHR.js";
22
22
  import "../chunk-EEOFQDT6.js";
23
- import "../chunk-22B7GE5T.js";
23
+ import "../chunk-ZHH3BEWU.js";
24
24
  import "../chunk-2VSZC6QM.js";
25
25
  import "../chunk-3PVYQFRQ.js";
26
26
  import "../chunk-HFXSNKCV.js";
@@ -45,11 +45,11 @@ import {
45
45
  shutdownCodebaseIndexHost,
46
46
  shutdownCodebaseIndexServer,
47
47
  symbolGraphService
48
- } from "../chunk-QDQY7NQ2.js";
48
+ } from "../chunk-A2PX7M7A.js";
49
49
  import {
50
50
  projectIndexServerEndpoint,
51
51
  projectIndexServerMetadataPath
52
- } from "../chunk-VGBUDLW4.js";
52
+ } from "../chunk-UOXX4SQZ.js";
53
53
  import {
54
54
  CircuitOpenError,
55
55
  IndexCircuitBreaker,
@@ -66,8 +66,8 @@ import {
66
66
  resolveIndexDir,
67
67
  runIndexer,
68
68
  tokenise
69
- } from "../chunk-TRDX25UH.js";
70
- import "../chunk-IYK7XGDZ.js";
69
+ } from "../chunk-TFEGJDH5.js";
70
+ import "../chunk-JJQB6R7Y.js";
71
71
  import "../chunk-ZLTFLC25.js";
72
72
  import "../chunk-A6BRWIXN.js";
73
73
  import "../chunk-UCYQTZ7F.js";
@@ -75,8 +75,8 @@ import {
75
75
  INDEXABLE_EXTENSIONS,
76
76
  detectLang,
77
77
  isIndexablePath
78
- } from "../chunk-TEBQ4VPZ.js";
79
- import "../chunk-LIJQMYYX.js";
78
+ } from "../chunk-YOHO4DVT.js";
79
+ import "../chunk-ELFFQ4RU.js";
80
80
  import "../chunk-V43EQ6VR.js";
81
81
  import "../chunk-D33S4RQG.js";
82
82
  export {
@@ -1,8 +1,12 @@
1
1
  import type { FileSymbols, SymbolLang } from './schema.js';
2
+ /** Soft cap per file (mirrors the 500 caps in generic-parser / tree-sitter,
3
+ * raised because top-level-only extraction yields far fewer candidates). */
4
+ export declare const JSON_MAX_SYMBOLS_DEFAULT = 1000;
2
5
  export declare function parseSymbols(opts: {
3
6
  file: string;
4
7
  content: string;
5
8
  lang: SymbolLang;
9
+ maxSymbols?: number | undefined;
6
10
  }): FileSymbols;
7
11
  export { detectLang } from './languages.js';
8
12
  //# sourceMappingURL=json-parser.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  parseFilesContent
3
- } from "../chunk-IYK7XGDZ.js";
3
+ } from "../chunk-JJQB6R7Y.js";
4
4
  import "../chunk-ZLTFLC25.js";
5
5
  import "../chunk-A6BRWIXN.js";
6
6
  import "../chunk-UCYQTZ7F.js";
7
- import "../chunk-TEBQ4VPZ.js";
7
+ import "../chunk-YOHO4DVT.js";
8
8
  import "../chunk-V43EQ6VR.js";
9
9
 
10
10
  // src/codebase-index/parser-worker-script.ts
@@ -10,7 +10,7 @@ import {
10
10
  projectIndexServerBuildId,
11
11
  projectIndexServerEndpoint,
12
12
  projectIndexServerMetadataPath
13
- } from "../chunk-VGBUDLW4.js";
13
+ } from "../chunk-UOXX4SQZ.js";
14
14
  import {
15
15
  fileGraphService,
16
16
  incomingCallsService,
@@ -22,15 +22,15 @@ import {
22
22
  searchService,
23
23
  statsService,
24
24
  symbolGraphService
25
- } from "../chunk-TRDX25UH.js";
26
- import "../chunk-IYK7XGDZ.js";
25
+ } from "../chunk-TFEGJDH5.js";
26
+ import "../chunk-JJQB6R7Y.js";
27
27
  import "../chunk-ZLTFLC25.js";
28
28
  import "../chunk-A6BRWIXN.js";
29
29
  import "../chunk-UCYQTZ7F.js";
30
30
  import {
31
31
  isIndexablePath
32
- } from "../chunk-TEBQ4VPZ.js";
33
- import "../chunk-LIJQMYYX.js";
32
+ } from "../chunk-YOHO4DVT.js";
33
+ import "../chunk-ELFFQ4RU.js";
34
34
  import "../chunk-V43EQ6VR.js";
35
35
 
36
36
  // src/codebase-index/project-server.ts
@@ -322,6 +322,7 @@ var walMaintenance = new WalMaintenance({
322
322
  const store = indexStorePool.acquire(projectRoot, { indexDir });
323
323
  try {
324
324
  store.optimize();
325
+ store.optimizeFtsIfNeeded();
325
326
  } finally {
326
327
  indexStorePool.release(store);
327
328
  }
@@ -359,6 +360,13 @@ function withWriteMutex(job) {
359
360
  function serverHealth() {
360
361
  const memory = process.memoryUsage();
361
362
  const now = Date.now();
363
+ let watchingClients = 0;
364
+ let oldestClientIdleMs = 0;
365
+ for (const client of clients) {
366
+ if (client.watchExternal) watchingClients++;
367
+ const idle = Math.max(0, now - client.lastSeenAt);
368
+ if (idle > oldestClientIdleMs) oldestClientIdleMs = idle;
369
+ }
362
370
  return {
363
371
  checkedAt: now,
364
372
  uptimeMs: Math.round(process.uptime() * 1e3),
@@ -374,9 +382,9 @@ function serverHealth() {
374
382
  queuedWrites,
375
383
  pendingExternalFiles: externalDebounceTimers.size + externalReadyFiles.size,
376
384
  watchingExternal: externalWatcher !== void 0,
377
- watchingClients: [...clients].filter((client) => client.watchExternal).length,
385
+ watchingClients,
378
386
  clientLeaseTimeoutMs: clientLeaseMs,
379
- oldestClientIdleMs: clients.size > 0 ? Math.max(...[...clients].map((client) => Math.max(0, now - client.lastSeenAt))) : 0,
387
+ oldestClientIdleMs,
380
388
  activity: indexActivity
381
389
  };
382
390
  }
@@ -942,6 +950,37 @@ void (async () => {
942
950
  markMetadataWritten?.();
943
951
  scheduleIdleStop();
944
952
  })();
945
- process.once("SIGINT", () => void stop("SIGINT"));
946
- process.once("SIGTERM", () => void stop("SIGTERM"));
953
+ var SIGNAL_GUARD = /* @__PURE__ */ Symbol.for(
954
+ "wrongstack.codebase-index.project-server.signalGuard"
955
+ );
956
+ var signalGuardStore = globalThis;
957
+ var signalGuard = signalGuardStore[SIGNAL_GUARD];
958
+ if (!signalGuard) {
959
+ let current = async () => void 0;
960
+ let armed = false;
961
+ const handlers = /* @__PURE__ */ new Map();
962
+ const disarm = () => {
963
+ if (!armed) return;
964
+ armed = false;
965
+ for (const [signal, handler] of handlers) process.removeListener(signal, handler);
966
+ handlers.clear();
967
+ };
968
+ signalGuard = {
969
+ arm(next) {
970
+ current = next;
971
+ if (armed) return;
972
+ armed = true;
973
+ for (const signal of ["SIGINT", "SIGTERM"]) {
974
+ const handler = () => {
975
+ disarm();
976
+ void current(signal);
977
+ };
978
+ handlers.set(signal, handler);
979
+ process.on(signal, handler);
980
+ }
981
+ }
982
+ };
983
+ signalGuardStore[SIGNAL_GUARD] = signalGuard;
984
+ }
985
+ signalGuard.arm(stop);
947
986
  //# sourceMappingURL=project-server.js.map
@@ -7,13 +7,13 @@ import {
7
7
  searchService,
8
8
  statsService,
9
9
  symbolGraphService
10
- } from "../chunk-TRDX25UH.js";
11
- import "../chunk-IYK7XGDZ.js";
10
+ } from "../chunk-TFEGJDH5.js";
11
+ import "../chunk-JJQB6R7Y.js";
12
12
  import "../chunk-ZLTFLC25.js";
13
13
  import "../chunk-A6BRWIXN.js";
14
14
  import "../chunk-UCYQTZ7F.js";
15
- import "../chunk-TEBQ4VPZ.js";
16
- import "../chunk-LIJQMYYX.js";
15
+ import "../chunk-YOHO4DVT.js";
16
+ import "../chunk-ELFFQ4RU.js";
17
17
  import "../chunk-V43EQ6VR.js";
18
18
 
19
19
  // src/codebase-index/worker.ts
@@ -13,7 +13,6 @@ export interface BulkSymbolRow {
13
13
  signature: string;
14
14
  docComment: string;
15
15
  scope: string;
16
- text: string;
17
16
  }
18
17
  export declare function bulkInsertSymbolsWithStatement(stmt: PrepareStatement, maxSqlVars: number, rows: BulkSymbolRow[]): void;
19
18
  export declare function bulkInsertFtsWithStatement(stmt: PrepareStatement, maxSqlVars: number, ftsAvailable: boolean, rows: Array<{
@@ -1,5 +1,5 @@
1
1
  export declare const METADATA_TABLE_SQL = "\n CREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n";
2
- export declare const CORE_TABLES_SQL = "\n CREATE TABLE IF NOT EXISTS files (\n file TEXT PRIMARY KEY,\n lang TEXT NOT NULL,\n mtime_ms INTEGER NOT NULL,\n -- Phase 2: xxHash64 of the file's UTF-8 bytes. Empty string when the\n -- indexer hasn't populated it yet (legacy rows, schema repaired by\n -- repairMissingColumns). Compared on incremental re-index so that a\n -- touch or branch-switch that leaves content byte-identical skips the\n -- expensive parse phase entirely (refactoring proposal Phase 2).\n content_hash TEXT NOT NULL DEFAULT '',\n symbol_count INTEGER NOT NULL DEFAULT 0,\n last_indexed INTEGER NOT NULL,\n -- Code Atlas grouping label, computed at index time from the ecosystem's\n -- own manifests (package.json, go.mod, Cargo.toml, \u2026). Stored rather than\n -- re-derived per query because the evidence lives on disk, not in the DB.\n package TEXT NOT NULL DEFAULT ''\n );\n CREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n lang TEXT NOT NULL,\n kind TEXT NOT NULL,\n name TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n col INTEGER NOT NULL,\n signature TEXT NOT NULL DEFAULT '',\n doc_comment TEXT NOT NULL DEFAULT '',\n scope TEXT NOT NULL DEFAULT '',\n text TEXT NOT NULL DEFAULT ''\n );\n";
2
+ export declare const CORE_TABLES_SQL = "\n CREATE TABLE IF NOT EXISTS files (\n file TEXT PRIMARY KEY,\n lang TEXT NOT NULL,\n mtime_ms INTEGER NOT NULL,\n -- Phase 2: xxHash64 of the file's UTF-8 bytes. Empty string when the\n -- indexer hasn't populated it yet (legacy rows, schema repaired by\n -- repairMissingColumns). Compared on incremental re-index so that a\n -- touch or branch-switch that leaves content byte-identical skips the\n -- expensive parse phase entirely (refactoring proposal Phase 2).\n content_hash TEXT NOT NULL DEFAULT '',\n symbol_count INTEGER NOT NULL DEFAULT 0,\n last_indexed INTEGER NOT NULL,\n -- Code Atlas grouping label, computed at index time from the ecosystem's\n -- own manifests (package.json, go.mod, Cargo.toml, \u2026). Stored rather than\n -- re-derived per query because the evidence lives on disk, not in the DB.\n package TEXT NOT NULL DEFAULT ''\n );\n CREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n lang TEXT NOT NULL,\n kind TEXT NOT NULL,\n name TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n col INTEGER NOT NULL,\n signature TEXT NOT NULL DEFAULT '',\n doc_comment TEXT NOT NULL DEFAULT '',\n scope TEXT NOT NULL DEFAULT ''\n );\n";
3
3
  export declare const FILE_INDEX_SQL: readonly ['CREATE INDEX IF NOT EXISTS idx_f_package ON files(package)'];
4
4
  export declare const SYMBOL_INDEX_SQL: readonly ['CREATE INDEX IF NOT EXISTS idx_s_name ON symbols(name)', 'CREATE INDEX IF NOT EXISTS idx_s_kind ON symbols(kind)', 'CREATE INDEX IF NOT EXISTS idx_s_lang ON symbols(lang)', 'CREATE INDEX IF NOT EXISTS idx_s_file ON symbols(file)', 'CREATE INDEX IF NOT EXISTS idx_s_lang_kind ON symbols(lang, kind)', 'CREATE INDEX IF NOT EXISTS idx_s_name_id ON symbols(name, id)'];
5
5
  export declare const REFS_TABLE_SQL = "\n CREATE TABLE IF NOT EXISTS refs (\n id INTEGER PRIMARY KEY,\n from_id INTEGER NOT NULL,\n to_name TEXT NOT NULL,\n to_id INTEGER,\n call_type TEXT NOT NULL,\n line INTEGER NOT NULL,\n lang TEXT NOT NULL DEFAULT '',\n module TEXT,\n to_file TEXT\n );\n";
@@ -25,9 +25,21 @@ export declare class IndexStore {
25
25
  private rollbackWriteTransaction;
26
26
  private seedLangFamilies;
27
27
  private repairMissingColumns;
28
+ /**
29
+ * P4: `symbols.text` duplicated name + signature + doc_comment (~19 MB on
30
+ * the live index) and is derived on demand now. In-place DROP COLUMN — no
31
+ * SCHEMA_VERSION bump, so no wipe-and-reparse. Best-effort: a busy or
32
+ * SQLite-without-DROP-COLUMN open leaves the column in place, where new
33
+ * inserts simply default it to '' and the next open retries.
34
+ */
35
+ private dropDeprecatedSymbolsColumns;
28
36
  private initSchema;
29
37
  private static readonly NEXT_SYMBOL_ID_KEY;
30
38
  private static readonly MAX_SQL_VARS;
39
+ /** P2: persisted FTS-mutation churn counter — see {@link optimizeFtsIfNeeded}. */
40
+ private static readonly FTS_CHURN_KEY;
41
+ /** P4: one-shot marker that the deprecated symbols.text column is gone. */
42
+ private static readonly SYMBOLS_TEXT_DROPPED_KEY;
31
43
  private ensureNextSymbolIdSeeded;
32
44
  private allocateSymbolIds;
33
45
  private invalidateIncomingRefsForFiles;
@@ -95,6 +107,32 @@ export declare class IndexStore {
95
107
  resolveRefsForNames(names: Iterable<string>): number;
96
108
  replaceEmptyFile(meta: FileMeta): void;
97
109
  optimize(): void;
110
+ /**
111
+ * P2: churn-gated FTS5 segment maintenance.
112
+ *
113
+ * FTS5 postings only compact when FTS5 itself merges them: every delete
114
+ * leaves tombstone postings in the segments, and neither VACUUM nor
115
+ * `PRAGMA optimize` reclaims them. Measured on the live index (2026-08-30):
116
+ * one delete+reinsert cycle grew symbols_fts_data 174.9→212.8 MB, while the
117
+ * FTS5 'optimize'/'rebuild' merge resets it (rebuild: 212.9→28.2 MB in
118
+ * 1.26 s for 131k rows). 'optimize' is the recurring command — an
119
+ * incremental merge that discards deleted docs — and only runs once churn
120
+ * crosses the gate, so a clean index never pays for it.
121
+ *
122
+ * Follows the {@link checkpointWal} contract: best-effort, returns whether
123
+ * it ran, safe to call from the daemon's single-threaded idle path.
124
+ */
125
+ optimizeFtsIfNeeded(options?: {
126
+ minChurnRatio?: number;
127
+ minChurnRows?: number;
128
+ }): boolean;
129
+ /**
130
+ * Best-effort churn bookkeeping for {@link optimizeFtsIfNeeded}. Counts the
131
+ * FTS rows a mutation inserts or deletes so the maintenance gate can fire
132
+ * after real churn, not on a timer. Persisted in metadata so the counter
133
+ * survives store open/close cycles in the daemon pool.
134
+ */
135
+ private recordFtsChurn;
98
136
  /**
99
137
  * P4.14: best-effort WAL checkpoint for idle-time maintenance.
100
138
  *
package/dist/diff.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  diffTool
3
- } from "./chunk-UKU2ZX4C.js";
3
+ } from "./chunk-P7ZQ2FAJ.js";
4
4
  import "./chunk-D33S4RQG.js";
5
5
  export {
6
6
  diffTool
package/dist/e2e.d.ts CHANGED
@@ -51,6 +51,45 @@ export declare function discoverE2EProjects(root: string, options: {
51
51
  includeSpecs?: boolean | undefined;
52
52
  signal: AbortSignal;
53
53
  }): Promise<E2EPlanOutput>;
54
- export declare const e2ePlanTool: Tool<E2EPlanInput, E2EPlanOutput>;
54
+ type E2EPlanContext = Parameters<Tool<E2EPlanInput, E2EPlanOutput>['execute']>[1];
55
+ export declare const e2ePlanTool: {
56
+ name: string;
57
+ category: string;
58
+ description: string;
59
+ usageHint: string;
60
+ permission: "auto";
61
+ mutating: false;
62
+ riskTier: "safe";
63
+ capabilities: string[];
64
+ icon: "test";
65
+ timeoutMs: number;
66
+ inputSchema: {
67
+ type: string;
68
+ properties: {
69
+ cwd: {
70
+ type: string;
71
+ description: string;
72
+ };
73
+ framework: {
74
+ type: string;
75
+ enum: string[];
76
+ description: string;
77
+ };
78
+ maxDepth: {
79
+ type: string;
80
+ minimum: number;
81
+ maximum: number;
82
+ description: string;
83
+ };
84
+ includeSpecs: {
85
+ type: string;
86
+ description: string;
87
+ };
88
+ };
89
+ };
90
+ execute(input: E2EPlanInput, ctx: E2EPlanContext, opts?: {
91
+ signal: AbortSignal;
92
+ }): Promise<E2EPlanOutput>;
93
+ };
55
94
  export {};
56
95
  //# sourceMappingURL=e2e.d.ts.map
package/dist/e2e.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  discoverE2EProjects,
3
3
  e2ePlanTool
4
- } from "./chunk-JRJJX3L5.js";
4
+ } from "./chunk-5WNDJHT6.js";
5
5
  import "./chunk-D33S4RQG.js";
6
6
  export {
7
7
  discoverE2EProjects,
package/dist/edit.js CHANGED
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  editTool
3
- } from "./chunk-U6DZWHBA.js";
3
+ } from "./chunk-TDLZIDCY.js";
4
4
  import "./chunk-FQZOHLG3.js";
5
- import "./chunk-QDQY7NQ2.js";
6
- import "./chunk-VGBUDLW4.js";
7
- import "./chunk-TRDX25UH.js";
8
- import "./chunk-IYK7XGDZ.js";
5
+ import "./chunk-A2PX7M7A.js";
6
+ import "./chunk-UOXX4SQZ.js";
7
+ import "./chunk-TFEGJDH5.js";
8
+ import "./chunk-JJQB6R7Y.js";
9
9
  import "./chunk-ZLTFLC25.js";
10
10
  import "./chunk-A6BRWIXN.js";
11
11
  import "./chunk-UCYQTZ7F.js";
12
- import "./chunk-TEBQ4VPZ.js";
13
- import "./chunk-LIJQMYYX.js";
12
+ import "./chunk-YOHO4DVT.js";
13
+ import "./chunk-ELFFQ4RU.js";
14
14
  import "./chunk-V43EQ6VR.js";
15
15
  import "./chunk-D33S4RQG.js";
16
16
  export {
package/dist/exec.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  isExecCommandAllowed,
8
8
  resetDangerBypass,
9
9
  resetExecPolicy
10
- } from "./chunk-T2F4S7U4.js";
10
+ } from "./chunk-WI3VDXHD.js";
11
11
  import "./chunk-BTSFTGIL.js";
12
12
  import "./chunk-NKNOBUBU.js";
13
13
  import "./chunk-2VSZC6QM.js";
package/dist/fetch.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  fetchTool
3
- } from "./chunk-IXMNTNW5.js";
3
+ } from "./chunk-UKGMDCXT.js";
4
4
  import {
5
5
  guardedFetch,
6
6
  guardedLookup
package/dist/format.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Tool } from '@wrongstack/core/types';
1
+ import type { Tool, ToolStreamEvent } from '@wrongstack/core/types';
2
2
  interface FormatInput {
3
3
  files?: string | string[] | undefined;
4
4
  fixer?: 'biome' | 'prettier' | 'auto' | undefined;
@@ -14,6 +14,46 @@ interface FormatOutput {
14
14
  output: string;
15
15
  truncated: boolean;
16
16
  }
17
- export declare const formatTool: Tool<FormatInput, FormatOutput>;
17
+ type FormatContext = Parameters<Tool<FormatInput, FormatOutput>['execute']>[1];
18
+ export declare const formatTool: {
19
+ name: string;
20
+ category: string;
21
+ description: string;
22
+ usageHint: string;
23
+ permission: "confirm";
24
+ subjectKey: string;
25
+ mutating: true;
26
+ capabilities: string[];
27
+ icon: "code";
28
+ timeoutMs: number;
29
+ inputSchema: {
30
+ type: string;
31
+ properties: {
32
+ files: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ fixer: {
37
+ type: string;
38
+ enum: string[];
39
+ description: string;
40
+ };
41
+ check: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ cwd: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ };
50
+ };
51
+ execute(input: FormatInput, ctx: FormatContext, opts?: {
52
+ signal: AbortSignal;
53
+ }): Promise<FormatOutput>;
54
+ executeStream(input: FormatInput, ctx: FormatContext, opts?: {
55
+ signal: AbortSignal;
56
+ }): AsyncGenerator<ToolStreamEvent<FormatOutput>>;
57
+ };
18
58
  export {};
19
59
  //# sourceMappingURL=format.d.ts.map
package/dist/format.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  formatTool
3
- } from "./chunk-SDLVH5RZ.js";
4
- import "./chunk-PQKK5JH7.js";
5
- import "./chunk-OUBDL3WH.js";
6
- import "./chunk-22B7GE5T.js";
3
+ } from "./chunk-3QQSBUXR.js";
4
+ import "./chunk-4E42D7UF.js";
5
+ import "./chunk-SOG7XIRF.js";
6
+ import "./chunk-ZHH3BEWU.js";
7
7
  import "./chunk-2VSZC6QM.js";
8
8
  import "./chunk-3PVYQFRQ.js";
9
9
  import "./chunk-HFXSNKCV.js";
package/dist/git.d.ts CHANGED
@@ -37,6 +37,75 @@ interface GitOutput {
37
37
  */
38
38
  warning?: string | undefined;
39
39
  }
40
- export declare const gitTool: Tool<GitInput, GitOutput>;
40
+ type GitContext = Parameters<Tool<GitInput, GitOutput>['execute']>[1];
41
+ export declare const gitTool: {
42
+ name: string;
43
+ category: string;
44
+ description: string;
45
+ usageHint: string;
46
+ permission: "confirm";
47
+ icon: "git";
48
+ subjectKey: string;
49
+ subjectFields: string[];
50
+ mutating: true;
51
+ capabilities: string[];
52
+ timeoutMs: number;
53
+ inputSchema: {
54
+ type: string;
55
+ properties: {
56
+ command: {
57
+ type: string;
58
+ enum: string[];
59
+ description: string;
60
+ };
61
+ files: {
62
+ type: string;
63
+ description: string;
64
+ };
65
+ message: {
66
+ type: string;
67
+ description: string;
68
+ };
69
+ branch: {
70
+ type: string;
71
+ description: string;
72
+ };
73
+ format: {
74
+ type: string;
75
+ enum: string[];
76
+ description: string;
77
+ };
78
+ limit: {
79
+ type: string;
80
+ description: string;
81
+ };
82
+ dry_run: {
83
+ type: string;
84
+ description: string;
85
+ };
86
+ worktreeAction: {
87
+ type: string;
88
+ enum: string[];
89
+ description: string;
90
+ };
91
+ worktreePath: {
92
+ type: string;
93
+ description: string;
94
+ };
95
+ newBranch: {
96
+ type: string;
97
+ description: string;
98
+ };
99
+ force: {
100
+ type: string;
101
+ description: string;
102
+ };
103
+ };
104
+ required: string[];
105
+ };
106
+ execute(input: GitInput, ctx: GitContext, opts?: {
107
+ signal: AbortSignal;
108
+ }): Promise<GitOutput>;
109
+ };
41
110
  export {};
42
111
  //# sourceMappingURL=git.d.ts.map
package/dist/git.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  gitTool
3
- } from "./chunk-RXISBFR5.js";
3
+ } from "./chunk-ZE6KLBUO.js";
4
4
  import "./chunk-D33S4RQG.js";
5
5
  export {
6
6
  gitTool
package/dist/glob.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  globTool
3
- } from "./chunk-UNSKG6DC.js";
4
- import "./chunk-U4D5S3VQ.js";
5
- import "./chunk-LIJQMYYX.js";
3
+ } from "./chunk-ICAXDRP6.js";
4
+ import "./chunk-NWZ6XGBJ.js";
5
+ import "./chunk-ELFFQ4RU.js";
6
6
  import "./chunk-D33S4RQG.js";
7
7
  export {
8
8
  globTool
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-UCYQTZ7F.js";
5
5
  import {
6
6
  detectLang
7
- } from "./chunk-TEBQ4VPZ.js";
7
+ } from "./chunk-YOHO4DVT.js";
8
8
  import {
9
9
  resolveWin32Command
10
10
  } from "./chunk-V43EQ6VR.js";
@@ -466,4 +466,4 @@ export {
466
466
  detectLang,
467
467
  parseSymbols
468
468
  };
469
- //# sourceMappingURL=go-parser-JXYKJHRC.js.map
469
+ //# sourceMappingURL=go-parser-IKHW67WE.js.map
package/dist/grep.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  __resetRgDetectionForTests,
3
3
  grepTool
4
- } from "./chunk-553IQUMO.js";
4
+ } from "./chunk-S2JRYDYG.js";
5
5
  import "./chunk-Q5JPPCZC.js";
6
- import "./chunk-U4D5S3VQ.js";
7
- import "./chunk-LIJQMYYX.js";
6
+ import "./chunk-NWZ6XGBJ.js";
7
+ import "./chunk-ELFFQ4RU.js";
8
8
  import "./chunk-D33S4RQG.js";
9
9
  export {
10
10
  __resetRgDetectionForTests,