@wrongstack/tools 0.303.0 → 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.
@@ -2713,6 +2713,86 @@ import {
2713
2713
  isFrugalPerf
2714
2714
  } from "@wrongstack/core/utils";
2715
2715
 
2716
+ // src/codebase-index/content-hash.ts
2717
+ var PRIME64_1 = 0x9e3779b185ebca87n;
2718
+ var PRIME64_2 = 0xc2b2ae3d27d4eb4fn;
2719
+ var PRIME64_3 = 0x165667b19e3779f9n;
2720
+ var PRIME64_4 = 0x85ebca77c2b2ae63n;
2721
+ var PRIME64_5 = 0x27d4eb2f165667c5n;
2722
+ var MASK64 = 0xffffffffffffffffn;
2723
+ function mul64(a, b) {
2724
+ return (a & MASK64) * (b & MASK64) & MASK64;
2725
+ }
2726
+ function rotl64(x, n) {
2727
+ const v = x & MASK64;
2728
+ return (v << BigInt(n) | v >> BigInt(64 - n)) & MASK64;
2729
+ }
2730
+ function readU64LE(buf, off) {
2731
+ let v = 0n;
2732
+ for (let i = 7; i >= 0; i--) {
2733
+ v = v << 8n | BigInt(buf[off + i] ?? 0);
2734
+ }
2735
+ return v & MASK64;
2736
+ }
2737
+ function readU32LE(buf, off) {
2738
+ return (BigInt(buf[off] ?? 0) | BigInt(buf[off + 1] ?? 0) << 8n | BigInt(buf[off + 2] ?? 0) << 16n | BigInt(buf[off + 3] ?? 0) << 24n) & MASK64;
2739
+ }
2740
+ function xxh64Round(acc, lane) {
2741
+ return mul64(rotl64(acc + mul64(lane, PRIME64_2) & MASK64, 31), PRIME64_1);
2742
+ }
2743
+ function xxh64MergeRound(acc, val) {
2744
+ return mul64(acc ^ xxh64Round(0n, val), PRIME64_1) + PRIME64_4 & MASK64;
2745
+ }
2746
+ function xxhash64Hex(buf, explicitLen) {
2747
+ const length = explicitLen ?? buf.length;
2748
+ let h;
2749
+ let off = 0;
2750
+ if (length >= 32) {
2751
+ let v1 = PRIME64_1 + PRIME64_2 & MASK64;
2752
+ let v2 = PRIME64_2;
2753
+ let v3 = 0n;
2754
+ let v4 = 0n - PRIME64_1 & MASK64;
2755
+ const end32 = length - 32;
2756
+ while (off <= end32) {
2757
+ v1 = xxh64Round(v1, readU64LE(buf, off));
2758
+ v2 = xxh64Round(v2, readU64LE(buf, off + 8));
2759
+ v3 = xxh64Round(v3, readU64LE(buf, off + 16));
2760
+ v4 = xxh64Round(v4, readU64LE(buf, off + 24));
2761
+ off += 32;
2762
+ }
2763
+ h = rotl64(v1, 1) + rotl64(v2, 7) + rotl64(v3, 12) + rotl64(v4, 18) & MASK64;
2764
+ h = xxh64MergeRound(h, v1);
2765
+ h = xxh64MergeRound(h, v2);
2766
+ h = xxh64MergeRound(h, v3);
2767
+ h = xxh64MergeRound(h, v4);
2768
+ } else {
2769
+ h = PRIME64_5;
2770
+ }
2771
+ h = h + BigInt(length) & MASK64;
2772
+ while (off + 8 <= length) {
2773
+ const k1 = xxh64Round(0n, readU64LE(buf, off));
2774
+ h = mul64(rotl64(h ^ k1, 27), PRIME64_1) + PRIME64_4 & MASK64;
2775
+ off += 8;
2776
+ }
2777
+ if (off + 4 <= length) {
2778
+ h = mul64(rotl64(h ^ mul64(readU32LE(buf, off), PRIME64_1), 23), PRIME64_2) + PRIME64_3 & MASK64;
2779
+ off += 4;
2780
+ }
2781
+ while (off < length) {
2782
+ h = mul64(rotl64(h ^ mul64(BigInt(buf[off] ?? 0), PRIME64_5), 11), PRIME64_1) & MASK64;
2783
+ off += 1;
2784
+ }
2785
+ h = (h ^ h >> 33n) & MASK64;
2786
+ h = mul64(h, PRIME64_2);
2787
+ h = (h ^ h >> 29n) & MASK64;
2788
+ h = mul64(h, PRIME64_3);
2789
+ h = (h ^ h >> 32n) & MASK64;
2790
+ return h.toString(16).padStart(16, "0");
2791
+ }
2792
+ function xxhash64String(content) {
2793
+ return xxhash64Hex(new TextEncoder().encode(content));
2794
+ }
2795
+
2716
2796
  // src/codebase-index/gitignore.ts
