@wrongstack/tools 0.9.20 → 0.10.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 (74) hide show
  1. package/dist/audit.js +2 -2
  2. package/dist/audit.js.map +1 -1
  3. package/dist/bash.js +86 -16
  4. package/dist/bash.js.map +1 -1
  5. package/dist/batch-tool-use.js +2 -2
  6. package/dist/batch-tool-use.js.map +1 -1
  7. package/dist/builtin.js +376 -159
  8. package/dist/builtin.js.map +1 -1
  9. package/dist/codebase-index/index.d.ts +24 -4
  10. package/dist/codebase-index/index.js +32 -23
  11. package/dist/codebase-index/index.js.map +1 -1
  12. package/dist/diff.js +25 -9
  13. package/dist/diff.js.map +1 -1
  14. package/dist/document.js +3 -2
  15. package/dist/document.js.map +1 -1
  16. package/dist/edit.js +3 -2
  17. package/dist/edit.js.map +1 -1
  18. package/dist/exec.js +96 -12
  19. package/dist/exec.js.map +1 -1
  20. package/dist/fetch.js +13 -6
  21. package/dist/fetch.js.map +1 -1
  22. package/dist/format.js +74 -4
  23. package/dist/format.js.map +1 -1
  24. package/dist/git.js +81 -8
  25. package/dist/git.js.map +1 -1
  26. package/dist/glob.js +15 -5
  27. package/dist/glob.js.map +1 -1
  28. package/dist/grep.js +32 -9
  29. package/dist/grep.js.map +1 -1
  30. package/dist/index.js +394 -170
  31. package/dist/index.js.map +1 -1
  32. package/dist/install.js +85 -8
  33. package/dist/install.js.map +1 -1
  34. package/dist/json.js +2 -2
  35. package/dist/json.js.map +1 -1
  36. package/dist/lint.js +74 -4
  37. package/dist/lint.js.map +1 -1
  38. package/dist/logs.js +2 -2
  39. package/dist/logs.js.map +1 -1
  40. package/dist/memory.js +13 -6
  41. package/dist/memory.js.map +1 -1
  42. package/dist/mode.js +4 -4
  43. package/dist/mode.js.map +1 -1
  44. package/dist/outdated.js +2 -2
  45. package/dist/outdated.js.map +1 -1
  46. package/dist/pack.js +377 -160
  47. package/dist/pack.js.map +1 -1
  48. package/dist/patch.js +3 -2
  49. package/dist/patch.js.map +1 -1
  50. package/dist/read.js +16 -5
  51. package/dist/read.js.map +1 -1
  52. package/dist/replace.js +3 -2
  53. package/dist/replace.js.map +1 -1
  54. package/dist/scaffold.js +3 -2
  55. package/dist/scaffold.js.map +1 -1
  56. package/dist/search.js +3 -2
  57. package/dist/search.js.map +1 -1
  58. package/dist/test.js +74 -4
  59. package/dist/test.js.map +1 -1
  60. package/dist/todo.js +21 -7
  61. package/dist/todo.js.map +1 -1
  62. package/dist/tool-help.js +5 -5
  63. package/dist/tool-help.js.map +1 -1
  64. package/dist/tool-search.js +2 -2
  65. package/dist/tool-search.js.map +1 -1
  66. package/dist/tool-use.js +4 -4
  67. package/dist/tool-use.js.map +1 -1
  68. package/dist/tree.js +16 -8
  69. package/dist/tree.js.map +1 -1
  70. package/dist/typecheck.js +74 -4
  71. package/dist/typecheck.js.map +1 -1
  72. package/dist/write.js +11 -4
  73. package/dist/write.js.map +1 -1
  74. package/package.json +2 -2
@@ -6,13 +6,33 @@ import '@wrongstack/core';
6
6
  * SQLite storage layer for the codebase index.
7
7
  *
8
8
  * Uses `node:sqlite` (synchronous API — DatabaseSync class).
