navvi 2.0.0
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 +201 -0
- package/README.md +179 -0
- package/bin/navvi.js +150 -0
- package/container/Dockerfile +63 -0
- package/container/marionette.py +147 -0
- package/container/navvi-server.py +652 -0
- package/container/requirements.txt +2 -0
- package/container/start.sh +126 -0
- package/docs/navvi-logo.png +0 -0
- package/mcp/server.mjs +1278 -0
- package/package.json +41 -0
- package/personas/default.yaml +5 -0
- package/personas/dev.yaml +15 -0
- package/personas/fry.yaml +18 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Navvi container entrypoint: start Xvfb, Firefox, x11vnc, noVNC, API server.
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
DISPLAY="${DISPLAY:-:1}"
|
|
6
|
+
SCREEN_SIZE="${SCREEN_SIZE:-1024x768x24}"
|
|
7
|
+
NAVVI_PORT="${NAVVI_PORT:-8024}"
|
|
8
|
+
VNC_PORT="${VNC_PORT:-6080}"
|
|
9
|
+
LOCALE="${LOCALE:-en-US}"
|
|
10
|
+
TIMEZONE="${TIMEZONE:-UTC}"
|
|
11
|
+
|
|
12
|
+
export DISPLAY
|
|
13
|
+
export TZ="$TIMEZONE"
|
|
14
|
+
|
|
15
|
+
# --- Persistence setup (Codespaces) ---
|
|
16
|
+
# Codespaces only persist /workspaces. Symlink browser profile, GPG, and
|
|
17
|
+
# gopass store to persistent storage so sessions survive restarts.
|
|
18
|
+
PERSIST_DIR="/workspaces/.codespaces/.persistedshare/navvi"
|
|
19
|
+
if [ -d "/workspaces/.codespaces/.persistedshare" ]; then
|
|
20
|
+
mkdir -p "$PERSIST_DIR"
|
|
21
|
+
|
|
22
|
+
# Firefox profile
|
|
23
|
+
if [ -d "$PERSIST_DIR/mozilla" ] && [ ! -L "$HOME/.mozilla" ]; then
|
|
24
|
+
rm -rf "$HOME/.mozilla"
|
|
25
|
+
ln -s "$PERSIST_DIR/mozilla" "$HOME/.mozilla"
|
|
26
|
+
echo "[navvi] Firefox profile linked to persistent storage"
|
|
27
|
+
elif [ -d "$HOME/.mozilla" ] && [ ! -L "$HOME/.mozilla" ]; then
|
|
28
|
+
cp -a "$HOME/.mozilla" "$PERSIST_DIR/mozilla"
|
|
29
|
+
rm -rf "$HOME/.mozilla"
|
|
30
|
+
ln -s "$PERSIST_DIR/mozilla" "$HOME/.mozilla"
|
|
31
|
+
echo "[navvi] Firefox profile moved to persistent storage"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# GPG keyring
|
|
35
|
+
if [ -d "$PERSIST_DIR/gnupg" ] && [ ! -L "$HOME/.gnupg" ]; then
|
|
36
|
+
rm -rf "$HOME/.gnupg"
|
|
37
|
+
ln -s "$PERSIST_DIR/gnupg" "$HOME/.gnupg"
|
|
38
|
+
echo "[navvi] GPG keyring linked to persistent storage"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Gopass store
|
|
42
|
+
if [ -d "$PERSIST_DIR/gopass/stores" ] && [ ! -L "$HOME/.local/share/gopass/stores" ]; then
|
|
43
|
+
mkdir -p "$HOME/.local/share/gopass"
|
|
44
|
+
rm -rf "$HOME/.local/share/gopass/stores"
|
|
45
|
+
ln -s "$PERSIST_DIR/gopass/stores" "$HOME/.local/share/gopass/stores"
|
|
46
|
+
echo "[navvi] Gopass store linked to persistent storage"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# --- Gopass init (if GPG key provided via env) ---
|
|
51
|
+
if [ -n "${GPG_PRIVATE_KEY:-}" ]; then
|
|
52
|
+
echo "[navvi] Importing GPG key for gopass..."
|
|
53
|
+
echo "$GPG_PRIVATE_KEY" | gpg --batch --import 2>/dev/null
|
|
54
|
+
GPG_ID=$(gpg --list-secret-keys --keyid-format long 2>/dev/null | grep sec | head -1 | awk '{print $2}' | cut -d/ -f2)
|
|
55
|
+
if [ -n "$GPG_ID" ]; then
|
|
56
|
+
echo "${GPG_ID}:6:" | gpg --import-ownertrust 2>/dev/null
|
|
57
|
+
if [ ! -d "$HOME/.local/share/gopass/stores/root" ]; then
|
|
58
|
+
gopass init --path "$HOME/.local/share/gopass/stores/root" "$GPG_ID" 2>/dev/null
|
|
59
|
+
fi
|
|
60
|
+
echo "[navvi] Gopass ready (key: ${GPG_ID:0:8}...)"
|
|
61
|
+
fi
|
|
62
|
+
unset GPG_PRIVATE_KEY
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# --- Graceful shutdown ---
|
|
66
|
+
# Firefox must shut down cleanly to flush cookies/IndexedDB to disk.
|
|
67
|
+
cleanup() {
|
|
68
|
+
echo "[navvi] Shutting down gracefully..."
|
|
69
|
+
if [ -n "$FIREFOX_PID" ] && kill -0 "$FIREFOX_PID" 2>/dev/null; then
|
|
70
|
+
kill -TERM "$FIREFOX_PID" 2>/dev/null
|
|
71
|
+
# Wait up to 10s for Firefox to flush profile data
|
|
72
|
+
for i in $(seq 1 10); do
|
|
73
|
+
kill -0 "$FIREFOX_PID" 2>/dev/null || break
|
|
74
|
+
sleep 1
|
|
75
|
+
done
|
|
76
|
+
kill -9 "$FIREFOX_PID" 2>/dev/null || true
|
|
77
|
+
echo "[navvi] Firefox stopped"
|
|
78
|
+
fi
|
|
79
|
+
if [ -n "$API_PID" ]; then kill "$API_PID" 2>/dev/null; fi
|
|
80
|
+
if [ -n "$NOVNC_PID" ]; then kill "$NOVNC_PID" 2>/dev/null; fi
|
|
81
|
+
if [ -n "$XVFB_PID" ]; then kill "$XVFB_PID" 2>/dev/null; fi
|
|
82
|
+
exit 0
|
|
83
|
+
}
|
|
84
|
+
trap cleanup SIGTERM SIGINT
|
|
85
|
+
|
|
86
|
+
# --- Start services ---
|
|
87
|
+
echo "[navvi] Starting Xvfb on $DISPLAY ($SCREEN_SIZE)..."
|
|
88
|
+
Xvfb "$DISPLAY" -screen 0 "$SCREEN_SIZE" -ac +extension GLX +render -noreset &
|
|
89
|
+
XVFB_PID=$!
|
|
90
|
+
sleep 1
|
|
91
|
+
|
|
92
|
+
if ! kill -0 "$XVFB_PID" 2>/dev/null; then
|
|
93
|
+
echo "[navvi] ERROR: Xvfb failed to start"
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
echo "[navvi] Starting Firefox ESR (Marionette on :2828)..."
|
|
98
|
+
firefox-esr \
|
|
99
|
+
--marionette \
|
|
100
|
+
--no-remote \
|
|
101
|
+
-width 1024 -height 768 \
|
|
102
|
+
about:blank &
|
|
103
|
+
FIREFOX_PID=$!
|
|
104
|
+
sleep 2
|
|
105
|
+
|
|
106
|
+
if ! kill -0 "$FIREFOX_PID" 2>/dev/null; then
|
|
107
|
+
echo "[navvi] ERROR: Firefox failed to start"
|
|
108
|
+
exit 1
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
echo "[navvi] Starting x11vnc..."
|
|
112
|
+
x11vnc -display "$DISPLAY" -forever -shared -nopw -rfbport 5900 -bg -q 2>/dev/null
|
|
113
|
+
|
|
114
|
+
echo "[navvi] Starting noVNC on port $VNC_PORT..."
|
|
115
|
+
/opt/novnc/utils/novnc_proxy --vnc localhost:5900 --listen "$VNC_PORT" --web /opt/novnc &
|
|
116
|
+
NOVNC_PID=$!
|
|
117
|
+
sleep 1
|
|
118
|
+
|
|
119
|
+
echo "[navvi] Starting navvi-server on port $NAVVI_PORT..."
|
|
120
|
+
python3 /opt/navvi/navvi-server.py \
|
|
121
|
+
--port "$NAVVI_PORT" \
|
|
122
|
+
--display "$DISPLAY" &
|
|
123
|
+
API_PID=$!
|
|
124
|
+
|
|
125
|
+
# Wait for any child to exit (keeps the shell alive to handle SIGTERM)
|
|
126
|
+
wait
|
|
Binary file
|