2717
2797
  import * as fs from "node:fs/promises";
2718
2798
  import * as path from "node:path";
@@ -3744,86 +3824,6 @@ function getParserPool() {
3744
3824
  return _pool;
3745
3825
  }
3746
3826
 
3747
- // src/codebase-index/content-hash.ts
3748
- var PRIME64_1 = 0x9e3779b185ebca87n;
3749
- var PRIME64_2 = 0xc2b2ae3d27d4eb4fn;
3750
- var PRIME64_3 = 0x165667b19e3779f9n;
3751
- var PRIME64_4 = 0x85ebca77c2b2ae63n;
3752
- var PRIME64_5 = 0x27d4eb2f165667c5n;
3753
- var MASK64 = 0xffffffffffffffffn;
3754
- function mul64(a, b) {
3755
- return (a & MASK64) * (b & MASK64) & MASK64;
3756
- }
3757
- function rotl64(x, n) {
3758
- const v = x & MASK64;
3759
- return (v << BigInt(n) | v >> BigInt(64 - n)) & MASK64;
3760
- }
3761
- function readU64LE(buf, off) {
3762
- let v = 0n;
3763
- for (let i = 7; i >= 0; i--) {
3764
- v = v << 8n | BigInt(buf[off + i] ?? 0);
3765
- }
3766
- return v & MASK64;
3767
- }
3768
- function readU32LE(buf, off) {
3769
- return (BigInt(buf[off] ?? 0) | BigInt(buf[off + 1] ?? 0) << 8n | BigInt(buf[off + 2] ?? 0) << 16n | BigInt(buf[off + 3] ?? 0) << 24n) & MASK64;
3770
- }
3771
- function xxh64Round(acc, lane) {
3772
- return mul64(rotl64(acc + mul64(lane, PRIME64_2) & MASK64, 31), PRIME64_1);
3773
- }
3774
- function xxh64MergeRound(acc, val) {
3775
- return mul64(acc ^ xxh64Round(0n, val), PRIME64_1) + PRIME64_4 & MASK64;
3776
- }
3777
- function xxhash64Hex(buf, explicitLen) {
3778
- const length = explicitLen ?? buf.length;
3779
- let h;
3780
- let off = 0;
3781
- if (length >= 32) {
3782
- let v1 = PRIME64_1 + PRIME64_2 & MASK64;
3783
- let v2 = PRIME64_2;
3784
- let v3 = 0n;
3785
- let v4 = 0n - PRIME64_1 & MASK64;
3786
- const end32 = length - 32;
3787
- while (off <= end32) {
3788
- v1 = xxh64Round(v1, readU64LE(buf, off));
3789
- v2 = xxh64Round(v2, readU64LE(buf, off + 8));
3790
- v3 = xxh64Round(v3, readU64LE(buf, off + 16));
3791
- v4 = xxh64Round(v4, readU64LE(buf, off + 24));
3792
- off += 32;
3793
- }
3794
- h = rotl64(v1, 1) + rotl64(v2, 7) + rotl64(v3, 12) + rotl64(v4, 18) & MASK64;
3795
- h = xxh64MergeRound(h, v1);
3796
- h = xxh64MergeRound(h, v2);
3797
- h = xxh64MergeRound(h, v3);
3798
- h = xxh64MergeRound(h, v4);
3799
- } else {
3800
- h = PRIME64_5;
3801
- }
3802
- h = h + BigInt(length) & MASK64;
3803
- while (off + 8 <= length) {
3804
- const k1 = xxh64Round(0n, readU64LE(buf, off));
3805
- h = mul64(rotl64(h ^ k1, 27), PRIME64_1) + PRIME64_4 & MASK64;
3806
- off += 8;
3807
- }
3808
- if (off + 4 <= length) {
3809
- h = mul64(rotl64(h ^ mul64(readU32LE(buf, off), PRIME64_1), 23), PRIME64_2) + PRIME64_3 & MASK64;
3810
- off += 4;
3811
- }
3812
- while (off < length) {
3813
- h = mul64(rotl64(h ^ mul64(BigInt(buf[off] ?? 0), PRIME64_5), 11), PRIME64_1) & MASK64;
3814
- off += 1;
3815
- }
3816
- h = (h ^ h >> 33n) & MASK64;
3817
- h = mul64(h, PRIME64_2);
3818
- h = (h ^ h >> 29n) & MASK64;
3819
- h = mul64(h, PRIME64_3);
3820
- h = (h ^ h >> 32n) & MASK64;
3821
- return h.toString(16).padStart(16, "0");
3822
- }
3823
- function xxhash64String(content) {
3824
- return xxhash64Hex(new TextEncoder().encode(content));
3825
- }
3826
-
3827
3827
  // src/codebase-index/writer.ts
