scai 0.1.71 → 0.1.73

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.
@@ -3,7 +3,7 @@ import path from 'path';
3
3
  import readline from 'readline';
4
4
  import { queryFiles, indexFile } from '../db/fileIndex.js';
5
5
  import { summaryModule } from '../pipeline/modules/summaryModule.js';
6
- import { summarizeCode } from '../utils/summarizer.js';
6
+ import { styleOutput } from '../utils/summarizer.js';
7
7
  import { detectFileType } from '../fileRules/detectFileType.js';
8
8
  import { generateEmbedding } from '../lib/generateEmbedding.js';
9
9
  import { sanitizeQueryForFts } from '../utils/sanitizeQuery.js';
@@ -31,7 +31,7 @@ export async function summarizeFile(filepath) {
31
31
  const match = matches.find(row => path.resolve(row.path) === filePathResolved);
32
32
  if (match?.summary) {
33
33
  console.log(`🧠 Cached summary for ${filepath}:\n`);
34
- console.log(summarizeCode(match.summary));
34
+ console.log(styleOutput(match.summary));
35
35
  return;
36
36
  }
37
37
  try {
@@ -64,7 +64,7 @@ export async function summarizeFile(filepath) {
64
64
  console.warn('⚠️ No summary generated.');
65
65
  return;
66
66
  }
67
- console.log(summarizeCode(response.summary));
67
+ console.log(styleOutput(response.summary));
68
68
  if (filePathResolved) {
69
69
  const fileType = detectFileType(filePathResolved);
70
70
  indexFile(filePathResolved, response.summary, fileType);
@@ -30,15 +30,22 @@ export async function autoInitIfNeeded() {
30
30
  }
31
31
  }
32
32
  }
33
- // 🗨 Prompt user
33
+ // 🗨 Prompt user with 10-second timeout
34
34
  function promptUser(question) {
35
35
  if (isYesMode)
36
36
  return Promise.resolve('y');
37
37
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
38
- return new Promise((resolve) => rl.question(question, (a) => {
39
- rl.close();
40
- resolve(a.trim());
41
- }));
38
+ return new Promise((resolve) => {
39
+ const timer = setTimeout(() => {
40
+ rl.close();
41
+ resolve('');
42
+ }, 10000); // 10 second timeout
43
+ rl.question(question, (answer) => {
44
+ clearTimeout(timer);
45
+ rl.close();
46
+ resolve(answer.trim());
47
+ });
48
+ });
42
49
  }
43
50
  // 🧭 Cross-platform browser opener
44
51
  function openBrowser(url) {
@@ -75,36 +82,43 @@ async function ensureOllamaRunning() {
75
82
  return;
76
83
  }
77
84
  console.log(chalk.yellow('⚙️ Ollama is not running. Attempting to start it...'));
85
+ let ollamaStarted = false;
78
86
  try {
79
87
  const child = spawn('ollama', ['serve'], {
80
88
  detached: true,
81
89
  stdio: 'ignore',
82
90
  windowsHide: true,
83
91
  });
84
- child.on('error', async (err) => {
85
- if (err.code === 'ENOENT') {
86
- console.log(chalk.red('❌ Ollama is not installed or not in PATH.'));
87
- console.log(chalk.yellow(`📦 Ollama is required to run local AI models.`));
88
- const answer = await promptUser('🌐 Would you like to open the download page in your browser? (y/N): ');
89
- if (answer.toLowerCase() === 'y') {
90
- openBrowser(OLLAMA_URL);
91
- }
92
- process.exit(1);
93
- }
94
- });
95
92
  child.unref();
96
- await new Promise((res) => setTimeout(res, 3000));
93
+ await new Promise((res) => setTimeout(res, 10000));
97
94
  if (await isOllamaRunning()) {
98
95
  console.log(chalk.green('✅ Ollama started successfully.'));
99
96
  ollamaAvailable = true;
97
+ return;
100
98
  }
101
- else {
102
- console.log(chalk.red('❌ Ollama did not start within timeout.'));
99
+ }
100
+ catch (err) {
101
+ if (err.code !== 'ENOENT') {
102
+ console.log(chalk.red('❌ Unexpected error starting Ollama.'));
103
103
  process.exit(1);
104
104
  }
105
105
  }
106
- catch {
107
- console.log(chalk.red('❌ Unexpected error starting Ollama.'));
106
+ // If we get here, Ollama likely isn't installed
107
+ console.log(chalk.red('❌ Ollama is not installed or not in PATH.'));
108
+ console.log(chalk.yellow(`📦 Ollama is required to run local AI models.`));
109
+ const answer = await promptUser('🌐 Would you like to open the download page in your browser? (y/N): ');
110
+ if (answer.toLowerCase() === 'y') {
111
+ openBrowser(OLLAMA_URL);
112
+ }
113
+ console.log(chalk.yellow('⏳ Waiting for you to install Ollama and press Enter to continue...'));
114
+ await promptUser('👉 Press Enter once Ollama is installed and ready: ');
115
+ // Retry once
116
+ if (await isOllamaRunning()) {
117
+ console.log(chalk.green('✅ Ollama detected. Continuing...'));
118
+ ollamaAvailable = true;
119
+ }
120
+ else {
121
+ console.log(chalk.red('❌ Ollama still not detected. Please check your installation.'));
108
122
  process.exit(1);
109
123
  }
110
124
  }
@@ -1,5 +1,5 @@
1
1
  import columnify from 'columnify';
2
- export function summarizeCode(summaryText) {
2
+ export function styleOutput(summaryText) {
3
3
  const terminalWidth = process.stdout.columns || 80;
4
4
  // You can control wrapping here
5
5
  const formatted = columnify([{ Summary: summaryText }], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"