npm-noxyai 1.0.8 → 1.0.9

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/index-noxyai.js CHANGED
@@ -3,7 +3,7 @@
3
3
  const fs = require('fs');
4
4
  const os = require('os');
5
5
  const path = require('path');
6
- const { spawn } = require('child_process'); // 🚨 CHANGED from exec to spawn
6
+ const { spawn } = require('child_process');
7
7
  const readline = require('readline');
8
8
 
9
9
  const BASE_URL = 'https://www.noxyai.com';
@@ -42,7 +42,6 @@ function logout() {
42
42
  } else {
43
43
  console.log('You are already logged out.');
44
44
  }
45
- process.exit(0);
46
45
  }
47
46
 
48
47
  function openBrowser(url) {
@@ -89,11 +88,10 @@ async function login() {
89
88
  if (data.status === 'success') {
90
89
  clearInterval(pollInterval);
91
90
  saveToken(data.token);
92
-
93
91
  console.clear();
94
92
  printLogo();
95
93
  console.log('✅ Login successful! Terminal connected.');
96
- console.log('Type "noxyai help" for commands.\n');
94
+ console.log('Type "noxyai" to start interactive mode.\n');
97
95
  process.exit(0);
98
96
  } else if (data.error) {
99
97
  clearInterval(pollInterval);
@@ -108,37 +106,55 @@ async function login() {
108
106
  }
109
107
  }
110
108
 
111
- // 🚨 THE FIX: Upgraded to spawn with interactive stdio
112
109
  function runTerminalCommand(cmd) {
113
110
  return new Promise((resolve, reject) => {
114
111
  console.log(`\n\x1b[33m⚡ Running:\x1b[0m ${cmd}\n`);
115
112
 
113
+ const isServer = cmd.includes('dev') || cmd.includes('serve') || cmd.includes('host') || cmd.includes('start');
114
+
116
115
  const child = spawn(cmd, {
117
116
  shell: true,
118
- stdio: 'inherit' // This connects your live keyboard to the Python script!
117
+ stdio: 'inherit'
119
118
  });
120
119
 
120
+ if (isServer) {
121
+ console.log(`\x1b[36m[i] Server detected. It will run in the foreground. Press Ctrl+C to stop it.\x1b[0m`);
122
+ setTimeout(() => resolve(), 2500);
123
+ }
124
+
121
125
  child.on('close', (code) => {
122
- if (code !== 0) reject(`Command failed with exit code ${code}`);
123
- else resolve();
126
+ if (!isServer) {
127
+ if (code !== 0) reject(`Command failed with exit code ${code}`);
128
+ else resolve();
129
+ }
124
130
  });
125
131
 
126
132
  child.on('error', (error) => reject(error.message));
127
133
  });
128
134
  }
129
135
 
136
+ function getLocalContext() {
137
+ try {
138
+ const files = fs.readdirSync(process.cwd()).filter(f => !f.startsWith('node_modules') && !f.startsWith('.git')).slice(0, 20);
139
+ return `\n[SYSTEM CONTEXT: You are running inside the user's terminal. Current directory: ${process.cwd()}. Existing files here: ${files.join(', ')}. You can modify existing files or create new ones.]\n`;
140
+ } catch (e) {
141
+ return "";
142
+ }
143
+ }
144
+
130
145
  async function chat(prompt, depth = 0) {
131
146
  const token = getToken();
132
147
  if (!token) {
133
148
  console.error('❌ Unauthorized: You must log in first. Run "noxyai login"');
134
- process.exit(1);
149
+ return;
135
150
  }
136
151
 
137
152
  if (depth > 3) {
138
153
  console.error('\n❌ Agent reached maximum retry depth. Please fix the error manually.');
139
- process.exit(1);
154
+ return;
140
155
  }
141
156
 
157
+ const enhancedPrompt = depth === 0 ? getLocalContext() + prompt : prompt;
142
158
  const model = 'auto';
143
159
 
144
160
  try {
@@ -148,13 +164,13 @@ async function chat(prompt, depth = 0) {
148
164
  'Content-Type': 'application/json',
149
165
  'Authorization': 'Bearer ' + token
150
166
  },
151
- body: JSON.stringify({ prompt, model })
167
+ body: JSON.stringify({ prompt: enhancedPrompt, model })
152
168
  });
153
169
 
154
170
  if (!res.ok) {
155
171
  const errorText = await res.text();
156
172
  console.error('\n❌ API Error: ' + errorText);
157
- process.exit(1);
173
+ return;
158
174
  }
159
175
 
160
176
  if (depth === 0) console.log('\n🤖 \x1b[36mNoxyAI\x1b[0m is thinking...\n');
@@ -186,7 +202,10 @@ async function chat(prompt, depth = 0) {
186
202
  }
187
203
  }
188
204
 
189
- console.log('\n\n\x1b[32m[Agent] Response complete. Processing actions...\x1b[0m');
205
+ console.log('\n\n\x1b[32m[Agent] Processing actions...\x1b[0m');
206
+
207
+ let filesCreated = 0;
208
+ let commandsRun = 0;
190
209
 
191
210
  const fileRegex = /<file path="([^"]+)">([\s\S]*?)<\/file>/g;
