9router-manager 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ARIS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,327 @@
1
+ # 9Router Manager
2
+
3
+ Manajemen 9Router AI gateway lokal — scan model, update combo, monitor provider.
4
+
5
+ **Cross-platform**: Windows, Linux, macOS supported.
6
+
7
+ **Tests: 88/88 pass · Node ≥18**
8
+
9
+ ## Fitur
10
+
11
+ - ✅ Scan semua model dari provider aktif
12
+ - ✅ Concurrent testing (configurable, default 1 worker — raise NINEROUTER_MAX_WORKERS env var untuk scan paralel)
13
+ - ✅ Auto-retry pada HTTP 429 (rate limit)
14
+ - ✅ Progress bar real-time
15
+ - ✅ Audit log untuk tracking perubahan (verify_token disanitasi, ditulis async)
16
+ - ✅ Setup auto-scan via scheduler interaktif (confirm + auto-exec, atau print-only mode)
17
+
18
+ ## Struktur
19
+
20
+ ```
21
+ 9router-manager/
22
+ ├── bin/
23
+ │ └── 9router-manager.js # Executable shim
24
+ ├── src/
25
+ │ ├── cli.js # CLI entry + commander setup
26
+ │ ├── env.js # .env loader + path/token helpers
27
+ │ ├── scan.js # API + concurrent scan logic
28
+ │ ├── combo.js # SQLite combo management
29
+ │ ├── metadata.js # Model pattern matching + sort keys
30
+ │ └── results.js # Read & print audit JSON
31
+ ├── tests/
32
+ │ ├── audit-shape.test.js
33
+ │ ├── cli.test.js
34
+ │ ├── combo.test.js
35
+ │ ├── env.test.js
36
+ │ ├── metadata.test.js
37
+ │ ├── paths.test.js
38
+ │ ├── results.test.js
39
+ │ └── scan.test.js
40
+ ├── bat/ # Windows batch scripts
41
+ │ ├── run-scan.bat
42
+ │ ├── check-results.bat
43
+ │ └── setup-scheduler.bat
44
+ ├── sh/ # Unix shell scripts
45
+ │ ├── run-scan.sh
46
+ │ ├── check-results.sh
47
+ │ ├── setup-scheduler.sh
48
+ │ └── setup-scheduler-macos.sh
49
+ ├── metadata.json # Model patterns + release dates
50
+ ├── package.json # Node.js package config
51
+ ├── .env # Konfigurasi lokal (password, path)
52
+ └── .env.template # Template dokumentasi
53
+ ```
54
+
55
+ ## Setup
56
+
57
+ ### 1. Konfigurasi
58
+
59
+ Gunakan perintah bawaan CLI untuk mengatur konfigurasi global (disimpan di `~/.9router/.env`):
60
+
61
+ ```bash
62
+ 9router-manager config
63
+ ```
64
+
65
+ Aplikasi akan meminta Anda untuk memasukkan:
66
+ - `NINEROUTER_PASSWORD` (password dashboard 9Router)
67
+ - `NINEROUTER_BASE_URL` (biarkan default jika menggunakan `localhost:20128`)
68
+
69
+ *(Jika Anda ingin konfigurasi per-folder, Anda masih bisa meng-copy `.env.template` ke `.env` di folder tersebut).*
70
+
71
+ ### 2. Setup Auto-Scan (Opsional)
72
+
73
+ **Cara cepat (via CLI):**
74
+ ```bash
75
+ 9router-manager setup # Tanyakan konfirmasi, lalu jalankan script
76
+ 9router-manager setup -y # Skip konfirmasi (untuk script/CI)
77
+ ```
78
+
79
+ **Cara manual (langsung ke script):**
80
+ ```bash
81
+ # Windows (as Administrator)
82
+ bat\setup-scheduler.bat
83
+
84
+ # Linux (cron)
85
+ ./sh/setup-scheduler.sh
86
+
87
+ # macOS (launchd)
88
+ ./sh/setup-scheduler-macos.sh
89
+ ```
90
+
91
+ ## Usage
92
+
93
+ ### CLI (Recommended)
94
+
95
+ After installation, simply type:
96
+ ```bash
97
+ 9router-manager
98
+ ```
99
+
100
+ Akan muncul menu interaktif:
101
+ ```
102
+ ╔═══════════════════════════════════════════════════╗
103
+ ║ 9Router Manager v0.0.1 ║
104
+ ╠═══════════════════════════════════════════════════╣
105
+ ║ AI Gateway Local - Model Scanner ║
106
+ ╚═══════════════════════════════════════════════════╝
107
+
108
+ [1] Run Model Scan
109
+ [2] List Combos
110
+ [3] Show Last Scan Results
111
+ [4] Test Single Model
112
+ [5] Setup Auto-Scan Scheduler
113
+ [6] Configure Settings
114
+ ────────────────────────────────────────────────────────────
115
+ [v] Version Info [h] Show Help [q] Quit
116
+
117
+ Pilihan (nomor/v/h/q):
118
+ ```
119
+
120
+ Atau gunakan command line mode:
121
+ ```bash
122
+ 9router-manager scan # Run scan
123
+ 9router-manager list # List combos
124
+ 9router-manager list --details # List combos + models in each
125
+ 9router-manager results # Check results
126
+ 9router-manager test <model> # Test single model
127
+ 9router-manager setup # Setup scheduler (interaktif)
128
+ 9router-manager setup -y # Setup scheduler (skip prompt)
129
+ 9router-manager config # Configure global settings (interaktif)
130
+ 9router-manager version # Version info
131
+ 9router-manager help # Show help
132
+ ```
133
+
134
+ ### Installation
135
+
136
+ Install globally via npm (recommended for development):
137
+
138
+ ```bash
139
+ npm link
140
+ ```
141
+
142
+ Setelah itu perintah `9router-manager` bisa dipanggil dari direktori manapun (entry-point dari `package.json`).
143
+
144
+ ### Shell Scripts (Fallback)
145
+
146
+ Jika CLI belum diinstall, bisa pakai shell scripts:
147
+
148
+ **Linux/macOS:**
149
+ ```bash
150
+ ./sh/run-scan.sh
151
+ ./sh/check-results.sh
152
+ ./sh/setup-scheduler.sh
153
+ ```
154
+
155
+ **Windows:**
156
+ ```bash
157
+ bat\run-scan.bat
158
+ bat\check-results.bat
159
+ bat\setup-scheduler.bat
160
+ ```
161
+
162
+ ### Direct Node
163
+
164
+ ```bash
165
+ node src/cli.js scan
166
+ node src/cli.js results
167
+ node src/cli.js test minimax/MiniMax-M2.7
168
+ ```
169
+
170
+ ### Commit
171
+
172
+ ```bash
173
+ git add .
174
+ git commit -m "feat: add new feature"
175
+ ```
176
+
177
+ Format: `type: short description`
178
+
179
+ ## Konfigurasi
180
+
181
+ | Variable | Default | Deskripsi |
182
+ |----------|---------|-----------|
183
+ | `NINEROUTER_PASSWORD` | (required) | Password dashboard 9Router |
184
+ | `NINEROUTER_BASE_URL` | `http://localhost:20128` | URL 9Router gateway |
185
+ | `NINEROUTER_DB_PATH` | OS-specific | Path SQLite DB |
186
+ | `NINEROUTER_AUDIT_PATH` | OS-specific | Audit log output |
187
+ | `NINEROUTER_TIMEOUT` | `8` | Timeout per model (detik) |
188
+ | `NINEROUTER_MAX_WORKERS` | `1` | Concurrent workers |
189
+ | `NINEROUTER_RETRY_429_MAX` | `2` | Max retry pada rate limit |
190
+ | `NINEROUTER_RETRY_429_DELAY` | `3.0` | Delay antar retry (detik) |
191
+ | `NINEROUTER_SLEEP` | `0.05` | Delay antar test (detik) |
192
+ | `NINEROUTER_PROMPT` | `1+1=?` | Prompt dikirim ke setiap model |
193
+ | `NINEROUTER_ENV_FILE` | (unset) | Override default .env search path |
194
+
195
+ ## Managed Combo
196
+
197
+ Target combo **tidak dikonfigurasi** — scanner mendeteksinya otomatis dari `/v1/models` × tabel `combos` SQLite.
198
+
199
+ - 0 combo cocok: scanner berhenti dengan error.
200
+ - Tepat 1 combo cocok: combo itu yang di-update.
201
+ - Lebih dari 1 cocok: scanner berhenti dengan error (target ambigu).
202
+
203
+ Managed combo berisi semua model dari semua provider yang berhasil response saat di-test.
204
+
205
+ - Menambah model baru yang mulai response
206
+ - Menghapus model yang tidak lagi response (timeout, 400, 402, 404, 429, error)
207
+ - Skip provider yang statusnya `active=false` di SQLite 9Router
208
+
209
+ ## Commit Types
210
+
211
+ | Type | Usage |
212
+ |------|-------|
213
+ | `feat` | Fitur baru |
214
+ | `fix` | Bug fix |
215
+ | `docs` | Dokumentasi |
216
+ | `style` | Formatting, typo |
217
+ | `refactor` | Refactoring |
218
+ | `perf` | Performa |
219
+ | `test` | Unit test |
220
+ | `build` | Build system |
221
+ | `ci` | CI/CD |
222
+ | `chore` | Config, dependency |
223
+ | `revert` | Revert commit |
224
+
225
+ ## Quick Start
226
+
227
+ ```bash
228
+ # 1. Install dependencies
229
+ npm install
230
+
231
+ # 2. Setup configuration
232
+ node src/cli.js config
233
+ # (You will be prompted to enter your 9Router password)
234
+
235
+ # 3. Run scan
236
+ npm run scan
237
+ # atau
238
+ node src/cli.js scan
239
+
240
+ # 4. Check results
241
+ npm run results
242
+ # atau
243
+ node src/cli.js results
244
+
245
+ # 5. Run tests
246
+ npm test
247
+ ```
248
+
249
+ ## Sub-commands
250
+
251
+ - `scan` — Run daily combo model scan
252
+ - `list` — List combos in database (use `--details` to show models)
253
+ - `results` / `check` / `status` — Show last scan results
254
+ - `test <model>` — Test a single model
255
+ - `setup` — Setup auto-scan scheduler (interactive; `-y` to skip prompt)
256
+ - `config` — Configure global settings (interactive)
257
+ - `version` — Show version info
258
+ - `help` — Show help
259
+
260
+ ## Per-Phase Test Scripts
261
+
262
+ ```bash
263
+ npm run env:test # 8 tests
264
+ npm run cli:test # 6 tests
265
+ npm run paths:test # 14 tests
266
+ npm run metadata:test # 22 tests
267
+ npm run combo:test # 9 tests
268
+ npm run scan:test # 16 tests
269
+ npm run results:test # 8 tests
270
+ npm run audit-shape:test # 10 tests
271
+ npm test # 88 tests total
272
+ ```
273
+
274
+ ## Key Files
275
+
276
+ | File | Platform | Description |
277
+ |------|----------|-------------|
278
+ | `bin/9router-manager.js` | All | Executable shim (`#!/usr/bin/env node`) |
279
+ | `src/cli.js` | All | CLI entry + commander setup + interactive menu |
280
+ | `src/scan.js` | All | API + concurrent scan logic |
281
+ | `src/combo.js` | All | SQLite combo management (async) |
282
+ | `src/env.js` | All | .env loader + path helpers |
283
+ | `src/metadata.js` | All | Model pattern matching + sort keys |
284
+ | `src/results.js` | All | Audit JSON reader/summarizer |
285
+ | `package.json` | All | Node.js package config |
286
+ | `sh/run-scan.sh` | Linux/macOS | Run scan (fallback) |
287
+ | `sh/check-results.sh` | Linux/macOS | Check results (fallback) |
288
+ | `bat/run-scan.bat` | Windows | Run scan (fallback) |
289
+
290
+ ## OS-Specific Paths
291
+
292
+ Default paths untuk setiap OS (jika `NINEROUTER_DB_PATH` / `NINEROUTER_AUDIT_PATH` tidak diset):
293
+
294
+ | OS | DB Path | Audit Path |
295
+ |----|---------|------------|
296
+ | Windows | `~/AppData/Roaming/9router/db/data.sqlite` | `%USERPROFILE%\AppData\Local\hermes\scripts\9router_daily_combo_model_scan_last.json` |
297
+ | Linux | `~/.9router/db/data.sqlite` (fallback: `~/.config/9router/`, `~/.local/share/9router/`, `snap`) | `~/.local/share/9router/audit/9router_daily_combo_model_scan_last.json` |
298
+ | macOS | `~/.9router/db/data.sqlite` (fallback: `~/.config/9router/`, `~/.local/share/9router/`) | `~/Library/Logs/9router-scan.log` |
299
+
300
+ ## Project Status
301
+
302
+ - [x] All rewrite phases complete
303
+ - [x] 88/88 tests pass (`npm test`)
304
+ - [x] `npm run lint` passes
305
+ - [x] No `AIO` references in the tree
306
+ - [x] Combo-agnostic audit file paths
307
+ - [x] Async audit write + sanitized verify_token
308
+ - [x] Multi-platform CI (Linux, macOS, Windows × Node 18/20/22)
309
+ - [x] `node bin/9router-manager.js` works end-to-end
310
+ - [x] Interactive menu with letter shortcuts (q/h/v)
311
+ - [x] `setup` command with confirm + auto-exec + non-TTY fallback
312
+
313
+ ## Open Questions
314
+
315
+ - **TypeScript?** Plain JS for now. Can be added later via `tsc --check` without a full rewrite.
316
+ - **Cookie store?** In-memory `Map` (single-session scan). Browser-equivalent `tough-cookie` is overkill for a one-shot CLI run.
317
+ - **Concurrency model?** Promise-based fan-out (capped by `NINEROUTER_MAX_WORKERS`). Watch SQLite write contention at the end of long runs.
318
+ - **Schema for `metadata.json`?** Ported as-is. Normalize later if it pays off.
319
+
320
+ ## Commit
321
+
322
+ ```bash
323
+ git add .
324
+ git commit -m "feat: add new feature"
325
+ ```
326
+
327
+ Format: `type: short description`
@@ -0,0 +1,60 @@
1
+ @echo off
2
+ setlocal EnableDelayedExpansion
3
+
4
+ title 9Router Scan - Cek Hasil
5
+
6
+ echo ============================================
7
+ echo Cek Hasil Scan
8
+ echo ============================================
9
+ echo.
10
+
11
+ REM Load .env from project root if exists
12
+ set "SCRIPT_DIR=%~dp0.."
13
+ for %%i in ("%SCRIPT_DIR%") do set "SCRIPT_DIR=%%~fi"
14
+ set "ENV_FILE=%SCRIPT_DIR%\.env"
15
+ if exist "%ENV_FILE%" (
16
+ for /f "usebackq tokens=1,* delims==" %%a in ("%ENV_FILE%") do (
17
+ set "%%a=%%b"
18
+ )
19
+ )
20
+
21
+ REM Resolve audit path dari environment atau use default
22
+ if defined NINEROUTER_AUDIT_PATH (
23
+ set "AUDIT_PATH=%NINEROUTER_AUDIT_PATH%"
24
+ ) else (
25
+ set "AUDIT_PATH=%USERPROFILE%\AppData\Local\hermes\scripts\9router_daily_combo_model_scan_last.json"
26
+ )
27
+
28
+ REM Expand ~ to userprofile if present
29
+ set "FIRST_CHAR=!AUDIT_PATH:~0,1!"
30
+ if "!FIRST_CHAR!"=="~" (
31
+ set "AUDIT_PATH=%USERPROFILE%!AUDIT_PATH:~1!"
32
+ )
33
+
34
+ REM Check file exists
35
+ if not exist "%AUDIT_PATH%" (
36
+ echo ERROR: Audit log tidak ditemukan:
37
+ echo %AUDIT_PATH%
38
+ echo.
39
+ echo Jalankan scan terlebih dahulu:
40
+ echo python scan.py
41
+ echo atau: .\bat\run-scan.bat
42
+ echo.
43
+ pause
44
+ exit /b 1
45
+ )
46
+
47
+ REM Run Python to display results
48
+ where python >nul 2>nul
49
+ if %errorlevel%==0 (
50
+ python check_results.py
51
+ ) else if defined PYTHON_EXE (
52
+ "%PYTHON_EXE%" check_results.py
53
+ ) else (
54
+ echo ERROR: Python tidak ditemukan!
55
+ pause
56
+ exit /b 1
57
+ )
58
+
59
+ echo.
60
+ pause
@@ -0,0 +1,65 @@
1
+ @echo off
2
+ setlocal EnableDelayedExpansion
3
+
4
+ title 9Router Combo Model Scan
5
+
6
+ echo ============================================
7
+ echo 9Router Combo Model Scan
8
+ echo ============================================
9
+ echo.
10
+
11
+ REM Resolve script directory (parent of bat folder)
12
+ set "SCRIPT_DIR=%~dp0.."
13
+ for %%i in ("%SCRIPT_DIR%") do set "SCRIPT_DIR=%%~fi"
14
+
15
+ REM Load .env from project root
16
+ set "ENV_FILE=%SCRIPT_DIR%\.env"
17
+ if exist "%ENV_FILE%" (
18
+ echo Loading config from .env...
19
+ for /f "usebackq tokens=1,* delims==" %%a in ("%ENV_FILE%") do (
20
+ set "%%a=%%b"
21
+ )
22
+ ) else (
23
+ echo WARNING: .env file not found at %ENV_FILE%
24
+ echo.
25
+ )
26
+
27
+ REM Debug: show what was loaded
28
+ REM echo DEBUG: NINEROUTER_PASSWORD=[%NINEROUTER_PASSWORD%]
29
+
30
+ REM Check password
31
+ if not defined NINEROUTER_PASSWORD (
32
+ echo ERROR: NINEROUTER_PASSWORD tidak diset!
33
+ echo Silakan isi password di file .env atau environment variable.
34
+ echo.
35
+ echo Cara setup:
36
+ echo 1. Copy .env.template ke .env
37
+ echo 2. Edit .env, isi NINEROUTER_PASSWORD
38
+ echo.
39
+ pause
40
+ exit /b 1
41
+ )
42
+
43
+ echo.
44
+ echo Menjalankan combo scan...
45
+ echo.
46
+
47
+ REM Change to script directory
48
+ cd /d "%SCRIPT_DIR%"
49
+
50
+ REM Try python from PATH first
51
+ where python >nul 2>nul
52
+ if %errorlevel%==0 (
53
+ python scan.py
54
+ ) else if defined PYTHON_EXE (
55
+ "%PYTHON_EXE%" scan.py
56
+ ) else (
57
+ echo ERROR: Python tidak ditemukan!
58
+ echo Pastikan Python terinstall atau atur PYTHON_EXE di .env
59
+ pause
60
+ exit /b 1
61
+ )
62
+
63
+ echo.
64
+ pause
65
+ exit /b 0
@@ -0,0 +1,75 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ title 9Router Combo Model Scan - Setup Scheduler
5
+
6
+ echo ============================================
7
+ echo Setup: Windows Task Scheduler
8
+ echo ============================================
9
+ echo.
10
+
11
+ REM Check admin privileges
12
+ net session >nul 2>&1
13
+ if %errorlevel% neq 0 (
14
+ echo WARNING:Perlu Administrator privilege!
15
+ echo Silakan klik kanan dan pilih ^"Run as administrator^"
16
+ echo.
17
+ pause
18
+ exit /b 1
19
+ )
20
+
21
+ REM Resolve script paths
22
+ set "SCRIPT_DIR=%~dp0"
23
+ set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
24
+
25
+ REM Determine Python executable
26
+ set "PYTHON_EXE="
27
+ where python >nul 2>nul
28
+ if %errorlevel%==0 (
29
+ set "PYTHON_EXE=python"
30
+ ) else (
31
+ set "PYTHON_EXE=C:\Users\Aris\AppData\Local\hermes\hermes-agent\venv\Scripts\python.exe"
32
+ )
33
+
34
+ REM Load password from .env if exists
35
+ if exist "%SCRIPT_DIR%\.env" (
36
+ for /f "usebackq tokens=1,* delims==" %%a in ("%SCRIPT_DIR%\.env") do (
37
+ set "%%a=%%b"
38
+ )
39
+ )
40
+
41
+ REM Build command - include env vars inline
42
+ set "CMD=""
43
+
44
+ REM Set minimum required env vars for the scheduled task
45
+ set "CMD=%CMD% set NINEROUTER_PASSWORD=%NINEROUTER_PASSWORD% && "
46
+ set "CMD=%CMD% "%PYTHON_EXE%" "%SCRIPT_DIR%\scan.py""
47
+ set "CMD=%CMD%""
48
+
49
+ echo Membuat scheduled task...
50
+ echo.
51
+ echo Command: %PYTHON_EXE% scan.py
52
+ echo Schedule: ONLOGON, delay 5 minutes
53
+ echo.
54
+
55
+ schtasks /Create /TN "9Router Combo Model Scan" /SC ONLOGON /DELAY 0005:00 /TR "cmd /c %CMD%" /F
56
+
57
+ if %errorlevel%==0 (
58
+ echo.
59
+ echo SUCCESS - Taskscheduler dibuat.
60
+ echo.
61
+ echo Scan akan jalan otomatis 5 menit setelah login Windows.
62
+ echo.
63
+ echo Untuk melihat task:
64
+ echo schtasks /query /TN "9Router Combo Model Scan"
65
+ echo.
66
+ echo Untuk hapus task:
67
+ echo schtasks /Delete /TN "9Router Combo Model Scan" /F
68
+ ) else (
69
+ echo.
70
+ echo GAGAL - Gagal membuat task.
71
+ echo Pastikan tidak ada task dengan nama yang sama.
72
+ )
73
+
74
+ echo.
75
+ pause
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../src/cli.js';
3
+
4
+ main().catch((err) => {
5
+ console.error('FATAL:', err.message);
6
+ process.exit(1);
7
+ });