scai 0.1.28 → 0.1.30
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/commands/AskCmd.js +34 -10
- package/dist/commands/BackupCmd.js +12 -0
- package/dist/commands/ResetDbCmd.js +4 -29
- package/dist/config/IgnoredExtensions.js +46 -49
- package/dist/config/StopWords.js +21 -15
- package/dist/db/backup.js +28 -0
- package/dist/index.js +13 -8
- package/package.json +1 -1
package/dist/commands/AskCmd.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import readline from 'readline';
|
|
2
|
-
import
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { searchFiles, queryFiles } from "../db/fileIndex.js";
|
|
4
|
+
import { sanitizeQueryForFts } from "../utils/sanitizeQuery.js";
|
|
3
5
|
import { generate } from "../lib/generate.js";
|
|
4
6
|
export async function runAskCommand(query) {
|
|
5
7
|
if (!query) {
|
|
@@ -12,21 +14,43 @@ export async function runAskCommand(query) {
|
|
|
12
14
|
}
|
|
13
15
|
console.log(`🔍 Searching for: "${query}"\n`);
|
|
14
16
|
const start = Date.now();
|
|
15
|
-
const
|
|
17
|
+
const semanticResults = await searchFiles(query, 5);
|
|
16
18
|
const duration = Date.now() - start;
|
|
17
|
-
console.log(`⏱️ searchFiles took ${duration}ms and returned ${
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
console.log(`⏱️ searchFiles took ${duration}ms and returned ${semanticResults.length} result(s)`);
|
|
20
|
+
// Also run fallback keyword search
|
|
21
|
+
const safeQuery = sanitizeQueryForFts(query);
|
|
22
|
+
const fallbackResults = queryFiles(safeQuery, 10);
|
|
23
|
+
// Merge semantic and fallback results
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const combinedResults = [];
|
|
26
|
+
for (const file of semanticResults) {
|
|
27
|
+
const resolved = path.resolve(file.path);
|
|
28
|
+
seen.add(resolved);
|
|
29
|
+
combinedResults.push(file); // Already scored
|
|
30
|
+
}
|
|
31
|
+
for (const file of fallbackResults) {
|
|
32
|
+
const resolved = path.resolve(file.path);
|
|
33
|
+
if (!seen.has(resolved)) {
|
|
34
|
+
seen.add(resolved);
|
|
35
|
+
combinedResults.push({
|
|
36
|
+
path: file.path,
|
|
37
|
+
summary: file.summary,
|
|
38
|
+
score: 0.0, // fallback score
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (combinedResults.length > 0) {
|
|
43
|
+
console.log('📊 Closest files based on semantic + keyword match:');
|
|
44
|
+
combinedResults.forEach((file, i) => {
|
|
45
|
+
console.log(` ${i + 1}. 📄 Path: ${file.path} | Score: ${file.score?.toFixed(3) ?? 'fallback'}`);
|
|
22
46
|
});
|
|
23
47
|
}
|
|
24
48
|
else {
|
|
25
|
-
console.log('⚠️ No similar
|
|
49
|
+
console.log('⚠️ No similar files found. Asking the model for context only...');
|
|
26
50
|
}
|
|
27
|
-
//
|
|
51
|
+
// Aggregate summaries
|
|
28
52
|
let allSummaries = '';
|
|
29
|
-
for (const file of
|
|
53
|
+
for (const file of combinedResults) {
|
|
30
54
|
if (!file?.summary) {
|
|
31
55
|
console.warn(`⚠️ No summary available for file: ${file?.path}`);
|
|
32
56
|
continue;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/commands/BackupCmd.ts
|
|
2
|
+
import { backupScaiFolder } from '../db/backup.js';
|
|
3
|
+
export async function runBackupCommand() {
|
|
4
|
+
console.log('🔁 Backing up .scai folder...');
|
|
5
|
+
const result = await backupScaiFolder();
|
|
6
|
+
if (result) {
|
|
7
|
+
console.log('✅ Backup complete.');
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
console.error('❌ Backup failed.');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,34 +1,9 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import fsp from 'fs/promises';
|
|
3
|
-
import { db } from '../db/client.js';
|
|
4
|
-
import { DB_PATH, SCAI_HOME } from '../constants.js';
|
|
5
|
-
import lockfile from 'proper-lockfile';
|
|
6
2
|
import path from 'path';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
async function backupScaiFolder() {
|
|
12
|
-
const backupDir = getBackupDir();
|
|
13
|
-
try {
|
|
14
|
-
await fsp.mkdir(backupDir, { recursive: true });
|
|
15
|
-
const files = await fsp.readdir(SCAI_HOME);
|
|
16
|
-
for (const file of files) {
|
|
17
|
-
const srcPath = path.join(SCAI_HOME, file);
|
|
18
|
-
const destPath = path.join(backupDir, file);
|
|
19
|
-
const stat = await fsp.stat(srcPath);
|
|
20
|
-
if (stat.isFile()) {
|
|
21
|
-
await fsp.copyFile(srcPath, destPath);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
console.log(`📦 Backed up .scai folder to: ${backupDir}`);
|
|
25
|
-
return backupDir;
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
console.warn('⚠️ Failed to back up .scai folder:', err instanceof Error ? err.message : err);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
3
|
+
import lockfile from 'proper-lockfile';
|
|
4
|
+
import { db } from '../db/client.js';
|
|
5
|
+
import { DB_PATH } from '../constants.js';
|
|
6
|
+
import { backupScaiFolder } from '../db/backup.js'; // <-- New import
|
|
32
7
|
export async function resetDatabase() {
|
|
33
8
|
console.log('🔁 Backing up existing .scai folder...');
|
|
34
9
|
await backupScaiFolder();
|
|
@@ -1,68 +1,65 @@
|
|
|
1
1
|
export const IGNORED_EXTENSIONS = [
|
|
2
|
-
// Media
|
|
2
|
+
// ─── Media Files ─────────────────────────────────────────────
|
|
3
3
|
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico',
|
|
4
4
|
'.mp4', '.mp3', '.mov', '.avi', '.mkv', '.flv', '.wav', '.flac',
|
|
5
5
|
'.aac', '.m4a', '.wma', '.3gp', '.webm', '.ogg', '.aiff', '.au',
|
|
6
|
-
//
|
|
6
|
+
// ─── Archive & Install Packages ─────────────────────────────
|
|
7
7
|
'.zip', '.tar', '.gz', '.bz2', '.xz', '.rar', '.7z',
|
|
8
8
|
'.jar', '.war', '.ear', '.deb', '.rpm', '.pkg', '.msi', '.dmg', '.cab', '.apk',
|
|
9
9
|
'.tar.gz', '.tar.bz2', '.tar.xz', '.tar.lzma', '.tar.zst',
|
|
10
|
-
// Binaries &
|
|
10
|
+
// ─── Binaries & Executables ─────────────────────────────────
|
|
11
11
|
'.exe', '.dll', '.bin', '.so', '.dylib', '.a', '.lib',
|
|
12
|
-
'.iso', '.img', '.elf', '.o', '.obj', '.msm',
|
|
12
|
+
'.iso', '.img', '.elf', '.o', '.obj', '.msm',
|
|
13
13
|
'.cmd', '.bat', '.ps1', '.sh', '.bash', '.run',
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
'.vbs', '.jscript',
|
|
15
|
+
// ─── Build / Runtime Cache ─────────────────────────────────
|
|
16
|
+
'.log', '.tmp', '.map', '.tsbuildinfo', '.coverage', '.eslintcache',
|
|
16
17
|
'.db', '.sqlite', '.pkl', '.sav', '.rdb', '.ldb',
|
|
17
|
-
'.pyc', '.class', '.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'.
|
|
21
|
-
|
|
22
|
-
// Certs, keys, credentials
|
|
18
|
+
'.pyc', '.class', '.yarn', '.webpack', '.babel', '.compilercache',
|
|
19
|
+
// ─── Fonts & Stylesheets ───────────────────────────────────
|
|
20
|
+
'.woff', '.woff2', '.ttf', '.eot', '.otf',
|
|
21
|
+
'.scss', '.sass', '.less', '.styl', '.css.map',
|
|
22
|
+
// ─── Certificates & Keys ───────────────────────────────────
|
|
23
23
|
'.crt', '.key', '.pem', '.pub', '.asc', '.gpg', '.p12', '.csr', '.der', '.pfx',
|
|
24
|
-
// Backups
|
|
25
|
-
'.bak', '.old', '.swp', '.swo', '.orig',
|
|
26
|
-
'.
|
|
27
|
-
|
|
28
|
-
'.
|
|
29
|
-
//
|
|
30
|
-
'.
|
|
31
|
-
|
|
24
|
+
// ─── Backups & Temp Files ──────────────────────────────────
|
|
25
|
+
'.bak', '.bakx', '.old', '.swp', '.swo', '.orig', '.~',
|
|
26
|
+
'.db-shm', '.db-wal',
|
|
27
|
+
'.log.old', '.log.1', '.log.2', '.log.3',
|
|
28
|
+
'.xml.bck', '.wbk', '.asd',
|
|
29
|
+
// ─── Editor / IDE Artifacts ────────────────────────────────
|
|
30
|
+
'.sublime-workspace', '.sublime-project',
|
|
31
|
+
'.iml', '.ipr', '.iws', '.idea', '.code-workspace', '.vscode',
|
|
32
|
+
'.ncb', '.suo', '.user', '.sdf',
|
|
33
|
+
'.classlist', '.nb-gradle', '.gradle',
|
|
34
|
+
// ─── System & OS Metadata ──────────────────────────────────
|
|
35
|
+
'.DS_Store', '.ds_store', '.thumb', '.ini', '.sys', '.lnk',
|
|
36
|
+
'.trash', '.trashes', '.localized', '.spotlight-v100',
|
|
37
|
+
'.~lock', '.appledouble',
|
|
38
|
+
// ─── GIS / Geospatial ──────────────────────────────────────
|
|
39
|
+
'.shp', '.shx', '.dbf', '.prj', '.qix', '.sbn', '.sbx',
|
|
40
|
+
'.shp.xml', '.cpg', '.gpkg', '.mif', '.mid',
|
|
41
|
+
// ─── Business Intelligence / Reporting ─────────────────────
|
|
32
42
|
'.pbix', '.rdl', '.rpt', '.bqy', '.iqy',
|
|
33
|
-
// ETL / DWH / Modeling
|
|
43
|
+
// ─── ETL / DWH / Modeling ──────────────────────────────────
|
|
34
44
|
'.abf', '.dtsx', '.bim', '.xmi',
|
|
35
|
-
// CAD / Engineering
|
|
45
|
+
// ─── CAD / Engineering ─────────────────────────────────────
|
|
36
46
|
'.dwg', '.dxf', '.step', '.stp', '.sldprt', '.sldasm',
|
|
37
47
|
'.iges', '.igs', '.3ds', '.fbx',
|
|
38
|
-
// Forms / Print / Publishing
|
|
48
|
+
// ─── Forms / Print / Publishing ────────────────────────────
|
|
39
49
|
'.xps', '.afpub', '.pub', '.indd', '.qxd', '.frm', '.frx', '.frl',
|
|
40
|
-
// ERP / Finance / Legacy DB
|
|
50
|
+
// ─── ERP / Finance / Legacy DB ─────────────────────────────
|
|
41
51
|
'.mbd', '.fdb', '.nav', '.accdb', '.mdb', '.gdb',
|
|
42
52
|
'.sap', '.sappkg', '.qbw', '.qbb',
|
|
43
|
-
// Lock
|
|
44
|
-
'.lck', '.lockfile', '.db-lock', '.pid', '.socket',
|
|
45
|
-
// Documentation
|
|
46
|
-
'.md',
|
|
47
|
-
|
|
48
|
-
'.
|
|
49
|
-
//
|
|
50
|
-
'.
|
|
51
|
-
'.
|
|
52
|
-
'.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
'.properties', // Java properties files (configuration)
|
|
56
|
-
'.xml.bck', // Backup XML files
|
|
57
|
-
'.bak', // General backup files
|
|
58
|
-
'.swp', // Swap files (e.g., vim/sublime temp files)
|
|
59
|
-
'.swo', // Swap files
|
|
60
|
-
'.orig', // Original backup files
|
|
61
|
-
'.old', // Old version files
|
|
62
|
-
'.~', // Temp files generated by some editors (e.g., vim)
|
|
63
|
-
'.md5', // MD5 checksums
|
|
64
|
-
'.sha1', // SHA1 checksums
|
|
65
|
-
'.sha256', // SHA256 checksums
|
|
66
|
-
'.tmp', // Temporary files
|
|
67
|
-
'.bak', // Backup file (for various applications)
|
|
53
|
+
// ─── Lock Files (Exclude lock *data*, not lock *configs*) ──
|
|
54
|
+
'.lck', '.lock', '.lockfile', '.db-lock', '.pid', '.sock', '.socket',
|
|
55
|
+
// ─── Documentation & Readme ────────────────────────────────
|
|
56
|
+
'.md', '.rst', '.txt',
|
|
57
|
+
// ─── Configuration Files ───────────────────────────────────
|
|
58
|
+
'.json', '.yaml', '.yml', '.xml', '.properties',
|
|
59
|
+
// ─── Scientific & Data Serialization ───────────────────────
|
|
60
|
+
'.npy', '.npz', '.feather', '.parquet', '.orc', '.avro',
|
|
61
|
+
'.hdf5', '.h5', '.rda', '.rds',
|
|
62
|
+
'.csv.gz', '.dump',
|
|
63
|
+
// ─── Misc Hashes & Metadata ────────────────────────────────
|
|
64
|
+
'.md5', '.sha1', '.sha256', '.xlsb', '.xar',
|
|
68
65
|
];
|
package/dist/config/StopWords.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* These common words are ignored from search queries
|
|
3
|
-
* to reduce noise and improve FTS and embedding match quality.
|
|
4
|
-
*/
|
|
5
1
|
export const STOP_WORDS = new Set([
|
|
6
2
|
// Articles & conjunctions
|
|
7
|
-
'a', 'an', 'and', 'but', 'or', 'nor',
|
|
3
|
+
'a', 'an', 'the', 'and', 'but', 'or', 'nor', 'yet', 'so',
|
|
8
4
|
// Prepositions
|
|
9
|
-
'at', 'by', 'for', 'from', 'in', 'into', 'of', 'on', 'to', 'with', 'about', 'above',
|
|
5
|
+
'at', 'by', 'for', 'from', 'in', 'into', 'of', 'on', 'to', 'with', 'about', 'above',
|
|
6
|
+
'below', 'under', 'over', 'through', 'within', 'without', 'across', 'behind', 'near',
|
|
10
7
|
// Pronouns
|
|
11
|
-
'i', 'me', 'my', 'mine', 'you', 'your', 'yours', 'he', 'him', 'his', 'she', 'her', 'hers',
|
|
12
|
-
'we', 'us', 'our', 'ours', 'they', 'them', 'their', 'theirs',
|
|
13
|
-
// Determiners
|
|
8
|
+
'i', 'me', 'my', 'mine', 'you', 'your', 'yours', 'he', 'him', 'his', 'she', 'her', 'hers',
|
|
9
|
+
'it', 'its', 'we', 'us', 'our', 'ours', 'they', 'them', 'their', 'theirs', 'someone', 'something',
|
|
10
|
+
// Determiners & quantifiers
|
|
14
11
|
'this', 'that', 'these', 'those', 'some', 'any', 'each', 'every', 'either', 'neither',
|
|
12
|
+
'few', 'several', 'all', 'many', 'much', 'most', 'more', 'less', 'another',
|
|
15
13
|
// Auxiliary and modal verbs
|
|
16
14
|
'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
17
15
|
'do', 'does', 'did',
|
|
@@ -19,10 +17,18 @@ export const STOP_WORDS = new Set([
|
|
|
19
17
|
'can', 'could', 'shall', 'should', 'will', 'would', 'may', 'might', 'must',
|
|
20
18
|
// Wh-words and generic question words
|
|
21
19
|
'what', 'which', 'who', 'whom', 'whose', 'where', 'when', 'why', 'how',
|
|
22
|
-
//
|
|
23
|
-
'
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
//
|
|
27
|
-
'
|
|
20
|
+
// Common verbs (noisy or generic)
|
|
21
|
+
'use', 'get', 'set', 'make', 'need', 'want', 'let', 'help', 'work',
|
|
22
|
+
'see', 'look', 'like', 'know', 'tell', 'show', 'call', 'create', 'put', 'run',
|
|
23
|
+
'start', 'stop', 'begin', 'end', 'open', 'close',
|
|
24
|
+
// Functional & filler words
|
|
25
|
+
'as', 'if', 'than', 'then', 'there', 'here', 'because', 'so', 'just', 'only',
|
|
26
|
+
'not', 'no', 'also', 'again', 'really', 'actually', 'maybe', 'please',
|
|
27
|
+
'very', 'too', 'quite', 'rather', 'even', 'still', 'ever', 'never',
|
|
28
|
+
'though', 'although', 'indeed', 'perhaps', 'such',
|
|
29
|
+
// Command fluff
|
|
30
|
+
'explain', 'describe', 'define', 'find', 'give', 'provide', 'show',
|
|
31
|
+
'tell', 'check',
|
|
32
|
+
// Miscellaneous low-information words
|
|
33
|
+
'yes', 'no', 'okay', 'ok', 'thing', 'stuff', 'way', 'anything'
|
|
28
34
|
]);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fsp from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { SCAI_HOME } from '../constants.js';
|
|
4
|
+
function getBackupDir() {
|
|
5
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
6
|
+
return path.join(SCAI_HOME, `backup-${timestamp}`);
|
|
7
|
+
}
|
|
8
|
+
export async function backupScaiFolder() {
|
|
9
|
+
const backupDir = getBackupDir();
|
|
10
|
+
try {
|
|
11
|
+
await fsp.mkdir(backupDir, { recursive: true });
|
|
12
|
+
const files = await fsp.readdir(SCAI_HOME);
|
|
13
|
+
for (const file of files) {
|
|
14
|
+
const srcPath = path.join(SCAI_HOME, file);
|
|
15
|
+
const destPath = path.join(backupDir, file);
|
|
16
|
+
const stat = await fsp.stat(srcPath);
|
|
17
|
+
if (stat.isFile()) {
|
|
18
|
+
await fsp.copyFile(srcPath, destPath);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
console.log(`📦 Backed up .scai folder to: ${backupDir}`);
|
|
22
|
+
return backupDir;
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.warn('⚠️ Failed to back up .scai folder:', err instanceof Error ? err.message : err);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { runFindCommand } from './commands/FindCmd.js';
|
|
|
19
19
|
import { startDaemon } from './commands/DaemonCmd.js';
|
|
20
20
|
import { runStopDaemonCommand } from "./commands/StopDaemonCmd.js";
|
|
21
21
|
import { runAskCommand } from './commands/AskCmd.js';
|
|
22
|
+
import { runBackupCommand } from './commands/BackupCmd.js';
|
|
22
23
|
// 🎛️ CLI Setup
|
|
23
24
|
const cmd = new Command('scai')
|
|
24
25
|
.version(version)
|
|
@@ -96,14 +97,6 @@ cmd
|
|
|
96
97
|
.action(() => {
|
|
97
98
|
Config.show();
|
|
98
99
|
});
|
|
99
|
-
// Add explanation about alpha features directly in the help menu
|
|
100
|
-
cmd.addHelpText('after', `
|
|
101
|
-
🚨 Alpha Features:
|
|
102
|
-
- The "index", "daemon", "stop-daemon", "reset-db" commands are considered alpha features.
|
|
103
|
-
- These commands are in active development and may change in the future.
|
|
104
|
-
|
|
105
|
-
💡 Use with caution and expect possible changes or instability.
|
|
106
|
-
`);
|
|
107
100
|
// 🔍 Indexing
|
|
108
101
|
cmd
|
|
109
102
|
.command('index [targetDir]')
|
|
@@ -112,6 +105,10 @@ cmd
|
|
|
112
105
|
.action((targetDir, options) => {
|
|
113
106
|
runIndexCommand(targetDir, { force: options.force });
|
|
114
107
|
});
|
|
108
|
+
cmd
|
|
109
|
+
.command('backup')
|
|
110
|
+
.description('Backup the current .scai folder')
|
|
111
|
+
.action(runBackupCommand);
|
|
115
112
|
// 🧠 Query and assistant
|
|
116
113
|
cmd
|
|
117
114
|
.command('find <query>')
|
|
@@ -150,6 +147,14 @@ cmd
|
|
|
150
147
|
}
|
|
151
148
|
runModulePipelineFromCLI(file, options);
|
|
152
149
|
});
|
|
150
|
+
// Add explanation about alpha features directly in the help menu
|
|
151
|
+
cmd.addHelpText('after', `
|
|
152
|
+
🚨 Alpha Features:
|
|
153
|
+
- The "index", "daemon", "stop-daemon", "reset-db" commands are considered alpha features.
|
|
154
|
+
- These commands are in active development and may change in the future.
|
|
155
|
+
|
|
156
|
+
💡 Use with caution and expect possible changes or instability.
|
|
157
|
+
`);
|
|
153
158
|
// ✅ Parse CLI args
|
|
154
159
|
cmd.parse(process.argv);
|
|
155
160
|
// 🔁 Apply global options post-parse
|