@ngommans/codefocus 0.1.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.

Potentially problematic release.


This version of @ngommans/codefocus might be problematic. Click here for more details.

Files changed (40) hide show
  1. package/README.md +124 -0
  2. package/dist/benchmark-43DOYNYR.js +465 -0
  3. package/dist/benchmark-43DOYNYR.js.map +1 -0
  4. package/dist/chunk-6XH2ZLP6.js +127 -0
  5. package/dist/chunk-6XH2ZLP6.js.map +1 -0
  6. package/dist/chunk-7RYHZOYF.js +27 -0
  7. package/dist/chunk-7RYHZOYF.js.map +1 -0
  8. package/dist/chunk-ITVAEU6K.js +250 -0
  9. package/dist/chunk-ITVAEU6K.js.map +1 -0
  10. package/dist/chunk-Q6DOBQ4F.js +231 -0
  11. package/dist/chunk-Q6DOBQ4F.js.map +1 -0
  12. package/dist/chunk-X7DRJUEX.js +543 -0
  13. package/dist/chunk-X7DRJUEX.js.map +1 -0
  14. package/dist/cli.js +111 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/commands-ICBN54MT.js +64 -0
  17. package/dist/commands-ICBN54MT.js.map +1 -0
  18. package/dist/config-OCBWYENF.js +12 -0
  19. package/dist/config-OCBWYENF.js.map +1 -0
  20. package/dist/extended-benchmark-5RUXDG3D.js +323 -0
  21. package/dist/extended-benchmark-5RUXDG3D.js.map +1 -0
  22. package/dist/find-W5UDE4US.js +63 -0
  23. package/dist/find-W5UDE4US.js.map +1 -0
  24. package/dist/graph-DZNBEATA.js +189 -0
  25. package/dist/graph-DZNBEATA.js.map +1 -0
  26. package/dist/map-6WOMDLCP.js +131 -0
  27. package/dist/map-6WOMDLCP.js.map +1 -0
  28. package/dist/mcp-7WYTXIQS.js +354 -0
  29. package/dist/mcp-7WYTXIQS.js.map +1 -0
  30. package/dist/mcp-server.js +369 -0
  31. package/dist/mcp-server.js.map +1 -0
  32. package/dist/query-DJNWYYJD.js +427 -0
  33. package/dist/query-DJNWYYJD.js.map +1 -0
  34. package/dist/query-PS6QVPXP.js +538 -0
  35. package/dist/query-PS6QVPXP.js.map +1 -0
  36. package/dist/root-ODTOXM2J.js +10 -0
  37. package/dist/root-ODTOXM2J.js.map +1 -0
  38. package/dist/watcher-LFBZAM5E.js +73 -0
  39. package/dist/watcher-LFBZAM5E.js.map +1 -0
  40. package/package.json +61 -0
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ indexProject
4
+ } from "./chunk-X7DRJUEX.js";
5
+ import "./chunk-Q6DOBQ4F.js";
6
+
7
+ // src/watcher.ts
8
+ import { extname } from "path";
9
+ import { execFileSync } from "child_process";
10
+ var TS_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
11
+ var IGNORE_PATTERNS = [
12
+ "**/node_modules/**",
13
+ "**/dist/**",
14
+ "**/.codefocus/**",
15
+ "**/__tests__/**",
16
+ "**/*.test.*",
17
+ "**/*.spec.*",
18
+ "**/*.d.ts"
19
+ ];
20
+ async function startWatcher(options) {
21
+ const { rootDir, dbPath, onReindex, debounceMs = 300 } = options;
22
+ const chokidar = await import("chokidar");
23
+ let debounceTimer = null;
24
+ let isIndexing = false;
25
+ const watcher = chokidar.watch("**/*.{ts,tsx,js,jsx}", {
26
+ cwd: rootDir,
27
+ ignored: IGNORE_PATTERNS,
28
+ ignoreInitial: true,
29
+ persistent: true
30
+ });
31
+ function scheduleReindex() {
32
+ if (debounceTimer) clearTimeout(debounceTimer);
33
+ debounceTimer = setTimeout(async () => {
34
+ if (isIndexing) return;
35
+ isIndexing = true;
36
+ try {
37
+ const stats = await indexProject(rootDir, dbPath);
38
+ onReindex?.(stats);
39
+ } catch (err) {
40
+ const message = err instanceof Error ? err.message : String(err);
41
+ console.error(`[watch] Re-index error: ${message}`);
42
+ } finally {
43
+ isIndexing = false;
44
+ }
45
+ }, debounceMs);
46
+ }
47
+ watcher.on("add", (_path) => scheduleReindex());
48
+ watcher.on("change", (_path) => scheduleReindex());
49
+ watcher.on("unlink", (_path) => scheduleReindex());
50
+ return {
51
+ close() {
52
+ if (debounceTimer) clearTimeout(debounceTimer);
53
+ watcher.close();
54
+ }
55
+ };
56
+ }
57
+ function getGitChangedFiles(rootDir) {
58
+ try {
59
+ const result = execFileSync("git", ["diff", "--name-only", "HEAD"], {
60
+ cwd: rootDir,
61
+ encoding: "utf-8",
62
+ timeout: 1e4
63
+ });
64
+ return result.trim().split("\n").filter((f) => f && TS_EXTENSIONS.has(extname(f)));
65
+ } catch {
66
+ return [];
67
+ }
68
+ }
69
+ export {
70
+ getGitChangedFiles,
71
+ startWatcher
72
+ };
73
+ //# sourceMappingURL=watcher-LFBZAM5E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/watcher.ts"],"sourcesContent":["import { resolve, extname } from \"node:path\";\nimport { execFileSync } from \"node:child_process\";\nimport { indexProject, type IndexStats } from \"./indexer.js\";\n\nconst TS_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\"]);\nconst IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/.codefocus/**\",\n \"**/__tests__/**\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/*.d.ts\",\n];\n\nexport interface WatcherOptions {\n rootDir: string;\n dbPath: string;\n /** Callback invoked after each re-index */\n onReindex?: (stats: IndexStats) => void;\n /** Debounce delay in ms (default: 300) */\n debounceMs?: number;\n}\n\nexport interface Watcher {\n /** Stop watching and clean up */\n close(): void;\n}\n\n/**\n * Watch for file changes and trigger incremental re-indexing.\n * Uses chokidar for reliable cross-platform file system watching.\n * Changes are debounced to avoid re-indexing on every keystroke.\n */\nexport async function startWatcher(options: WatcherOptions): Promise<Watcher> {\n const { rootDir, dbPath, onReindex, debounceMs = 300 } = options;\n\n const chokidar = await import(\"chokidar\");\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let isIndexing = false;\n\n const watcher = chokidar.watch(\"**/*.{ts,tsx,js,jsx}\", {\n cwd: rootDir,\n ignored: IGNORE_PATTERNS,\n ignoreInitial: true,\n persistent: true,\n });\n\n function scheduleReindex(): void {\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(async () => {\n if (isIndexing) return;\n isIndexing = true;\n try {\n const stats = await indexProject(rootDir, dbPath);\n onReindex?.(stats);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[watch] Re-index error: ${message}`);\n } finally {\n isIndexing = false;\n }\n }, debounceMs);\n }\n\n watcher.on(\"add\", (_path: string) => scheduleReindex());\n watcher.on(\"change\", (_path: string) => scheduleReindex());\n watcher.on(\"unlink\", (_path: string) => scheduleReindex());\n\n return {\n close() {\n if (debounceTimer) clearTimeout(debounceTimer);\n watcher.close();\n },\n };\n}\n\n/**\n * Get list of files changed since last git commit.\n * Useful for git-hook-triggered incremental re-indexing.\n */\nexport function getGitChangedFiles(rootDir: string): string[] {\n try {\n const result = execFileSync(\"git\", [\"diff\", \"--name-only\", \"HEAD\"], {\n cwd: rootDir,\n encoding: \"utf-8\",\n timeout: 10_000,\n });\n\n return result\n .trim()\n .split(\"\\n\")\n .filter((f) => f && TS_EXTENSIONS.has(extname(f)));\n } catch {\n return [];\n }\n}\n"],"mappings":";;;;;;;AAAA,SAAkB,eAAe;AACjC,SAAS,oBAAoB;AAG7B,IAAM,gBAAgB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAC5D,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqBA,eAAsB,aAAa,SAA2C;AAC5E,QAAM,EAAE,SAAS,QAAQ,WAAW,aAAa,IAAI,IAAI;AAEzD,QAAM,WAAW,MAAM,OAAO,UAAU;AAExC,MAAI,gBAAsD;AAC1D,MAAI,aAAa;AAEjB,QAAM,UAAU,SAAS,MAAM,wBAAwB;AAAA,IACrD,KAAK;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IACf,YAAY;AAAA,EACd,CAAC;AAED,WAAS,kBAAwB;AAC/B,QAAI,cAAe,cAAa,aAAa;AAC7C,oBAAgB,WAAW,YAAY;AACrC,UAAI,WAAY;AAChB,mBAAa;AACb,UAAI;AACF,cAAM,QAAQ,MAAM,aAAa,SAAS,MAAM;AAChD,oBAAY,KAAK;AAAA,MACnB,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,gBAAQ,MAAM,2BAA2B,OAAO,EAAE;AAAA,MACpD,UAAE;AACA,qBAAa;AAAA,MACf;AAAA,IACF,GAAG,UAAU;AAAA,EACf;AAEA,UAAQ,GAAG,OAAO,CAAC,UAAkB,gBAAgB,CAAC;AACtD,UAAQ,GAAG,UAAU,CAAC,UAAkB,gBAAgB,CAAC;AACzD,UAAQ,GAAG,UAAU,CAAC,UAAkB,gBAAgB,CAAC;AAEzD,SAAO;AAAA,IACL,QAAQ;AACN,UAAI,cAAe,cAAa,aAAa;AAC7C,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AACF;AAMO,SAAS,mBAAmB,SAA2B;AAC5D,MAAI;AACF,UAAM,SAAS,aAAa,OAAO,CAAC,QAAQ,eAAe,MAAM,GAAG;AAAA,MAClE,KAAK;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,WAAO,OACJ,KAAK,EACL,MAAM,IAAI,EACV,OAAO,CAAC,MAAM,KAAK,cAAc,IAAI,QAAQ,CAAC,CAAC,CAAC;AAAA,EACrD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@ngommans/codefocus",
3
+ "version": "0.1.0",
4
+ "description": "Smart code context aggregator — AST-powered search that returns structured, ranked code context for LLM agents",
5
+ "type": "module",
6
+ "bin": {
7
+ "codefocus": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsup --watch",
15
+ "lint": "tsc --noEmit",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "benchmark": "node dist/cli.js benchmark",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "keywords": [
25
+ "code-search",
26
+ "ast",
27
+ "tree-sitter",
28
+ "llm",
29
+ "context",
30
+ "developer-tools"
31
+ ],
32
+ "author": "Nick Gommans <ngommans@ngommans.ca>",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/ngommans/codefocus.git"
37
+ },
38
+ "homepage": "https://github.com/ngommans/codefocus",
39
+ "bugs": {
40
+ "url": "https://github.com/ngommans/codefocus/issues"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "~1.18.2",
44
+ "better-sqlite3": "^11.7.0",
45
+ "zod": "^3.25.0",
46
+ "chokidar": "^5.0.0",
47
+ "fast-glob": "^3.3.3",
48
+ "graphology": "^0.25.4",
49
+ "graphology-metrics": "^2.3.0",
50
+ "js-tiktoken": "^1.0.18",
51
+ "tree-sitter": "^0.21.1",
52
+ "tree-sitter-typescript": "^0.23.2"
53
+ },
54
+ "devDependencies": {
55
+ "@types/better-sqlite3": "^7.6.12",
56
+ "@types/node": "^22.13.0",
57
+ "tsup": "^8.3.6",
58
+ "typescript": "^5.7.3",
59
+ "vitest": "^3.0.4"
60
+ }
61
+ }