3828
3828
  import { expectDefined as expectDefined4 } from "@wrongstack/core/utils";
3829
3829
  import * as fs8 from "node:fs";
@@ -5413,7 +5413,7 @@ var IndexStore = class _IndexStore {
5413
5413
  const ftsSchema = this.stmt(
5414
5414
  "SELECT sql FROM sqlite_master WHERE type='table' AND name='symbols_fts'"
5415
5415
  ).get();
5416
- if (ftsSchema?.sql && ftsSchema.sql.includes("unicode61")) {
5416
+ if (ftsSchema?.sql?.includes("unicode61")) {
5417
5417
  this.db.exec("DROP TABLE IF EXISTS symbols_fts");
5418
5418
  }
5419
5419
  this.db.exec(SYMBOLS_FTS_SQL);
@@ -5906,9 +5906,13 @@ var IndexStore = class _IndexStore {
5906
5906
  sim: cosineSimilarity(queryVec, decodeVector(r.vector))
5907
5907
  })).sort((a, b) => b.sim - a.sim);
5908
5908
  const bm25Rank = /* @__PURE__ */ new Map();
5909
- bm25Rows.forEach((r, i) => bm25Rank.set(r.id, i));
5909
+ bm25Rows.forEach((r, i) => {
5910
+ bm25Rank.set(r.id, i);
5911
+ });
5910
5912
  const vecRank = /* @__PURE__ */ new Map();
5911
- vecScores.forEach((r, i) => vecRank.set(r.id, i));
5913
+ vecScores.forEach((r, i) => {
5914
+ vecRank.set(r.id, i);
5915
+ });
5912
5916
  const fused = reciprocalRankFusion(bm25Rank, vecRank, 60);
5913
5917
  const fusedScore = new Map(fused);
