kly 0.0.1

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.
@@ -0,0 +1,307 @@
1
+ import { Api, Model } from "@mariozechner/pi-ai";
2
+
3
+ //#region src/types.d.ts
4
+ type Language = "typescript" | "javascript" | "swift";
5
+ type SymbolKind = "class" | "function" | "method" | "interface" | "type" | "enum" | "variable" | "protocol" | "struct";
6
+ interface SymbolInfo {
7
+ name: string;
8
+ kind: SymbolKind;
9
+ description: string;
10
+ }
11
+ interface FileIndex {
12
+ path: string;
13
+ name: string;
14
+ description: string;
15
+ language: Language;
16
+ imports: string[];
17
+ exports: string[];
18
+ symbols: SymbolInfo[];
19
+ summary: string;
20
+ hash: string;
21
+ indexedAt: number;
22
+ }
23
+ interface KlyConfig {
24
+ llm: {
25
+ provider: string;
26
+ model: string;
27
+ apiKey: string;
28
+ };
29
+ include: string[];
30
+ exclude: string[];
31
+ }
32
+ interface ParseResult {
33
+ imports: string[];
34
+ exports: string[];
35
+ symbols: SymbolInfo[];
36
+ }
37
+ interface BranchState {
38
+ lastCommit: string;
39
+ lastBuilt: number;
40
+ forkedFrom?: string;
41
+ }
42
+ interface GitState {
43
+ version: number;
44
+ configHash: string;
45
+ branches: Record<string, BranchState>;
46
+ }
47
+ interface GitCommit {
48
+ hash: string;
49
+ author: string;
50
+ email: string;
51
+ date: number;
52
+ message: string;
53
+ }
54
+ interface ErrorFrame {
55
+ file: string;
56
+ line: number;
57
+ column?: number;
58
+ function?: string;
59
+ }
60
+ interface EnrichedFrame {
61
+ file: string;
62
+ line: number;
63
+ column?: number;
64
+ function?: string;
65
+ fileDescription: string;
66
+ fileSummary: string;
67
+ symbols: SymbolInfo[];
68
+ language: Language;
69
+ importedBy: string[];
70
+ importsFrom: string[];
71
+ lastModified: GitCommit | null;
72
+ recentCommits: GitCommit[];
73
+ }
74
+ interface EnrichedErrorStack {
75
+ frames: EnrichedFrame[];
76
+ affectedFiles: number;
77
+ }
78
+ interface GitDiff {
79
+ added: string[];
80
+ modified: string[];
81
+ deleted: string[];
82
+ renamed: Array<{
83
+ from: string;
84
+ to: string;
85
+ }>;
86
+ }
87
+ //#endregion
88
+ //#region src/config.d.ts
89
+ declare function getKlyDir(root: string): string;
90
+ declare function getConfigPath(root: string): string;
91
+ declare function getDbDir(root: string): string;
92
+ declare function getDbPath(root: string, dbName: string): string;
93
+ declare function getStatePath(root: string): string;
94
+ declare function isInitialized(root: string): boolean;
95
+ declare function initKlyDir(root: string, config?: KlyConfig): void;
96
+ declare function loadConfig(root: string): KlyConfig;
97
+ declare function hashConfig(config: KlyConfig): string;
98
+ //#endregion
99
+ //#region src/database.d.ts
100
+ interface SearchResult {
101
+ file: FileIndex;
102
+ score: number;
103
+ }
104
+ declare class IndexDatabase {
105
+ private db;
106
+ constructor(dbPath: string);
107
+ private init;
108
+ getFile(filePath: string): FileIndex | undefined;
109
+ upsertFile(fileIndex: FileIndex): void;
110
+ upsertFiles(fileIndexes: FileIndex[]): void;
111
+ removeFile(filePath: string): void;
112
+ removeFiles(paths: string[]): void;
113
+ searchFiles(query: string, limit?: number): SearchResult[];
114
+ getAllFiles(): FileIndex[];
115
+ getFileCount(): number;
116
+ getLanguageStats(): Record<string, number>;
117
+ getMetadata(key: string): string | undefined;
118
+ setMetadata(key: string, value: string): void;
119
+ upsertDependencies(fromPath: string, toPaths: string[]): void;
120
+ upsertBatchDependencies(entries: Array<{
121
+ fromPath: string;
122
+ toPaths: string[];
123
+ }>): void;
124
+ removeDependencies(fromPath: string): void;
125
+ removeDependenciesBatch(fromPaths: string[]): void;
126
+ getDependencies(filePath: string): string[];
127
+ getDependents(filePath: string): string[];
128
+ removeAllDependencies(): void;
129
+ close(): void;
130
+ private updateFtsSymbolsText;
131
+ }
132
+ //#endregion
133
+ //#region src/scanner.d.ts
134
+ declare function scanFiles(root: string, config: KlyConfig): Promise<string[]>;
135
+ //#endregion
136
+ //#region src/hasher.d.ts
137
+ declare function hashFile(root: string, filePath: string): string;
138
+ declare function hasChanged(oldHash: string, newHash: string): boolean;
139
+ //#endregion
140
+ //#region src/git.d.ts
141
+ declare function isGitRepo(root: string): boolean;
142
+ declare function getCurrentBranch(root: string): string | null;
143
+ declare function getCurrentCommit(root: string): string;
144
+ declare function getChangedFiles(root: string, from: string, to?: string): GitDiff;
145
+ declare function isAncestor(root: string, ancestor: string, descendant: string): boolean;
146
+ declare function getMergeBase(root: string, a: string, b: string): string | null;
147
+ declare function getFileHistory(root: string, filePath: string, limit?: number): GitCommit[];
148
+ declare function branchToDbName(branch: string | null, commitHash?: string): string;
149
+ //#endregion
150
+ //#region src/store.d.ts
151
+ declare function openDatabase(root: string, dbName?: string): IndexDatabase;
152
+ declare function resolveDbName(root: string): string;
153
+ declare function copyDatabase(root: string, fromName: string, toName: string): void;
154
+ declare function loadState(root: string): GitState;
155
+ declare function saveState(root: string, state: GitState): void;
156
+ declare function getBranchState(state: GitState, dbName: string): BranchState | undefined;
157
+ declare function setBranchState(state: GitState, dbName: string, branchState: BranchState): void;
158
+ declare function getFileFromDb(root: string, filePath: string): FileIndex | undefined;
159
+ declare function getAllFilesFromDb(root: string): FileIndex[];
160
+ declare function listBranchDbs(root: string): string[];
161
+ declare function removeBranchDb(root: string, dbName: string): void;
162
+ //#endregion
163
+ //#region src/diff-filter.d.ts
164
+ interface FilteredDiff {
165
+ toIndex: string[];
166
+ toDelete: string[];
167
+ renamed: Array<{
168
+ from: string;
169
+ to: string;
170
+ }>;
171
+ }
172
+ declare function filterGitDiff(diff: GitDiff, config: KlyConfig): FilteredDiff;
173
+ //#endregion
174
+ //#region src/parser/base.d.ts
175
+ declare abstract class BaseParser {
176
+ abstract readonly extensions: string[];
177
+ abstract parse(content: string, filePath: string): ParseResult;
178
+ supports(filePath: string): boolean;
179
+ }
180
+ //#endregion
181
+ //#region src/parser/index.d.ts
182
+ declare class ParserManager {
183
+ private parsers;
184
+ constructor();
185
+ getParser(filePath: string): BaseParser | undefined;
186
+ parse(content: string, filePath: string): ParseResult | null;
187
+ getLanguage(filePath: string): Language | undefined;
188
+ }
189
+ //#endregion
190
+ //#region src/llm/index.d.ts
191
+ interface LLMIndexResult {
192
+ name: string;
193
+ description: string;
194
+ summary: string;
195
+ symbols: {
196
+ name: string;
197
+ description: string;
198
+ }[];
199
+ }
200
+ declare class LLMService {
201
+ private model;
202
+ private batcher;
203
+ constructor(config: KlyConfig);
204
+ private getEnvKeyName;
205
+ indexFile(filePath: string, content: string, symbols: SymbolInfo[]): Promise<LLMIndexResult>;
206
+ indexFiles(files: {
207
+ path: string;
208
+ content: string;
209
+ symbols: SymbolInfo[];
210
+ }[]): Promise<Map<string, LLMIndexResult>>;
211
+ private parseResponse;
212
+ }
213
+ //#endregion
214
+ //#region src/indexer.d.ts
215
+ interface IndexProgress {
216
+ total: number;
217
+ completed: number;
218
+ current: string;
219
+ skipped: number;
220
+ }
221
+ type ProgressCallback = (progress: IndexProgress) => void;
222
+ interface IndexOptions {
223
+ incremental?: boolean;
224
+ full?: boolean;
225
+ quiet?: boolean;
226
+ onProgress?: ProgressCallback;
227
+ }
228
+ interface BuildResult {
229
+ totalFiles: number;
230
+ newFiles: number;
231
+ updatedFiles: number;
232
+ deletedFiles: number;
233
+ unchangedFiles: number;
234
+ branch: string;
235
+ commit: string;
236
+ durationMs: number;
237
+ }
238
+ declare function buildIndex(root: string, options?: IndexOptions): Promise<BuildResult>;
239
+ //#endregion
240
+ //#region src/query.d.ts
241
+ declare function searchFiles(db: IndexDatabase, query: string, limit?: number): SearchResult[];
242
+ declare function searchFilesWithRerank(db: IndexDatabase, model: Model<Api>, query: string, topK?: number): Promise<SearchResult[]>;
243
+ declare function filterByLanguage(db: IndexDatabase, language: string): FileIndex[];
244
+ declare function filterByPath(db: IndexDatabase, pathPattern: string): FileIndex[];
245
+ //#endregion
246
+ //#region src/llm/reranker.d.ts
247
+ /**
248
+ * Rerank search results using LLM.
249
+ * Takes FTS5 candidates and returns them reordered by semantic relevance.
250
+ */
251
+ declare function rerankResults(model: Model<Api>, query: string, candidates: SearchResult[], topK?: number): Promise<SearchResult[]>;
252
+ //#endregion
253
+ //#region src/graph.d.ts
254
+ type GraphFormat = "json" | "mermaid" | "ascii" | "svg";
255
+ interface GraphNode {
256
+ path: string;
257
+ name: string;
258
+ language: Language;
259
+ }
260
+ interface GraphEdge {
261
+ from: string;
262
+ to: string;
263
+ }
264
+ interface DependencyGraph {
265
+ nodes: Map<string, GraphNode>;
266
+ edges: GraphEdge[];
267
+ }
268
+ declare function isRelativeImport(importPath: string): boolean;
269
+ /**
270
+ * Resolve a relative import path to a file path that exists in the index.
271
+ */
272
+ declare function resolveImport(fromFile: string, importPath: string, indexedPaths: Set<string>): string | undefined;
273
+ /**
274
+ * Build a dependency graph from indexed files.
275
+ */
276
+ declare function buildDependencyGraph(db: IndexDatabase, options?: {
277
+ focus?: string;
278
+ depth?: number;
279
+ }): DependencyGraph;
280
+ /**
281
+ * Generate Mermaid syntax from a dependency graph.
282
+ */
283
+ declare function generateMermaid(graph: DependencyGraph): string;
284
+ /**
285
+ * Render a Mermaid diagram string to ASCII/Unicode art.
286
+ */
287
+ declare function renderGraphAscii(mermaid: string): string;
288
+ /**
289
+ * Render a Mermaid diagram string to SVG.
290
+ */
291
+ declare function renderGraphSvg(mermaid: string): string;
292
+ //#endregion
293
+ //#region src/enrich.d.ts
294
+ /**
295
+ * Enrich error stack frames with file descriptions, dependencies, and git history.
296
+ *
297
+ * For each frame, looks up the file in the kly index and augments it with:
298
+ * - File description, summary, symbols, language (from index)
299
+ * - importedBy / importsFrom (from dependencies table)
300
+ * - Recent git commits (from git log)
301
+ *
302
+ * Frames whose files are not in the index are included with empty/default values.
303
+ */
304
+ declare function enrichErrorStack(db: IndexDatabase, root: string, frames: ErrorFrame[]): EnrichedErrorStack;
305
+ //#endregion
306
+ export { type BranchState, type BuildResult, type DependencyGraph, type EnrichedErrorStack, type EnrichedFrame, type ErrorFrame, type FileIndex, type FilteredDiff, type GitCommit, type GitDiff, type GitState, type GraphEdge, type GraphFormat, type GraphNode, IndexDatabase, type IndexOptions, type IndexProgress, type KlyConfig, LLMService, type Language, type ParseResult, ParserManager, type ProgressCallback, type SearchResult, type SymbolInfo, type SymbolKind, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
307
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { A as getCurrentBranch, B as getConfigPath, C as openDatabase, D as setBranchState, E as saveState, F as isGitRepo, G as hashConfig, H as getDbPath, I as hasChanged, J as loadConfig, K as initKlyDir, L as hashFile, M as getFileHistory, N as getMergeBase, O as branchToDbName, P as isAncestor, R as scanFiles, S as loadState, T as resolveDbName, U as getKlyDir, V as getDbDir, W as getStatePath, _ as copyDatabase, a as searchFilesWithRerank, b as getFileFromDb, c as buildDependencyGraph, d as renderGraphAscii, f as renderGraphSvg, g as filterGitDiff, h as ParserManager, i as searchFiles, j as getCurrentCommit, k as getChangedFiles, l as generateMermaid, m as LLMService, n as filterByLanguage, o as rerankResults, p as resolveImport, q as isInitialized, r as filterByPath, s as buildIndex, t as enrichErrorStack, u as isRelativeImport, v as getAllFilesFromDb, w as removeBranchDb, x as listBranchDbs, y as getBranchState, z as IndexDatabase } from "./enrich-BHaZ2daX.mjs";
2
+ export { IndexDatabase, LLMService, ParserManager, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "kly",
3
+ "version": "0.0.1",
4
+ "description": "Code repository file-level indexing tool for AI agents",
5
+ "homepage": "https://github.com/xinyao27/kly#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/xinyao27/kly/issues"
8
+ },
9
+ "license": "MIT",
10
+ "author": {
11
+ "name": "xinyao",
12
+ "email": "hi@xinyao.me"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/xinyao27/kly.git"
17
+ },
18
+ "funding": "https://github.com/sponsors/xinyao27",
19
+ "bin": {
20
+ "kly": "./dist/cli.mjs"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "type": "module",
26
+ "exports": {
27
+ ".": "./dist/index.mjs",
28
+ "./cli": "./dist/cli.mjs",
29
+ "./package.json": "./package.json"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "dev": "vp pack --watch",
36
+ "build": "vp pack",
37
+ "check": "vp check --fix",
38
+ "lint": "vp lint --fix",
39
+ "fmt": "vp fmt",
40
+ "test": "vp test",
41
+ "test:coverage": "vp test --coverage",
42
+ "prepublishOnly": "npm run build",
43
+ "up": "taze major -Ir",
44
+ "prepare": "vp config",
45
+ "postinstall": "node-gyp rebuild --directory=node_modules/tree-sitter || true",
46
+ "release": "bumpp"
47
+ },
48
+ "dependencies": {
49
+ "@clack/prompts": "^1.1.0",
50
+ "@mariozechner/pi-ai": "^0.63.2",
51
+ "beautiful-mermaid": "^1.1.3",
52
+ "better-sqlite3": "^12.8.0",
53
+ "commander": "^14.0.3",
54
+ "globby": "^16.2.0",
55
+ "p-limit": "^7.3.0",
56
+ "tree-sitter": "^0.25.0",
57
+ "tree-sitter-swift": "^0.7.1",
58
+ "tree-sitter-typescript": "^0.23.2",
59
+ "yaml": "^2.8.3"
60
+ },
61
+ "devDependencies": {
62
+ "@types/better-sqlite3": "^7.6.13",
63
+ "@types/node": "^25.5.0",
64
+ "@types/picomatch": "^4.0.2",
65
+ "@typescript/native-preview": "7.0.0-dev.20260317.1",
66
+ "bumpp": "^11.0.1",
67
+ "taze": "^19.10.0",
68
+ "typescript": "~6.0.2",
69
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
70
+ "vite-plus": "latest"
71
+ },
72
+ "packageManager": "pnpm@10.33.0",
73
+ "pnpm": {
74
+ "overrides": {
75
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
76
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
77
+ }
78
+ },
79
+ "inlinedDependencies": {
80
+ "picomatch": "2.3.1"
81
+ }
82
+ }