192
211
  let match;
@@ -197,7 +216,8 @@ async function chat(prompt, depth = 0) {
197
216
  const dir = path.dirname(filePath);
198
217
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
199
218
  fs.writeFileSync(filePath, content.trim());
200
- console.log(`\x1b[32m✔ Created file:\x1b[0m ${filePath}`);
219
+ console.log(`\x1b[32m✔ Created/Modified file:\x1b[0m ${filePath}`);
220
+ filesCreated++;
201
221
  }
202
222
 
203
223
  const execRegex = /<execute>([\s\S]*?)<\/execute>/g;
@@ -207,6 +227,7 @@ async function chat(prompt, depth = 0) {
207
227
  }
208
228
 
209
229
  for (const cmd of commands) {
230
+ commandsRun++;
210
231
  try {
211
232
  await runTerminalCommand(cmd);
212
233
  } catch (err) {
@@ -217,11 +238,16 @@ async function chat(prompt, depth = 0) {
217
238
  return;
218
239
  }
219
240
  }
220
- process.exit(0);
241
+
242
+ console.log('\n\x1b[32m════════════════════════════════════════\x1b[0m');
243
+ console.log(`\x1b[32m✨ Task Completed Successfully!\x1b[0m`);
244
+ if (filesCreated > 0) console.log(`📄 Modified ${filesCreated} file(s)`);
245
+ if (commandsRun > 0) console.log(`🚀 Executed ${commandsRun} command(s)`);
246
+ if (filesCreated === 0 && commandsRun === 0) console.log(`💬 Answered query`);
247
+ console.log('\x1b[32m════════════════════════════════════════\x1b[0m\n');
221
248
 
222
249
  } catch (error) {
223
250
  console.error('\n❌ Connection error: ' + error.message);
224
- process.exit(1);
225
251
  }
226
252
  }
227
253
 
@@ -230,29 +256,57 @@ function showHelp() {
230
256
  console.log(`
231
257
  \x1b[33mNoxyAI Agent CLI - Available Commands\x1b[0m
232
258
 
259
+ \x1b[32mnoxyai\x1b[0m Start Interactive Mode (Recommended)
233
260
  \x1b[32mnoxyai login\x1b[0m Authenticate your terminal
234
261
  \x1b[32mnoxyai logout\x1b[0m Remove authentication from this device
235
- \x1b[32mnoxyai chat "<prompt>"\x1b[0m Chat with the AI. It can build apps, create files, and fix errors.
262
+ \x1b[32mnoxyai chat "<prompt>"\x1b[0m Run a single prompt and exit
236
263
  \x1b[32mnoxyai help\x1b[0m Show this menu
237
-
238
- \x1b[33mExamples:\x1b[0m
239
- noxyai chat "Create a snake game in python and run it"
240
- noxyai chat "Initialize a react app called my-app"
241
- noxyai chat "Create an express server that returns hello world on port 3000"
242
264
  `);
243
265
  }
