sverklo 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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/bin/sverklo.d.ts +2 -0
  4. package/dist/bin/sverklo.js +41 -0
  5. package/dist/bin/sverklo.js.map +1 -0
  6. package/dist/src/index.d.ts +3 -0
  7. package/dist/src/index.js +3 -0
  8. package/dist/src/index.js.map +1 -0
  9. package/dist/src/indexer/describer.d.ts +2 -0
  10. package/dist/src/indexer/describer.js +112 -0
  11. package/dist/src/indexer/describer.js.map +1 -0
  12. package/dist/src/indexer/embedder.d.ts +4 -0
  13. package/dist/src/indexer/embedder.js +249 -0
  14. package/dist/src/indexer/embedder.js.map +1 -0
  15. package/dist/src/indexer/file-discovery.d.ts +9 -0
  16. package/dist/src/indexer/file-discovery.js +52 -0
  17. package/dist/src/indexer/file-discovery.js.map +1 -0
  18. package/dist/src/indexer/graph-builder.d.ts +5 -0
  19. package/dist/src/indexer/graph-builder.js +77 -0
  20. package/dist/src/indexer/graph-builder.js.map +1 -0
  21. package/dist/src/indexer/indexer.d.ts +26 -0
  22. package/dist/src/indexer/indexer.js +180 -0
  23. package/dist/src/indexer/indexer.js.map +1 -0
  24. package/dist/src/indexer/parser.d.ts +2 -0
  25. package/dist/src/indexer/parser.js +467 -0
  26. package/dist/src/indexer/parser.js.map +1 -0
  27. package/dist/src/indexer/setup.d.ts +1 -0
  28. package/dist/src/indexer/setup.js +38 -0
  29. package/dist/src/indexer/setup.js.map +1 -0
  30. package/dist/src/indexer/watcher.d.ts +2 -0
  31. package/dist/src/indexer/watcher.js +51 -0
  32. package/dist/src/indexer/watcher.js.map +1 -0
  33. package/dist/src/memory/git-state.d.ts +4 -0
  34. package/dist/src/memory/git-state.js +12 -0
  35. package/dist/src/memory/git-state.js.map +1 -0
  36. package/dist/src/memory/staleness.d.ts +4 -0
  37. package/dist/src/memory/staleness.js +19 -0
  38. package/dist/src/memory/staleness.js.map +1 -0
  39. package/dist/src/search/hybrid-search.d.ts +13 -0
  40. package/dist/src/search/hybrid-search.js +97 -0
  41. package/dist/src/search/hybrid-search.js.map +1 -0
  42. package/dist/src/search/pagerank.d.ts +4 -0
  43. package/dist/src/search/pagerank.js +64 -0
  44. package/dist/src/search/pagerank.js.map +1 -0
  45. package/dist/src/search/token-budget.d.ts +10 -0
  46. package/dist/src/search/token-budget.js +67 -0
  47. package/dist/src/search/token-budget.js.map +1 -0
  48. package/dist/src/server/mcp-server.d.ts +1 -0
  49. package/dist/src/server/mcp-server.js +120 -0
  50. package/dist/src/server/mcp-server.js.map +1 -0
  51. package/dist/src/server/tools/dependencies.d.ts +29 -0
  52. package/dist/src/server/tools/dependencies.js +118 -0
  53. package/dist/src/server/tools/dependencies.js.map +1 -0
  54. package/dist/src/server/tools/find-references.d.ts +20 -0
  55. package/dist/src/server/tools/find-references.js +80 -0
  56. package/dist/src/server/tools/find-references.js.map +1 -0
  57. package/dist/src/server/tools/forget.d.ts +16 -0
  58. package/dist/src/server/tools/forget.js +24 -0
  59. package/dist/src/server/tools/forget.js.map +1 -0
  60. package/dist/src/server/tools/index-status.d.ts +10 -0
  61. package/dist/src/server/tools/index-status.js +21 -0
  62. package/dist/src/server/tools/index-status.js.map +1 -0
  63. package/dist/src/server/tools/lookup.d.ts +25 -0
  64. package/dist/src/server/tools/lookup.js +54 -0
  65. package/dist/src/server/tools/lookup.js.map +1 -0
  66. package/dist/src/server/tools/memories.d.ts +24 -0
  67. package/dist/src/server/tools/memories.js +61 -0
  68. package/dist/src/server/tools/memories.js.map +1 -0
  69. package/dist/src/server/tools/overview.d.ts +19 -0
  70. package/dist/src/server/tools/overview.js +32 -0
  71. package/dist/src/server/tools/overview.js.map +1 -0
  72. package/dist/src/server/tools/recall.d.ts +29 -0
  73. package/dist/src/server/tools/recall.js +113 -0
  74. package/dist/src/server/tools/recall.js.map +1 -0
  75. package/dist/src/server/tools/remember.d.ts +39 -0
  76. package/dist/src/server/tools/remember.js +56 -0
  77. package/dist/src/server/tools/remember.js.map +1 -0
  78. package/dist/src/server/tools/search.d.ts +33 -0
  79. package/dist/src/server/tools/search.js +43 -0
  80. package/dist/src/server/tools/search.js.map +1 -0
  81. package/dist/src/storage/chunk-store.d.ts +25 -0
  82. package/dist/src/storage/chunk-store.js +74 -0
  83. package/dist/src/storage/chunk-store.js.map +1 -0
  84. package/dist/src/storage/database.d.ts +2 -0
  85. package/dist/src/storage/database.js +140 -0
  86. package/dist/src/storage/database.js.map +1 -0
  87. package/dist/src/storage/embedding-store.d.ts +14 -0
  88. package/dist/src/storage/embedding-store.js +42 -0
  89. package/dist/src/storage/embedding-store.js.map +1 -0
  90. package/dist/src/storage/file-store.d.ts +19 -0
  91. package/dist/src/storage/file-store.js +44 -0
  92. package/dist/src/storage/file-store.js.map +1 -0
  93. package/dist/src/storage/graph-store.d.ts +16 -0
  94. package/dist/src/storage/graph-store.js +37 -0
  95. package/dist/src/storage/graph-store.js.map +1 -0
  96. package/dist/src/storage/memory-embedding-store.d.ts +13 -0
  97. package/dist/src/storage/memory-embedding-store.js +38 -0
  98. package/dist/src/storage/memory-embedding-store.js.map +1 -0
  99. package/dist/src/storage/memory-store.d.ts +29 -0
  100. package/dist/src/storage/memory-store.js +86 -0
  101. package/dist/src/storage/memory-store.js.map +1 -0
  102. package/dist/src/types/index.d.ts +87 -0
  103. package/dist/src/types/index.js +21 -0
  104. package/dist/src/types/index.js.map +1 -0
  105. package/dist/src/utils/config.d.ts +2 -0
  106. package/dist/src/utils/config.js +18 -0
  107. package/dist/src/utils/config.js.map +1 -0
  108. package/dist/src/utils/ignore.d.ts +2 -0
  109. package/dist/src/utils/ignore.js +72 -0
  110. package/dist/src/utils/ignore.js.map +1 -0
  111. package/dist/src/utils/logger.d.ts +2 -0
  112. package/dist/src/utils/logger.js +16 -0
  113. package/dist/src/utils/logger.js.map +1 -0
  114. package/dist/src/utils/tokens.d.ts +2 -0
  115. package/dist/src/utils/tokens.js +12 -0
  116. package/dist/src/utils/tokens.js.map +1 -0
  117. package/package.json +59 -0
