scai 0.1.60 ā 0.1.62
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 +1 -1
- package/dist/config.js +5 -6
- package/dist/constants.js +1 -1
- package/dist/index.js +4 -5
- package/dist/modelSetup.js +66 -50
- package/dist/scripts/dbcheck.js +4 -4
- package/package.json +1 -1
package/dist/commands/AskCmd.js
CHANGED
|
@@ -17,7 +17,7 @@ export async function runAskCommand(query) {
|
|
|
17
17
|
console.error('ā No question provided.\nš Usage: scai ask "your question"');
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
console.log(`š Using index root: ${getIndexDir}`);
|
|
20
|
+
console.log(`š Using index root: ${getIndexDir()}`);
|
|
21
21
|
console.log(`š Searching for: "${query}"\n`);
|
|
22
22
|
// š© STEP 1: Semantic Search
|
|
23
23
|
const start = Date.now();
|
package/dist/config.js
CHANGED
|
@@ -6,6 +6,7 @@ import { getRepoKeyForPath, normalizePath } from './utils/normalizePath.js';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
const defaultConfig = {
|
|
8
8
|
model: 'llama3',
|
|
9
|
+
contextLength: 8192,
|
|
9
10
|
language: 'ts',
|
|
10
11
|
indexDir: '',
|
|
11
12
|
githubToken: '',
|
|
@@ -17,7 +18,7 @@ function ensureConfigDir() {
|
|
|
17
18
|
fs.mkdirSync(SCAI_HOME, { recursive: true });
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
function readConfig() {
|
|
21
|
+
export function readConfig() {
|
|
21
22
|
try {
|
|
22
23
|
const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
23
24
|
return { ...defaultConfig, ...JSON.parse(content) };
|
|
@@ -91,9 +92,7 @@ export const Config = {
|
|
|
91
92
|
// Ensure repoKey doesn't contain an absolute path, only the repo name or a relative path
|
|
92
93
|
const scaiRepoRoot = path.join(SCAI_REPOS, path.basename(repoKey)); // Use repo name as key to avoid double paths
|
|
93
94
|
// Set the active repo to the provided indexDir
|
|
94
|
-
|
|
95
|
-
cfg.activeRepo = repoKey;
|
|
96
|
-
await writeConfig(cfg); // Persist the change in activeRepo
|
|
95
|
+
this.setActiveRepo(scaiRepoRoot);
|
|
97
96
|
// Call setRepoIndexDir to update the repo's indexDir and other settings
|
|
98
97
|
await this.setRepoIndexDir(scaiRepoRoot, absPath); // Set the indexDir for the repo
|
|
99
98
|
// Ensure base folders exist
|
|
@@ -103,7 +102,7 @@ export const Config = {
|
|
|
103
102
|
// Init DB if not exists
|
|
104
103
|
const dbPath = path.join(scaiRepoRoot, 'db.sqlite');
|
|
105
104
|
if (!fs.existsSync(dbPath)) {
|
|
106
|
-
console.log(
|
|
105
|
+
console.log(`š¦ Database not found. ${chalk.green('Initializing DB')} at ${normalizePath(dbPath)}`);
|
|
107
106
|
getDbForRepo(); // Now DB creation works after config update
|
|
108
107
|
}
|
|
109
108
|
console.log(`ā
Index directory set to: ${normalizePath(absPath)}`);
|
|
@@ -129,7 +128,7 @@ export const Config = {
|
|
|
129
128
|
},
|
|
130
129
|
setActiveRepo(repoKey) {
|
|
131
130
|
const cfg = readConfig();
|
|
132
|
-
cfg.activeRepo = repoKey;
|
|
131
|
+
cfg.activeRepo = normalizePath(repoKey);
|
|
133
132
|
writeConfig(cfg);
|
|
134
133
|
console.log(`ā
Active repo switched to: ${repoKey}`);
|
|
135
134
|
},
|
package/dist/constants.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import { Command } from "commander";
|
|
3
|
-
import { Config } from './config.js';
|
|
1
|
+
#!/usr/bin/env node
|
|
4
2
|
import { createRequire } from 'module';
|
|
5
3
|
const require = createRequire(import.meta.url);
|
|
6
4
|
const { version } = require('../package.json');
|
|
7
|
-
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { Config } from './config.js';
|
|
8
7
|
import { suggestCommitMessage } from "./commands/CommitSuggesterCmd.js";
|
|
9
8
|
import { handleRefactor } from "./commands/RefactorCmd.js";
|
|
10
9
|
import { generateTests } from "./commands/TestGenCmd.js";
|
|
@@ -27,8 +26,8 @@ import { validateGitHubTokenAgainstRepo } from "./github/githubAuthCheck.js";
|
|
|
27
26
|
import { checkGit } from "./commands/GitCmd.js";
|
|
28
27
|
import { runSwitchCommand, runInteractiveSwitch } from "./commands/SwitchCmd.js";
|
|
29
28
|
import { execSync } from "child_process";
|
|
30
|
-
import { dirname, resolve } from "path";
|
|
31
29
|
import { fileURLToPath } from "url";
|
|
30
|
+
import { dirname, resolve } from "path";
|
|
32
31
|
// šļø CLI Setup
|
|
33
32
|
const cmd = new Command('scai')
|
|
34
33
|
.version(version)
|
package/dist/modelSetup.js
CHANGED
|
@@ -1,96 +1,112 @@
|
|
|
1
1
|
import { spawn, execSync } from 'child_process';
|
|
2
2
|
import * as readline from 'readline';
|
|
3
|
-
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { getDbForRepo } from './db/client.js'; // Ensure this function works correctly
|
|
7
|
+
import { readConfig, writeConfig } from './config.js';
|
|
8
|
+
import { CONFIG_PATH } from './constants.js';
|
|
9
|
+
// Constants
|
|
4
10
|
const MODEL_PORT = 11434;
|
|
5
|
-
const REQUIRED_MODELS = ['llama3', 'mistral']; //
|
|
6
|
-
|
|
11
|
+
const REQUIRED_MODELS = ['llama3', 'mistral']; // Expand as needed
|
|
12
|
+
const isYesMode = process.argv.includes('--yes') || process.env.SCAI_YES === '1';
|
|
13
|
+
// š§ Auto init config/db if missing
|
|
14
|
+
export async function autoInitIfNeeded() {
|
|
15
|
+
const cfg = readConfig();
|
|
16
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
17
|
+
console.log(chalk.green('š ļø Config not found. Initializing...'));
|
|
18
|
+
writeConfig({}); // This will create config.json with defaults
|
|
19
|
+
}
|
|
20
|
+
const activeRepo = cfg.activeRepo && cfg.repos[cfg.activeRepo];
|
|
21
|
+
if (activeRepo) {
|
|
22
|
+
const dbPath = path.join(activeRepo.indexDir, 'scai.db');
|
|
23
|
+
if (!fs.existsSync(dbPath)) {
|
|
24
|
+
console.log(chalk.green('š¦ DB not found. Initializing...'));
|
|
25
|
+
getDbForRepo(); // This creates the DB
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// š Ensure Ollama server is running
|
|
7
30
|
async function ensureOllamaRunning() {
|
|
8
31
|
try {
|
|
9
32
|
const res = await fetch(`http://localhost:${MODEL_PORT}`);
|
|
10
33
|
if (res.ok) {
|
|
11
34
|
console.log('ā
Ollama is already running.');
|
|
35
|
+
return;
|
|
12
36
|
}
|
|
13
37
|
}
|
|
14
|
-
catch
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
else {
|
|
20
|
-
console.error('ā Unexpected error during Ollama health check:', error);
|
|
21
|
-
}
|
|
38
|
+
catch {
|
|
39
|
+
// Continue to spawn below
|
|
40
|
+
}
|
|
41
|
+
console.log(chalk.yellow('āļø Ollama is not running. Starting it in the background...'));
|
|
42
|
+
try {
|
|
22
43
|
const child = spawn('ollama', ['serve'], {
|
|
23
44
|
detached: true,
|
|
24
45
|
stdio: 'ignore',
|
|
25
46
|
windowsHide: true,
|
|
26
47
|
});
|
|
27
48
|
child.unref();
|
|
28
|
-
await new Promise((res) => setTimeout(res, 3000));
|
|
49
|
+
await new Promise((res) => setTimeout(res, 3000));
|
|
50
|
+
console.log('ā
Ollama started.');
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.error('ā Failed to start Ollama:', err);
|
|
54
|
+
process.exit(1);
|
|
29
55
|
}
|
|
30
56
|
}
|
|
31
|
-
//
|
|
57
|
+
// š§° List installed models
|
|
32
58
|
async function getInstalledModels() {
|
|
33
59
|
try {
|
|
34
60
|
const result = execSync('ollama list', { encoding: 'utf-8' });
|
|
35
|
-
|
|
61
|
+
return result
|
|
36
62
|
.split('\n')
|
|
37
|
-
.map((line) => line.split(/\s+/)[0].split(':')[0])
|
|
38
|
-
.filter((model) => REQUIRED_MODELS.includes(model));
|
|
39
|
-
return installedModels;
|
|
63
|
+
.map((line) => line.split(/\s+/)[0].split(':')[0])
|
|
64
|
+
.filter((model) => REQUIRED_MODELS.includes(model));
|
|
40
65
|
}
|
|
41
|
-
catch (
|
|
42
|
-
console.error('ā
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error('ā Could not fetch installed models:', err);
|
|
43
68
|
return [];
|
|
44
69
|
}
|
|
45
70
|
}
|
|
46
|
-
// Prompt user
|
|
71
|
+
// š¬ Prompt user
|
|
47
72
|
function promptUser(question) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return new Promise((resolve) => rl.question(question, (answer) => {
|
|
73
|
+
if (isYesMode)
|
|
74
|
+
return Promise.resolve('y');
|
|
75
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
76
|
+
return new Promise((resolve) => rl.question(question, (a) => {
|
|
53
77
|
rl.close();
|
|
54
|
-
resolve(
|
|
78
|
+
resolve(a.trim());
|
|
55
79
|
}));
|
|
56
80
|
}
|
|
57
|
-
//
|
|
81
|
+
// š„ Download missing models
|
|
58
82
|
async function ensureModelsDownloaded() {
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
console.log('ā
All required models are
|
|
83
|
+
const installed = await getInstalledModels();
|
|
84
|
+
const missing = REQUIRED_MODELS.filter((m) => !installed.includes(m));
|
|
85
|
+
if (!missing.length) {
|
|
86
|
+
console.log('ā
All required models are installed.');
|
|
63
87
|
return;
|
|
64
88
|
}
|
|
65
|
-
console.log(
|
|
66
|
-
const answer = await promptUser('Do you want to download
|
|
89
|
+
console.log(chalk.yellow(`š¦ Missing models: ${missing.join(', ')}`));
|
|
90
|
+
const answer = await promptUser('ā¬ļø Do you want to download them now? (y/N): ');
|
|
67
91
|
if (answer.toLowerCase() !== 'y') {
|
|
68
|
-
console.log('š«
|
|
92
|
+
console.log('š« Aborting due to missing models.');
|
|
69
93
|
process.exit(1);
|
|
70
94
|
}
|
|
71
|
-
for (const model of
|
|
95
|
+
for (const model of missing) {
|
|
72
96
|
try {
|
|
73
|
-
console.log(`ā¬ļø
|
|
97
|
+
console.log(`ā¬ļø Pulling ${model}...`);
|
|
74
98
|
execSync(`ollama pull ${model}`, { stdio: 'inherit' });
|
|
75
|
-
console.log(`ā
|
|
99
|
+
console.log(chalk.green(`ā
Pulled ${model}`));
|
|
76
100
|
}
|
|
77
101
|
catch (err) {
|
|
78
|
-
console.error(`ā Failed to pull ${model}:`, err
|
|
102
|
+
console.error(`ā Failed to pull ${model}:`, err);
|
|
79
103
|
process.exit(1);
|
|
80
104
|
}
|
|
81
105
|
}
|
|
82
106
|
}
|
|
83
|
-
//
|
|
107
|
+
// š Main bootstrap logic
|
|
84
108
|
export async function bootstrap() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Ensure models are downloaded once
|
|
89
|
-
await ensureModelsDownloaded();
|
|
90
|
-
// Now your CLI logic can proceed here...
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.error('ā Error during initialization:', error instanceof Error ? error.message : error);
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
109
|
+
await autoInitIfNeeded();
|
|
110
|
+
await ensureOllamaRunning();
|
|
111
|
+
await ensureModelsDownloaded();
|
|
96
112
|
}
|
package/dist/scripts/dbcheck.js
CHANGED
|
@@ -207,20 +207,20 @@ randomFunctions.forEach(row => {
|
|
|
207
207
|
console.log(` ${row.preview}\n`);
|
|
208
208
|
});
|
|
209
209
|
// === Column View of 100 Files ===
|
|
210
|
-
console.log('\nš Table View: First
|
|
210
|
+
console.log('\nš Table View: First 500 Files');
|
|
211
211
|
console.log('-------------------------------------------');
|
|
212
212
|
const fileRows = db.prepare(`
|
|
213
213
|
SELECT id, filename, type, processing_status, functions_extracted_at, length(summary) AS summary_len
|
|
214
214
|
FROM files
|
|
215
|
-
LIMIT
|
|
215
|
+
LIMIT 500
|
|
216
216
|
`).all();
|
|
217
217
|
console.table(fileRows);
|
|
218
218
|
// === Column View of 100 Functions ===
|
|
219
|
-
console.log('\nš Table View: First
|
|
219
|
+
console.log('\nš Table View: First 500 Functions');
|
|
220
220
|
console.log('-------------------------------------------');
|
|
221
221
|
const functionRows = db.prepare(`
|
|
222
222
|
SELECT id, file_id, name, start_line, end_line, length(content) AS length
|
|
223
223
|
FROM functions
|
|
224
|
-
LIMIT
|
|
224
|
+
LIMIT 500
|
|
225
225
|
`).all();
|
|
226
226
|
console.table(functionRows);
|