neuroncli 2.1.1__tar.gz → 2.3.0__tar.gz
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.
- {neuroncli-2.1.1 → neuroncli-2.3.0}/PKG-INFO +3 -20
- {neuroncli-2.1.1 → neuroncli-2.3.0}/README.md +2 -19
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/auth.py +159 -74
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/config.py +1 -1
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/PKG-INFO +3 -20
- {neuroncli-2.1.1 → neuroncli-2.3.0}/pyproject.toml +1 -1
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/__init__.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/__main__.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/agent.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/cli.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/git_integration.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/ollama_client.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/openrouter_client.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/prompts.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/provider.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/session.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/tools.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli/ui.py +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/SOURCES.txt +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/dependency_links.txt +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/entry_points.txt +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/requires.txt +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/neuroncli.egg-info/top_level.txt +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/setup.cfg +0 -0
- {neuroncli-2.1.1 → neuroncli-2.3.0}/tests/test_agent.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuroncli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: AI Coding Agent — Free Claude Code alternative powered by Kimi K2.5 + Ollama
|
|
5
5
|
Author-email: Rahul S <rahultech72216@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -34,25 +34,8 @@ Requires-Dist: requests>=2.28.0
|
|
|
34
34
|
## Install
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
# Windows
|
|
38
|
-
pip install neuroncli
|
|
39
|
-
|
|
40
|
-
# Linux / macOS (modern distros use pipx)
|
|
41
|
-
pipx install neuroncli
|
|
42
|
-
|
|
43
|
-
# If pipx not installed:
|
|
44
|
-
# sudo apt install pipx && pipx ensurepath (Debian/Ubuntu)
|
|
45
|
-
# sudo dnf install pipx && pipx ensurepath (Fedora)
|
|
46
|
-
# brew install pipx && pipx ensurepath (macOS)
|
|
47
|
-
|
|
48
|
-
# From source (any platform)
|
|
49
|
-
git clone https://github.com/RAHUL-DevelopeRR/neuroncli.git
|
|
50
|
-
cd neuroncli && pip install -e .
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
# Linux/macOS auto-install script
|
|
55
|
-
curl -fsSL https://raw.githubusercontent.com/RAHUL-DevelopeRR/neuroncli/master/install.sh | bash
|
|
37
|
+
pip install neuroncli # Windows / macOS / Cloud VMs
|
|
38
|
+
pip install neuroncli --break-system-packages # Linux (Ubuntu 23+, Debian 12+, Fedora 38+)
|
|
56
39
|
```
|
|
57
40
|
|
|
58
41
|
## Quick Start
|
|
@@ -9,25 +9,8 @@
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
# Windows
|
|
13
|
-
pip install neuroncli
|
|
14
|
-
|
|
15
|
-
# Linux / macOS (modern distros use pipx)
|
|
16
|
-
pipx install neuroncli
|
|
17
|
-
|
|
18
|
-
# If pipx not installed:
|
|
19
|
-
# sudo apt install pipx && pipx ensurepath (Debian/Ubuntu)
|
|
20
|
-
# sudo dnf install pipx && pipx ensurepath (Fedora)
|
|
21
|
-
# brew install pipx && pipx ensurepath (macOS)
|
|
22
|
-
|
|
23
|
-
# From source (any platform)
|
|
24
|
-
git clone https://github.com/RAHUL-DevelopeRR/neuroncli.git
|
|
25
|
-
cd neuroncli && pip install -e .
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# Linux/macOS auto-install script
|
|
30
|
-
curl -fsSL https://raw.githubusercontent.com/RAHUL-DevelopeRR/neuroncli/master/install.sh | bash
|
|
12
|
+
pip install neuroncli # Windows / macOS / Cloud VMs
|
|
13
|
+
pip install neuroncli --break-system-packages # Linux (Ubuntu 23+, Debian 12+, Fedora 38+)
|
|
31
14
|
```
|
|
32
15
|
|
|
33
16
|
## Quick Start
|
|
@@ -27,8 +27,10 @@ from pathlib import Path
|
|
|
27
27
|
|
|
28
28
|
CONFIG_DIR = Path.home() / ".neuroncli"
|
|
29
29
|
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
30
|
-
CALLBACK_PORT = 19284 #
|
|
31
|
-
|
|
30
|
+
CALLBACK_PORT = 19284 # Local server port to catch the redirect from zero-x.live
|
|
31
|
+
LOCAL_CALLBACK = f"http://localhost:{CALLBACK_PORT}"
|
|
32
|
+
# OpenRouter callback → zero-x.live → redirects to localhost with ?code=
|
|
33
|
+
CALLBACK_URL = "https://zero-x.live/neuroncli/callback"
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
# ── PKCE helpers ──────────────────────────────────────────────────
|
|
@@ -78,10 +80,22 @@ def store_api_key(key: str) -> None:
|
|
|
78
80
|
# ── OAuth PKCE flow ──────────────────────────────────────────────
|
|
79
81
|
|
|
80
82
|
class _OAuthCallbackHandler(http.server.BaseHTTPRequestHandler):
|
|
81
|
-
"""Tiny HTTP handler that captures the OAuth redirect code.
|
|
83
|
+
"""Tiny HTTP handler that captures the OAuth redirect code.
|
|
84
|
+
Handles redirects from zero-x.live callback page."""
|
|
82
85
|
|
|
83
86
|
auth_code: str | None = None
|
|
84
87
|
|
|
88
|
+
def _send_cors_headers(self):
|
|
89
|
+
"""Allow cross-origin requests from zero-x.live."""
|
|
90
|
+
self.send_header("Access-Control-Allow-Origin", "*")
|
|
91
|
+
self.send_header("Access-Control-Allow-Methods", "GET, OPTIONS")
|
|
92
|
+
|
|
93
|
+
def do_OPTIONS(self):
|
|
94
|
+
"""Handle CORS preflight."""
|
|
95
|
+
self.send_response(200)
|
|
96
|
+
self._send_cors_headers()
|
|
97
|
+
self.end_headers()
|
|
98
|
+
|
|
85
99
|
def do_GET(self):
|
|
86
100
|
parsed = urllib.parse.urlparse(self.path)
|
|
87
101
|
params = urllib.parse.parse_qs(parsed.query)
|
|
@@ -93,6 +107,7 @@ class _OAuthCallbackHandler(http.server.BaseHTTPRequestHandler):
|
|
|
93
107
|
# Show success page
|
|
94
108
|
self.send_response(200)
|
|
95
109
|
self.send_header("Content-Type", "text/html")
|
|
110
|
+
self._send_cors_headers()
|
|
96
111
|
self.end_headers()
|
|
97
112
|
self.wfile.write(b"""
|
|
98
113
|
<html>
|
|
@@ -112,7 +127,7 @@ class _OAuthCallbackHandler(http.server.BaseHTTPRequestHandler):
|
|
|
112
127
|
border-radius: 24px;
|
|
113
128
|
backdrop-filter: blur(20px);
|
|
114
129
|
}
|
|
115
|
-
h1 { color: #
|
|
130
|
+
h1 { color: #f0a028; font-size: 2em; }
|
|
116
131
|
p { color: #aaa; font-size: 1.1em; }
|
|
117
132
|
</style>
|
|
118
133
|
</head>
|
|
@@ -164,16 +179,11 @@ def _exchange_code_for_key(code: str, code_verifier: str) -> str:
|
|
|
164
179
|
|
|
165
180
|
def run_oauth_flow() -> str | None:
|
|
166
181
|
"""
|
|
167
|
-
Run
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
4. Exchange code for API key
|
|
172
|
-
5. Store key locally
|
|
173
|
-
|
|
174
|
-
Returns the API key on success, None on failure.
|
|
182
|
+
Run OAuth PKCE + manual paste IN PARALLEL:
|
|
183
|
+
- Background thread: localhost server waits for callback (10 min)
|
|
184
|
+
- Foreground: user can paste key manually while waiting
|
|
185
|
+
- Whichever succeeds first wins.
|
|
175
186
|
"""
|
|
176
|
-
# Reset
|
|
177
187
|
_OAuthCallbackHandler.auth_code = None
|
|
178
188
|
|
|
179
189
|
# Generate PKCE pair
|
|
@@ -188,83 +198,160 @@ def run_oauth_flow() -> str | None:
|
|
|
188
198
|
f"&code_challenge_method=S256"
|
|
189
199
|
)
|
|
190
200
|
|
|
191
|
-
# Start callback server in background
|
|
201
|
+
# Start callback server in background thread
|
|
202
|
+
server = None
|
|
192
203
|
try:
|
|
193
204
|
server = http.server.HTTPServer(("127.0.0.1", CALLBACK_PORT), _OAuthCallbackHandler)
|
|
194
205
|
except OSError:
|
|
195
|
-
# Port in use —
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
server
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
206
|
+
pass # Port in use — skip background listener
|
|
207
|
+
|
|
208
|
+
server_thread = None
|
|
209
|
+
if server:
|
|
210
|
+
server.timeout = 600 # 10 MINUTES — enough for signup + email verify + survey
|
|
211
|
+
def _listen():
|
|
212
|
+
try:
|
|
213
|
+
server.handle_request()
|
|
214
|
+
except Exception:
|
|
215
|
+
pass
|
|
216
|
+
finally:
|
|
217
|
+
server.server_close()
|
|
218
|
+
server_thread = threading.Thread(target=_listen, daemon=True)
|
|
219
|
+
server_thread.start()
|
|
203
220
|
|
|
204
221
|
# Open browser
|
|
222
|
+
print("\n \033[96m\033[1m[AUTH]\033[0m Opening browser for OpenRouter login...")
|
|
205
223
|
try:
|
|
206
224
|
webbrowser.open(auth_url)
|
|
207
225
|
except Exception:
|
|
208
|
-
|
|
226
|
+
pass
|
|
209
227
|
|
|
210
|
-
|
|
228
|
+
# Show user-friendly instructions
|
|
229
|
+
print(f" \033[90m──────────────────────────────────────────────\033[0m")
|
|
230
|
+
print(f" \033[97mSign up / log in to OpenRouter in your browser.\033[0m")
|
|
231
|
+
print(f" \033[97mAfter login, you'll be redirected back here.\033[0m")
|
|
232
|
+
print(f" \033[90m──────────────────────────────────────────────\033[0m")
|
|
233
|
+
print(f" \033[90mIf auto-redirect doesn't work:\033[0m")
|
|
234
|
+
print(f" \033[90m1. Go to: \033[4mhttps://openrouter.ai/settings/keys\033[0m")
|
|
235
|
+
print(f" \033[90m2. Click 'Create Key' -> copy the key\033[0m")
|
|
236
|
+
print(f" \033[90m3. Paste it below\033[0m")
|
|
237
|
+
print(f" \033[90m──────────────────────────────────────────────\033[0m\n")
|
|
238
|
+
|
|
239
|
+
# PARALLEL: Wait for EITHER OAuth callback OR manual paste
|
|
240
|
+
# Poll every 2 seconds to check if background OAuth succeeded
|
|
241
|
+
import time
|
|
242
|
+
import sys
|
|
243
|
+
import select
|
|
244
|
+
|
|
245
|
+
api_key = None
|
|
246
|
+
|
|
247
|
+
# On Windows, we can't use select() on stdin. Use a simpler approach.
|
|
248
|
+
if sys.platform == "win32":
|
|
249
|
+
api_key = _windows_parallel_auth(server_thread, code_verifier)
|
|
250
|
+
else:
|
|
251
|
+
api_key = _unix_parallel_auth(server_thread, code_verifier)
|
|
211
252
|
|
|
212
|
-
#
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
253
|
+
# Clean up server
|
|
254
|
+
if server:
|
|
255
|
+
try:
|
|
256
|
+
server.server_close()
|
|
257
|
+
except Exception:
|
|
258
|
+
pass
|
|
259
|
+
|
|
260
|
+
if api_key:
|
|
261
|
+
store_api_key(api_key)
|
|
262
|
+
print(f"\n \033[92m\033[1m[OK] API key saved to {CONFIG_FILE}\033[0m")
|
|
263
|
+
print(f" \033[92m\033[1m You won't be asked again.\033[0m\n")
|
|
264
|
+
return api_key
|
|
219
265
|
|
|
266
|
+
print(f"\n \033[90mNo API key provided. Using Ollama fallback if available.\033[0m\n")
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _check_oauth_result(code_verifier: str) -> str | None:
|
|
271
|
+
"""Check if the background OAuth server received a code."""
|
|
220
272
|
code = _OAuthCallbackHandler.auth_code
|
|
221
273
|
if not code:
|
|
222
|
-
|
|
223
|
-
|
|
274
|
+
return None
|
|
275
|
+
try:
|
|
276
|
+
return _exchange_code_for_key(code, code_verifier)
|
|
277
|
+
except RuntimeError:
|
|
278
|
+
return None
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def _validate_key(key: str) -> bool:
|
|
282
|
+
"""Check if a pasted key looks valid."""
|
|
283
|
+
key = key.strip()
|
|
284
|
+
return len(key) > 10 and (key.startswith("sk-or-") or key.startswith("sk-"))
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _windows_parallel_auth(server_thread, code_verifier: str) -> str | None:
|
|
288
|
+
"""Windows: prompt for manual paste while checking OAuth in background."""
|
|
289
|
+
import time
|
|
224
290
|
|
|
225
|
-
print(
|
|
226
|
-
print(" \033[
|
|
291
|
+
print(" \033[93mPaste your API key below (or wait for auto-redirect):\033[0m")
|
|
292
|
+
print(" \033[93m> \033[0m", end="", flush=True)
|
|
227
293
|
|
|
228
|
-
# Exchange code for key
|
|
229
294
|
try:
|
|
230
|
-
|
|
231
|
-
except
|
|
232
|
-
|
|
233
|
-
|
|
295
|
+
key = input().strip()
|
|
296
|
+
except (EOFError, KeyboardInterrupt):
|
|
297
|
+
key = ""
|
|
298
|
+
|
|
299
|
+
if key and _validate_key(key):
|
|
300
|
+
return key
|
|
301
|
+
|
|
302
|
+
# Check if OAuth completed while user was typing
|
|
303
|
+
result = _check_oauth_result(code_verifier)
|
|
304
|
+
if result:
|
|
305
|
+
print(" \033[92m[v] Auto-redirect succeeded!\033[0m")
|
|
306
|
+
return result
|
|
234
307
|
|
|
235
|
-
#
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
308
|
+
# Neither worked — wait up to 30 more seconds for OAuth
|
|
309
|
+
print(" \033[90mWaiting for browser redirect...\033[0m", end="", flush=True)
|
|
310
|
+
for _ in range(15):
|
|
311
|
+
time.sleep(2)
|
|
312
|
+
result = _check_oauth_result(code_verifier)
|
|
313
|
+
if result:
|
|
314
|
+
print(f" \033[92mv\033[0m")
|
|
315
|
+
return result
|
|
316
|
+
print(".", end="", flush=True)
|
|
239
317
|
|
|
240
|
-
|
|
318
|
+
print(f" \033[91mx\033[0m")
|
|
319
|
+
return None
|
|
241
320
|
|
|
242
321
|
|
|
243
|
-
def
|
|
244
|
-
"""
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
print(
|
|
248
|
-
print(
|
|
249
|
-
print(f" \033[90m3. Copy the key (starts with sk-or-...)\033[0m\n")
|
|
322
|
+
def _unix_parallel_auth(server_thread, code_verifier: str) -> str | None:
|
|
323
|
+
"""Unix: prompt for manual paste while checking OAuth in background."""
|
|
324
|
+
import time
|
|
325
|
+
|
|
326
|
+
print(" \033[93mPaste your API key below (or wait for auto-redirect):\033[0m")
|
|
327
|
+
print(" \033[93m> \033[0m", end="", flush=True)
|
|
250
328
|
|
|
251
329
|
try:
|
|
252
|
-
key = input(
|
|
330
|
+
key = input().strip()
|
|
253
331
|
except (EOFError, KeyboardInterrupt):
|
|
254
|
-
|
|
332
|
+
key = ""
|
|
255
333
|
|
|
256
|
-
if
|
|
257
|
-
print(f"\n \033[90mSkipped. Using Ollama fallback if available.\033[0m\n")
|
|
258
|
-
return None
|
|
259
|
-
|
|
260
|
-
if key.startswith("sk-or-") or key.startswith("sk-"):
|
|
261
|
-
store_api_key(key)
|
|
262
|
-
print(f" \033[92m\033[1m[OK] API key saved to {CONFIG_FILE}\033[0m\n")
|
|
334
|
+
if key and _validate_key(key):
|
|
263
335
|
return key
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
336
|
+
|
|
337
|
+
# Check if OAuth completed while user was typing
|
|
338
|
+
result = _check_oauth_result(code_verifier)
|
|
339
|
+
if result:
|
|
340
|
+
print(" \033[92m[v] Auto-redirect succeeded!\033[0m")
|
|
341
|
+
return result
|
|
342
|
+
|
|
343
|
+
# Neither worked — wait up to 30 more seconds for OAuth
|
|
344
|
+
print(" \033[90mWaiting for browser redirect...\033[0m", end="", flush=True)
|
|
345
|
+
for _ in range(15):
|
|
346
|
+
time.sleep(2)
|
|
347
|
+
result = _check_oauth_result(code_verifier)
|
|
348
|
+
if result:
|
|
349
|
+
print(f" \033[92mv\033[0m")
|
|
350
|
+
return result
|
|
351
|
+
print(".", end="", flush=True)
|
|
352
|
+
|
|
353
|
+
print(f" \033[91mx\033[0m")
|
|
354
|
+
return None
|
|
268
355
|
|
|
269
356
|
|
|
270
357
|
# ── Public API ────────────────────────────────────────────────────
|
|
@@ -274,12 +361,11 @@ def ensure_api_key() -> str | None:
|
|
|
274
361
|
Ensure an API key is available. Checks in order:
|
|
275
362
|
1. OPENROUTER_API_KEY env var
|
|
276
363
|
2. ~/.neuroncli/config.json
|
|
277
|
-
3.
|
|
278
|
-
4. Manual key paste (fallback if OAuth fails)
|
|
364
|
+
3. OAuth PKCE (background) + manual paste (foreground) — in parallel
|
|
279
365
|
|
|
280
366
|
Returns the API key or None if all methods fail.
|
|
281
367
|
"""
|
|
282
|
-
# Check env var
|
|
368
|
+
# Check env var
|
|
283
369
|
env_key = os.environ.get("OPENROUTER_API_KEY")
|
|
284
370
|
if env_key:
|
|
285
371
|
return env_key
|
|
@@ -289,12 +375,11 @@ def ensure_api_key() -> str | None:
|
|
|
289
375
|
if stored_key:
|
|
290
376
|
return stored_key
|
|
291
377
|
|
|
292
|
-
# First run —
|
|
293
|
-
print("\n \033[96m\033[1m
|
|
294
|
-
print(" ║ Welcome to NeuronCLI!
|
|
295
|
-
print(" ║
|
|
296
|
-
print("
|
|
297
|
-
print(" ╚════════════════════════════════════════════════╝\033[0m")
|
|
378
|
+
# First run — welcome message
|
|
379
|
+
print("\n \033[96m\033[1m╔══════════════════════════════════════════════════╗")
|
|
380
|
+
print(" ║ Welcome to NeuronCLI! ║")
|
|
381
|
+
print(" ║ Free AI coding agent — one-time setup below. ║")
|
|
382
|
+
print(" ╚══════════════════════════════════════════════════╝\033[0m")
|
|
298
383
|
|
|
299
384
|
return run_oauth_flow()
|
|
300
385
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuroncli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: AI Coding Agent — Free Claude Code alternative powered by Kimi K2.5 + Ollama
|
|
5
5
|
Author-email: Rahul S <rahultech72216@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -34,25 +34,8 @@ Requires-Dist: requests>=2.28.0
|
|
|
34
34
|
## Install
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
# Windows
|
|
38
|
-
pip install neuroncli
|
|
39
|
-
|
|
40
|
-
# Linux / macOS (modern distros use pipx)
|
|
41
|
-
pipx install neuroncli
|
|
42
|
-
|
|
43
|
-
# If pipx not installed:
|
|
44
|
-
# sudo apt install pipx && pipx ensurepath (Debian/Ubuntu)
|
|
45
|
-
# sudo dnf install pipx && pipx ensurepath (Fedora)
|
|
46
|
-
# brew install pipx && pipx ensurepath (macOS)
|
|
47
|
-
|
|
48
|
-
# From source (any platform)
|
|
49
|
-
git clone https://github.com/RAHUL-DevelopeRR/neuroncli.git
|
|
50
|
-
cd neuroncli && pip install -e .
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
# Linux/macOS auto-install script
|
|
55
|
-
curl -fsSL https://raw.githubusercontent.com/RAHUL-DevelopeRR/neuroncli/master/install.sh | bash
|
|
37
|
+
pip install neuroncli # Windows / macOS / Cloud VMs
|
|
38
|
+
pip install neuroncli --break-system-packages # Linux (Ubuntu 23+, Debian 12+, Fedora 38+)
|
|
56
39
|
```
|
|
57
40
|
|
|
58
41
|
## Quick Start
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|