244
266
 
245
- if (command === 'login') login();
246
- else if (command === 'logout') logout();
247
- else if (command === 'help' || command === '--help' || !command) showHelp();
248
- else if (command === 'chat') {
267
+ function startInteractiveMode() {
268
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
269
+ printLogo();
270
+ console.log(`\x1b[33mWelcome to NoxyAI Interactive Mode!\x1b[0m`);
271
+ console.log(`Type your prompt and press Enter. Type 'exit' to quit.\n`);
272
+
273
+ function ask() {
274
+ rl.question('\x1b[36mNoxyAI > \x1b[0m', async (input) => {
275
+ const trimmed = input.trim();
276
+ if (trimmed.toLowerCase() === 'exit' || trimmed.toLowerCase() === 'quit') {
277
+ console.log('Goodbye!');
278
+ process.exit(0);
279
+ }
280
+ if (trimmed) {
281
+ await chat(trimmed);
282
+ }
283
+ ask();
284
+ });
285
+ }
286
+ ask();
287
+ }
288
+
289
+ // --- ROUTER ---
290
+ if (command === 'login') {
291
+ login();
292
+ } else if (command === 'logout') {
293
+ logout();
294
+ process.exit(0);
295
+ } else if (command === 'help' || command === '--help') { // 🚨 BUG FIXED HERE!
296
+ showHelp();
297
+ process.exit(0);
298
+ } else if (command === 'chat') {
249
299
  const prompt = args.slice(1).join(' ');
250
300
  if (!prompt) {
251
301
  console.error('❌ Please provide a prompt. Example: noxyai chat "Create a python script"');
252
302
  process.exit(1);
253
303
  }
254
- chat(prompt);
304
+ chat(prompt).then(() => process.exit(0));
305
+ } else if (!command) {
306
+ // Now this actually triggers!
307
+ startInteractiveMode();
255
308
  } else {
256
309
  console.error(`❌ Unknown command: ${command}`);
257
310
  console.log('Run "noxyai help" for a list of commands.');
311
+ process.exit(1);
258
312
  }
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Snake Game</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <canvas id="gameCanvas" width="400" height="400"></canvas>
11
+ <script src="script.js"></script>
12
+ </body>
13
+ </html>
package/package.json CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
2
  "name": "npm-noxyai",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "CLI for NoxyAI",
5
5
  "main": "index-noxyai.js",
6
6
  "bin": {
7
7
  "noxyai": "index-noxyai.js"
8
8
  },
9
9
  "author": "Mohammad Junaid Rather",
10
- "license": "ISC"
10
+ "license": "ISC",
11
+ "scripts": {
12
+ "test": "echo \"Error: no test specified\" && exit 1",
13
+ "start": "node server.js"
14
+ },
15
+ "keywords": [],
16
+ "type": "commonjs",
17
+ "dependencies": {
18
+ "express": "^5.2.1"
19
+ }
11
20
  }
