codetree-claude 1.0.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 (108) hide show
  1. package/.codetreerc.default.json +41 -0
  2. package/README.md +171 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +185 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +131 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +111 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/hook/hook-client.d.ts +6 -0
  12. package/dist/hook/hook-client.d.ts.map +1 -0
  13. package/dist/hook/hook-client.js +48 -0
  14. package/dist/hook/hook-client.js.map +1 -0
  15. package/dist/hook/pre-tool-use.bundled.js +162 -0
  16. package/dist/hook/pre-tool-use.d.ts +14 -0
  17. package/dist/hook/pre-tool-use.d.ts.map +1 -0
  18. package/dist/hook/pre-tool-use.js +140 -0
  19. package/dist/hook/pre-tool-use.js.map +1 -0
  20. package/dist/index.d.ts +10 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +12 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/indexer/extractor-registry.d.ts +10 -0
  25. package/dist/indexer/extractor-registry.d.ts.map +1 -0
  26. package/dist/indexer/extractor-registry.js +39 -0
  27. package/dist/indexer/extractor-registry.js.map +1 -0
  28. package/dist/indexer/extractors/generic.d.ts +11 -0
  29. package/dist/indexer/extractors/generic.d.ts.map +1 -0
  30. package/dist/indexer/extractors/generic.js +12 -0
  31. package/dist/indexer/extractors/generic.js.map +1 -0
  32. package/dist/indexer/extractors/go.d.ts +10 -0
  33. package/dist/indexer/extractors/go.d.ts.map +1 -0
  34. package/dist/indexer/extractors/go.js +119 -0
  35. package/dist/indexer/extractors/go.js.map +1 -0
  36. package/dist/indexer/extractors/java.d.ts +10 -0
  37. package/dist/indexer/extractors/java.d.ts.map +1 -0
  38. package/dist/indexer/extractors/java.js +89 -0
  39. package/dist/indexer/extractors/java.js.map +1 -0
  40. package/dist/indexer/extractors/javascript.d.ts +11 -0
  41. package/dist/indexer/extractors/javascript.d.ts.map +1 -0
  42. package/dist/indexer/extractors/javascript.js +190 -0
  43. package/dist/indexer/extractors/javascript.js.map +1 -0
  44. package/dist/indexer/extractors/python.d.ts +11 -0
  45. package/dist/indexer/extractors/python.d.ts.map +1 -0
  46. package/dist/indexer/extractors/python.js +115 -0
  47. package/dist/indexer/extractors/python.js.map +1 -0
  48. package/dist/indexer/extractors/types.d.ts +26 -0
  49. package/dist/indexer/extractors/types.d.ts.map +1 -0
  50. package/dist/indexer/extractors/types.js +36 -0
  51. package/dist/indexer/extractors/types.js.map +1 -0
  52. package/dist/indexer/hasher.d.ts +11 -0
  53. package/dist/indexer/hasher.d.ts.map +1 -0
  54. package/dist/indexer/hasher.js +41 -0
  55. package/dist/indexer/hasher.js.map +1 -0
  56. package/dist/indexer/ignore.d.ts +15 -0
  57. package/dist/indexer/ignore.d.ts.map +1 -0
  58. package/dist/indexer/ignore.js +63 -0
  59. package/dist/indexer/ignore.js.map +1 -0
  60. package/dist/indexer/indexer.d.ts +64 -0
  61. package/dist/indexer/indexer.d.ts.map +1 -0
  62. package/dist/indexer/indexer.js +295 -0
  63. package/dist/indexer/indexer.js.map +1 -0
  64. package/dist/indexer/watcher.d.ts +16 -0
  65. package/dist/indexer/watcher.d.ts.map +1 -0
  66. package/dist/indexer/watcher.js +79 -0
  67. package/dist/indexer/watcher.js.map +1 -0
  68. package/dist/server/ipc.d.ts +38 -0
  69. package/dist/server/ipc.d.ts.map +1 -0
  70. package/dist/server/ipc.js +212 -0
  71. package/dist/server/ipc.js.map +1 -0
  72. package/dist/server/mcp-server.d.ts +2 -0
  73. package/dist/server/mcp-server.d.ts.map +1 -0
  74. package/dist/server/mcp-server.js +133 -0
  75. package/dist/server/mcp-server.js.map +1 -0
  76. package/dist/server/tools/codetree-find-refs.d.ts +46 -0
  77. package/dist/server/tools/codetree-find-refs.d.ts.map +1 -0
  78. package/dist/server/tools/codetree-find-refs.js +83 -0
  79. package/dist/server/tools/codetree-find-refs.js.map +1 -0
  80. package/dist/server/tools/codetree-read.d.ts +46 -0
  81. package/dist/server/tools/codetree-read.d.ts.map +1 -0
  82. package/dist/server/tools/codetree-read.js +82 -0
  83. package/dist/server/tools/codetree-read.js.map +1 -0
  84. package/dist/server/tools/codetree-search.d.ts +59 -0
  85. package/dist/server/tools/codetree-search.d.ts.map +1 -0
  86. package/dist/server/tools/codetree-search.js +92 -0
  87. package/dist/server/tools/codetree-search.js.map +1 -0
  88. package/dist/server/tools/codetree-structure.d.ts +55 -0
  89. package/dist/server/tools/codetree-structure.d.ts.map +1 -0
  90. package/dist/server/tools/codetree-structure.js +137 -0
  91. package/dist/server/tools/codetree-structure.js.map +1 -0
  92. package/dist/server/tools/codetree-summary.d.ts +36 -0
  93. package/dist/server/tools/codetree-summary.d.ts.map +1 -0
  94. package/dist/server/tools/codetree-summary.js +94 -0
  95. package/dist/server/tools/codetree-summary.js.map +1 -0
  96. package/dist/setup/install.d.ts +26 -0
  97. package/dist/setup/install.d.ts.map +1 -0
  98. package/dist/setup/install.js +127 -0
  99. package/dist/setup/install.js.map +1 -0
  100. package/dist/storage/cache.d.ts +29 -0
  101. package/dist/storage/cache.d.ts.map +1 -0
  102. package/dist/storage/cache.js +54 -0
  103. package/dist/storage/cache.js.map +1 -0
  104. package/dist/storage/database.d.ts +52 -0
  105. package/dist/storage/database.d.ts.map +1 -0
  106. package/dist/storage/database.js +346 -0
  107. package/dist/storage/database.js.map +1 -0
  108. package/package.json +60 -0