9
- * Database file: {projectRoot}/.codebase-index/index.db
9
+ * Database file: ~/.wrongstack/projects/<hash>/codebase-index/index.db — kept
10
+ * out of the repo so it never clutters the working tree or needs gitignoring.
10
11
  */
11
12
 
13
+ /**
14
+ * Resolve the per-project index directory. By default it lives under the
15
+ * global project dir (`~/.wrongstack/projects/<hash>/codebase-index`),
16
+ * matching every other piece of per-project state. Callers may pass an
17
+ * explicit `override` (used by tests and any wiring that already resolved the
18
+ * path) to avoid touching the real home directory.
19
+ */
20
+ declare function resolveIndexDir(projectRoot: string, override?: string): string;
21
+ /**
22
+ * Optional index-directory override carried on the run context's `meta` bag.
23
+ * Production leaves it unset (the index resolves to the global per-project
24
+ * dir); tests and bespoke wiring set `meta.codebaseIndexDir` to redirect it.
25
+ */
26
+ declare function codebaseIndexDirOverride(ctx: {
27
+ meta?: Record<string, unknown>;
28
+ }): string | undefined;
12
29
  declare class IndexStore {
13
- private projectRoot;
14
30
  private db;
15
- constructor(projectRoot: string);
31
+ /** Absolute path to this project's index directory. */
32
+ private readonly indexDir;
33
+ constructor(projectRoot: string, opts?: {
34
+ indexDir?: string;
35
+ });
16
36
  private initSchema;
17
37
  insertSymbols(symbols: Symbol[], nextId: number): number;
18
38
  deleteSymbolsForFile(file: string): void;
@@ -117,4 +137,4 @@ declare function lspKindToInternalKind(k: number): SymbolKind | null;
117
137
  */
118
138
  declare function internalKindToLspKind(k: SymbolKind): number | null;
119
139
 
120
- export { FileMeta, IndexStats, IndexStore, SearchResult, Symbol, SymbolKind, SymbolLang, buildBm25Index, buildIndexableText, internalKindToLspKind, lspKindToInternalKind, tokenise };
140
+ export { FileMeta, IndexStats, IndexStore, SearchResult, Symbol, SymbolKind, SymbolLang, buildBm25Index, buildIndexableText, codebaseIndexDirOverride, internalKindToLspKind, lspKindToInternalKind, resolveIndexDir, tokenise };
@@ -1,6 +1,6 @@
1
1
  import * as fs2 from 'node:fs/promises';
2
2
  import * as path4 from 'node:path';
3
- import { compileGlob } from '@wrongstack/core';
3
+ import { resolveWstackPaths, compileGlob } from '@wrongstack/core';
4
4
  import { createRequire } from 'node:module';
5
5
  import * as fs from 'node:fs';
6
6
  import { mkdirSync, writeFileSync } from 'node:fs';
@@ -81,8 +81,14 @@ function internalKindToLspKind(k) {
81
81
  }
82
82
 
83
83
  // src/codebase-index/writer.ts
84
- var INDEX_DIR = ".codebase-index";
85
84
  var DB_FILE = "index.db";
85
+ function resolveIndexDir(projectRoot, override) {
86
+ return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
87
+ }
88
+ function codebaseIndexDirOverride(ctx) {
89
+ const v = ctx.meta?.["codebaseIndexDir"];
90
+ return typeof v === "string" ? v : void 0;
91
+ }
86
92
  var warningSilenced = false;
87
93
  function silenceSqliteExperimentalWarning() {
88
94
  if (warningSilenced) return;
@@ -110,16 +116,16 @@ function loadDatabaseSync() {
110
116
  return DatabaseSyncCtor;
111
117
  }
112
118
  var IndexStore = class {
113
- constructor(projectRoot) {
114
- this.projectRoot = projectRoot;
115
- const dir = path4.join(projectRoot, INDEX_DIR);
116
- fs.mkdirSync(dir, { recursive: true });
119
+ db;
120
+ /** Absolute path to this project's index directory. */
121
+ indexDir;
122
+ constructor(projectRoot, opts = {}) {
123
+ this.indexDir = resolveIndexDir(projectRoot, opts.indexDir);
124
+ fs.mkdirSync(this.indexDir, { recursive: true });
117
125
  const Database = loadDatabaseSync();
118
- this.db = new Database(path4.join(dir, DB_FILE));
126
+ this.db = new Database(path4.join(this.indexDir, DB_FILE));
119
127
  this.initSchema();
120
128
  }
121
- projectRoot;
122
- db;
123
129
  initSchema() {
124
130
  this.db.exec(`
125
131
  CREATE TABLE IF NOT EXISTS metadata (
@@ -310,7 +316,7 @@ var IndexStore = class {
310
316
  totalFiles,
311
317
  byLang,
312
318
  byKind,
313
- indexPath: path4.join(this.projectRoot, INDEX_DIR),
319
+ indexPath: this.indexDir,
314
320
  lastIndexed,
315
321
  sizeBytes,
316
322
  version: SCHEMA_VERSION
@@ -403,7 +409,7 @@ var IndexStore = class {
403
409
  }));
404
410
  }
405
411
  sizeBytes() {
406
- const dbPath = path4.join(this.projectRoot, INDEX_DIR, DB_FILE);
412
+ const dbPath = path4.join(this.indexDir, DB_FILE);
407
413
  try {
408
414
  return fs.statSync(dbPath).size;
409
415
  } catch {
@@ -1679,8 +1685,8 @@ async function parseFile(file, content, lang) {
1679
1685
  }
1680
1686
  }
1681
1687
  async function runIndexer(_ctx, opts) {
1682
- const { projectRoot, force = false, langs, ignore = [] } = opts;
1683
- const store = new IndexStore(projectRoot);
1688
+ const { projectRoot, force = false, langs, ignore = [], indexDir } = opts;
1689
+ const store = new IndexStore(projectRoot, { indexDir });
1684
1690
  const startMs = Date.now();
1685
1691
  const errors = [];
1686
1692
  const langStats = {};
@@ -1797,8 +1803,8 @@ async function runIndexer(_ctx, opts) {
1797
1803
  var codebaseIndexTool = {
1798
1804
  name: "codebase-index",
1799
1805
  category: "Project",
1800
- description: "Build or update the symbol index for the project. Runs incrementally by default \u2014 only re-indexes files that changed since the last run.",
1801
- usageHint: "Call with `force: true` to wipe and rebuild the index from scratch. Use `langs` to limit to specific languages. First call without arguments to do an incremental index.",
1806
+ description: "Build or incrementally update the project-wide symbol index. This powers fast codebase search and understanding. By default it only processes files that have changed since the last indexing run.",
1807
+ usageHint: "IMPORTANT FOR LARGE CODEBASES:\n\n- First run (or after major changes): consider `force: true` for a clean rebuild.\n- Normal usage: call without arguments for fast incremental updates.\n- Use `langs` to restrict to specific languages if you only care about certain parts of the project.\nThis tool is relatively expensive \u2014 do not call it on every turn. Use it when the index is stale or before heavy codebase-search sessions.",
1802
1808
  permission: "auto",
1803
1809
  mutating: true,
1804
1810
  timeoutMs: 12e4,
@@ -1820,7 +1826,8 @@ var codebaseIndexTool = {
1820
1826
  const result = await runIndexer(ctx, {
1821
1827
  projectRoot: ctx.projectRoot,
1822
1828
  force: input.force ?? false,
1823
- langs: input.langs
1829
+ langs: input.langs,
1830
+ indexDir: codebaseIndexDirOverride(ctx)
1824
1831
  });
1825
1832
  return result;
1826
1833
  }
@@ -1918,10 +1925,11 @@ var Bm25Index = class {
1918
1925
  var codebaseSearchTool = {
1919
1926
  name: "codebase-search",
1920
1927
  category: "Project",
1921
- description: "Search indexed code symbols by name, signature, or doc comment. Uses BM25 ranking for relevance.",
1922
- usageHint: "Pass `query` for keyword search. Filter with `kind` (class/function/interface/etc), `lang` (ts/js/etc), `file` (substring). `limit` caps results (default 20).",
1928
+ description: "Semantic/keyword search over the indexed codebase symbols (functions, classes, interfaces, etc.). Uses BM25 ranking. Much more powerful and structured than raw `grep` for finding code by name or concept.",
1929
+ usageHint: "PREFERRED FOR CODE UNDERSTANDING:\n\n- Use when you need to find where something is defined or used by name.\n- `kind` filter is very useful (e.g. only functions or only interfaces).\n- Combine with `file` filter to scope to a specific directory or module.\nThis is generally better than `grep` when you are looking for symbols rather than arbitrary text patterns.",
1923
1930
  permission: "auto",
1924
1931
  mutating: false,
1932
+ capabilities: ["fs.read"],
1925
1933
  timeoutMs: 1e4,
1926
1934
  inputSchema: {
1927
1935
  type: "object",
@@ -1956,7 +1964,7 @@ var codebaseSearchTool = {
1956
1964
  required: ["query"]
1957
1965
  },
1958
1966
  async execute(input, ctx) {
1959
- const store = new IndexStore(ctx.projectRoot);
1967
+ const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
1960
1968
  try {
1961
1969
  const limit = Math.min(input.limit ?? 20, 100);
1962
1970
  const candidates = store.search(input.query, {
@@ -2001,10 +2009,11 @@ var codebaseSearchTool = {
2001
2009
  var codebaseStatsTool = {
2002
2010
  name: "codebase-stats",
2003
2011
  category: "Project",
2004
- description: "Return statistics about the symbol index: total symbols, files, breakdown by language and kind, index size, and last update time.",
2005
- usageHint: "No arguments needed. Use to check if the index is stale or healthy before running a search.",
2012
+ description: "Return health and statistics about the current symbol index (total symbols, files, language/kind breakdown, size, last update). Useful to decide whether to re-index.",
2013
+ usageHint: "CALL BEFORE HEAVY CODEBASE-SEARCH WORK:\n\n- Use to see if the index is up-to-date or needs a refresh.\n- No arguments required.\n- Helps avoid wasting tokens on searches against a stale index.\nLightweight and safe to call frequently.",
2006
2014
  permission: "auto",
2007
2015
  mutating: false,
2016
+ capabilities: ["fs.read"],
2008
2017
  timeoutMs: 5e3,
2009
2018
  inputSchema: {
2010
2019
  type: "object",
@@ -2012,7 +2021,7 @@ var codebaseStatsTool = {
2012
2021
  additionalProperties: false
2013
2022
  },
2014
2023
  async execute(_input, ctx) {
2015
- const store = new IndexStore(ctx.projectRoot);
2024
+ const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
2016
2025
  try {
2017
2026
  const stats = store.getStats();
2018
2027
  return {
@@ -2031,6 +2040,6 @@ var codebaseStatsTool = {
2031
2040
  }
2032
2041
  };
2033
2042
 
2034
- export { IndexStore, SCHEMA_VERSION, buildBm25Index, buildIndexableText, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, internalKindToLspKind, lspKindToInternalKind, tokenise };
2043
+ export { IndexStore, SCHEMA_VERSION, buildBm25Index, buildIndexableText, codebaseIndexDirOverride, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, internalKindToLspKind, lspKindToInternalKind, resolveIndexDir, tokenise };
2035
2044
  //# sourceMappingURL=index.js.map
2036
2045
  //# sourceMappingURL=index.js.map