5914
5918
  const sorted = [...bm25Rows].sort(
@@ -6518,6 +6522,9 @@ var YIELD_EVERY_N = 50;
6518
6522
  function resolveParallelBatch() {
6519
6523
  return indexParallelBatchSize(availableParallelism());
6520
6524
  }
6525
+ function shouldUseParserWorkerPool(candidateFileCount, parseBatchCount) {
6526
+ return !isFrugalPerf() && candidateFileCount >= WORKER_POOL_THRESHOLD && parseBatchCount > 1;
6527
+ }
6521
6528
  function yieldEventLoop() {
6522
6529
  return new Promise((resolve2) => setImmediate(resolve2));
6523
6530
  }
@@ -6694,11 +6701,7 @@ async function resolveProjectRelations(store, projectRoot, opts) {
6694
6701
  const structure = await detectModuleRoots(projectRoot, indexedFiles);
6695
6702
  if (opts.signal?.aborted) return;
6696
6703
  store.setFilePackages(assignPackageLabels(structure, indexedFiles));
6697
- const resolver = new ModuleResolver(
6698
- structure,
6699
- indexedFiles,
6700
- store.getNamespaceDeclarations()
6701
- );
6704
+ const resolver = new ModuleResolver(structure, indexedFiles, store.getNamespaceDeclarations());
6702
6705
  const pending = store.getUnresolvedImports(opts.onlyFiles);
6703
6706
  const resolutions = [];
6704
6707
  for (const entry of pending) {
@@ -6723,6 +6726,10 @@ async function runIndexerWithStore(store, opts) {
6723
6726
  const errors = [];
6724
6727
  const langStats = {};
6725
6728
  let filesIndexed = 0;
6729
+ let filesParsed = 0;
6730
+ let filesSkipped = 0;
6731
+ let filesEmpty = 0;
6732
+ let filesFailed = 0;
6726
6733
  let symbolsIndexed = 0;
6727
6734
  const isGitIgnored = await loadGitignoreMatcher(projectRoot);
6728
6735
  let files;
@@ -6764,12 +6771,14 @@ async function runIndexerWithStore(store, opts) {
6764
6771
  langStats[meta.lang] = (langStats[meta.lang] ?? 0) + meta.symbolCount;
6765
6772
  symbolsIndexed += meta.symbolCount;
6766
6773
  filesIndexed++;
6774
+ filesSkipped++;
6767
6775
  filesPreSkipped++;
6768
6776
  return false;
6769
6777
  });
6770
6778
  if (filesPreSkipped > 0) opts.onProgress?.(filesPreSkipped, totalFilesForProgress);
6771
6779
  }
6772
6780
  const parallelBatch = resolveParallelBatch();
6781
+ const parserPoolCandidateCount = files.length;
6773
6782
  let filesSinceLastYield = 0;
6774
6783
  for (let batchStart = 0; batchStart < files.length; batchStart += parallelBatch) {
6775
6784
  const batchEnd = Math.min(batchStart + parallelBatch, files.length);
@@ -6862,7 +6871,7 @@ async function runIndexerWithStore(store, opts) {
6862
6871
  });
6863
6872
  }
6864
6873
  if (toParse.length > 0) {
6865
- let pool = toParse.length >= WORKER_POOL_THRESHOLD ? getParserPool() : null;
6874
+ let pool = shouldUseParserWorkerPool(parserPoolCandidateCount, toParse.length) ? getParserPool() : null;
6866
6875
  if (pool) {
6867
6876
  try {
6868
6877
  await pool.ensureReady();
@@ -6912,12 +6921,14 @@ async function runIndexerWithStore(store, opts) {
6912
6921
  const err = settled.reason;
6913
6922
  if (err instanceof Error && isAbortError(err)) throw err;
6914
6923
  errors.push(`batch error: ${file}: ${err instanceof Error ? err.message : String(err)}`);
6924
+ filesFailed++;
6915
6925
  continue;
6916
6926
  }
6917
6927
  const result = settled.value;
6918
6928
  if (result.error) {
6919
6929
  if (result.missing) store.deleteFile(file);
6920
6930
  errors.push(`${file}: ${result.error}`);
6931
+ filesFailed++;
6921
6932
  continue;
6922
6933
  }
6923
6934
  const { stat: stat2, lang, parsed } = result;
@@ -6925,6 +6936,7 @@ async function runIndexerWithStore(store, opts) {
6925
6936
  langStats[lang] = (langStats[lang] ?? 0) + result.skippedMeta.symbolCount;
6926
6937
  symbolsIndexed += result.skippedMeta.symbolCount;
6927
6938
  filesIndexed++;
6939
+ filesSkipped++;
6928
6940
  const stored = existingMeta.get(file);
6929
6941
  if (stored && stored.mtimeMs !== result.skippedMeta.mtimeMs) {
6930
6942
  store.upsertFile({
@@ -6949,6 +6961,7 @@ async function runIndexerWithStore(store, opts) {
6949
6961
  contentHash: result.contentHash ?? ""
6950
6962
  });
6951
6963
  filesIndexed++;
6964
+ filesEmpty++;
6952
6965
  }
6953
6966
  continue;
6954
6967
  }
@@ -6962,6 +6975,7 @@ async function runIndexerWithStore(store, opts) {
6962
6975
  contentHash: result.contentHash ?? ""
6963
6976
  });
6964
6977
  filesIndexed++;
6978
+ filesEmpty++;
6965
6979
  continue;
6966
6980
  }
6967
6981
  batchEntries.push({
@@ -6983,6 +6997,7 @@ async function runIndexerWithStore(store, opts) {
6983
6997
  symbolsIndexed += count;
6984
6998
  langStats[entry.lang] = (langStats[entry.lang] ?? 0) + count;
6985
6999
  filesIndexed++;
7000
+ filesParsed++;
6986
7001
  }
6987
7002
  } catch (err) {
6988
7003
  const message = err instanceof Error ? err.message : String(err);
@@ -6995,6 +7010,7 @@ async function runIndexerWithStore(store, opts) {
6995
7010
  symbolsIndexed += symbolsWithIds.length;
6996
7011
  langStats[entry.lang] = (langStats[entry.lang] ?? 0) + symbolsWithIds.length;
6997
7012
  filesIndexed++;
7013
+ filesParsed++;
6998
7014
  if (entry.refs.length > 0 && symbolsWithIds.length > 0) {
6999
7015
  const fallbackBatch = assignRefsToSymbols2(entry.refs, symbolsWithIds);
7000
7016
  if (fallbackBatch.length > 0) store.insertRefsBatch(fallbackBatch);
@@ -7012,6 +7028,7 @@ async function runIndexerWithStore(store, opts) {
7012
7028
  contentHash: entry.contentHash
7013
7029
  });
7014
7030
  } catch (innerErr) {
7031
+ filesFailed++;
7015
7032
  errors.push(
7016
7033
  `fallback write failed: ${entry.file}: ${innerErr instanceof Error ? innerErr.message : String(innerErr)}`
7017
7034
  );
@@ -7044,6 +7061,12 @@ async function runIndexerWithStore(store, opts) {
7044
7061
  const durationMs = Date.now() - startMs;
7045
7062
  return {
7046
7063
  filesIndexed,
7064
+ fileOutcomes: {
7065
+ parsed: filesParsed,
7066
+ skipped: filesSkipped,
7067
+ empty: filesEmpty,
7068
+ failed: filesFailed
7069
+ },
7047
7070
  symbolsIndexed,
7048
7071
  langStats,
7049
7072
  durationMs,
package/dist/index.d.ts CHANGED
@@ -5,10 +5,10 @@ export { auditTool } from './audit.js';
5
5
  export { bashTool } from './bash.js';
6
6
  export { batchToolUseTool } from './batch-tool-use.js';
7
7
  export * from './browser/index.js';
8
- export { builtinTools, OPTIONAL_TOOLS, TIER1_TOOLS, TIER2_TOOLS, TIER3_TOOLS } from './builtin.js';
8
+ export { builtinTools, OFF_ONLY_TOOLS, OPTIONAL_TOOLS, TIER1_TOOLS, TIER2_TOOLS, TIER3_TOOLS, } from './builtin.js';
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
- export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, resolveProjectIndexDaemonAvailability, codebaseIndexStats, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
11
+ export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, codebaseIndexStats, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, resolveProjectIndexDaemonAvailability, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
12
12
  export { designTool } from './design.js';
13
13
  export { diffTool } from './diff.js';
14
14
  export { documentTool } from './document.js';
@@ -43,7 +43,7 @@ export { readTool } from './read.js';
43
43
  export { replaceTool } from './replace.js';
44
44
  export { scaffoldTool } from './scaffold.js';
45
45
  export { searchTool } from './search.js';
46
- export { applySessionKanbanBoardToTodos, applySessionKanbanTaskToSource, attachSessionKanbanMirror, ensureSessionKanbanBoard, hydrateSessionKanban, mirrorSessionPlanToKanban, mirrorSessionTasksToKanban, mirrorSessionTodosToKanban, projectSessionPlanToKanban, projectSessionTasksToKanban, projectSessionTodosToKanban, SESSION_KANBAN_COLUMNS, } from './session-kanban.js';
46
+ export { applySessionKanbanBoardToTodos, applySessionKanbanTaskToSource, attachSessionKanbanMirror, ensureSessionKanbanBoard, hydrateSessionKanban, mirrorSessionPlanToKanban, mirrorSessionTasksToKanban, mirrorSessionTodosToKanban, projectSessionPlanToKanban, projectSessionTasksToKanban, projectSessionTodosToKanban, rebindSessionKanbanTask, SESSION_KANBAN_COLUMNS, } from './session-kanban.js';
47
47
  export { makeSkillTool } from './skill.js';
48
48
  export { taskTool } from './task.js';
49
49
  export { testTool } from './test.js';