scai 0.1.39 → 0.1.40
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,53 @@
|
|
|
1
|
+
import { db } from '../db/client.js';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { log } from '../utils/log.js';
|
|
5
|
+
export async function runInspectCommand(fileArg) {
|
|
6
|
+
if (!fileArg) {
|
|
7
|
+
log('❌ Please provide a file path to inspect.');
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const resolvedPath = path.resolve(fileArg).replace(/\\/g, '/');
|
|
11
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
12
|
+
log(`❌ File does not exist: ${resolvedPath}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const file = db
|
|
16
|
+
.prepare(`SELECT * FROM files WHERE REPLACE(path, '\\', '/') = ?`)
|
|
17
|
+
.get(resolvedPath);
|
|
18
|
+
if (!file) {
|
|
19
|
+
log(`❌ File not found in database: ${resolvedPath}`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
log(`🔍 Inspecting: ${resolvedPath}`);
|
|
23
|
+
console.log('----------------------------------------');
|
|
24
|
+
console.log(`🆔 File ID: ${file.id}`);
|
|
25
|
+
console.log(`📄 Indexed at: ${file.indexed_at || '❌ Not yet'}`);
|
|
26
|
+
console.log(`🧠 Summary present: ${file.summary ? '✅' : '❌'}`);
|
|
27
|
+
console.log(`🧠 Embedding present: ${file.embedding ? '✅' : '❌'}`);
|
|
28
|
+
const isExtracted = file.processing_status?.includes('extracted');
|
|
29
|
+
console.log(`📌 Functions extracted: ${isExtracted ? '✅' : '❌'}`);
|
|
30
|
+
console.log(`📆 Extracted at: ${file.functions_extracted_at || '❌ Not yet'}`);
|
|
31
|
+
console.log(`⚙️ Processing status: ${file.processing_status || 'unknown'}`);
|
|
32
|
+
// 📝 Show summary preview
|
|
33
|
+
if (file.summary) {
|
|
34
|
+
console.log('\n📝 Summary:');
|
|
35
|
+
console.log(file.summary.slice(0, 300) + (file.summary.length > 300 ? '...' : ''));
|
|
36
|
+
}
|
|
37
|
+
// 🧑💻 Show extracted functions
|
|
38
|
+
const functions = db
|
|
39
|
+
.prepare(`SELECT name, start_line, end_line FROM functions WHERE file_id = ? ORDER BY start_line ASC`)
|
|
40
|
+
.all(file.id);
|
|
41
|
+
if (functions.length > 0) {
|
|
42
|
+
console.log(`\n🧑💻 Extracted Functions (${functions.length}):`);
|
|
43
|
+
for (const fn of functions) {
|
|
44
|
+
const start = fn.start_line ?? '?';
|
|
45
|
+
const end = fn.end_line ?? '?';
|
|
46
|
+
console.log(`- ${fn.name} (lines ${start}–${end})`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.log('\n🧑💻 Extracted Functions: ❌ None');
|
|
51
|
+
}
|
|
52
|
+
console.log('\n✅ Inspection complete.');
|
|
53
|
+
}
|
|
@@ -10,29 +10,33 @@ import { log } from '../../utils/log.js';
|
|
|
10
10
|
* within each function into the database.
|
|
11
11
|
*/
|
|
12
12
|
export async function extractFromJS(filePath, content, fileId) {
|
|
13
|
-
const ast = parse(content, {
|
|
13
|
+
const ast = parse(content, {
|
|
14
|
+
ecmaVersion: 'latest',
|
|
15
|
+
sourceType: 'module',
|
|
16
|
+
locations: true,
|
|
17
|
+
});
|
|
14
18
|
const functions = [];
|
|
15
19
|
walkSimple(ast, {
|
|
16
20
|
FunctionDeclaration(node) {
|
|
17
21
|
const name = node.id?.name || `${path.basename(filePath)}:<anon>`;
|
|
18
|
-
const
|
|
19
|
-
const
|
|
22
|
+
const start_line = node?.loc?.start.line ?? -1;
|
|
23
|
+
const end_line = node?.loc?.end.line ?? -1;
|
|
20
24
|
const body = content.slice(node.start, node.end);
|
|
21
|
-
functions.push({ name,
|
|
25
|
+
functions.push({ name, start_line, end_line, body });
|
|
22
26
|
},
|
|
23
27
|
FunctionExpression(node) {
|
|
24
28
|
const name = `${path.basename(filePath)}:<anon>`;
|
|
25
|
-
const
|
|
26
|
-
const
|
|
29
|
+
const start_line = node?.loc?.start.line ?? -1;
|
|
30
|
+
const end_line = node?.loc?.end.line ?? -1;
|
|
27
31
|
const body = content.slice(node.start, node.end);
|
|
28
|
-
functions.push({ name,
|
|
32
|
+
functions.push({ name, start_line, end_line, body });
|
|
29
33
|
},
|
|
30
34
|
ArrowFunctionExpression(node) {
|
|
31
35
|
const name = `${path.basename(filePath)}:<anon>`;
|
|
32
|
-
const
|
|
33
|
-
const
|
|
36
|
+
const start_line = node?.loc?.start.line ?? -1;
|
|
37
|
+
const end_line = node?.loc?.end.line ?? -1;
|
|
34
38
|
const body = content.slice(node.start, node.end);
|
|
35
|
-
functions.push({ name,
|
|
39
|
+
functions.push({ name, start_line, end_line, body });
|
|
36
40
|
},
|
|
37
41
|
});
|
|
38
42
|
if (functions.length === 0) {
|
|
@@ -51,14 +55,18 @@ export async function extractFromJS(filePath, content, fileId) {
|
|
|
51
55
|
`).run({
|
|
52
56
|
file_id: fileId,
|
|
53
57
|
name: fn.name,
|
|
54
|
-
start_line: fn.
|
|
55
|
-
end_line: fn.
|
|
58
|
+
start_line: fn.start_line,
|
|
59
|
+
end_line: fn.end_line,
|
|
56
60
|
content: fn.body,
|
|
57
61
|
embedding: JSON.stringify(embedding),
|
|
58
62
|
lang: 'js'
|
|
59
63
|
});
|
|
60
64
|
const callerId = result.lastInsertRowid;
|
|
61
|
-
const fnAst = parse(
|
|
65
|
+
const fnAst = parse(content, {
|
|
66
|
+
ecmaVersion: 'latest',
|
|
67
|
+
sourceType: 'module',
|
|
68
|
+
locations: true,
|
|
69
|
+
});
|
|
62
70
|
const calls = [];
|
|
63
71
|
walkSimple(fnAst, {
|
|
64
72
|
CallExpression(node) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import path from "path";
|
|
2
1
|
// utils/fileClassifier.ts
|
|
2
|
+
import path from 'path';
|
|
3
3
|
export function isGeneratedOrBundledFile(filePath) {
|
|
4
4
|
const base = path.basename(filePath);
|
|
5
|
+
const isMinified = /\.min\.(js|ts)$/.test(base); // ✅ New check
|
|
5
6
|
const isHashNamed = /[-_.](worker|bundle|chunk|[a-f0-9]{6,})\.(js|ts)$/.test(base);
|
|
6
7
|
const isInOutputFolder = /[\\/]dist[\\/]|[\\/]build[\\/]|[\\/]assets[\\/]|[\\/]node_modules[\\/]/i.test(filePath);
|
|
7
|
-
return isHashNamed || isInOutputFolder;
|
|
8
|
+
return isMinified || isHashNamed || isInOutputFolder;
|
|
8
9
|
}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { runStopDaemonCommand } from "./commands/StopDaemonCmd.js";
|
|
|
21
21
|
import { runAskCommand } from './commands/AskCmd.js';
|
|
22
22
|
import { runBackupCommand } from './commands/BackupCmd.js';
|
|
23
23
|
import { runMigrateCommand } from "./commands/MigrateCmd.js";
|
|
24
|
+
import { runInspectCommand } from "./commands/InspectCmd.js";
|
|
24
25
|
// 🎛️ CLI Setup
|
|
25
26
|
const cmd = new Command('scai')
|
|
26
27
|
.version(version)
|
|
@@ -138,6 +139,13 @@ cmd
|
|
|
138
139
|
.command('migrate')
|
|
139
140
|
.description('Run DB migration scripts')
|
|
140
141
|
.action(runMigrateCommand);
|
|
142
|
+
cmd
|
|
143
|
+
.command('inspect')
|
|
144
|
+
.argument('<filepath>', 'Path to the file to inspect')
|
|
145
|
+
.description('Inspect a specific file and print its indexed summary and functions')
|
|
146
|
+
.action(async (filepath) => {
|
|
147
|
+
await runInspectCommand(filepath);
|
|
148
|
+
});
|
|
141
149
|
cmd
|
|
142
150
|
.command('reset-db')
|
|
143
151
|
.description('Delete and reset the SQLite database')
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { db } from "../db/client.js";
|
|
3
3
|
import { log } from "../utils/log.js";
|
|
4
4
|
try {
|
|
5
|
+
// Add `processing_status` column if it doesn't exist
|
|
5
6
|
db.prepare(`
|
|
6
7
|
ALTER TABLE files ADD COLUMN processing_status TEXT DEFAULT 'unprocessed'
|
|
7
8
|
`).run();
|
|
@@ -15,4 +16,19 @@ catch (e) {
|
|
|
15
16
|
log(`❌ Migration failed: ${e instanceof Error ? e.message : e}`);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
try {
|
|
20
|
+
// Add `functions_extracted_at` column if it doesn't exist
|
|
21
|
+
db.prepare(`
|
|
22
|
+
ALTER TABLE files ADD COLUMN functions_extracted_at TEXT
|
|
23
|
+
`).run();
|
|
24
|
+
log('✅ Added functions_extracted_at column.');
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
if (e instanceof Error && e.message.includes('duplicate column name')) {
|
|
28
|
+
log('ℹ️ Column functions_extracted_at already exists. Skipping.');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
log(`❌ Migration failed: ${e instanceof Error ? e.message : e}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
18
34
|
// Add more migration steps here as needed.
|