clast-ai 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.
- package/.claude-plugin/plugin.json +22 -0
- package/.mcp.json +8 -0
- package/LICENSE +21 -0
- package/README.md +419 -0
- package/commands/clast-status.md +9 -0
- package/dist/config/defaults.d.ts +19 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +44 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +48 -0
- package/dist/config/index.js.map +1 -0
- package/dist/db/index.d.ts +16 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +54 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/queries.d.ts +44 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +251 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +94 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/types.d.ts +44 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/llm/comment-generator.d.ts +26 -0
- package/dist/llm/comment-generator.d.ts.map +1 -0
- package/dist/llm/comment-generator.js +106 -0
- package/dist/llm/comment-generator.js.map +1 -0
- package/dist/llm/index.d.ts +24 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +54 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/prompts.d.ts +9 -0
- package/dist/llm/prompts.d.ts.map +1 -0
- package/dist/llm/prompts.js +79 -0
- package/dist/llm/prompts.js.map +1 -0
- package/dist/parser/call-resolver.d.ts +15 -0
- package/dist/parser/call-resolver.d.ts.map +1 -0
- package/dist/parser/call-resolver.js +16 -0
- package/dist/parser/call-resolver.js.map +1 -0
- package/dist/parser/extractor.d.ts +17 -0
- package/dist/parser/extractor.d.ts.map +1 -0
- package/dist/parser/extractor.js +254 -0
- package/dist/parser/extractor.js.map +1 -0
- package/dist/parser/index.d.ts +24 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +190 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/languages.d.ts +11 -0
- package/dist/parser/languages.d.ts.map +1 -0
- package/dist/parser/languages.js +74 -0
- package/dist/parser/languages.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +88 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/register-tools.d.ts +7 -0
- package/dist/server/register-tools.d.ts.map +1 -0
- package/dist/server/register-tools.js +17 -0
- package/dist/server/register-tools.js.map +1 -0
- package/dist/server/tools/clast-call-graph.d.ts +4 -0
- package/dist/server/tools/clast-call-graph.d.ts.map +1 -0
- package/dist/server/tools/clast-call-graph.js +70 -0
- package/dist/server/tools/clast-call-graph.js.map +1 -0
- package/dist/server/tools/clast-comment.d.ts +5 -0
- package/dist/server/tools/clast-comment.d.ts.map +1 -0
- package/dist/server/tools/clast-comment.js +64 -0
- package/dist/server/tools/clast-comment.js.map +1 -0
- package/dist/server/tools/clast-file-summary.d.ts +4 -0
- package/dist/server/tools/clast-file-summary.d.ts.map +1 -0
- package/dist/server/tools/clast-file-summary.js +42 -0
- package/dist/server/tools/clast-file-summary.js.map +1 -0
- package/dist/server/tools/clast-get-context.d.ts +4 -0
- package/dist/server/tools/clast-get-context.d.ts.map +1 -0
- package/dist/server/tools/clast-get-context.js +80 -0
- package/dist/server/tools/clast-get-context.js.map +1 -0
- package/dist/server/tools/clast-reindex.d.ts +5 -0
- package/dist/server/tools/clast-reindex.d.ts.map +1 -0
- package/dist/server/tools/clast-reindex.js +36 -0
- package/dist/server/tools/clast-reindex.js.map +1 -0
- package/dist/server/tools/clast-search.d.ts +4 -0
- package/dist/server/tools/clast-search.d.ts.map +1 -0
- package/dist/server/tools/clast-search.js +29 -0
- package/dist/server/tools/clast-search.js.map +1 -0
- package/dist/server/tools/clast-status.d.ts +5 -0
- package/dist/server/tools/clast-status.d.ts.map +1 -0
- package/dist/server/tools/clast-status.js +23 -0
- package/dist/server/tools/clast-status.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher/gitignore.d.ts +9 -0
- package/dist/watcher/gitignore.d.ts.map +1 -0
- package/dist/watcher/gitignore.js +38 -0
- package/dist/watcher/gitignore.js.map +1 -0
- package/dist/watcher/index.d.ts +23 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +111 -0
- package/dist/watcher/index.js.map +1 -0
- package/package.json +65 -0
- package/skills/clast-explore/SKILL.md +41 -0
- package/src/config/defaults.ts +61 -0
- package/src/config/index.ts +55 -0
- package/src/db/index.ts +63 -0
- package/src/db/queries.ts +332 -0
- package/src/db/schema.ts +106 -0
- package/src/db/types.ts +47 -0
- package/src/llm/comment-generator.ts +131 -0
- package/src/llm/index.ts +80 -0
- package/src/llm/prompts.ts +95 -0
- package/src/parser/call-resolver.ts +17 -0
- package/src/parser/extractor.ts +303 -0
- package/src/parser/index.ts +226 -0
- package/src/parser/languages.ts +86 -0
- package/src/server/index.ts +109 -0
- package/src/server/register-tools.ts +30 -0
- package/src/server/tools/clast-call-graph.ts +82 -0
- package/src/server/tools/clast-comment.ts +76 -0
- package/src/server/tools/clast-file-summary.ts +59 -0
- package/src/server/tools/clast-get-context.ts +97 -0
- package/src/server/tools/clast-reindex.ts +52 -0
- package/src/server/tools/clast-search.ts +38 -0
- package/src/server/tools/clast-status.ts +37 -0
- package/src/types.ts +69 -0
- package/src/watcher/gitignore.ts +42 -0
- package/src/watcher/index.ts +131 -0
- package/tsconfig.json +20 -0
package/dist/db/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import initSqlJs from 'sql.js';
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { initializeSchema } from './schema.js';
|
|
5
|
+
import { Queries } from './queries.js';
|
|
6
|
+
export class ClastDatabase {
|
|
7
|
+
db;
|
|
8
|
+
dbPath;
|
|
9
|
+
saveTimer = null;
|
|
10
|
+
queries;
|
|
11
|
+
constructor(db, dbPath) {
|
|
12
|
+
this.db = db;
|
|
13
|
+
this.dbPath = dbPath;
|
|
14
|
+
initializeSchema(this.db);
|
|
15
|
+
this.queries = new Queries(this.db);
|
|
16
|
+
// Auto-save every 10 seconds
|
|
17
|
+
this.saveTimer = setInterval(() => this.save(), 10000);
|
|
18
|
+
}
|
|
19
|
+
static async open(dbPath) {
|
|
20
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
21
|
+
const SQL = await initSqlJs();
|
|
22
|
+
let db;
|
|
23
|
+
if (existsSync(dbPath)) {
|
|
24
|
+
const buffer = readFileSync(dbPath);
|
|
25
|
+
db = new SQL.Database(buffer);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
db = new SQL.Database();
|
|
29
|
+
}
|
|
30
|
+
return new ClastDatabase(db, dbPath);
|
|
31
|
+
}
|
|
32
|
+
save() {
|
|
33
|
+
try {
|
|
34
|
+
const data = this.db.export();
|
|
35
|
+
writeFileSync(this.dbPath, Buffer.from(data));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error('[clast] Failed to save database:', err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
close() {
|
|
42
|
+
if (this.saveTimer) {
|
|
43
|
+
clearInterval(this.saveTimer);
|
|
44
|
+
this.saveTimer = null;
|
|
45
|
+
}
|
|
46
|
+
this.save();
|
|
47
|
+
this.db.close();
|
|
48
|
+
}
|
|
49
|
+
get raw() {
|
|
50
|
+
return this.db;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export { Queries } from './queries.js';
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAA4B,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,aAAa;IAChB,EAAE,CAAW;IACb,MAAM,CAAS;IACf,SAAS,GAA0C,IAAI,CAAC;IACzD,OAAO,CAAU;IAExB,YAAoB,EAAY,EAAE,MAAc;QAC9C,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEpC,6BAA6B;QAC7B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAc;QAC9B,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhD,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAE9B,IAAI,EAAY,CAAC;QACjB,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,IAAI;QACF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;YAC9B,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;CACF;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Database } from 'sql.js';
|
|
2
|
+
import type { FileRow, AstNodeRow, CallEdgeRow, CommentRow, StatusRow } from './types.js';
|
|
3
|
+
export declare class Queries {
|
|
4
|
+
private db;
|
|
5
|
+
constructor(db: Database);
|
|
6
|
+
private run;
|
|
7
|
+
private get;
|
|
8
|
+
private all;
|
|
9
|
+
private getLastInsertId;
|
|
10
|
+
upsertFile(filePath: string, hash: string, language: string, nodeCount: number): void;
|
|
11
|
+
deleteFile(filePath: string): void;
|
|
12
|
+
getFileHash(filePath: string): string | null;
|
|
13
|
+
getAllFiles(): FileRow[];
|
|
14
|
+
insertNode(node: Omit<AstNodeRow, 'id'>): number;
|
|
15
|
+
insertNodes(nodes: Omit<AstNodeRow, 'id'>[]): number[];
|
|
16
|
+
getNodeById(id: number): AstNodeRow | undefined;
|
|
17
|
+
getNodeByName(name: string): AstNodeRow[];
|
|
18
|
+
getNodesByFile(filePath: string): AstNodeRow[];
|
|
19
|
+
searchNodes(query: string, type?: string, limit?: number): AstNodeRow[];
|
|
20
|
+
insertEdge(edge: Omit<CallEdgeRow, 'id'>): number;
|
|
21
|
+
insertEdges(edges: Omit<CallEdgeRow, 'id'>[]): void;
|
|
22
|
+
getCallersOf(nameOrId: string | number, depth?: number): AstNodeRow[];
|
|
23
|
+
getCalleesOf(nameOrId: string | number, depth?: number): AstNodeRow[];
|
|
24
|
+
getCallEdgesForNode(nodeId: number): {
|
|
25
|
+
outgoing: CallEdgeRow[];
|
|
26
|
+
incoming: CallEdgeRow[];
|
|
27
|
+
};
|
|
28
|
+
insertComment(nodeId: number, text: string, source: 'original' | 'generated'): number;
|
|
29
|
+
getCommentsForNode(nodeId: number): CommentRow[];
|
|
30
|
+
deleteCommentsBySource(nodeId: number, source: 'original' | 'generated'): void;
|
|
31
|
+
getNodeWithContext(name: string): {
|
|
32
|
+
nodes: AstNodeRow[];
|
|
33
|
+
comments: CommentRow[];
|
|
34
|
+
callers: AstNodeRow[];
|
|
35
|
+
callees: AstNodeRow[];
|
|
36
|
+
};
|
|
37
|
+
getStatus(): StatusRow;
|
|
38
|
+
deleteNodesForFile(filePath: string): void;
|
|
39
|
+
resolveEdges(): number;
|
|
40
|
+
getNodesWithoutComments(limit?: number): AstNodeRow[];
|
|
41
|
+
/** Flush the in-memory database to a Uint8Array for saving to disk. */
|
|
42
|
+
export(): Uint8Array;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1F,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAW;gBAET,EAAE,EAAE,QAAQ;IAIxB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,GAAG;IAYX,OAAO,CAAC,GAAG;IAaX,OAAO,CAAC,eAAe;IAUvB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQrF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASlC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK5C,WAAW,IAAI,OAAO,EAAE;IAMxB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM;IAahD,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE;IAetD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI/C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE;IAOzC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAO9C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,UAAU,EAAE;IAgB3E,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,MAAM;IASjD,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI;IAanD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,UAAU,EAAE;IAuBxE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,UAAU,EAAE;IAyBxE,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE;IAczF,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM;IASrF,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAIhD,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAM9E,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;QAChC,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,CAAC;QACtB,OAAO,EAAE,UAAU,EAAE,CAAC;KACvB;IAmBD,SAAS,IAAI,SAAS;IAoBtB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM1C,YAAY,IAAI,MAAM;IAyBtB,uBAAuB,CAAC,KAAK,GAAE,MAAY,GAAG,UAAU,EAAE;IAU1D,uEAAuE;IACvE,MAAM,IAAI,UAAU;CAGrB"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
export class Queries {
|
|
2
|
+
db;
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
}
|
|
6
|
+
run(sql, params = []) {
|
|
7
|
+
this.db.run(sql, params);
|
|
8
|
+
}
|
|
9
|
+
get(sql, params = []) {
|
|
10
|
+
const result = this.db.exec(sql, params);
|
|
11
|
+
if (result.length === 0 || result[0].values.length === 0)
|
|
12
|
+
return undefined;
|
|
13
|
+
const columns = result[0].columns;
|
|
14
|
+
const values = result[0].values[0];
|
|
15
|
+
const obj = {};
|
|
16
|
+
for (let i = 0; i < columns.length; i++) {
|
|
17
|
+
obj[columns[i]] = values[i];
|
|
18
|
+
}
|
|
19
|
+
return obj;
|
|
20
|
+
}
|
|
21
|
+
all(sql, params = []) {
|
|
22
|
+
const result = this.db.exec(sql, params);
|
|
23
|
+
if (result.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
const columns = result[0].columns;
|
|
26
|
+
return result[0].values.map(values => {
|
|
27
|
+
const obj = {};
|
|
28
|
+
for (let i = 0; i < columns.length; i++) {
|
|
29
|
+
obj[columns[i]] = values[i];
|
|
30
|
+
}
|
|
31
|
+
return obj;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
getLastInsertId() {
|
|
35
|
+
const result = this.db.exec('SELECT last_insert_rowid() as id');
|
|
36
|
+
if (result.length > 0 && result[0].values.length > 0) {
|
|
37
|
+
return Number(result[0].values[0][0]);
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
// --- File operations ---
|
|
42
|
+
upsertFile(filePath, hash, language, nodeCount) {
|
|
43
|
+
this.run(`INSERT OR REPLACE INTO files (file_path, hash, language, last_indexed, node_count)
|
|
44
|
+
VALUES (?, ?, ?, ?, ?)`, [filePath, hash, language, Date.now(), nodeCount]);
|
|
45
|
+
}
|
|
46
|
+
deleteFile(filePath) {
|
|
47
|
+
// Manually cascade since sql.js foreign key cascade can be unreliable
|
|
48
|
+
this.run(`DELETE FROM comments WHERE node_id IN (SELECT id FROM ast_nodes WHERE file_path = ?)`, [filePath]);
|
|
49
|
+
this.run(`DELETE FROM call_edges WHERE caller_id IN (SELECT id FROM ast_nodes WHERE file_path = ?)`, [filePath]);
|
|
50
|
+
this.run(`DELETE FROM call_edges WHERE callee_id IN (SELECT id FROM ast_nodes WHERE file_path = ?)`, [filePath]);
|
|
51
|
+
this.run(`DELETE FROM ast_nodes WHERE file_path = ?`, [filePath]);
|
|
52
|
+
this.run(`DELETE FROM files WHERE file_path = ?`, [filePath]);
|
|
53
|
+
}
|
|
54
|
+
getFileHash(filePath) {
|
|
55
|
+
const row = this.get(`SELECT hash FROM files WHERE file_path = ?`, [filePath]);
|
|
56
|
+
return row?.hash ?? null;
|
|
57
|
+
}
|
|
58
|
+
getAllFiles() {
|
|
59
|
+
return this.all(`SELECT * FROM files`);
|
|
60
|
+
}
|
|
61
|
+
// --- Node operations ---
|
|
62
|
+
insertNode(node) {
|
|
63
|
+
this.run(`INSERT INTO ast_nodes (file_path, name, type, signature, start_line, end_line, start_col, end_col, parent_id, language, body_text)
|
|
64
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
65
|
+
node.file_path, node.name, node.type, node.signature,
|
|
66
|
+
node.start_line, node.end_line, node.start_col, node.end_col,
|
|
67
|
+
node.parent_id, node.language, node.body_text,
|
|
68
|
+
]);
|
|
69
|
+
return this.getLastInsertId();
|
|
70
|
+
}
|
|
71
|
+
insertNodes(nodes) {
|
|
72
|
+
const ids = [];
|
|
73
|
+
this.run('BEGIN TRANSACTION');
|
|
74
|
+
try {
|
|
75
|
+
for (const node of nodes) {
|
|
76
|
+
ids.push(this.insertNode(node));
|
|
77
|
+
}
|
|
78
|
+
this.run('COMMIT');
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
this.run('ROLLBACK');
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
return ids;
|
|
85
|
+
}
|
|
86
|
+
getNodeById(id) {
|
|
87
|
+
return this.get(`SELECT * FROM ast_nodes WHERE id = ?`, [id]);
|
|
88
|
+
}
|
|
89
|
+
getNodeByName(name) {
|
|
90
|
+
return this.all(`SELECT * FROM ast_nodes WHERE name = ? ORDER BY file_path, start_line`, [name]);
|
|
91
|
+
}
|
|
92
|
+
getNodesByFile(filePath) {
|
|
93
|
+
return this.all(`SELECT * FROM ast_nodes WHERE file_path = ? ORDER BY start_line`, [filePath]);
|
|
94
|
+
}
|
|
95
|
+
searchNodes(query, type, limit = 20) {
|
|
96
|
+
const pattern = `%${query}%`;
|
|
97
|
+
if (type) {
|
|
98
|
+
return this.all(`SELECT * FROM ast_nodes WHERE name LIKE ? AND type = ? LIMIT ?`, [pattern, type, limit]);
|
|
99
|
+
}
|
|
100
|
+
return this.all(`SELECT * FROM ast_nodes WHERE name LIKE ? LIMIT ?`, [pattern, limit]);
|
|
101
|
+
}
|
|
102
|
+
// --- Edge operations ---
|
|
103
|
+
insertEdge(edge) {
|
|
104
|
+
this.run(`INSERT INTO call_edges (caller_id, callee_id, callee_name, file_path, line)
|
|
105
|
+
VALUES (?, ?, ?, ?, ?)`, [edge.caller_id, edge.callee_id, edge.callee_name, edge.file_path, edge.line]);
|
|
106
|
+
return this.getLastInsertId();
|
|
107
|
+
}
|
|
108
|
+
insertEdges(edges) {
|
|
109
|
+
this.run('BEGIN TRANSACTION');
|
|
110
|
+
try {
|
|
111
|
+
for (const edge of edges) {
|
|
112
|
+
this.insertEdge(edge);
|
|
113
|
+
}
|
|
114
|
+
this.run('COMMIT');
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
this.run('ROLLBACK');
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
getCallersOf(nameOrId, depth = 2) {
|
|
122
|
+
const whereClause = typeof nameOrId === 'number'
|
|
123
|
+
? 'callee_id = ?'
|
|
124
|
+
: 'callee_name = ?';
|
|
125
|
+
const sql = `
|
|
126
|
+
WITH RECURSIVE caller_chain(id, depth) AS (
|
|
127
|
+
SELECT caller_id, 1
|
|
128
|
+
FROM call_edges
|
|
129
|
+
WHERE ${whereClause}
|
|
130
|
+
UNION
|
|
131
|
+
SELECT ce.caller_id, cc.depth + 1
|
|
132
|
+
FROM call_edges ce
|
|
133
|
+
JOIN caller_chain cc ON ce.callee_id = cc.id
|
|
134
|
+
WHERE cc.depth < ?
|
|
135
|
+
)
|
|
136
|
+
SELECT DISTINCT an.* FROM ast_nodes an
|
|
137
|
+
JOIN caller_chain cc ON an.id = cc.id
|
|
138
|
+
ORDER BY an.file_path, an.start_line
|
|
139
|
+
`;
|
|
140
|
+
return this.all(sql, [nameOrId, depth]);
|
|
141
|
+
}
|
|
142
|
+
getCalleesOf(nameOrId, depth = 2) {
|
|
143
|
+
const whereClause = typeof nameOrId === 'number'
|
|
144
|
+
? 'an.id = ?'
|
|
145
|
+
: 'an.name = ?';
|
|
146
|
+
const sql = `
|
|
147
|
+
WITH RECURSIVE callee_chain(id, name, depth) AS (
|
|
148
|
+
SELECT ce.callee_id, ce.callee_name, 1
|
|
149
|
+
FROM call_edges ce
|
|
150
|
+
JOIN ast_nodes an ON ce.caller_id = an.id
|
|
151
|
+
WHERE ${whereClause}
|
|
152
|
+
UNION
|
|
153
|
+
SELECT ce2.callee_id, ce2.callee_name, cc.depth + 1
|
|
154
|
+
FROM call_edges ce2
|
|
155
|
+
JOIN callee_chain cc ON ce2.caller_id = cc.id
|
|
156
|
+
WHERE cc.depth < ? AND cc.id IS NOT NULL
|
|
157
|
+
)
|
|
158
|
+
SELECT DISTINCT an.* FROM ast_nodes an
|
|
159
|
+
JOIN callee_chain cc ON an.id = cc.id
|
|
160
|
+
WHERE cc.id IS NOT NULL
|
|
161
|
+
ORDER BY an.file_path, an.start_line
|
|
162
|
+
`;
|
|
163
|
+
return this.all(sql, [nameOrId, depth]);
|
|
164
|
+
}
|
|
165
|
+
getCallEdgesForNode(nodeId) {
|
|
166
|
+
const outgoing = this.all(`SELECT * FROM call_edges WHERE caller_id = ?`, [nodeId]);
|
|
167
|
+
const incoming = this.all(`SELECT * FROM call_edges WHERE callee_id = ?`, [nodeId]);
|
|
168
|
+
return { outgoing, incoming };
|
|
169
|
+
}
|
|
170
|
+
// --- Comment operations ---
|
|
171
|
+
insertComment(nodeId, text, source) {
|
|
172
|
+
this.run(`INSERT INTO comments (node_id, text, source, generated_at)
|
|
173
|
+
VALUES (?, ?, ?, ?)`, [nodeId, text, source, source === 'generated' ? Date.now() : null]);
|
|
174
|
+
return this.getLastInsertId();
|
|
175
|
+
}
|
|
176
|
+
getCommentsForNode(nodeId) {
|
|
177
|
+
return this.all(`SELECT * FROM comments WHERE node_id = ?`, [nodeId]);
|
|
178
|
+
}
|
|
179
|
+
deleteCommentsBySource(nodeId, source) {
|
|
180
|
+
this.run(`DELETE FROM comments WHERE node_id = ? AND source = ?`, [nodeId, source]);
|
|
181
|
+
}
|
|
182
|
+
// --- Context (combined) ---
|
|
183
|
+
getNodeWithContext(name) {
|
|
184
|
+
const nodes = this.getNodeByName(name);
|
|
185
|
+
if (nodes.length === 0) {
|
|
186
|
+
return { nodes: [], comments: [], callers: [], callees: [] };
|
|
187
|
+
}
|
|
188
|
+
const allComments = [];
|
|
189
|
+
for (const node of nodes) {
|
|
190
|
+
allComments.push(...this.getCommentsForNode(node.id));
|
|
191
|
+
}
|
|
192
|
+
const callers = this.getCallersOf(name, 1);
|
|
193
|
+
const callees = this.getCalleesOf(name, 1);
|
|
194
|
+
return { nodes, comments: allComments, callers, callees };
|
|
195
|
+
}
|
|
196
|
+
// --- Status ---
|
|
197
|
+
getStatus() {
|
|
198
|
+
const result = this.get(`
|
|
199
|
+
SELECT
|
|
200
|
+
(SELECT COUNT(*) FROM files) as files_indexed,
|
|
201
|
+
(SELECT COUNT(*) FROM ast_nodes) as total_nodes,
|
|
202
|
+
(SELECT COUNT(*) FROM call_edges) as total_edges,
|
|
203
|
+
(SELECT COUNT(*) FROM comments) as total_comments,
|
|
204
|
+
(SELECT MAX(last_indexed) FROM files) as last_indexed
|
|
205
|
+
`);
|
|
206
|
+
return result ?? {
|
|
207
|
+
files_indexed: 0,
|
|
208
|
+
total_nodes: 0,
|
|
209
|
+
total_edges: 0,
|
|
210
|
+
total_comments: 0,
|
|
211
|
+
last_indexed: null,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// --- Bulk operations ---
|
|
215
|
+
deleteNodesForFile(filePath) {
|
|
216
|
+
this.run(`DELETE FROM comments WHERE node_id IN (SELECT id FROM ast_nodes WHERE file_path = ?)`, [filePath]);
|
|
217
|
+
this.run(`DELETE FROM call_edges WHERE caller_id IN (SELECT id FROM ast_nodes WHERE file_path = ?)`, [filePath]);
|
|
218
|
+
this.run(`DELETE FROM ast_nodes WHERE file_path = ?`, [filePath]);
|
|
219
|
+
}
|
|
220
|
+
resolveEdges() {
|
|
221
|
+
// Count unresolved before
|
|
222
|
+
const before = this.get(`SELECT COUNT(*) as cnt FROM call_edges WHERE callee_id IS NULL`);
|
|
223
|
+
const beforeCount = before?.cnt ?? 0;
|
|
224
|
+
this.run(`
|
|
225
|
+
UPDATE call_edges
|
|
226
|
+
SET callee_id = (
|
|
227
|
+
SELECT an.id FROM ast_nodes an
|
|
228
|
+
WHERE an.name = call_edges.callee_name
|
|
229
|
+
LIMIT 1
|
|
230
|
+
)
|
|
231
|
+
WHERE callee_id IS NULL
|
|
232
|
+
`);
|
|
233
|
+
const after = this.get(`SELECT COUNT(*) as cnt FROM call_edges WHERE callee_id IS NULL`);
|
|
234
|
+
const afterCount = after?.cnt ?? 0;
|
|
235
|
+
return beforeCount - afterCount;
|
|
236
|
+
}
|
|
237
|
+
getNodesWithoutComments(limit = 100) {
|
|
238
|
+
return this.all(`
|
|
239
|
+
SELECT an.* FROM ast_nodes an
|
|
240
|
+
LEFT JOIN comments c ON an.id = c.node_id
|
|
241
|
+
WHERE c.id IS NULL
|
|
242
|
+
AND an.type IN ('function', 'method', 'class', 'interface', 'struct', 'trait')
|
|
243
|
+
LIMIT ?
|
|
244
|
+
`, [limit]);
|
|
245
|
+
}
|
|
246
|
+
/** Flush the in-memory database to a Uint8Array for saving to disk. */
|
|
247
|
+
export() {
|
|
248
|
+
return this.db.export();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAmEvC,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAiBnD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const SCHEMA_VERSION = 1;
|
|
2
|
+
const CREATE_TABLES = `
|
|
3
|
+
CREATE TABLE IF NOT EXISTS _clast_meta (
|
|
4
|
+
key TEXT PRIMARY KEY,
|
|
5
|
+
value TEXT NOT NULL
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
9
|
+
file_path TEXT PRIMARY KEY,
|
|
10
|
+
hash TEXT NOT NULL,
|
|
11
|
+
language TEXT NOT NULL,
|
|
12
|
+
last_indexed INTEGER NOT NULL,
|
|
13
|
+
node_count INTEGER NOT NULL DEFAULT 0
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS ast_nodes (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
file_path TEXT NOT NULL,
|
|
19
|
+
name TEXT NOT NULL,
|
|
20
|
+
type TEXT NOT NULL,
|
|
21
|
+
signature TEXT NOT NULL DEFAULT '',
|
|
22
|
+
start_line INTEGER NOT NULL,
|
|
23
|
+
end_line INTEGER NOT NULL,
|
|
24
|
+
start_col INTEGER NOT NULL,
|
|
25
|
+
end_col INTEGER NOT NULL,
|
|
26
|
+
parent_id INTEGER,
|
|
27
|
+
language TEXT NOT NULL,
|
|
28
|
+
body_text TEXT NOT NULL DEFAULT '',
|
|
29
|
+
FOREIGN KEY (file_path) REFERENCES files(file_path) ON DELETE CASCADE,
|
|
30
|
+
FOREIGN KEY (parent_id) REFERENCES ast_nodes(id) ON DELETE CASCADE
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_name ON ast_nodes(name);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_type ON ast_nodes(type);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file ON ast_nodes(file_path);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_name_type ON ast_nodes(name, type);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS call_edges (
|
|
39
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
40
|
+
caller_id INTEGER NOT NULL,
|
|
41
|
+
callee_id INTEGER,
|
|
42
|
+
callee_name TEXT NOT NULL,
|
|
43
|
+
file_path TEXT NOT NULL,
|
|
44
|
+
line INTEGER NOT NULL,
|
|
45
|
+
FOREIGN KEY (caller_id) REFERENCES ast_nodes(id) ON DELETE CASCADE,
|
|
46
|
+
FOREIGN KEY (callee_id) REFERENCES ast_nodes(id) ON DELETE SET NULL
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_edges_caller ON call_edges(caller_id);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_edges_callee ON call_edges(callee_id);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_edges_callee_name ON call_edges(callee_name);
|
|
52
|
+
|
|
53
|
+
CREATE TABLE IF NOT EXISTS comments (
|
|
54
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
55
|
+
node_id INTEGER NOT NULL,
|
|
56
|
+
text TEXT NOT NULL,
|
|
57
|
+
source TEXT NOT NULL CHECK(source IN ('original', 'generated')),
|
|
58
|
+
generated_at INTEGER,
|
|
59
|
+
FOREIGN KEY (node_id) REFERENCES ast_nodes(id) ON DELETE CASCADE
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_comments_node ON comments(node_id);
|
|
63
|
+
`;
|
|
64
|
+
export function initializeSchema(db) {
|
|
65
|
+
db.run('PRAGMA foreign_keys = ON');
|
|
66
|
+
const currentVersion = getSchemaVersion(db);
|
|
67
|
+
if (currentVersion < SCHEMA_VERSION) {
|
|
68
|
+
// sql.js doesn't support multi-statement exec with CREATE TABLE IF NOT EXISTS well,
|
|
69
|
+
// so we split and execute each statement
|
|
70
|
+
const statements = CREATE_TABLES.split(';')
|
|
71
|
+
.map(s => s.trim())
|
|
72
|
+
.filter(s => s.length > 0);
|
|
73
|
+
for (const stmt of statements) {
|
|
74
|
+
db.run(stmt);
|
|
75
|
+
}
|
|
76
|
+
setSchemaVersion(db, SCHEMA_VERSION);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function getSchemaVersion(db) {
|
|
80
|
+
try {
|
|
81
|
+
const result = db.exec(`SELECT value FROM _clast_meta WHERE key = 'schema_version'`);
|
|
82
|
+
if (result.length > 0 && result[0].values.length > 0) {
|
|
83
|
+
return parseInt(String(result[0].values[0][0]), 10);
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function setSchemaVersion(db, version) {
|
|
92
|
+
db.run(`INSERT OR REPLACE INTO _clast_meta (key, value) VALUES ('schema_version', ?)`, [String(version)]);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DrB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAY;IAC3C,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAEnC,MAAM,cAAc,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAE5C,IAAI,cAAc,GAAG,cAAc,EAAE,CAAC;QACpC,oFAAoF;QACpF,yCAAyC;QACzC,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE7B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;QACD,gBAAgB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAY;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CACpB,4DAA4D,CAC7D,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAY,EAAE,OAAe;IACrD,EAAE,CAAC,GAAG,CACJ,8EAA8E,EAC9E,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface FileRow {
|
|
2
|
+
file_path: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
language: string;
|
|
5
|
+
last_indexed: number;
|
|
6
|
+
node_count: number;
|
|
7
|
+
}
|
|
8
|
+
export interface AstNodeRow {
|
|
9
|
+
id: number;
|
|
10
|
+
file_path: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
signature: string;
|
|
14
|
+
start_line: number;
|
|
15
|
+
end_line: number;
|
|
16
|
+
start_col: number;
|
|
17
|
+
end_col: number;
|
|
18
|
+
parent_id: number | null;
|
|
19
|
+
language: string;
|
|
20
|
+
body_text: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CallEdgeRow {
|
|
23
|
+
id: number;
|
|
24
|
+
caller_id: number;
|
|
25
|
+
callee_id: number | null;
|
|
26
|
+
callee_name: string;
|
|
27
|
+
file_path: string;
|
|
28
|
+
line: number;
|
|
29
|
+
}
|
|
30
|
+
export interface CommentRow {
|
|
31
|
+
id: number;
|
|
32
|
+
node_id: number;
|
|
33
|
+
text: string;
|
|
34
|
+
source: 'original' | 'generated';
|
|
35
|
+
generated_at: number | null;
|
|
36
|
+
}
|
|
37
|
+
export interface StatusRow {
|
|
38
|
+
files_indexed: number;
|
|
39
|
+
total_nodes: number;
|
|
40
|
+
total_edges: number;
|
|
41
|
+
total_comments: number;
|
|
42
|
+
last_indexed: number | null;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B"}
|
package/dist/db/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LlmClient } from './index.js';
|
|
2
|
+
import type { Queries } from '../db/queries.js';
|
|
3
|
+
import type { ClastConfig } from '../config/index.js';
|
|
4
|
+
export declare class CommentGenerator {
|
|
5
|
+
private client;
|
|
6
|
+
private queries;
|
|
7
|
+
private config;
|
|
8
|
+
constructor(client: LlmClient, queries: Queries, config: ClastConfig);
|
|
9
|
+
get isAvailable(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a comment for a specific node.
|
|
12
|
+
* Returns the generated comment text, or null if generation is disabled/failed.
|
|
13
|
+
*/
|
|
14
|
+
generateForNode(nodeId: number): Promise<string | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Batch generate comments for nodes without any comments.
|
|
17
|
+
* Returns counts of successes and failures.
|
|
18
|
+
*/
|
|
19
|
+
batchGenerate(limit?: number, onProgress?: (current: number, total: number) => void): Promise<{
|
|
20
|
+
success: number;
|
|
21
|
+
failed: number;
|
|
22
|
+
skipped: number;
|
|
23
|
+
}>;
|
|
24
|
+
private buildPrompt;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=comment-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-generator.d.ts","sourceRoot":"","sources":["../../src/llm/comment-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW;IAMpE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;OAGG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsC7D;;;OAGG;IACG,aAAa,CACjB,KAAK,GAAE,MAAY,EACnB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAuChE,OAAO,CAAC,WAAW;CAapB"}
|