sapper-iq 1.1.1 → 1.1.2

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 +34 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
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
@@ -19,6 +19,18 @@ process.on('unhandledRejection', (reason) => {
19
19
  console.error(chalk.red('\n❌ Unhandled rejection:'), reason);
20
20
  });
21
21
 
22
+ // Prevent Ctrl+C from killing the whole process
23
+ let ctrlCCount = 0;
24
+ process.on('SIGINT', () => {
25
+ ctrlCCount++;
26
+ if (ctrlCCount >= 2) {
27
+ console.log(chalk.red('\nForce quitting...'));
28
+ process.exit(1);
29
+ }
30
+ console.log(chalk.yellow('\n\nUse "exit" to close Sapper safely, or Ctrl+C again to force quit.'));
31
+ setTimeout(() => { ctrlCCount = 0; }, 2000); // Reset after 2 seconds
32
+ });
33
+
22
34
  // Initialize versioning
23
35
  let CURRENT_VERSION = "1.1.0";
24
36
  try {
@@ -37,31 +49,27 @@ let rl = readline.createInterface({
37
49
  historySize: 100
38
50
  });
39
51
 
40
- async function safeQuestion(query) {
41
- return new Promise((resolve, reject) => {
42
- process.stdout.write(query);
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
- });
54
- });
55
- }
56
-
57
52
  function recreateReadline() {
58
- rl.close();
53
+ if (rl) rl.close();
59
54
  rl = readline.createInterface({
60
55
  input: process.stdin,
61
56
  output: process.stdout,
62
57
  terminal: true,
63
58
  historySize: 100
64
59
  });
60
+ // Force resume stdin to keep process alive
61
+ process.stdin.resume();
62
+ }
63
+
64
+ async function safeQuestion(query) {
65
+ // Ensure we are ready to receive input
66
+ if (rl.closed) recreateReadline();
67
+
68
+ return new Promise((resolve) => {
69
+ rl.question(query, (answer) => {
70
+ resolve(answer ? answer.trim() : '');
71
+ });
72
+ });
65
73
  }
66
74
 
67
75
  // Directories to ignore when listing files
@@ -128,8 +136,11 @@ const tools = {
128
136
  stdio: 'inherit', shell: useShell
129
137
  });
130
138
  proc.on('close', (code) => {
131
- recreateReadline();
132
- resolve(`Command completed with code ${code}`);
139
+ // Delay slightly to let terminal settle
140
+ setTimeout(() => {
141
+ recreateReadline();
142
+ resolve(`Command completed with code ${code}`);
143
+ }, 100);
133
144
  });
134
145
  });
135
146
  }
@@ -428,4 +439,7 @@ WORKFLOW:
428
439
  }
429
440
  }
430
441
 
442
+ // Keep-alive interval - prevents Node from exiting when event loop is empty
443
+ setInterval(() => {}, 1000);
444
+
431
445
  runSapper();