sapper-iq 1.1.3 → 1.1.5

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 +36 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
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
@@ -27,7 +27,13 @@ process.on('SIGINT', () => {
27
27
  console.log(chalk.red('\nForce quitting...'));
28
28
  process.exit(1);
29
29
  }
30
- console.log(chalk.yellow('\n\nUse "exit" to close Sapper safely, or Ctrl+C again to force quit.'));
30
+ // Clear current line and move to new one - stops ghost output
31
+ process.stdout.clearLine(0);
32
+ process.stdout.cursorTo(0);
33
+ console.log(chalk.yellow('\nStopping AI stream... (Ctrl+C again to force quit)'));
34
+
35
+ // Reset terminal immediately
36
+ resetTerminal();
31
37
  setTimeout(() => { ctrlCCount = 0; }, 2000); // Reset after 2 seconds
32
38
  });
33
39
 
@@ -294,13 +300,26 @@ PATCH vs WRITE:
294
300
  - Use WRITE only for new files or complete rewrites
295
301
 
296
302
  WORKFLOW:
297
- 1. LIST or SEARCH → 2. READ relevant files → 3. ANALYZE and RESPOND`
303
+ 1. LIST or SEARCH → 2. READ relevant files → 3. ANALYZE and RESPOND
304
+
305
+ IMPORTANT RULES:
306
+ - Be concise. Do not generate repetitive lists or filler text.
307
+ - If a list exceeds 10 items, summarize instead of listing everything.
308
+ - Never repeat the same content multiple times.
309
+ - Stop writing when you've made your point.`
298
310
  }];
299
311
  }
300
312
 
301
313
  // Main conversation loop - never exits unless user types 'exit'
302
314
  while (true) {
303
315
  try {
316
+ // Context size warning - large context causes hangs
317
+ const contextSize = JSON.stringify(messages).length;
318
+ if (contextSize > 32000) {
319
+ console.log(chalk.red.bold('\n⚠️ WARNING: Context is very large (~' + Math.round(contextSize/1024) + 'KB). Sapper might hang.'));
320
+ console.log(chalk.yellow('👉 Suggestion: Type /prune to keep only the latest analysis.'));
321
+ }
322
+
304
323
  const input = await safeQuestion(chalk.blue.bold('\nIbrahim ➔ '));
305
324
 
306
325
  if (input.toLowerCase() === 'exit') process.exit();
@@ -382,10 +401,18 @@ WORKFLOW:
382
401
  spinner.stop();
383
402
 
384
403
  let msg = '';
404
+ const MAX_RESPONSE_LENGTH = 15000; // Guard against infinite loops
405
+
385
406
  process.stdout.write(chalk.white('Sapper: '));
386
407
  for await (const chunk of response) {
387
- process.stdout.write(chunk.message.content);
388
- msg += chunk.message.content;
408
+ const content = chunk.message.content;
409
+ process.stdout.write(content);
410
+ msg += content;
411
+
412
+ if (msg.length > MAX_RESPONSE_LENGTH) {
413
+ console.log(chalk.red('\n\n⚠️ RESPONSE TOO LONG: Forcing stop to prevent infinite loop.'));
414
+ break;
415
+ }
389
416
  }
390
417
  console.log();
391
418
  messages.push({ role: 'assistant', content: msg });
@@ -399,6 +426,8 @@ WORKFLOW:
399
426
  // Prevent infinite tool loops
400
427
  if (toolRounds >= MAX_TOOL_ROUNDS) {
401
428
  console.log(chalk.yellow(`\n⚠️ Tool limit reached (${MAX_TOOL_ROUNDS} rounds). Stopping auto-execution.`));
429
+ console.log(chalk.gray('💡 Tip: Type /prune after analysis to reduce context size.'));
430
+ resetTerminal(); // Ensure terminal is responsive
402
431
  messages.push({
403
432
  role: 'user',
404
433
  content: 'STOP using tools now. You have enough information. Please provide your analysis based on what you have read.'
@@ -446,6 +475,9 @@ WORKFLOW:
446
475
  // Normal response - save and wait for next input
447
476
  fs.writeFileSync(CONTEXT_FILE, JSON.stringify(messages));
448
477
  active = false;
478
+ spinner.stop(); // Ensure spinner is dead
479
+ resetTerminal(); // Force terminal back to normal state
480
+ process.stdout.write('\n'); // Force newline to break out of stream mode
449
481
  }
450
482
  }
451
483
  }