sapper-iq 1.0.23 → 1.0.25

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/sapper.mjs +26 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "AI-powered development assistant that executes commands and builds projects",
5
5
  "main": "sapper.mjs",
6
6
  "bin": {
package/sapper.mjs CHANGED
@@ -11,6 +11,14 @@ import { dirname, join } from 'path';
11
11
  const __filename = fileURLToPath(import.meta.url);
12
12
  const __dirname = dirname(__filename);
13
13
 
14
+ // Prevent process from exiting on unhandled errors
15
+ process.on('uncaughtException', (err) => {
16
+ console.error(chalk.red('\n❌ Uncaught exception:'), err.message);
17
+ });
18
+ process.on('unhandledRejection', (reason) => {
19
+ console.error(chalk.red('\n❌ Unhandled rejection:'), reason);
20
+ });
21
+
14
22
  // Initialize versioning
15
23
  let CURRENT_VERSION = "1.1.0";
16
24
  try {
@@ -30,9 +38,19 @@ let rl = readline.createInterface({
30
38
  });
31
39
 
32
40
  async function safeQuestion(query) {
33
- return new Promise((resolve) => {
41
+ return new Promise((resolve, reject) => {
34
42
  process.stdout.write(query);
35
43
  rl.once('line', (answer) => { resolve(answer.trim()); });
44
+ rl.once('close', () => {
45
+ // Readline was closed - recreate it and try again
46
+ recreateReadline();
47
+ resolve(''); // Return empty string to continue the loop
48
+ });
49
+ rl.once('error', (err) => {
50
+ console.error(chalk.red('Readline error:'), err.message);
51
+ recreateReadline();
52
+ resolve('');
53
+ });
36
54
  });
37
55
  }
38
56
 
@@ -166,7 +184,8 @@ WORKFLOW:
166
184
  }];
167
185
  }
168
186
 
169
- const ask = async () => {
187
+ // Main conversation loop - never exits unless user types 'exit'
188
+ while (true) {
170
189
  try {
171
190
  const input = await safeQuestion(chalk.blue.bold('\nIbrahim ➔ '));
172
191
 
@@ -182,7 +201,7 @@ WORKFLOW:
182
201
  role: 'system',
183
202
  content: messages[0].content // Keep system prompt
184
203
  }];
185
- return await ask();
204
+ continue;
186
205
  }
187
206
 
188
207
  messages.push({ role: 'user', content: input });
@@ -201,7 +220,8 @@ WORKFLOW:
201
220
  } catch (ollamaError) {
202
221
  spinner.stop();
203
222
  console.error(chalk.red('\n❌ Ollama error:'), ollamaError.message);
204
- return await ask();
223
+ active = false;
224
+ continue;
205
225
  }
206
226
  spinner.stop();
207
227
 
@@ -265,11 +285,9 @@ WORKFLOW:
265
285
  }
266
286
  } catch (error) {
267
287
  console.error(chalk.red('\n❌ Error:'), error.message);
288
+ // Loop continues automatically
268
289
  }
269
- // ALWAYS call ask() again with await - keep the conversation going
270
- await ask();
271
- };
272
- await ask();
290
+ }
273
291
  }
274
292
 
275
293
  runSapper();