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.
- package/.codetreerc.default.json +41 -0
- package/README.md +171 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +185 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +131 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +111 -0
- package/dist/config.js.map +1 -0
- package/dist/hook/hook-client.d.ts +6 -0
- package/dist/hook/hook-client.d.ts.map +1 -0
- package/dist/hook/hook-client.js +48 -0
- package/dist/hook/hook-client.js.map +1 -0
- package/dist/hook/pre-tool-use.bundled.js +162 -0
- package/dist/hook/pre-tool-use.d.ts +14 -0
- package/dist/hook/pre-tool-use.d.ts.map +1 -0
- package/dist/hook/pre-tool-use.js +140 -0
- package/dist/hook/pre-tool-use.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/extractor-registry.d.ts +10 -0
- package/dist/indexer/extractor-registry.d.ts.map +1 -0
- package/dist/indexer/extractor-registry.js +39 -0
- package/dist/indexer/extractor-registry.js.map +1 -0
- package/dist/indexer/extractors/generic.d.ts +11 -0
- package/dist/indexer/extractors/generic.d.ts.map +1 -0
- package/dist/indexer/extractors/generic.js +12 -0
- package/dist/indexer/extractors/generic.js.map +1 -0
- package/dist/indexer/extractors/go.d.ts +10 -0
- package/dist/indexer/extractors/go.d.ts.map +1 -0
- package/dist/indexer/extractors/go.js +119 -0
- package/dist/indexer/extractors/go.js.map +1 -0
- package/dist/indexer/extractors/java.d.ts +10 -0
- package/dist/indexer/extractors/java.d.ts.map +1 -0
- package/dist/indexer/extractors/java.js +89 -0
- package/dist/indexer/extractors/java.js.map +1 -0
- package/dist/indexer/extractors/javascript.d.ts +11 -0
- package/dist/indexer/extractors/javascript.d.ts.map +1 -0
- package/dist/indexer/extractors/javascript.js +190 -0
- package/dist/indexer/extractors/javascript.js.map +1 -0
- package/dist/indexer/extractors/python.d.ts +11 -0
- package/dist/indexer/extractors/python.d.ts.map +1 -0
- package/dist/indexer/extractors/python.js +115 -0
- package/dist/indexer/extractors/python.js.map +1 -0
- package/dist/indexer/extractors/types.d.ts +26 -0
- package/dist/indexer/extractors/types.d.ts.map +1 -0
- package/dist/indexer/extractors/types.js +36 -0
- package/dist/indexer/extractors/types.js.map +1 -0
- package/dist/indexer/hasher.d.ts +11 -0
- package/dist/indexer/hasher.d.ts.map +1 -0
- package/dist/indexer/hasher.js +41 -0
- package/dist/indexer/hasher.js.map +1 -0
- package/dist/indexer/ignore.d.ts +15 -0
- package/dist/indexer/ignore.d.ts.map +1 -0
- package/dist/indexer/ignore.js +63 -0
- package/dist/indexer/ignore.js.map +1 -0
- package/dist/indexer/indexer.d.ts +64 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +295 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/watcher.d.ts +16 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +79 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/server/ipc.d.ts +38 -0
- package/dist/server/ipc.d.ts.map +1 -0
- package/dist/server/ipc.js +212 -0
- package/dist/server/ipc.js.map +1 -0
- package/dist/server/mcp-server.d.ts +2 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/mcp-server.js +133 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/server/tools/codetree-find-refs.d.ts +46 -0
- package/dist/server/tools/codetree-find-refs.d.ts.map +1 -0
- package/dist/server/tools/codetree-find-refs.js +83 -0
- package/dist/server/tools/codetree-find-refs.js.map +1 -0
- package/dist/server/tools/codetree-read.d.ts +46 -0
- package/dist/server/tools/codetree-read.d.ts.map +1 -0
- package/dist/server/tools/codetree-read.js +82 -0
- package/dist/server/tools/codetree-read.js.map +1 -0
- package/dist/server/tools/codetree-search.d.ts +59 -0
- package/dist/server/tools/codetree-search.d.ts.map +1 -0
- package/dist/server/tools/codetree-search.js +92 -0
- package/dist/server/tools/codetree-search.js.map +1 -0
- package/dist/server/tools/codetree-structure.d.ts +55 -0
- package/dist/server/tools/codetree-structure.d.ts.map +1 -0
- package/dist/server/tools/codetree-structure.js +137 -0
- package/dist/server/tools/codetree-structure.js.map +1 -0
- package/dist/server/tools/codetree-summary.d.ts +36 -0
- package/dist/server/tools/codetree-summary.d.ts.map +1 -0
- package/dist/server/tools/codetree-summary.js +94 -0
- package/dist/server/tools/codetree-summary.js.map +1 -0
- package/dist/setup/install.d.ts +26 -0
- package/dist/setup/install.d.ts.map +1 -0
- package/dist/setup/install.js +127 -0
- package/dist/setup/install.js.map +1 -0
- package/dist/storage/cache.d.ts +29 -0
- package/dist/storage/cache.d.ts.map +1 -0
- package/dist/storage/cache.js +54 -0
- package/dist/storage/cache.js.map +1 -0
- package/dist/storage/database.d.ts +52 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +346 -0
- package/dist/storage/database.js.map +1 -0
- 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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"}
|