@@ -0,0 +1,29 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { Memory, MemoryCategory } from "../types/index.js";
3
+ export declare class MemoryStore {
4
+ private db;
5
+ private insertStmt;
6
+ private getByIdStmt;
7
+ private getAllStmt;
8
+ private getByCategoryStmt;
9
+ private deleteStmt;
10
+ private updateStmt;
11
+ private searchFtsStmt;
12
+ private touchAccessStmt;
13
+ private markStaleStmt;
14
+ private getStaleStmt;
15
+ constructor(db: Database.Database);
16
+ insert(category: MemoryCategory, content: string, tags: string[] | null, confidence: number, gitSha: string | null, gitBranch: string | null, relatedFiles: string[] | null): number;
17
+ getById(id: number): Memory | undefined;
18
+ getAll(limit?: number): Memory[];
19
+ getByCategory(category: MemoryCategory, limit?: number): Memory[];
20
+ delete(id: number): boolean;
21
+ update(id: number, content: string, tags?: string[]): void;
22
+ searchFts(query: string, limit?: number): (Memory & {
23
+ rank: number;
24
+ })[];
25
+ touchAccess(id: number): void;
26
+ markStale(id: number, stale: boolean): void;
27
+ getStale(): Memory[];
28
+ count(): number;
29
+ }
@@ -0,0 +1,86 @@
1
+ export class MemoryStore {
2
+ db;
3
+ insertStmt;
4
+ getByIdStmt;
5
+ getAllStmt;
6
+ getByCategoryStmt;
7
+ deleteStmt;
8
+ updateStmt;
9
+ searchFtsStmt;
10
+ touchAccessStmt;
11
+ markStaleStmt;
12
+ getStaleStmt;
13
+ constructor(db) {
14
+ this.db = db;
15
+ this.insertStmt = db.prepare(`
16
+ INSERT INTO memories (category, content, tags, confidence, git_sha, git_branch, related_files, created_at, updated_at, last_accessed)
17
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
18
+ `);
19
+ this.getByIdStmt = db.prepare("SELECT * FROM memories WHERE id = ?");
20
+ this.getAllStmt = db.prepare("SELECT * FROM memories ORDER BY created_at DESC LIMIT ?");
21
+ this.getByCategoryStmt = db.prepare("SELECT * FROM memories WHERE category = ? ORDER BY created_at DESC LIMIT ?");
22
+ this.deleteStmt = db.prepare("DELETE FROM memories WHERE id = ?");
23
+ this.updateStmt = db.prepare("UPDATE memories SET content = ?, tags = ?, updated_at = ? WHERE id = ?");
24
+ this.searchFtsStmt = db.prepare(`
25
+ SELECT m.*, rank
26
+ FROM memories_fts fts
27
+ JOIN memories m ON m.id = fts.rowid
28
+ WHERE memories_fts MATCH ?
29
+ ORDER BY rank
30
+ LIMIT ?
31
+ `);
32
+ this.touchAccessStmt = db.prepare("UPDATE memories SET last_accessed = ?, access_count = access_count + 1 WHERE id = ?");
33
+ this.markStaleStmt = db.prepare("UPDATE memories SET is_stale = ? WHERE id = ?");
34
+ this.getStaleStmt = db.prepare("SELECT * FROM memories WHERE is_stale = 1 ORDER BY created_at DESC");
35
+ }
36
+ insert(category, content, tags, confidence, gitSha, gitBranch, relatedFiles) {
37
+ const now = Date.now();
38
+ const result = this.insertStmt.run(category, content, tags ? JSON.stringify(tags) : null, confidence, gitSha, gitBranch, relatedFiles ? JSON.stringify(relatedFiles) : null, now, now, now);
39
+ return Number(result.lastInsertRowid);
40
+ }
41
+ getById(id) {
42
+ return this.getByIdStmt.get(id);
43
+ }
44
+ getAll(limit = 50) {
45
+ return this.getAllStmt.all(limit);
46
+ }
47
+ getByCategory(category, limit = 50) {
48
+ return this.getByCategoryStmt.all(category, limit);
49
+ }
50
+ delete(id) {
51
+ const result = this.deleteStmt.run(id);
52
+ return result.changes > 0;
53
+ }
54
+ update(id, content, tags) {
55
+ this.updateStmt.run(content, tags ? JSON.stringify(tags) : null, Date.now(), id);
56
+ }
57
+ searchFts(query, limit = 20) {
58
+ try {
59
+ const safeQuery = query
60
+ .replace(/["'(){}[\]*:^~!@#$%&]/g, " ")
61
+ .split(/\s+/)
62
+ .filter((w) => w.length > 1)
63
+ .map((w) => `"${w}"`)
64
+ .join(" OR ");
65
+ if (!safeQuery)
66
+ return [];
67
+ return this.searchFtsStmt.all(safeQuery, limit);
68
+ }
69
+ catch {
70
+ return [];
71
+ }
72
+ }
73
+ touchAccess(id) {
74
+ this.touchAccessStmt.run(Date.now(), id);
75
+ }
76
+ markStale(id, stale) {
77
+ this.markStaleStmt.run(stale ? 1 : 0, id);
78
+ }
79
+ getStale() {
80
+ return this.getStaleStmt.all();
81
+ }
82
+ count() {
83
+ return this.db.prepare("SELECT COUNT(*) as c FROM memories").get().c;
84
+ }
85
+ }
86
+ //# sourceMappingURL=memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/storage/memory-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ export interface ProjectConfig {
2
+ rootPath: string;
3
+ name: string;
4
+ dataDir: string;
5
+ dbPath: string;
6
+ }
7
+ export interface FileRecord {
8
+ id: number;
9
+ path: string;
10
+ language: string | null;
11
+ hash: string;
12
+ last_modified: number;
13
+ size_bytes: number;
14
+ pagerank: number;
15
+ indexed_at: number;
16
+ }
17
+ export type ChunkType = "function" | "class" | "method" | "type" | "interface" | "module" | "block" | "variable" | "import";
18
+ export interface CodeChunk {
19
+ id: number;
20
+ file_id: number;
21
+ type: ChunkType;
22
+ name: string | null;
23
+ signature: string | null;
24
+ start_line: number;
25
+ end_line: number;
26
+ content: string;
27
+ description: string | null;
28
+ token_count: number;
29
+ }
30
+ export interface SearchResult {
31
+ chunk: CodeChunk;
32
+ file: FileRecord;
33
+ score: number;
34
+ }
35
+ export interface DependencyEdge {
36
+ source_file_id: number;
37
+ target_file_id: number;
38
+ reference_count: number;
39
+ }
40
+ export type MemoryCategory = "decision" | "preference" | "pattern" | "context" | "todo";
41
+ export interface Memory {
42
+ id: number;
43
+ category: MemoryCategory;
44
+ content: string;
45
+ tags: string | null;
46
+ confidence: number;
47
+ git_sha: string | null;
48
+ git_branch: string | null;
49
+ related_files: string | null;
50
+ created_at: number;
51
+ updated_at: number;
52
+ last_accessed: number;
53
+ access_count: number;
54
+ is_stale: number;
55
+ }
56
+ export interface IndexStatus {
57
+ projectName: string;
58
+ rootPath: string;
59
+ fileCount: number;
60
+ chunkCount: number;
61
+ languages: string[];
62
+ lastIndexedAt: number | null;
63
+ indexing: boolean;
64
+ progress?: {
65
+ done: number;
66
+ total: number;
67
+ };
68
+ }
69
+ export interface ParsedChunk {
70
+ type: ChunkType;
71
+ name: string | null;
72
+ signature: string | null;
73
+ startLine: number;
74
+ endLine: number;
75
+ content: string;
76
+ }
77
+ export interface ParseResult {
78
+ chunks: ParsedChunk[];
79
+ imports: ImportRef[];
80
+ }
81
+ export interface ImportRef {
82
+ source: string;
83
+ names: string[];
84
+ isRelative: boolean;
85
+ }
86
+ export declare const SUPPORTED_LANGUAGES: Record<string, string[]>;
87
+ export declare function detectLanguage(filePath: string): string | null;
@@ -0,0 +1,21 @@
1
+ export const SUPPORTED_LANGUAGES = {
2
+ typescript: [".ts", ".tsx", ".mts", ".cts"],
3
+ javascript: [".js", ".jsx", ".mjs", ".cjs"],
4
+ python: [".py", ".pyi"],
5
+ go: [".go"],
6
+ rust: [".rs"],
7
+ java: [".java"],
8
+ c: [".c", ".h"],
9
+ cpp: [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx"],
10
+ ruby: [".rb"],
11
+ php: [".php"],
12
+ };
13
+ export function detectLanguage(filePath) {
14
+ const ext = "." + filePath.split(".").pop()?.toLowerCase();
15
+ for (const [lang, exts] of Object.entries(SUPPORTED_LANGUAGES)) {
16
+ if (exts.includes(ext))
17
+ return lang;
18
+ }
19
+ return null;
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAuGA,MAAM,CAAC,MAAM,mBAAmB,GAA6B;IAC3D,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC3C,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,CAAC,KAAK,CAAC;IACX,IAAI,EAAE,CAAC,KAAK,CAAC;IACb,IAAI,EAAE,CAAC,OAAO,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;IACf,GAAG,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;IACnD,IAAI,EAAE,CAAC,KAAK,CAAC;IACb,GAAG,EAAE,CAAC,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ProjectConfig } from "../types/index.js";
2
+ export declare function getProjectConfig(rootPath: string): ProjectConfig;
@@ -0,0 +1,18 @@
1
+ import { join } from "node:path";
2
+ import { createHash } from "node:crypto";
3
+ import { mkdirSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ const DATA_ROOT = join(homedir(), ".sverklo");
6
+ export function getProjectConfig(rootPath) {
7
+ const hash = createHash("sha256").update(rootPath).digest("hex").slice(0, 12);
8
+ const name = rootPath.split("/").pop() || "unknown";
9
+ const dataDir = join(DATA_ROOT, `${name}-${hash}`);
10
+ mkdirSync(dataDir, { recursive: true });
11
+ return {
12
+ rootPath,
13
+ name,
14
+ dataDir,
15
+ dbPath: join(dataDir, "index.db"),
16
+ };
17
+ }
18
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACnD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,OAAO;QACL,QAAQ;QACR,IAAI;QACJ,OAAO;QACP,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type Ignore } from "ignore";
2
+ export declare function createIgnoreFilter(rootPath: string): Ignore;
@@ -0,0 +1,72 @@
1
+ import ignore from "ignore";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ const HARDCODED_IGNORES = [
5
+ "node_modules",
6
+ ".git",
7
+ "dist",
8
+ "build",
9
+ "out",
10
+ "__pycache__",
11
+ ".pytest_cache",
12
+ "vendor",
13
+ ".next",
14
+ ".nuxt",
15
+ ".svelte-kit",
16
+ ".venv",
17
+ "venv",
18
+ "env",
19
+ ".env",
20
+ "target", // Rust
21
+ "Pods", // iOS
22
+ ".gradle",
23
+ "*.min.js",
24
+ "*.min.css",
25
+ "*.map",
26
+ "*.lock",
27
+ "package-lock.json",
28
+ "yarn.lock",
29
+ "pnpm-lock.yaml",
30
+ "*.wasm",
31
+ "*.png",
32
+ "*.jpg",
33
+ "*.jpeg",
34
+ "*.gif",
35
+ "*.ico",
36
+ "*.svg",
37
+ "*.woff",
38
+ "*.woff2",
39
+ "*.ttf",
40
+ "*.eot",
41
+ "*.mp3",
42
+ "*.mp4",
43
+ "*.avi",
44
+ "*.pdf",
45
+ "*.zip",
46
+ "*.tar",
47
+ "*.gz",
48
+ "*.exe",
49
+ "*.dll",
50
+ "*.so",
51
+ "*.dylib",
52
+ "*.bin",
53
+ "*.dat",
54
+ "*.db",
55
+ "*.sqlite",
56
+ ".DS_Store",
57
+ "Thumbs.db",
58
+ ];
59
+ export function createIgnoreFilter(rootPath) {
60
+ const ig = ignore();
61
+ ig.add(HARDCODED_IGNORES);
62
+ const gitignorePath = join(rootPath, ".gitignore");
63
+ if (existsSync(gitignorePath)) {
64
+ ig.add(readFileSync(gitignorePath, "utf-8"));
65
+ }
66
+ const customIgnorePath = join(rootPath, ".sverkloignore");
67
+ if (existsSync(customIgnorePath)) {
68
+ ig.add(readFileSync(customIgnorePath, "utf-8"));
69
+ }
70
+ return ig;
71
+ }
72
+ //# sourceMappingURL=ignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.js","sourceRoot":"","sources":["../../../src/utils/ignore.ts"],"names":[],"mappings":"AAAA,OAAO,MAAuB,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,iBAAiB,GAAG;IACxB,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,aAAa;IACb,eAAe;IACf,QAAQ;IACR,OAAO;IACP,OAAO;IACP,aAAa;IACb,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;IACN,QAAQ,EAAE,OAAO;IACjB,MAAM,EAAE,MAAM;IACd,SAAS;IACT,UAAU;IACV,WAAW;IACX,OAAO;IACP,QAAQ;IACR,mBAAmB;IACnB,WAAW;IACX,gBAAgB;IAChB,QAAQ;IACR,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,SAAS;IACT,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,SAAS;IACT,OAAO;IACP,OAAO;IACP,MAAM;IACN,UAAU;IACV,WAAW;IACX,WAAW;CACZ,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEpB,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAE1B,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAC1D,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function log(msg: string, ...args: unknown[]): void;
2
+ export declare function logError(msg: string, err?: unknown): void;
@@ -0,0 +1,16 @@
1
+ const LOG_ENABLED = process.env.SVERKLO_DEBUG === "1";
2
+ export function log(msg, ...args) {
3
+ if (LOG_ENABLED) {
4
+ process.stderr.write(`[sverklo] ${msg}\n`);
5
+ if (args.length > 0) {
6
+ process.stderr.write(JSON.stringify(args, null, 2) + "\n");
7
+ }
8
+ }
9
+ }
10
+ export function logError(msg, err) {
11
+ process.stderr.write(`[sverklo:error] ${msg}\n`);
12
+ if (err instanceof Error) {
13
+ process.stderr.write(` ${err.message}\n`);
14
+ }
15
+ }
16
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,CAAC;AAEtD,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,GAAG,IAAe;IACjD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,GAAa;IACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function estimateTokens(text: string): number;
2
+ export declare function truncateToTokenBudget(text: string, budget: number): string;
@@ -0,0 +1,12 @@
1
+ // Fast token count approximation. ~1 token per 4 chars for code.
2
+ // Good enough for budget management. Exact counting is too slow per-chunk.
3
+ export function estimateTokens(text) {
4
+ return Math.ceil(text.length / 3.5);
5
+ }
6
+ export function truncateToTokenBudget(text, budget) {
7
+ const charBudget = Math.floor(budget * 3.5);
8
+ if (text.length <= charBudget)
9
+ return text;
10
+ return text.slice(0, charBudget) + "\n// ... truncated";
11
+ }
12
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/utils/tokens.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,IAAY,EACZ,MAAc;IAEd,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,MAAM,IAAI,UAAU;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,oBAAoB,CAAC;AAC1D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "sverklo",
3
+ "version": "0.1.0",
4
+ "description": "Sverklo — local-first code intelligence MCP server. Hybrid search, PageRank ranking, semantic embeddings. Zero config.",
5
+ "type": "module",
6
+ "bin": {
7
+ "sverklo": "dist/bin/sverklo.js"
8
+ },
9
+ "main": "./dist/src/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "start": "node dist/bin/sverklo.js",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "lint": "eslint src/",
22
+ "prepublishOnly": "rm -rf dist && npm run build"
23
+ },
24
+ "keywords": [
25
+ "sverklo",
26
+ "mcp",
27
+ "code-search",
28
+ "semantic-search",
29
+ "codebase-indexing",
30
+ "pagerank",
31
+ "claude-code",
32
+ "cursor",
33
+ "ai-coding",
34
+ "developer-tools",
35
+ "code-intelligence"
36
+ ],
37
+ "homepage": "https://github.com/nicenemo/sverklo",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/nicenemo/sverklo.git"
41
+ },
42
+ "license": "MIT",
43
+ "engines": {
44
+ "node": ">=20"
45
+ },
46
+ "dependencies": {
47
+ "@modelcontextprotocol/sdk": "^1.12.0",
48
+ "better-sqlite3": "^11.7.0",
49
+ "chokidar": "^4.0.0",
50
+ "ignore": "^7.0.0",
51
+ "onnxruntime-node": "^1.21.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/better-sqlite3": "^7.6.12",
55
+ "@types/node": "^22.0.0",
56
+ "typescript": "^5.7.0",
57
+ "vitest": "^3.0.0"
58
+ }
59
+ }