@@ -0,0 +1,127 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { join, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ /**
7
+ * Register CodeTree hook in Claude Code settings.
8
+ */
9
+ export function installHook(projectRoot, hookScriptPath) {
10
+ // Find or create .claude/settings.json
11
+ const claudeDir = join(projectRoot, ".claude");
12
+ const settingsPath = join(claudeDir, "settings.json");
13
+ if (!existsSync(claudeDir)) {
14
+ mkdirSync(claudeDir, { recursive: true });
15
+ }
16
+ let settings = {};
17
+ if (existsSync(settingsPath)) {
18
+ try {
19
+ settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
20
+ }
21
+ catch {
22
+ // Invalid JSON, start fresh
23
+ }
24
+ }
25
+ // Add hook
26
+ if (!settings.hooks)
27
+ settings.hooks = {};
28
+ if (!settings.hooks.PreToolUse)
29
+ settings.hooks.PreToolUse = [];
30
+ // Check if hook already exists
31
+ const existingHook = settings.hooks.PreToolUse.find((h) => h.hooks?.some((hook) => hook.command?.includes("codetree")));
32
+ if (existingHook) {
33
+ return { success: true, message: "Hook already registered" };
34
+ }
35
+ // Normalize path for the hook command
36
+ const normalizedPath = hookScriptPath.replace(/\\/g, "/");
37
+ settings.hooks.PreToolUse.push({
38
+ matcher: "Read|Grep|Glob",
39
+ hooks: [
40
+ {
41
+ type: "command",
42
+ command: `node "${normalizedPath}"`,
43
+ },
44
+ ],
45
+ });
46
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
47
+ return { success: true, message: `Hook registered in ${settingsPath}` };
48
+ }
49
+ /**
50
+ * Register CodeTree MCP server.
51
+ */
52
+ export function installMcpServer(projectRoot, serverScriptPath) {
53
+ // Use .mcp.json at project root (Claude Code convention)
54
+ const mcpConfigPath = join(projectRoot, ".mcp.json");
55
+ let config = {};
56
+ if (existsSync(mcpConfigPath)) {
57
+ try {
58
+ config = JSON.parse(readFileSync(mcpConfigPath, "utf-8"));
59
+ }
60
+ catch {
61
+ // Invalid JSON, start fresh
62
+ }
63
+ }
64
+ if (!config.mcpServers)
65
+ config.mcpServers = {};
66
+ // Check if already registered
67
+ if (config.mcpServers.codetree) {
68
+ return { success: true, message: "MCP server already registered" };
69
+ }
70
+ const normalizedPath = serverScriptPath.replace(/\\/g, "/");
71
+ config.mcpServers.codetree = {
72
+ command: "node",
73
+ args: [normalizedPath],
74
+ cwd: projectRoot,
75
+ env: {
76
+ CODETREE_PROJECT_ROOT: projectRoot,
77
+ },
78
+ };
79
+ writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2), "utf-8");
80
+ return { success: true, message: `MCP server registered in ${mcpConfigPath}` };
81
+ }
82
+ /**
83
+ * Create default .codetreerc.json if it doesn't exist.
84
+ */
85
+ export function createDefaultConfig(projectRoot) {
86
+ const configPath = join(projectRoot, ".codetreerc.json");
87
+ if (existsSync(configPath)) {
88
+ return { success: true, path: configPath };
89
+ }
90
+ // Read default config
91
+ const defaultConfigPath = join(__dirname, "..", "..", ".codetreerc.default.json");
92
+ let defaultConfig;
93
+ if (existsSync(defaultConfigPath)) {
94
+ defaultConfig = readFileSync(defaultConfigPath, "utf-8");
95
+ }
96
+ else {
97
+ // Inline defaults
98
+ defaultConfig = JSON.stringify({
99
+ projectRoot: ".",
100
+ ignore: [".git", "node_modules", "dist", "build", "coverage", ".next", "__pycache__", ".cache"],
101
+ ignoreBinary: true,
102
+ maxFileSize: 1048576,
103
+ cache: { memoryLimitMB: 256, dbPath: ".codetree/index.db", contentCacheMaxMB: 512 },
104
+ ipc: { port: 0, host: "127.0.0.1" },
105
+ watch: { enabled: true, debounceMs: 300, usePolling: false },
106
+ symbols: { enabled: true, languages: ["javascript", "typescript", "python", "java", "go", "rust", "ruby", "csharp"] },
107
+ telemetry: { enabled: true, statsFile: ".codetree/stats.json" },
108
+ }, null, 2);
109
+ }
110
+ writeFileSync(configPath, defaultConfig, "utf-8");
111
+ return { success: true, path: configPath };
112
+ }
113
+ /**
114
+ * Add .codetree/ to .gitignore.
115
+ */
116
+ export function updateGitignore(projectRoot) {
117
+ const gitignorePath = join(projectRoot, ".gitignore");
118
+ let content = "";
119
+ if (existsSync(gitignorePath)) {
120
+ content = readFileSync(gitignorePath, "utf-8");
121
+ }
122
+ if (!content.includes(".codetree/")) {
123
+ content += "\n# CodeTree cache\n.codetree/\n";
124
+ writeFileSync(gitignorePath, content, "utf-8");
125
+ }
126
+ }
127
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/setup/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface CacheEntry {
2
+ content: string;
3
+ hash: string;
4
+ mtimeMs: number;
5
+ size: number;
6
+ }
7
+ /**
8
+ * In-memory LRU cache for hot file contents.
9
+ * This sits in front of the SQLite content_cache for frequently accessed files.
10
+ */
11
+ export declare class ContentCache {
12
+ private cache;
13
+ private hits;
14
+ private misses;
15
+ constructor(maxSizeMB: number);
16
+ get(path: string): CacheEntry | undefined;
17
+ set(path: string, entry: CacheEntry): void;
18
+ delete(path: string): void;
19
+ has(path: string): boolean;
20
+ clear(): void;
21
+ getStats(): {
22
+ hits: number;
23
+ misses: number;
24
+ hitRate: number;
25
+ size: number;
26
+ entries: number;
27
+ };
28
+ }
29
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/storage/cache.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAEP,SAAS,EAAE,MAAM;IAU7B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAUzC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAI1C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,IAAI;IAMb,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAU7F"}
@@ -0,0 +1,54 @@
1
+ import { LRUCache } from "lru-cache";
2
+ /**
3
+ * In-memory LRU cache for hot file contents.
4
+ * This sits in front of the SQLite content_cache for frequently accessed files.
5
+ */
6
+ export class ContentCache {
7
+ cache;
8
+ hits = 0;
9
+ misses = 0;
10
+ constructor(maxSizeMB) {
11
+ this.cache = new LRUCache({
12
+ maxSize: maxSizeMB * 1024 * 1024,
13
+ sizeCalculation: (entry) => {
14
+ // Approximate memory: content bytes + overhead
15
+ return Buffer.byteLength(entry.content, "utf-8") + 200;
16
+ },
17
+ });
18
+ }
19
+ get(path) {
20
+ const entry = this.cache.get(path);
21
+ if (entry) {
22
+ this.hits++;
23
+ }
24
+ else {
25
+ this.misses++;
26
+ }
27
+ return entry;
28
+ }
29
+ set(path, entry) {
30
+ this.cache.set(path, entry);
31
+ }
32
+ delete(path) {
33
+ this.cache.delete(path);
34
+ }
35
+ has(path) {
36
+ return this.cache.has(path);
37
+ }
38
+ clear() {
39
+ this.cache.clear();
40
+ this.hits = 0;
41
+ this.misses = 0;
42
+ }
43
+ getStats() {
44
+ const total = this.hits + this.misses;
45
+ return {
46
+ hits: this.hits,
47
+ misses: this.misses,
48
+ hitRate: total > 0 ? this.hits / total : 0,
49
+ size: this.cache.calculatedSize,
50
+ entries: this.cache.size,
51
+ };
52
+ }
53
+ }
54
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/storage/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AASrC;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,KAAK,CAA+B;IACpC,IAAI,GAAG,CAAC,CAAC;IACT,MAAM,GAAG,CAAC,CAAC;IAEnB,YAAY,SAAiB;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAqB;YAC5C,OAAO,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;YAChC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;gBACzB,+CAA+C;gBAC/C,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC;YACzD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,IAAY;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,GAAG,CAAC,IAAY,EAAE,KAAiB;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc;YAC/B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;SACzB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ import type { CodeTreeConfig } from "../config.js";
2
+ export interface FileRecord {
3
+ path: string;
4
+ hash: string;
5
+ size: number;
6
+ mtime_ms: number;
7
+ language: string | null;
8
+ line_count: number;
9
+ indexed_at: number;
10
+ }
11
+ export interface SymbolRecord {
12
+ id?: number;
13
+ file_path: string;
14
+ name: string;
15
+ kind: string;
16
+ line_start: number | null;
17
+ line_end: number | null;
18
+ signature: string | null;
19
+ exported: boolean;
20
+ }
21
+ export interface DependencyRecord {
22
+ source_path: string;
23
+ target_spec: string;
24
+ target_resolved: string | null;
25
+ }
26
+ export declare class Database {
27
+ private config;
28
+ private db;
29
+ private dbPath;
30
+ private saveTimer;
31
+ private dirty;
32
+ constructor(config: CodeTreeConfig);
33
+ init(): Promise<void>;
34
+ private markDirty;
35
+ persistToDisk(): void;
36
+ upsertFile(file: FileRecord): void;
37
+ getFile(path: string): FileRecord | null;
38
+ getAllFiles(): FileRecord[];
39
+ deleteFile(path: string): void;
40
+ getFileCount(): number;
41
+ upsertSymbols(filePath: string, symbols: SymbolRecord[]): void;
42
+ searchSymbols(query: string, kind?: string, limit?: number): SymbolRecord[];
43
+ getSymbolsForFile(filePath: string): SymbolRecord[];
44
+ upsertDependencies(sourcePath: string, deps: DependencyRecord[]): void;
45
+ findDependents(targetPath: string): DependencyRecord[];
46
+ cacheContent(path: string, content: Buffer): void;
47
+ getCachedContent(path: string): Buffer | null;
48
+ evictContentCache(maxSizeMB: number): void;
49
+ searchFiles(pattern: string): FileRecord[];
50
+ close(): void;
51
+ }
52
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAwBnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAoDD,qBAAa,QAAQ;IAMP,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,EAAE,CAA8B;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,KAAK,CAAS;gBAEF,MAAM,EAAE,cAAc;IAIpC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,OAAO,CAAC,SAAS;IAOjB,aAAa,IAAI,IAAI;IAiBrB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAclC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAaxC,WAAW,IAAI,UAAU,EAAE;IAe3B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM9B,YAAY,IAAI,MAAM;IAQtB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI;IAsB9D,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,YAAY,EAAE;IA+BvE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE;IAyBnD,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAiBtE,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAsBtD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAUjD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAe7C,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAgC1C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE;IAgB1C,KAAK,IAAI,IAAI;CAWd"}
@@ -0,0 +1,346 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ const SCHEMA_SQL = `
4
+ CREATE TABLE IF NOT EXISTS files (
5
+ path TEXT PRIMARY KEY,
6
+ hash TEXT NOT NULL,
7
+ size INTEGER NOT NULL,
8
+ mtime_ms INTEGER NOT NULL,
9
+ language TEXT,
10
+ line_count INTEGER DEFAULT 0,
11
+ indexed_at INTEGER NOT NULL
12
+ );
13
+
14
+ CREATE TABLE IF NOT EXISTS symbols (
15
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
16
+ file_path TEXT NOT NULL,
17
+ name TEXT NOT NULL,
18
+ kind TEXT NOT NULL,
19
+ line_start INTEGER,
20
+ line_end INTEGER,
21
+ signature TEXT,
22
+ exported INTEGER DEFAULT 0,
23
+ FOREIGN KEY (file_path) REFERENCES files(path) ON DELETE CASCADE
24
+ );
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
27
+ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_path);
28
+ CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
29
+
30
+ CREATE TABLE IF NOT EXISTS dependencies (
31
+ source_path TEXT NOT NULL,
32
+ target_spec TEXT NOT NULL,
33
+ target_resolved TEXT,
34
+ PRIMARY KEY (source_path, target_spec),
35
+ FOREIGN KEY (source_path) REFERENCES files(path) ON DELETE CASCADE
36
+ );
37
+
38
+ CREATE INDEX IF NOT EXISTS idx_deps_target ON dependencies(target_resolved);
39
+
40
+ CREATE TABLE IF NOT EXISTS content_cache (
41
+ path TEXT PRIMARY KEY,
42
+ content BLOB NOT NULL,
43
+ accessed_at INTEGER NOT NULL,
44
+ FOREIGN KEY (path) REFERENCES files(path) ON DELETE CASCADE
45
+ );
46
+
47
+ CREATE TABLE IF NOT EXISTS meta (
48
+ key TEXT PRIMARY KEY,
49
+ value TEXT NOT NULL
50
+ );
51
+ `;
52
+ export class Database {
53
+ config;
54
+ db = null;
55
+ dbPath;
56
+ saveTimer = null;
57
+ dirty = false;
58
+ constructor(config) {
59
+ this.config = config;
60
+ this.dbPath = config.cache.dbPath;
61
+ }
62
+ async init() {
63
+ // Dynamic import for sql.js
64
+ const initSqlJs = (await import("sql.js")).default;
65
+ const SQL = await initSqlJs();
66
+ // Ensure directory exists
67
+ const dir = dirname(this.dbPath);
68
+ if (!existsSync(dir)) {
69
+ mkdirSync(dir, { recursive: true });
70
+ }
71
+ // Load existing database or create new
72
+ if (existsSync(this.dbPath)) {
73
+ const buffer = readFileSync(this.dbPath);
74
+ this.db = new SQL.Database(buffer);
75
+ }
76
+ else {
77
+ this.db = new SQL.Database();
78
+ }
79
+ // Enable WAL-like behavior and foreign keys
80
+ this.db.run("PRAGMA journal_mode=MEMORY");
81
+ this.db.run("PRAGMA foreign_keys=ON");
82
+ this.db.run("PRAGMA synchronous=OFF");
83
+ // Create schema
84
+ this.db.run(SCHEMA_SQL);
85
+ // Set schema version
86
+ this.db.run("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', '1')");
87
+ }
88
+ markDirty() {
89
+ this.dirty = true;
90
+ if (!this.saveTimer) {
91
+ this.saveTimer = setTimeout(() => this.persistToDisk(), 5000);
92
+ }
93
+ }
94
+ persistToDisk() {
95
+ if (!this.db || !this.dirty)
96
+ return;
97
+ try {
98
+ const data = this.db.export();
99
+ const buffer = Buffer.from(data);
100
+ const dir = dirname(this.dbPath);
101
+ if (!existsSync(dir))
102
+ mkdirSync(dir, { recursive: true });
103
+ writeFileSync(this.dbPath, buffer);
104
+ this.dirty = false;
105
+ }
106
+ catch (err) {
107
+ console.error("[codetree] Failed to persist database:", err);
108
+ }
109
+ this.saveTimer = null;
110
+ }
111
+ // ─── File Operations ───────────────────────────────────────────
112
+ upsertFile(file) {
113
+ if (!this.db)
114
+ throw new Error("Database not initialized");
115
+ const stmt = this.db.prepare(`INSERT OR REPLACE INTO files (path, hash, size, mtime_ms, language, line_count, indexed_at)
116
+ VALUES (?, ?, ?, ?, ?, ?, ?)`);
117
+ stmt.run([
118
+ file.path, file.hash, file.size, file.mtime_ms,
119
+ file.language, file.line_count, file.indexed_at,
120
+ ]);
121
+ stmt.free();
122
+ this.markDirty();
123
+ }
124
+ getFile(path) {
125
+ if (!this.db)
126
+ throw new Error("Database not initialized");
127
+ const stmt = this.db.prepare("SELECT * FROM files WHERE path = ?");
128
+ stmt.bind([path]);
129
+ if (stmt.step()) {
130
+ const row = stmt.getAsObject();
131
+ stmt.free();
132
+ return row;
133
+ }
134
+ stmt.free();
135
+ return null;
136
+ }
137
+ getAllFiles() {
138
+ if (!this.db)
139
+ throw new Error("Database not initialized");
140
+ const results = this.db.exec("SELECT * FROM files ORDER BY path");
141
+ if (results.length === 0)
142
+ return [];
143
+ return results[0].values.map((row) => ({
144
+ path: row[0],
145
+ hash: row[1],
146
+ size: row[2],
147
+ mtime_ms: row[3],
148
+ language: row[4],
149
+ line_count: row[5],
150
+ indexed_at: row[6],
151
+ }));
152
+ }
153
+ deleteFile(path) {
154
+ if (!this.db)
155
+ throw new Error("Database not initialized");
156
+ this.db.run("DELETE FROM files WHERE path = ?", [path]);
157
+ this.markDirty();
158
+ }
159
+ getFileCount() {
160
+ if (!this.db)
161
+ throw new Error("Database not initialized");
162
+ const result = this.db.exec("SELECT COUNT(*) FROM files");
163
+ return result.length > 0 ? result[0].values[0][0] : 0;
164
+ }
165
+ // ─── Symbol Operations ─────────────────────────────────────────
166
+ upsertSymbols(filePath, symbols) {
167
+ if (!this.db)
168
+ throw new Error("Database not initialized");
169
+ // Delete existing symbols for file
170
+ this.db.run("DELETE FROM symbols WHERE file_path = ?", [filePath]);
171
+ if (symbols.length === 0)
172
+ return;
173
+ const stmt = this.db.prepare(`INSERT INTO symbols (file_path, name, kind, line_start, line_end, signature, exported)
174
+ VALUES (?, ?, ?, ?, ?, ?, ?)`);
175
+ for (const sym of symbols) {
176
+ stmt.run([
177
+ sym.file_path, sym.name, sym.kind,
178
+ sym.line_start, sym.line_end, sym.signature,
179
+ sym.exported ? 1 : 0,
180
+ ]);
181
+ }
182
+ stmt.free();
183
+ this.markDirty();
184
+ }
185
+ searchSymbols(query, kind, limit = 50) {
186
+ if (!this.db)
187
+ throw new Error("Database not initialized");
188
+ let sql = "SELECT * FROM symbols WHERE name LIKE ?";
189
+ const params = [`%${query}%`];
190
+ if (kind) {
191
+ sql += " AND kind = ?";
192
+ params.push(kind);
193
+ }
194
+ sql += ` LIMIT ${limit}`;
195
+ const stmt = this.db.prepare(sql);
196
+ stmt.bind(params);
197
+ const results = [];
198
+ while (stmt.step()) {
199
+ const row = stmt.getAsObject();
200
+ results.push({
201
+ id: row.id,
202
+ file_path: row.file_path,
203
+ name: row.name,
204
+ kind: row.kind,
205
+ line_start: row.line_start,
206
+ line_end: row.line_end,
207
+ signature: row.signature,
208
+ exported: row.exported === 1,
209
+ });
210
+ }
211
+ stmt.free();
212
+ return results;
213
+ }
214
+ getSymbolsForFile(filePath) {
215
+ if (!this.db)
216
+ throw new Error("Database not initialized");
217
+ const stmt = this.db.prepare("SELECT * FROM symbols WHERE file_path = ? ORDER BY line_start");
218
+ stmt.bind([filePath]);
219
+ const results = [];
220
+ while (stmt.step()) {
221
+ const row = stmt.getAsObject();
222
+ results.push({
223
+ id: row.id,
224
+ file_path: row.file_path,
225
+ name: row.name,
226
+ kind: row.kind,
227
+ line_start: row.line_start,
228
+ line_end: row.line_end,
229
+ signature: row.signature,
230
+ exported: row.exported === 1,
231
+ });
232
+ }
233
+ stmt.free();
234
+ return results;
235
+ }
236
+ // ─── Dependency Operations ─────────────────────────────────────
237
+ upsertDependencies(sourcePath, deps) {
238
+ if (!this.db)
239
+ throw new Error("Database not initialized");
240
+ this.db.run("DELETE FROM dependencies WHERE source_path = ?", [sourcePath]);
241
+ if (deps.length === 0)
242
+ return;
243
+ const stmt = this.db.prepare(`INSERT OR REPLACE INTO dependencies (source_path, target_spec, target_resolved)
244
+ VALUES (?, ?, ?)`);
245
+ for (const dep of deps) {
246
+ stmt.run([dep.source_path, dep.target_spec, dep.target_resolved]);
247
+ }
248
+ stmt.free();
249
+ this.markDirty();
250
+ }
251
+ findDependents(targetPath) {
252
+ if (!this.db)
253
+ throw new Error("Database not initialized");
254
+ const stmt = this.db.prepare("SELECT * FROM dependencies WHERE target_resolved = ?");
255
+ stmt.bind([targetPath]);
256
+ const results = [];
257
+ while (stmt.step()) {
258
+ const row = stmt.getAsObject();
259
+ results.push({
260
+ source_path: row.source_path,
261
+ target_spec: row.target_spec,
262
+ target_resolved: row.target_resolved,
263
+ });
264
+ }
265
+ stmt.free();
266
+ return results;
267
+ }
268
+ // ─── Content Cache Operations ──────────────────────────────────
269
+ cacheContent(path, content) {
270
+ if (!this.db)
271
+ throw new Error("Database not initialized");
272
+ const stmt = this.db.prepare(`INSERT OR REPLACE INTO content_cache (path, content, accessed_at) VALUES (?, ?, ?)`);
273
+ stmt.run([path, content, Date.now()]);
274
+ stmt.free();
275
+ this.markDirty();
276
+ }
277
+ getCachedContent(path) {
278
+ if (!this.db)
279
+ throw new Error("Database not initialized");
280
+ const stmt = this.db.prepare("SELECT content FROM content_cache WHERE path = ?");
281
+ stmt.bind([path]);
282
+ if (stmt.step()) {
283
+ const row = stmt.get();
284
+ stmt.free();
285
+ // Update access time
286
+ this.db.run("UPDATE content_cache SET accessed_at = ? WHERE path = ?", [Date.now(), path]);
287
+ return Buffer.from(row[0]);
288
+ }
289
+ stmt.free();
290
+ return null;
291
+ }
292
+ evictContentCache(maxSizeMB) {
293
+ if (!this.db)
294
+ throw new Error("Database not initialized");
295
+ const result = this.db.exec("SELECT SUM(LENGTH(content)) as total FROM content_cache");
296
+ if (result.length === 0)
297
+ return;
298
+ const totalBytes = result[0].values[0][0] || 0;
299
+ const maxBytes = maxSizeMB * 1024 * 1024;
300
+ if (totalBytes <= maxBytes)
301
+ return;
302
+ // Delete oldest entries until under limit
303
+ const toDelete = totalBytes - maxBytes;
304
+ this.db.run(`
305
+ DELETE FROM content_cache WHERE path IN (
306
+ SELECT path FROM content_cache
307
+ ORDER BY accessed_at ASC
308
+ LIMIT (
309
+ SELECT COUNT(*) FROM content_cache
310
+ WHERE accessed_at <= (
311
+ SELECT accessed_at FROM content_cache ORDER BY accessed_at ASC
312
+ LIMIT 1 OFFSET (SELECT COUNT(*)/4 FROM content_cache)
313
+ )
314
+ )
315
+ )
316
+ `);
317
+ this.markDirty();
318
+ }
319
+ // ─── Search Operations ─────────────────────────────────────────
320
+ searchFiles(pattern) {
321
+ if (!this.db)
322
+ throw new Error("Database not initialized");
323
+ const stmt = this.db.prepare("SELECT * FROM files WHERE path LIKE ? ORDER BY path LIMIT 100");
324
+ stmt.bind([`%${pattern}%`]);
325
+ const results = [];
326
+ while (stmt.step()) {
327
+ const row = stmt.getAsObject();
328
+ results.push(row);
329
+ }
330
+ stmt.free();
331
+ return results;
332
+ }
333
+ // ─── Lifecycle ─────────────────────────────────────────────────
334
+ close() {
335
+ if (this.saveTimer) {
336
+ clearTimeout(this.saveTimer);
337
+ this.saveTimer = null;
338
+ }
339
+ this.persistToDisk();
340
+ if (this.db) {
341
+ this.db.close();
342
+ this.db = null;
343
+ }
344
+ }
345
+ }
346
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}