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 +21 -0
- package/README.md +327 -0
- package/bat/check-results.bat +60 -0
- package/bat/run-scan.bat +65 -0
- package/bat/setup-scheduler.bat +75 -0
- package/bin/9router-manager.js +7 -0
- package/metadata.json +1536 -0
- package/package.json +65 -0
- package/sh/check-results.sh +54 -0
- package/sh/run-scan.sh +57 -0
- package/sh/setup-scheduler-macos.sh +109 -0
- package/sh/setup-scheduler.sh +114 -0
- package/src/cli.js +799 -0
- package/src/combo.js +165 -0
- package/src/env.js +126 -0
- package/src/metadata.js +137 -0
- package/src/password.js +142 -0
- package/src/results.js +134 -0
- package/src/scan.js +293 -0
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "9router-manager",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "9Router AI Gateway Local - Combo Model Scanner (Node.js)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "ARIS",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"9router-manager": "bin/9router-manager.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./src/cli.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"bin",
|
|
14
|
+
"src",
|
|
15
|
+
"bat",
|
|
16
|
+
"sh",
|
|
17
|
+
"metadata.json",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"start": "node src/cli.js",
|
|
26
|
+
"test": "node --test tests/*.test.js",
|
|
27
|
+
"env:test": "node --test tests/env.test.js",
|
|
28
|
+
"cli:test": "node --test tests/cli.test.js",
|
|
29
|
+
"paths:test": "node --test tests/paths.test.js",
|
|
30
|
+
"metadata:test": "node --test tests/metadata.test.js",
|
|
31
|
+
"combo:test": "node --test tests/combo.test.js",
|
|
32
|
+
"scan:test": "node --test tests/scan.test.js",
|
|
33
|
+
"results:test": "node --test tests/results.test.js",
|
|
34
|
+
"audit-shape:test": "node --test tests/audit-shape.test.js",
|
|
35
|
+
"password:test": "node --test tests/password.test.js",
|
|
36
|
+
"lint": "node --check src/*.js bin/*.js tests/*.test.js",
|
|
37
|
+
"scan": "node src/cli.js scan",
|
|
38
|
+
"results": "node src/cli.js results",
|
|
39
|
+
"list": "node src/cli.js list",
|
|
40
|
+
"version": "node src/cli.js version",
|
|
41
|
+
"help": "node src/cli.js help",
|
|
42
|
+
"prepublishOnly": "npm run lint && npm test"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"better-sqlite3": "^11.0.0",
|
|
46
|
+
"cli-progress": "^3.12.0",
|
|
47
|
+
"commander": "^12.0.0",
|
|
48
|
+
"dotenv": "^16.4.5"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"9router",
|
|
52
|
+
"ai-gateway",
|
|
53
|
+
"model-scanner",
|
|
54
|
+
"cli",
|
|
55
|
+
"nodejs"
|
|
56
|
+
],
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/arssnndr/9router-manager.git"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/arssnndr/9router-manager",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/arssnndr/9router-manager/issues"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 9Router - Check Last Scan Results - Cross-platform launcher
|
|
3
|
+
# Usage: ./check-results.sh
|
|
4
|
+
# Or: 9router-manager results (after installation)
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
cd "$SCRIPT_DIR"
|
|
10
|
+
|
|
11
|
+
# Try CLI first if installed
|
|
12
|
+
if command -v 9router-manager &> /dev/null; then
|
|
13
|
+
9router-manager results
|
|
14
|
+
exit $?
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Fallback: direct Python execution
|
|
18
|
+
# Load .env if exists
|
|
19
|
+
ENV_FILE="$SCRIPT_DIR/.env"
|
|
20
|
+
if [[ -f "$ENV_FILE" ]]; then
|
|
21
|
+
set -a
|
|
22
|
+
source "$ENV_FILE"
|
|
23
|
+
set +a
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Default audit path for Linux/macOS
|
|
27
|
+
AUDIT_PATH="${NINEROUTER_AUDIT_PATH:-$HOME/.local/share/hermes/scripts/9router_daily_combo_model_scan_last.json}"
|
|
28
|
+
|
|
29
|
+
# Expand ~ if present
|
|
30
|
+
AUDIT_PATH="${AUDIT_PATH/#\~/$HOME}"
|
|
31
|
+
|
|
32
|
+
if [[ ! -f "$AUDIT_PATH" ]]; then
|
|
33
|
+
echo "ERROR: Audit log not found:"
|
|
34
|
+
echo " $AUDIT_PATH"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Run scan first:"
|
|
37
|
+
echo " 9router-manager scan"
|
|
38
|
+
echo " or: ./run-scan.sh"
|
|
39
|
+
echo ""
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Detect Python
|
|
44
|
+
PYTHON_CMD=""
|
|
45
|
+
if command -v python3 &> /dev/null; then
|
|
46
|
+
PYTHON_CMD="python3"
|
|
47
|
+
elif command -v python &> /dev/null; then
|
|
48
|
+
PYTHON_CMD="python"
|
|
49
|
+
else
|
|
50
|
+
echo "ERROR: Python not found!"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
"$PYTHON_CMD" "$SCRIPT_DIR/check_results.py"
|
package/sh/run-scan.sh
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 9Router Model Scanner - Cross-platform launcher
|
|
3
|
+
# Usage: ./run-scan.sh
|
|
4
|
+
# Or: 9router-manager scan (after installation)
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
cd "$SCRIPT_DIR"
|
|
10
|
+
|
|
11
|
+
# Try CLI first if installed
|
|
12
|
+
if command -v 9router-manager &> /dev/null; then
|
|
13
|
+
9router-manager scan
|
|
14
|
+
exit $?
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Fallback: direct Python execution
|
|
18
|
+
# Load .env if exists
|
|
19
|
+
ENV_FILE="$SCRIPT_DIR/.env"
|
|
20
|
+
if [[ -f "$ENV_FILE" ]]; then
|
|
21
|
+
echo "Loading config from .env..."
|
|
22
|
+
set -a
|
|
23
|
+
source "$ENV_FILE"
|
|
24
|
+
set +a
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Check password
|
|
28
|
+
if [[ -z "$NINEROUTER_PASSWORD" ]]; then
|
|
29
|
+
echo "ERROR: NINEROUTER_PASSWORD is not set!"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Setup instructions:"
|
|
32
|
+
echo " 1. cp .env.template .env"
|
|
33
|
+
echo " 2. Edit .env, set NINEROUTER_PASSWORD"
|
|
34
|
+
echo ""
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Detect Python
|
|
39
|
+
PYTHON_CMD=""
|
|
40
|
+
if command -v python3 &> /dev/null; then
|
|
41
|
+
PYTHON_CMD="python3"
|
|
42
|
+
elif command -v python &> /dev/null; then
|
|
43
|
+
PYTHON_CMD="python"
|
|
44
|
+
else
|
|
45
|
+
echo "ERROR: Python not found!"
|
|
46
|
+
echo "Please install Python or set PYTHON_EXE in .env"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo ""
|
|
51
|
+
echo "Running combo scan..."
|
|
52
|
+
echo ""
|
|
53
|
+
|
|
54
|
+
"$PYTHON_CMD" "$SCRIPT_DIR/scan.py"
|
|
55
|
+
|
|
56
|
+
echo ""
|
|
57
|
+
echo "Scan completed."
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 9Router - Setup Auto-Scan on macOS (launchd)
|
|
3
|
+
# Usage: ./setup-scheduler-macos.sh
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
cd "$SCRIPT_DIR"
|
|
9
|
+
|
|
10
|
+
echo "============================================"
|
|
11
|
+
echo " 9Router - Auto-Scan Setup (macOS/launchd)"
|
|
12
|
+
echo "============================================"
|
|
13
|
+
echo ""
|
|
14
|
+
|
|
15
|
+
# Check if running on macOS
|
|
16
|
+
if [[ "$(uname)" != "Darwin" ]]; then
|
|
17
|
+
echo "WARNING: This script is designed for macOS."
|
|
18
|
+
echo "For Linux, use setup-scheduler.sh instead."
|
|
19
|
+
echo ""
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Load .env
|
|
23
|
+
ENV_FILE="$SCRIPT_DIR/.env"
|
|
24
|
+
if [[ -f "$ENV_FILE" ]]; then
|
|
25
|
+
echo "Loading config from .env..."
|
|
26
|
+
set -a
|
|
27
|
+
source "$ENV_FILE"
|
|
28
|
+
set +a
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Check password
|
|
32
|
+
if [[ -z "$NINEROUTER_PASSWORD" ]]; then
|
|
33
|
+
echo "ERROR: NINEROUTER_PASSWORD is not set!"
|
|
34
|
+
echo "Please edit .env and set NINEROUTER_PASSWORD"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Detect Python
|
|
39
|
+
PYTHON_CMD=""
|
|
40
|
+
if command -v python3 &> /dev/null; then
|
|
41
|
+
PYTHON_CMD="python3"
|
|
42
|
+
elif command -v python &> /dev/null; then
|
|
43
|
+
PYTHON_CMD="python"
|
|
44
|
+
else
|
|
45
|
+
echo "ERROR: Python not found!"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
PYTHON_PATH=$(which "$PYTHON_CMD")
|
|
50
|
+
echo "Python: $PYTHON_PATH"
|
|
51
|
+
|
|
52
|
+
SCRIPT_ABS=$(realpath "$SCRIPT_DIR/scan.py")
|
|
53
|
+
PLIST_LABEL="com.9router.daily-scan"
|
|
54
|
+
LAUNCHD_DIR="$HOME/Library/LaunchAgents"
|
|
55
|
+
PLIST_FILE="$LAUNCHD_DIR/$PLIST_LABEL.plist"
|
|
56
|
+
|
|
57
|
+
echo ""
|
|
58
|
+
echo "=== launchd Setup ==="
|
|
59
|
+
echo "This will create a launchd agent to run scan at login."
|
|
60
|
+
echo ""
|
|
61
|
+
|
|
62
|
+
# Create LaunchAgents directory
|
|
63
|
+
mkdir -p "$LAUNCHD_DIR"
|
|
64
|
+
|
|
65
|
+
# Create the launchd plist
|
|
66
|
+
cat > "$PLIST_FILE" << PLISTEOF
|
|
67
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
68
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
69
|
+
<plist version="1.0">
|
|
70
|
+
<dict>
|
|
71
|
+
<key>Label</key>
|
|
72
|
+
<string>$PLIST_LABEL</string>
|
|
73
|
+
<key>ProgramArguments</key>
|
|
74
|
+
<array>
|
|
75
|
+
<string>/bin/bash</string>
|
|
76
|
+
<string>$SCRIPT_DIR/run-scan.sh</string>
|
|
77
|
+
</array>
|
|
78
|
+
<key>RunAtLoad</key>
|
|
79
|
+
<true/>
|
|
80
|
+
<key>StartInterval</key>
|
|
81
|
+
<integer>86400</integer>
|
|
82
|
+
<key>StandardOutPath</key>
|
|
83
|
+
<string>$HOME/Library/Logs/9router-scan.log</string>
|
|
84
|
+
<key>StandardErrorPath</key>
|
|
85
|
+
<string>$HOME/Library/Logs/9router-scan.error.log</string>
|
|
86
|
+
</dict>
|
|
87
|
+
</plist>
|
|
88
|
+
PLISTEOF
|
|
89
|
+
|
|
90
|
+
echo "Created: $PLIST_FILE"
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
# Load the service
|
|
94
|
+
echo "Loading launchd service..."
|
|
95
|
+
launchctl load "$PLIST_FILE" 2>/dev/null || echo "Note: launchctl may require elevated permissions"
|
|
96
|
+
|
|
97
|
+
echo "SUCCESS - launchd agent created!"
|
|
98
|
+
echo ""
|
|
99
|
+
echo "To check status:"
|
|
100
|
+
echo " launchctl list | grep 9router"
|
|
101
|
+
echo ""
|
|
102
|
+
echo "To view logs:"
|
|
103
|
+
echo " tail -f ~/Library/Logs/9router-scan.log"
|
|
104
|
+
echo ""
|
|
105
|
+
echo "To unload (stop):"
|
|
106
|
+
echo " launchctl unload $PLIST_FILE"
|
|
107
|
+
echo ""
|
|
108
|
+
echo "To remove completely:"
|
|
109
|
+
echo " launchctl unload $PLIST_FILE && rm $PLIST_FILE"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 9Router - Setup Auto-Scan on Linux (Cron)
|
|
3
|
+
# Usage: ./setup-scheduler.sh
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
9
|
+
cd "$PROJECT_ROOT"
|
|
10
|
+
|
|
11
|
+
echo "============================================"
|
|
12
|
+
echo " 9Router - Auto-Scan Setup (Linux/Cron)"
|
|
13
|
+
echo "============================================"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Load .env
|
|
17
|
+
ENV_FILE="$PROJECT_ROOT/.env"
|
|
18
|
+
if [[ -f "$ENV_FILE" ]]; then
|
|
19
|
+
echo "Loading config from .env..."
|
|
20
|
+
set -a
|
|
21
|
+
source "$ENV_FILE"
|
|
22
|
+
set +a
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check password
|
|
26
|
+
if [[ -z "$NINEROUTER_PASSWORD" ]]; then
|
|
27
|
+
echo "ERROR: NINEROUTER_PASSWORD is not set!"
|
|
28
|
+
echo "Please edit .env and set NINEROUTER_PASSWORD"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Detect Python
|
|
33
|
+
PYTHON_CMD=""
|
|
34
|
+
if command -v python3 &> /dev/null; then
|
|
35
|
+
PYTHON_CMD="python3"
|
|
36
|
+
elif command -v python &> /dev/null; then
|
|
37
|
+
PYTHON_CMD="python"
|
|
38
|
+
else
|
|
39
|
+
echo "ERROR: Python not found!"
|
|
40
|
+
echo "Please install Python or set PYTHON_EXE in .env"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
PYTHON_PATH=$(which "$PYTHON_CMD")
|
|
45
|
+
echo "Python: $PYTHON_PATH"
|
|
46
|
+
echo "Project root: $PROJECT_ROOT"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
# Use run-scan.sh as the cron entry point (handles .env loading internally)
|
|
50
|
+
RUNNER_SCRIPT="$SCRIPT_DIR/run-scan.sh"
|
|
51
|
+
if [[ ! -x "$RUNNER_SCRIPT" ]]; then
|
|
52
|
+
chmod +x "$RUNNER_SCRIPT"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
echo "=== Cron Setup ==="
|
|
56
|
+
echo "This will create a cron job to run scan via run-scan.sh."
|
|
57
|
+
echo ""
|
|
58
|
+
echo "Schedule options:"
|
|
59
|
+
echo " 1. At login/reboot (recommended)"
|
|
60
|
+
echo " 2. Daily at specific time"
|
|
61
|
+
echo " 3. Hourly"
|
|
62
|
+
echo ""
|
|
63
|
+
read -p "Choose option (1-3) [1]: " SCHEDULE_CHOICE
|
|
64
|
+
SCHEDULE_CHOICE="${SCHEDULE_CHOICE:-1}"
|
|
65
|
+
|
|
66
|
+
case "$SCHEDULE_CHOICE" in
|
|
67
|
+
1)
|
|
68
|
+
# @reboot + delay to let services come up
|
|
69
|
+
CRON_CMD="@reboot sleep 300 && $RUNNER_SCRIPT"
|
|
70
|
+
CRON_DESC="Run once at system startup (5 min delay)"
|
|
71
|
+
;;
|
|
72
|
+
2)
|
|
73
|
+
read -p "Enter time (HH:MM) [09:00]: " TIME_INPUT
|
|
74
|
+
TIME_INPUT="${TIME_INPUT:-09:00}"
|
|
75
|
+
HOUR="${TIME_INPUT%%:*}"
|
|
76
|
+
MINUTE="${TIME_INPUT##*:}"
|
|
77
|
+
CRON_CMD="$MINUTE $HOUR * * * $RUNNER_SCRIPT"
|
|
78
|
+
CRON_DESC="Run daily at $TIME_INPUT"
|
|
79
|
+
;;
|
|
80
|
+
3)
|
|
81
|
+
CRON_CMD="0 * * * * $RUNNER_SCRIPT"
|
|
82
|
+
CRON_DESC="Run every hour"
|
|
83
|
+
;;
|
|
84
|
+
*)
|
|
85
|
+
echo "Invalid option. Using default (login/reboot)..."
|
|
86
|
+
CRON_CMD="@reboot sleep 300 && $RUNNER_SCRIPT"
|
|
87
|
+
CRON_DESC="Run once at system startup (5 min delay)"
|
|
88
|
+
;;
|
|
89
|
+
esac
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
echo "Schedule: $CRON_DESC"
|
|
93
|
+
echo "Command: $CRON_CMD"
|
|
94
|
+
echo ""
|
|
95
|
+
|
|
96
|
+
# Add to crontab (idempotent: remove existing 9router entry first)
|
|
97
|
+
EXISTING=$(crontab -l 2>/dev/null | grep -F "run-scan.sh" | grep -F "9router" || true)
|
|
98
|
+
if [[ -n "$EXISTING" ]]; then
|
|
99
|
+
echo "Removing existing 9router cron entry..."
|
|
100
|
+
(crontab -l 2>/dev/null | grep -v -F "run-scan.sh" | grep -v -F "9router_daily_combo_model_scan") | crontab -
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
(crontab -l 2>/dev/null; echo "$CRON_CMD") | crontab -
|
|
104
|
+
|
|
105
|
+
echo "SUCCESS - Cron job created!"
|
|
106
|
+
echo ""
|
|
107
|
+
echo "To view cron jobs:"
|
|
108
|
+
echo " crontab -l"
|
|
109
|
+
echo ""
|
|
110
|
+
echo "To remove:"
|
|
111
|
+
echo " crontab -e # then delete the run-scan.sh line"
|
|
112
|
+
echo ""
|
|
113
|
+
echo "To view logs:"
|
|
114
|
+
echo " tail -f ~/.local/share/9router/audit/*.log 2>/dev/null || echo 'No logs yet'"
|