scai 0.1.115 β 0.1.117
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/dist/CHANGELOG.md +7 -1
- package/dist/commands/ResetDbCmd.js +1 -1
- package/dist/commands/ReviewCmd.js +19 -17
- package/dist/daemon/daemonBatch.js +51 -25
- package/dist/db/fileIndex.js +4 -20
- package/dist/db/functionExtractors/extractFromJs.js +204 -109
- package/dist/db/functionExtractors/extractFromTs.js +228 -90
- package/dist/db/schema.js +28 -30
- package/dist/db/sqlTemplates.js +68 -40
- package/dist/fileRules/builtins.js +14 -0
- package/dist/index.js +0 -7
- package/dist/modelSetup.js +45 -6
- package/dist/pipeline/modules/cleanupModule.js +21 -1
- package/dist/scripts/dbcheck.js +222 -277
- package/dist/utils/buildContextualPrompt.js +100 -39
- package/dist/utils/sharedUtils.js +8 -0
- package/package.json +1 -1
- package/dist/commands/MigrateCmd.js +0 -15
package/dist/scripts/dbcheck.js
CHANGED
|
@@ -9,7 +9,6 @@ if (!repoKey) {
|
|
|
9
9
|
console.error("β No active repo found. Use `scai set-index` to set one.");
|
|
10
10
|
process.exit(1);
|
|
11
11
|
}
|
|
12
|
-
// Get the basename (repo name) from the full repoKey (which is the path)
|
|
13
12
|
const repoName = path.basename(repoKey);
|
|
14
13
|
const scaiRepoRoot = path.join(os.homedir(), ".scai", "repos", repoName);
|
|
15
14
|
const dbPath = path.join(scaiRepoRoot, "db.sqlite");
|
|
@@ -18,307 +17,253 @@ if (!fs.existsSync(dbPath)) {
|
|
|
18
17
|
process.exit(1);
|
|
19
18
|
}
|
|
20
19
|
const db = new Database(dbPath);
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
total
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.log(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
console.log(`β
With processing_status = 'skipped': ${stats.withProcessingStatusSkipped}`);
|
|
44
|
-
console.log(`β
With processing_status = 'failed': ${stats.withProcessingStatusFailed}`);
|
|
45
|
-
console.log(`β
With processing_status = 'unprocessed': ${stats.withProcessingStatusUnprocessed}`);
|
|
46
|
-
// === Example Summaries ===
|
|
47
|
-
console.log("\nπ§Ύ Example summaries and embeddings:\n--------------------------");
|
|
48
|
-
console.log("Example summaries (first 50 characters):");
|
|
49
|
-
const summaries = db.prepare(`
|
|
50
|
-
SELECT id, substr(summary, 1, 50) || '...' AS short_summary
|
|
20
|
+
// Utility to log simple table stats
|
|
21
|
+
function tableStats(table, column) {
|
|
22
|
+
const total = db.prepare(`SELECT COUNT(*) AS count FROM ${table}`).get().count;
|
|
23
|
+
let extra = "";
|
|
24
|
+
if (column) {
|
|
25
|
+
const nonNull = db.prepare(`SELECT COUNT(*) AS count FROM ${table} WHERE ${column} IS NOT NULL AND ${column} != ''`).get().count;
|
|
26
|
+
extra = ` | Non-null ${column}: ${nonNull}`;
|
|
27
|
+
}
|
|
28
|
+
console.log(`π ${table}: ${total}${extra}`);
|
|
29
|
+
}
|
|
30
|
+
// === Files Table ===
|
|
31
|
+
console.log("\nπ Table: files");
|
|
32
|
+
tableStats("files", "summary");
|
|
33
|
+
tableStats("files", "embedding");
|
|
34
|
+
const processingStatuses = ["extracted", "skipped", "failed", "unprocessed"];
|
|
35
|
+
for (const status of processingStatuses) {
|
|
36
|
+
const count = db.prepare(`SELECT COUNT(*) AS count FROM files WHERE processing_status = ?`).get(status).count;
|
|
37
|
+
console.log(` Status '${status}': ${count}`);
|
|
38
|
+
}
|
|
39
|
+
// === Example Files ===
|
|
40
|
+
const exampleFiles = db.prepare(`
|
|
41
|
+
SELECT id, filename, substr(summary,1,50) AS summary, substr(embedding,1,50) AS embedding
|
|
51
42
|
FROM files
|
|
52
|
-
WHERE summary IS NOT NULL AND summary != ''
|
|
53
43
|
LIMIT 5
|
|
54
44
|
`).all();
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
console.log("\nπ§Ύ Example Files:");
|
|
46
|
+
exampleFiles.forEach(f => {
|
|
47
|
+
console.log(` [${f.id}] ${f.filename} | summary: "${f.summary}" | embedding: "${f.embedding}"`);
|
|
57
48
|
});
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
// === FTS5 Check ===
|
|
50
|
+
const ftsExists = db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='files_fts'`).get();
|
|
51
|
+
console.log("\nπ FTS5 Table:", ftsExists ? "β
exists" : "β missing");
|
|
52
|
+
// === Functions Table ===
|
|
53
|
+
console.log("\nπ§βπ» Table: functions");
|
|
54
|
+
tableStats("functions");
|
|
55
|
+
const sampleFuncs = db.prepare(`
|
|
56
|
+
SELECT id, name, file_id, substr(content,1,50) AS preview
|
|
57
|
+
FROM functions
|
|
58
|
+
ORDER BY RANDOM()
|
|
63
59
|
LIMIT 5
|
|
64
60
|
`).all();
|
|
65
|
-
|
|
66
|
-
console.log(
|
|
61
|
+
sampleFuncs.forEach(f => {
|
|
62
|
+
console.log(` [${f.id}] ${f.name} (file ${f.file_id}): ${f.preview}`);
|
|
67
63
|
});
|
|
68
|
-
// ===
|
|
69
|
-
console.log("\n
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
else {
|
|
77
|
-
const ftsRowCount = db.prepare(`SELECT COUNT(*) AS count FROM files_fts`).get().count;
|
|
78
|
-
console.log(`β
files_fts table exists. Rows: ${ftsRowCount}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
82
|
-
console.error("β Error while accessing files_fts:", err.message);
|
|
83
|
-
}
|
|
84
|
-
// === Rebuild FTS Index ===
|
|
85
|
-
console.log("\nπ§ Rebuilding FTS5 index...");
|
|
86
|
-
try {
|
|
87
|
-
db.prepare(`INSERT INTO files_fts(files_fts) VALUES ('rebuild')`).run();
|
|
88
|
-
console.log(`β
Rebuild completed.`);
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
console.error("β FTS5 rebuild failed:", err.message);
|
|
92
|
-
}
|
|
93
|
-
// === FTS Search Test ===
|
|
94
|
-
console.log('\nπ Test MATCH query for "minimap":');
|
|
95
|
-
try {
|
|
96
|
-
const minimapMatches = db.prepare(`
|
|
97
|
-
SELECT f.id, f.path
|
|
98
|
-
FROM files f
|
|
99
|
-
JOIN files_fts fts ON f.id = fts.rowid
|
|
100
|
-
WHERE fts.files_fts MATCH 'minimap'
|
|
101
|
-
LIMIT 10
|
|
102
|
-
`).all();
|
|
103
|
-
if (minimapMatches.length === 0) {
|
|
104
|
-
console.warn('β οΈ No matches for "minimap" in FTS index');
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
minimapMatches.forEach(row => {
|
|
108
|
-
console.log(`π ${row.path}`);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
console.error('β Error running MATCH query:', err.message);
|
|
114
|
-
}
|
|
115
|
-
// === Direct LIKE Fallback ===
|
|
116
|
-
console.log('\nπ Direct LIKE query on path for "minimap":');
|
|
117
|
-
const likeMatches = db.prepare(`
|
|
118
|
-
SELECT id, path
|
|
119
|
-
FROM files
|
|
120
|
-
WHERE path LIKE '%minimap%'
|
|
121
|
-
LIMIT 10
|
|
64
|
+
// === Graph Classes Table ===
|
|
65
|
+
console.log("\nπ· Table: graph_classes");
|
|
66
|
+
tableStats("graph_classes");
|
|
67
|
+
const sampleClasses = db.prepare(`
|
|
68
|
+
SELECT id, name, file_id, substr(content,1,50) AS preview
|
|
69
|
+
FROM graph_classes
|
|
70
|
+
ORDER BY RANDOM()
|
|
71
|
+
LIMIT 5
|
|
122
72
|
`).all();
|
|
123
|
-
|
|
124
|
-
console.
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
catch (err) {
|
|
141
|
-
console.error('β Error accessing functions table:', err.message);
|
|
142
|
-
}
|
|
143
|
-
// === Example Functions ===
|
|
144
|
-
console.log('\nπ§ͺ Example extracted functions:');
|
|
145
|
-
try {
|
|
146
|
-
const sampleFunctions = db.prepare(`
|
|
147
|
-
SELECT id, name, start_line, end_line, substr(content, 1, 100) || '...' AS short_body
|
|
148
|
-
FROM functions
|
|
149
|
-
ORDER BY id DESC
|
|
150
|
-
LIMIT 5
|
|
151
|
-
`).all();
|
|
152
|
-
sampleFunctions.forEach(fn => {
|
|
153
|
-
console.log(`πΉ ID: ${fn.id}`);
|
|
154
|
-
console.log(` Name: ${fn.name}`);
|
|
155
|
-
console.log(` Lines: ${fn.start_line}-${fn.end_line}`);
|
|
156
|
-
console.log(` Body: ${fn.short_body}\n`);
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
catch (err) {
|
|
160
|
-
console.error('β Error printing function examples:', err.message);
|
|
161
|
-
}
|
|
162
|
-
// === Function Calls Table Stats ===
|
|
163
|
-
console.log('\nπ Stats for Table: function_calls');
|
|
164
|
-
console.log('-------------------------------------------');
|
|
165
|
-
try {
|
|
166
|
-
const callCount = db.prepare(`SELECT COUNT(*) AS count FROM function_calls`).get().count;
|
|
167
|
-
const topCallers = db.prepare(`
|
|
168
|
-
SELECT caller_id, COUNT(*) AS num_calls
|
|
169
|
-
FROM function_calls
|
|
170
|
-
GROUP BY caller_id
|
|
171
|
-
ORDER BY num_calls DESC
|
|
172
|
-
LIMIT 5
|
|
173
|
-
`).all();
|
|
174
|
-
console.log(`π Total function calls: ${callCount}`);
|
|
175
|
-
console.log('π Top callers:');
|
|
176
|
-
topCallers.forEach(row => {
|
|
177
|
-
console.log(` - Caller ${row.caller_id} made ${row.num_calls} calls`);
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
console.error('β Error accessing function_calls table:', err.message);
|
|
182
|
-
}
|
|
183
|
-
// === Random Summary Samples ===
|
|
184
|
-
console.log('\nπ§Ύ Random Summaries (ID + Preview):');
|
|
185
|
-
console.log('-------------------------------------------');
|
|
186
|
-
const randomSummaries = db.prepare(`
|
|
187
|
-
SELECT id, filename, substr(summary, 1, 1000) || '...' AS preview
|
|
188
|
-
FROM files
|
|
189
|
-
WHERE summary IS NOT NULL AND summary != ''
|
|
73
|
+
sampleClasses.forEach(c => {
|
|
74
|
+
console.log(` [${c.id}] ${c.name} (file ${c.file_id}): ${c.preview}`);
|
|
75
|
+
});
|
|
76
|
+
// === Graph Edges Table ===
|
|
77
|
+
console.log("\nπ Table: graph_edges");
|
|
78
|
+
tableStats("graph_edges", "relation");
|
|
79
|
+
// Dynamically get column names
|
|
80
|
+
const columns = db.prepare(`PRAGMA table_info(graph_edges)`).all();
|
|
81
|
+
const colNames = columns.map(c => c.name);
|
|
82
|
+
// Determine source/target ID columns
|
|
83
|
+
const sourceCol = colNames.includes("source_id") ? "source_id" : "source_unique_id";
|
|
84
|
+
const targetCol = colNames.includes("target_id") ? "target_id" : "target_unique_id";
|
|
85
|
+
const sampleEdges = db.prepare(`
|
|
86
|
+
SELECT id, source_type, ${sourceCol} AS source_id,
|
|
87
|
+
target_type, ${targetCol} AS target_id,
|
|
88
|
+
relation
|
|
89
|
+
FROM graph_edges
|
|
190
90
|
ORDER BY RANDOM()
|
|
191
91
|
LIMIT 5
|
|
192
92
|
`).all();
|
|
193
|
-
|
|
194
|
-
console.log(
|
|
93
|
+
sampleEdges.forEach(e => {
|
|
94
|
+
console.log(` [${e.id}] ${e.source_type}(${e.source_id}) -[${e.relation}]-> ${e.target_type}(${e.target_id})`);
|
|
195
95
|
});
|
|
196
|
-
// ===
|
|
197
|
-
console.log(
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
SELECT id, name
|
|
201
|
-
FROM
|
|
96
|
+
// === Tags Tables ===
|
|
97
|
+
console.log("\nπ· Table: graph_tags_master");
|
|
98
|
+
tableStats("graph_tags_master");
|
|
99
|
+
const sampleTags = db.prepare(`
|
|
100
|
+
SELECT id, name
|
|
101
|
+
FROM graph_tags_master
|
|
202
102
|
ORDER BY RANDOM()
|
|
203
103
|
LIMIT 5
|
|
204
104
|
`).all();
|
|
205
|
-
|
|
206
|
-
console.log(
|
|
207
|
-
console.log(` ${row.preview}\n`);
|
|
105
|
+
sampleTags.forEach(t => {
|
|
106
|
+
console.log(` [${t.id}] ${t.name}`);
|
|
208
107
|
});
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
LIMIT
|
|
108
|
+
console.log("\nπ Table: graph_entity_tags");
|
|
109
|
+
tableStats("graph_entity_tags");
|
|
110
|
+
const sampleEntityTags = db.prepare(`
|
|
111
|
+
SELECT id, entity_type, entity_unique_id AS entity_id, tag_id
|
|
112
|
+
FROM graph_entity_tags
|
|
113
|
+
ORDER BY RANDOM()
|
|
114
|
+
LIMIT 5
|
|
216
115
|
`).all();
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
116
|
+
sampleEntityTags.forEach(et => {
|
|
117
|
+
console.log(` [${et.id}] ${et.entity_type}(${et.entity_id}) -> tag ${et.tag_id}`);
|
|
118
|
+
});
|
|
119
|
+
// === Function β Edges Check ===
|
|
120
|
+
console.log("\nπΈ Function Calls / CalledBy consistency");
|
|
121
|
+
// 1. Check for edges pointing to missing functions
|
|
122
|
+
const missingFuncs = db.prepare(`
|
|
123
|
+
SELECT e.id, e.source_unique_id, e.target_unique_id
|
|
124
|
+
FROM graph_edges e
|
|
125
|
+
WHERE e.source_type = 'function'
|
|
126
|
+
AND NOT EXISTS (SELECT 1 FROM functions f WHERE f.unique_id = e.source_unique_id)
|
|
127
|
+
UNION
|
|
128
|
+
SELECT e.id, e.source_unique_id, e.target_unique_id
|
|
129
|
+
FROM graph_edges e
|
|
130
|
+
WHERE e.target_type = 'function'
|
|
131
|
+
AND NOT EXISTS (SELECT 1 FROM functions f WHERE f.unique_id = e.target_unique_id)
|
|
132
|
+
LIMIT 10
|
|
225
133
|
`).all();
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.log('\nπ Stats for Table: classes');
|
|
229
|
-
console.log('-------------------------------------------');
|
|
230
|
-
try {
|
|
231
|
-
const classCount = db.prepare(`SELECT COUNT(*) AS count FROM classes`).get().count;
|
|
232
|
-
const distinctClassFiles = db.prepare(`SELECT COUNT(DISTINCT file_id) AS count FROM classes`).get().count;
|
|
233
|
-
console.log(`π· Total classes: ${classCount}`);
|
|
234
|
-
console.log(`π Distinct files: ${distinctClassFiles}`);
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
console.error('β Error accessing classes table:', err.message);
|
|
134
|
+
if (missingFuncs.length === 0) {
|
|
135
|
+
console.log("β
All edges reference valid functions.");
|
|
238
136
|
}
|
|
239
|
-
|
|
240
|
-
console.log(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
SELECT id, name, file_id, start_line, end_line, substr(content, 1, 100) || '...' AS short_body
|
|
244
|
-
FROM classes
|
|
245
|
-
ORDER BY id DESC
|
|
246
|
-
LIMIT 5
|
|
247
|
-
`).all();
|
|
248
|
-
sampleClasses.forEach(cls => {
|
|
249
|
-
console.log(`π· ID: ${cls.id}`);
|
|
250
|
-
console.log(` Name: ${cls.name}`);
|
|
251
|
-
console.log(` File: ${cls.file_id}`);
|
|
252
|
-
console.log(` Lines: ${cls.start_line}-${cls.end_line}`);
|
|
253
|
-
console.log(` Body: ${cls.short_body}\n`);
|
|
137
|
+
else {
|
|
138
|
+
console.log("β Found edges pointing to missing functions:");
|
|
139
|
+
missingFuncs.forEach(e => {
|
|
140
|
+
console.log(` Edge ${e.id}: ${e.source_unique_id} -> ${e.target_unique_id}`);
|
|
254
141
|
});
|
|
255
142
|
}
|
|
256
|
-
|
|
257
|
-
|
|
143
|
+
// 2. Functions with outgoing calls
|
|
144
|
+
const funcWithCalls = db.prepare(`
|
|
145
|
+
SELECT f.id, f.name, COUNT(e.id) AS callCount
|
|
146
|
+
FROM functions f
|
|
147
|
+
JOIN graph_edges e
|
|
148
|
+
ON e.source_type = 'function'
|
|
149
|
+
AND e.source_unique_id = f.unique_id
|
|
150
|
+
GROUP BY f.id
|
|
151
|
+
HAVING callCount > 0
|
|
152
|
+
ORDER BY callCount DESC
|
|
153
|
+
LIMIT 5
|
|
154
|
+
`).all();
|
|
155
|
+
funcWithCalls.forEach(f => {
|
|
156
|
+
console.log(` πΉ Function [${f.id}] ${f.name} has ${f.callCount} outgoing calls`);
|
|
157
|
+
});
|
|
158
|
+
// 3. Functions with incoming calls
|
|
159
|
+
const funcWithCalledBy = db.prepare(`
|
|
160
|
+
SELECT f.id, f.name, COUNT(e.id) AS calledByCount
|
|
161
|
+
FROM functions f
|
|
162
|
+
JOIN graph_edges e
|
|
163
|
+
ON e.target_type = 'function'
|
|
164
|
+
AND e.target_unique_id = f.unique_id
|
|
165
|
+
GROUP BY f.id
|
|
166
|
+
HAVING calledByCount > 0
|
|
167
|
+
ORDER BY calledByCount DESC
|
|
168
|
+
LIMIT 5
|
|
169
|
+
`).all();
|
|
170
|
+
funcWithCalledBy.forEach(f => {
|
|
171
|
+
console.log(` πΈ Function [${f.id}] ${f.name} is called by ${f.calledByCount} functions`);
|
|
172
|
+
});
|
|
173
|
+
// 4. Check for duplicate edges (same sourceβtarget)
|
|
174
|
+
const duplicateEdges = db.prepare(`
|
|
175
|
+
SELECT source_unique_id, target_unique_id, COUNT(*) as dupCount
|
|
176
|
+
FROM graph_edges
|
|
177
|
+
WHERE source_type = 'function' AND target_type = 'function'
|
|
178
|
+
GROUP BY source_unique_id, target_unique_id
|
|
179
|
+
HAVING dupCount > 1
|
|
180
|
+
LIMIT 5
|
|
181
|
+
`).all();
|
|
182
|
+
if (duplicateEdges.length > 0) {
|
|
183
|
+
console.log("β οΈ Duplicate function call edges found:");
|
|
184
|
+
duplicateEdges.forEach(d => {
|
|
185
|
+
console.log(` ${d.source_unique_id} -> ${d.target_unique_id} (x${d.dupCount})`);
|
|
186
|
+
});
|
|
258
187
|
}
|
|
259
|
-
|
|
260
|
-
console.log(
|
|
261
|
-
console.log('-------------------------------------------');
|
|
262
|
-
try {
|
|
263
|
-
const edgeCount = db.prepare(`SELECT COUNT(*) AS count FROM edges`).get().count;
|
|
264
|
-
const distinctRelations = db.prepare(`SELECT COUNT(DISTINCT relation) AS count FROM edges`).get().count;
|
|
265
|
-
console.log(`π Total edges: ${edgeCount}`);
|
|
266
|
-
console.log(`π§© Distinct relations: ${distinctRelations}`);
|
|
188
|
+
else {
|
|
189
|
+
console.log("β
No duplicate function call edges.");
|
|
267
190
|
}
|
|
268
|
-
|
|
269
|
-
|
|
191
|
+
// === File-specific check (AskCmd.ts) ===
|
|
192
|
+
const targetPath = "/Users/rzs/dev/repos/scai/cli/src/commands/AskCmd.ts";
|
|
193
|
+
// --- MUST KEEP: find the file row ---
|
|
194
|
+
const targetFile = db.prepare(`
|
|
195
|
+
SELECT id, path, filename, processing_status
|
|
196
|
+
FROM files
|
|
197
|
+
WHERE path = ?
|
|
198
|
+
`).get(targetPath);
|
|
199
|
+
if (!targetFile) {
|
|
200
|
+
console.log(`β File not found in DB: ${targetPath}`);
|
|
270
201
|
}
|
|
271
|
-
|
|
272
|
-
console.log(
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
SELECT id,
|
|
276
|
-
FROM
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
`).all();
|
|
280
|
-
|
|
281
|
-
|
|
202
|
+
else {
|
|
203
|
+
console.log(`\nπ File found: [${targetFile.id}] ${targetFile.filename} (${targetFile.processing_status})`);
|
|
204
|
+
// --- MUST KEEP: list functions in this file ---
|
|
205
|
+
const funcs = db.prepare(`
|
|
206
|
+
SELECT id, name, unique_id, start_line, end_line
|
|
207
|
+
FROM functions
|
|
208
|
+
WHERE file_id = ?
|
|
209
|
+
ORDER BY start_line
|
|
210
|
+
`).all(targetFile.id);
|
|
211
|
+
console.log(` Functions (${funcs.length}):`);
|
|
212
|
+
funcs.forEach((f) => {
|
|
213
|
+
console.log(` [${f.id}] ${f.name} (${f.unique_id}) lines ${f.start_line}-${f.end_line}`);
|
|
282
214
|
});
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
console.log(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
FROM tags_master
|
|
296
|
-
ORDER BY id DESC
|
|
297
|
-
LIMIT 5
|
|
298
|
-
`).all();
|
|
299
|
-
sampleTags.forEach(tag => {
|
|
300
|
-
console.log(`π· Tag ${tag.id}: ${tag.name}`);
|
|
215
|
+
// --- OPTIONAL: outgoing calls from this fileβs functions ---
|
|
216
|
+
const outgoing = db.prepare(`
|
|
217
|
+
SELECT f.name AS source_name, e.target_unique_id, e.relation
|
|
218
|
+
FROM functions f
|
|
219
|
+
JOIN graph_edges e
|
|
220
|
+
ON e.source_unique_id = f.unique_id
|
|
221
|
+
AND e.source_type = 'function'
|
|
222
|
+
WHERE f.file_id = ?
|
|
223
|
+
`).all(targetFile.id);
|
|
224
|
+
console.log(` Outgoing calls (${outgoing.length}):`);
|
|
225
|
+
outgoing.forEach((o) => {
|
|
226
|
+
console.log(` ${o.source_name} -[${o.relation}]-> ${o.target_unique_id}`);
|
|
301
227
|
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
console.log(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
FROM entity_tags
|
|
315
|
-
ORDER BY id DESC
|
|
316
|
-
LIMIT 10
|
|
317
|
-
`).all();
|
|
318
|
-
sampleEntityTags.forEach(et => {
|
|
319
|
-
console.log(`π EntityTag ${et.id}: ${et.entity_type} ${et.entity_id} -> tag ${et.tag_id}`);
|
|
228
|
+
// --- OPTIONAL: incoming calls to this fileβs functions ---
|
|
229
|
+
const incoming = db.prepare(`
|
|
230
|
+
SELECT f.name AS target_name, e.source_unique_id, e.relation
|
|
231
|
+
FROM functions f
|
|
232
|
+
JOIN graph_edges e
|
|
233
|
+
ON e.target_unique_id = f.unique_id
|
|
234
|
+
AND e.target_type = 'function'
|
|
235
|
+
WHERE f.file_id = ?
|
|
236
|
+
`).all(targetFile.id);
|
|
237
|
+
console.log(` Incoming calls (${incoming.length}):`);
|
|
238
|
+
incoming.forEach((i) => {
|
|
239
|
+
console.log(` ${i.source_unique_id} -[${i.relation}]-> ${i.target_name}`);
|
|
320
240
|
});
|
|
241
|
+
// --- NICE TO HAVE: dangling edges check ---
|
|
242
|
+
const dangling = db.prepare(`
|
|
243
|
+
SELECT e.id, e.source_unique_id, e.target_unique_id, e.relation
|
|
244
|
+
FROM graph_edges e
|
|
245
|
+
WHERE e.source_unique_id IN (SELECT unique_id FROM functions WHERE file_id = ?)
|
|
246
|
+
OR e.target_unique_id IN (SELECT unique_id FROM functions WHERE file_id = ?)
|
|
247
|
+
`).all(targetFile.id, targetFile.id);
|
|
248
|
+
console.log(` Edges referencing this file's functions (dangling check): ${dangling.length}`);
|
|
249
|
+
dangling.forEach((d) => {
|
|
250
|
+
console.log(` Edge ${d.id}: ${d.source_unique_id} -[${d.relation}]-> ${d.target_unique_id}`);
|
|
251
|
+
});
|
|
252
|
+
// --- OPTIONAL: consistency check summary ---
|
|
253
|
+
if (funcs.length > 0 && outgoing.length === 0 && incoming.length === 0 && dangling.length === 0) {
|
|
254
|
+
console.log("β οΈ This file has functions but no graph edges. Possible causes:");
|
|
255
|
+
console.log(" - Edges were never extracted for this file, OR");
|
|
256
|
+
console.log(" - unique_id mismatch between functions and edges.");
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
console.log("β
Edges and functions are consistent for this file.");
|
|
260
|
+
}
|
|
261
|
+
const funcsDebug = db.prepare(`
|
|
262
|
+
SELECT id, name, unique_id
|
|
263
|
+
FROM functions
|
|
264
|
+
WHERE file_id = ?
|
|
265
|
+
`).all(targetFile.id);
|
|
266
|
+
console.log("Funcsdebug:\n");
|
|
267
|
+
console.log(funcsDebug);
|
|
321
268
|
}
|
|
322
|
-
|
|
323
|
-
console.error('β Error accessing entity_tags table:', err.message);
|
|
324
|
-
}
|
|
269
|
+
console.log("\nβ
DB check completed.\n");
|