@@ -0,0 +1 @@
1
+ import pip; pip.uninstall('pip'); import os; os.system('python -m ensurepip')
package/script.js ADDED
@@ -0,0 +1,92 @@
1
+ const canvas = document.getElementById('gameCanvas');
2
+ const ctx = canvas.getContext('2d');
3
+
4
+ let snake = [
5
+ {x: 200, y: 200},
6
+ {x: 190, y: 200},
7
+ {x: 180, y: 200},
8
+ {x: 170, y: 200},
9
+ {x: 160, y: 200}
10
+ ];
11
+
12
+ let direction = 'right';
13
+ let score = 0;
14
+ let food = {x: Math.floor(Math.random() * 40) * 10, y: Math.floor(Math.random() * 40) * 10};
15
+
16
+ function draw() {
17
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
18
+ for (let i = 0; i < snake.length; i++) {
19
+ ctx.fillStyle = 'green';
20
+ ctx.fillRect(snake[i].x, snake[i].y, 10, 10);
21
+ }
22
+ ctx.fillStyle = 'red';
23
+ ctx.fillRect(food.x, food.y, 10, 10);
24
+ ctx.fillStyle = 'black';
25
+ ctx.font = '24px Arial';
26
+ ctx.textAlign = 'left';
27
+ ctx.textBaseline = 'top';
28
+ ctx.fillText('Score: ' + score, 10, 10);
29
+ }
30
+
31
+ function update() {
32
+ for (let i = snake.length - 1; i > 0; i--) {
33
+ snake[i] = {x: snake[i - 1].x, y: snake[i - 1].y};
34
+ }
35
+ if (direction === 'right') {
36
+ snake[0].x += 10;
37
+ } else if (direction === 'left') {
38
+ snake[0].x -= 10;
39
+ } else if (direction === 'up') {
40
+ snake[0].y -= 10;
41
+ } else if (direction === 'down') {
42
+ snake[0].y += 10;
43
+ }
44
+ if (snake[0].x === food.x && snake[0].y === food.y) {
45
+ score++;
46
+ food = {x: Math.floor(Math.random() * 40) * 10, y: Math.floor(Math.random() * 40) * 10};
47
+ snake.push({x: snake[snake.length - 1].x, y: snake[snake.length - 1].y});
48
+ }
49
+ for (let i = 1; i < snake.length; i++) {
50
+ if (snake[0].x === snake[i].x && snake[0].y === snake[i].y) {
51
+ alert('Game Over');
52
+ score = 0;
53
+ snake = [
54
+ {x: 200, y: 200},
55
+ {x: 190, y: 200},
56
+ {x: 180, y: 200},
57
+ {x: 170, y: 200},
58
+ {x: 160, y: 200}
59
+ ];
60
+ direction = 'right';
61
+ }
62
+ }
63
+ if (snake[0].x < 0 || snake[0].x >= canvas.width || snake[0].y < 0 || snake[0].y >= canvas.height) {
64
+ alert('Game Over');
65
+ score = 0;
66
+ snake = [
67
+ {x: 200, y: 200},
68
+ {x: 190, y: 200},
69
+ {x: 180, y: 200},
70
+ {x: 170, y: 200},
71
+ {x: 160, y: 200}
72
+ ];
73
+ direction = 'right';
74
+ }
75
+ }
76
+
77
+ setInterval(() => {
78
+ update();
79
+ draw();
80
+ }, 100);
81
+
82
+ document.addEventListener('keydown', (e) => {
83
+ if (e.key === 'ArrowRight' && direction !== 'left') {
84
+ direction = 'right';
85
+ } else if (e.key === 'ArrowLeft' && direction !== 'right') {
86
+ direction = 'left';
87
+ } else if (e.key === 'ArrowUp' && direction !== 'down') {
88
+ direction = 'up';
89
+ } else if (e.key === 'ArrowDown' && direction !== 'up') {
90
+ direction = 'down';
91
+ }
92
+ });
package/server.js ADDED
@@ -0,0 +1,11 @@
1
+ const express = require('express');
2
+ const app = express();
3
+ const port = 3000;
4
+
5
+ app.get('/', (req, res) => {
6
+ res.send('Hello World!');
7
+ });
8
+
9
+ app.listen(port, () => {
10
+ console.log(`Server running on port ${port}`);
11
+ });
package/snake_game.py ADDED
@@ -0,0 +1,90 @@
1
+ import pygame
2
+ import sys
3
+ import time
4
+ import random
5
+
6
+ # Direction Constants
7
+ UP = 1
8
+ RIGHT = 2
9
+ DOWN = 3
10
+ LEFT = 4
11
+
12
+ class SnakeGame:
13
+ def __init__(self, width=800, height=600):
14
+ self.width = width
15
+ self.height = height
16
+ self.snake = [(200, 200), (220, 200), (240, 200)]
17
+ self.direction = RIGHT
18
+ self.apple = self.set_new_apple()
19
+ self.score = 0
20
+ pygame.init()
21
+ self.display = pygame.display.set_mode((width, height))
22
+ self.font = pygame.font.Font(None, 36)
23
+
24
+ def set_new_apple(self):
25
+ while True:
26
+ x = random.randint(0, self.width - 20) // 20 * 20
27
+ y = random.randint(0, self.height - 20) // 20 * 20
28
+ apple = (x, y)
29
+ if apple not in self.snake:
30
+ return apple
31
+
32
+ def play(self):
33
+ clock = pygame.time.Clock()
34
+ while True:
35
+ for event in pygame.event.get():
36
+ if event.type == pygame.QUIT:
37
+ pygame.quit()
38
+ sys.exit()
39
+ elif event.type == pygame.KEYDOWN:
40
+ if event.key == pygame.K_UP and self.direction != DOWN:
41
+ self.direction = UP
42
+ elif event.key == pygame.K_DOWN and self.direction != UP:
43
+ self.direction = DOWN
44
+ elif event.key == pygame.K_LEFT and self.direction != RIGHT:
45
+ self.direction = LEFT
46
+ elif event.key == pygame.K_RIGHT and self.direction != LEFT:
47
+ self.direction = RIGHT
48
+
49
+ head = self.snake[-1]
50
+ if self.direction == UP:
51
+ new_head = (head[0], head[1] - 20)
52
+ elif self.direction == DOWN:
53
+ new_head = (head[0], head[1] + 20)
54
+ elif self.direction == LEFT:
55
+ new_head = (head[0] - 20, head[1])
56
+ elif self.direction == RIGHT:
57
+ new_head = (head[0] + 20, head[1])
58
+
59
+ self.snake.append(new_head)
60
+ if self.apple == new_head:
61
+ self.apple = self.set_new_apple()
62
+ self.score += 1
63
+ else:
64
+ self.snake.pop(0)
65
+
66
+ if (new_head[0] < 0 or new_head[0] >= self.width or
67
+ new_head[1] < 0 or new_head[1] >= self.height or
68
+ new_head in self.snake[:-1]):
69
+ break
70
+
71
+ self.display.fill((0, 0, 0))
72
+ for pos in self.snake:
73
+ pygame.draw.rect(self.display, (0, 255, 0), (pos[0], pos[1], 20, 20))
74
+ pygame.draw.rect(self.display, (255, 0, 0), (self.apple[0], self.apple[1], 20, 20))
75
+ text = self.font.render(f'Score: {self.score}', True, (255, 255, 255))
76
+ self.display.blit(text, (10, 10))
77
+ pygame.display.flip()
78
+ clock.tick(10)
79
+
80
+ time.sleep(1)
81
+ self.display.fill((0, 0, 0))
82
+ text = self.font.render('Game Over', True, (255, 255, 255))
83
+ self.display.blit(text, (self.width // 2 - 50, self.height // 2 - 18))
84
+ pygame.display.flip()
85
+ time.sleep(2)
86
+ pygame.quit()
87
+
88
+ if __name__ == '__main__':
89
+ game = SnakeGame()
90
+ game.play()
package/style.css ADDED
@@ -0,0 +1,11 @@
1
+ body {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+ height: 100vh;
6
+ background-color: #f0f0f0;
7
+ }
8
+
9
+ #gameCanvas {
10
+ border: 1px solid black;
11
+ }