chore(discord-bridge): dashboard-ul se muta de pe /punte pe /claude
https://claude-agent.tailf7372d.ts.net/claude Redenumire completa: tailscale serve, DASHBOARD_PREFIX, teste, documentatie, ops/install.sh (implicitul pentru instalari noi). Vechiul /punte a fost scos din serve si intoarce 404. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
This commit is contained in:
@@ -47,7 +47,7 @@ input/ # Oracle DMP files for import
|
|||||||
- **Chatbot architecture**: `proxmox/lxc104-flowise/docs/prd.md`
|
- **Chatbot architecture**: `proxmox/lxc104-flowise/docs/prd.md`
|
||||||
- **Docker Sandboxes (sbx) — agenți AI izolați**: `proxmox/lxc102-docker/README.md`
|
- **Docker Sandboxes (sbx) — agenți AI izolați**: `proxmox/lxc102-docker/README.md`
|
||||||
- **Punte Discord → Claude Code (comandă LXC 171 de pe telefon, dintr-un guild privat)**: `proxmox/lxc171-claude-agent/discord-bridge/README.md`
|
- **Punte Discord → Claude Code (comandă LXC 171 de pe telefon, dintr-un guild privat)**: `proxmox/lxc171-claude-agent/discord-bridge/README.md`
|
||||||
- **Dashboard de control al punții Discord (stare, restart, orfani, confirmări; https://claude-agent.tailf7372d.ts.net/punte)**: `proxmox/lxc171-claude-agent/discord-bridge/dashboard/README.md`
|
- **Dashboard de control al punții Discord (stare, restart, orfani, confirmări; https://claude-agent.tailf7372d.ts.net/claude)**: `proxmox/lxc171-claude-agent/discord-bridge/dashboard/README.md`
|
||||||
- **Disaster recovery**: `proxmox/vm109-windows-dr/README.md`
|
- **Disaster recovery**: `proxmox/vm109-windows-dr/README.md`
|
||||||
- **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
|
- **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
|
||||||
- **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
|
- **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ Aceleasi lucruri, cu butoane, in **dashboard-ul de control**
|
|||||||
jurnale:
|
jurnale:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://claude-agent.tailf7372d.ts.net/punte # din tailnet (ca /echo la moltbot)
|
https://claude-agent.tailf7372d.ts.net/claude # din tailnet (ca /echo la moltbot)
|
||||||
grep DASHBOARD_TOKEN ~/.claude-discord/env # tokenul de login
|
grep DASHBOARD_TOKEN ~/.claude-discord/env # tokenul de login
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ de server (stdlib `http.server`, zero dependinte), aceiasi tokeni de design, ace
|
|||||||
tipar de endpoint-uri ca in `handlers/eco.py`.
|
tipar de endpoint-uri ca in `handlers/eco.py`.
|
||||||
|
|
||||||
```
|
```
|
||||||
https://claude-agent.tailf7372d.ts.net/punte <- din tailnet, ca /echo la moltbot
|
https://claude-agent.tailf7372d.ts.net/claude <- din tailnet, ca /echo la moltbot
|
||||||
http://127.0.0.1:18790 <- local / prin tunel SSH
|
http://127.0.0.1:18790 <- local / prin tunel SSH
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ systemctl --user enable --now claude-discord-dashboard
|
|||||||
```
|
```
|
||||||
|
|
||||||
Setari optionale in `~/.claude-discord/env`: `DASHBOARD_BIND` (implicit `127.0.0.1`),
|
Setari optionale in `~/.claude-discord/env`: `DASHBOARD_BIND` (implicit `127.0.0.1`),
|
||||||
`DASHBOARD_PORT` (implicit `18790`), `DASHBOARD_PREFIX` (implicit gol; `/punte` cand e
|
`DASHBOARD_PORT` (implicit `18790`), `DASHBOARD_PREFIX` (implicit gol; `/claude` cand e
|
||||||
publicat prin `tailscale serve --set-path`).
|
publicat prin `tailscale serve --set-path`).
|
||||||
|
|
||||||
## Acces
|
## Acces
|
||||||
@@ -110,12 +110,12 @@ legat de `127.0.0.1`, iar `tailscaled` e singurul care ajunge la el si il public
|
|||||||
tailnet, cu HTTPS si certificat de la Tailscale.
|
tailnet, cu HTTPS si certificat de la Tailscale.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo tailscale serve --bg --set-path /punte http://127.0.0.1:18790
|
sudo tailscale serve --bg --set-path /claude http://127.0.0.1:18790
|
||||||
tailscale serve status
|
tailscale serve status
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
https://claude-agent.tailf7372d.ts.net/punte
|
https://claude-agent.tailf7372d.ts.net/claude
|
||||||
```
|
```
|
||||||
|
|
||||||
Vizibil doar in tailnet (`tailnet only`) — nu e `funnel`, deci nu iese in internet.
|
Vizibil doar in tailnet (`tailnet only`) — nu e `funnel`, deci nu iese in internet.
|
||||||
@@ -124,13 +124,13 @@ Configuratia e persistata de `tailscaled`, deci supravietuieste repornirilor.
|
|||||||
**Montarea sub prefix**, cele doua capcane si cum sunt rezolvate:
|
**Montarea sub prefix**, cele doua capcane si cum sunt rezolvate:
|
||||||
|
|
||||||
- `tailscale serve --set-path` **taie** prefixul inainte de a proxa, deci serverul
|
- `tailscale serve --set-path` **taie** prefixul inainte de a proxa, deci serverul
|
||||||
vede `/api/status`, nu `/punte/api/status`. Toate URL-urile din pagini sunt
|
vede `/api/status`, nu `/claude/api/status`. Toate URL-urile din pagini sunt
|
||||||
**relative**, deci merg la orice prefix, fara sa stie de el. `DASHBOARD_PREFIX`
|
**relative**, deci merg la orice prefix, fara sa stie de el. `DASHBOARD_PREFIX`
|
||||||
e nevoie doar pentru redirecturi si e acceptat si intact pe intrare (`curl`
|
e nevoie doar pentru redirecturi si e acceptat si intact pe intrare (`curl`
|
||||||
direct pe localhost cu `/punte/...` functioneaza).
|
direct pe localhost cu `/claude/...` functioneaza).
|
||||||
- adresa **fara slash final** (`/punte`) ar rezolva `api/status` la radacina
|
- adresa **fara slash final** (`/claude`) ar rezolva `api/status` la radacina
|
||||||
hostului, unde proxy-ul nu mai trimite nimic incoace; de aceea forma fara slash
|
hostului, unde proxy-ul nu mai trimite nimic incoace; de aceea forma fara slash
|
||||||
primeste un 301 catre `/punte/`.
|
primeste un 301 catre `/claude/`.
|
||||||
|
|
||||||
### Prin tunel SSH
|
### Prin tunel SSH
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ COOKIE_MAX_AGE = 60 * 60 * 24 * 30
|
|||||||
|
|
||||||
|
|
||||||
def mount_prefix() -> str:
|
def mount_prefix() -> str:
|
||||||
"""Prefixul sub care e montat panoul (`DASHBOARD_PREFIX`, ex. `/punte`).
|
"""Prefixul sub care e montat panoul (`DASHBOARD_PREFIX`, ex. `/claude`).
|
||||||
|
|
||||||
`tailscale serve --set-path /punte` TAIE prefixul inainte de a proxa, deci in
|
`tailscale serve --set-path /claude` TAIE prefixul inainte de a proxa, deci in
|
||||||
mod normal aici ajunge `/api/status`. Prefixul e acceptat totusi si intact,
|
mod normal aici ajunge `/api/status`. Prefixul e acceptat totusi si intact,
|
||||||
pentru cazul unui proxy care nu taie si pentru `curl` direct pe localhost.
|
pentru cazul unui proxy care nu taie si pentru `curl` direct pe localhost.
|
||||||
Paginile nu depind de el: toate URL-urile din HTML sunt relative.
|
Paginile nu depind de el: toate URL-urile din HTML sunt relative.
|
||||||
@@ -402,7 +402,7 @@ class Handler(SimpleHTTPRequestHandler):
|
|||||||
raw = urlparse(self.path).path
|
raw = urlparse(self.path).path
|
||||||
path = strip_prefix(raw)
|
path = strip_prefix(raw)
|
||||||
if path == "/" and not raw.endswith("/"):
|
if path == "/" and not raw.endswith("/"):
|
||||||
# `/punte` fara slash final: URL-urile relative din pagina s-ar
|
# `/claude` fara slash final: URL-urile relative din pagina s-ar
|
||||||
# rezolva la radacina hostului (`/api/status`), unde proxy-ul nu mai
|
# rezolva la radacina hostului (`/api/status`), unde proxy-ul nu mai
|
||||||
# trimite nimic incoace. Fortam forma cu slash.
|
# trimite nimic incoace. Fortam forma cu slash.
|
||||||
self.send_response(301)
|
self.send_response(301)
|
||||||
@@ -418,7 +418,7 @@ class Handler(SimpleHTTPRequestHandler):
|
|||||||
# Prefixul reintra AICI in mod deliberat. Un "/login.html" absolut ar
|
# Prefixul reintra AICI in mod deliberat. Un "/login.html" absolut ar
|
||||||
# arunca browserul in radacina hostului (alt serviciu), iar un
|
# arunca browserul in radacina hostului (alt serviciu), iar un
|
||||||
# "login.html" relativ se rezolva gresit cand adresa vine fara slash
|
# "login.html" relativ se rezolva gresit cand adresa vine fara slash
|
||||||
# final (`/punte` -> `/login.html`). Cu prefixul reatasat, ambele
|
# final (`/claude` -> `/login.html`). Cu prefixul reatasat, ambele
|
||||||
# forme ajung unde trebuie, si direct pe localhost la fel: calea de
|
# forme ajung unde trebuie, si direct pe localhost la fel: calea de
|
||||||
# intrare e curatata oricum de `strip_prefix`.
|
# intrare e curatata oricum de `strip_prefix`.
|
||||||
self.send_response(302)
|
self.send_response(302)
|
||||||
|
|||||||
@@ -63,4 +63,4 @@ DASHBOARD_PORT=18790
|
|||||||
# Prefixul sub care il publica `tailscale serve --set-path` (vezi dashboard/README.md).
|
# Prefixul sub care il publica `tailscale serve --set-path` (vezi dashboard/README.md).
|
||||||
# Gol = montat in radacina. Paginile au URL-uri relative, deci prefixul e nevoie
|
# Gol = montat in radacina. Paginile au URL-uri relative, deci prefixul e nevoie
|
||||||
# doar pentru redirecturi.
|
# doar pentru redirecturi.
|
||||||
DASHBOARD_PREFIX=/punte
|
DASHBOARD_PREFIX=/claude
|
||||||
|
|||||||
@@ -138,11 +138,11 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# --- 6b. tailscale serve pentru dashboard ----------------------------------
|
# --- 6b. tailscale serve pentru dashboard ----------------------------------
|
||||||
# Publica panoul in tailnet la https://<host>.<tailnet>.ts.net/punte, exact ca
|
# Publica panoul in tailnet la https://<host>.<tailnet>.ts.net/claude, exact ca
|
||||||
# dashboard-ul lui echo de pe LXC 110 (/echo). Serviciul ramane legat de
|
# dashboard-ul lui echo de pe LXC 110 (/echo). Serviciul ramane legat de
|
||||||
# 127.0.0.1: tailscaled e singurul care ajunge la el.
|
# 127.0.0.1: tailscaled e singurul care ajunge la el.
|
||||||
DASH_PREFIX="$(grep -E '^DASHBOARD_PREFIX=' "$STATE_DIR/env" 2>/dev/null | cut -d= -f2- || true)"
|
DASH_PREFIX="$(grep -E '^DASHBOARD_PREFIX=' "$STATE_DIR/env" 2>/dev/null | cut -d= -f2- || true)"
|
||||||
DASH_PREFIX="${DASH_PREFIX:-/punte}"
|
DASH_PREFIX="${DASH_PREFIX:-/claude}"
|
||||||
DASH_PORT="$(grep -E '^DASHBOARD_PORT=' "$STATE_DIR/env" 2>/dev/null | cut -d= -f2- || true)"
|
DASH_PORT="$(grep -E '^DASHBOARD_PORT=' "$STATE_DIR/env" 2>/dev/null | cut -d= -f2- || true)"
|
||||||
DASH_PORT="${DASH_PORT:-18790}"
|
DASH_PORT="${DASH_PORT:-18790}"
|
||||||
if ! command -v tailscale >/dev/null 2>&1; then
|
if ! command -v tailscale >/dev/null 2>&1; then
|
||||||
|
|||||||
@@ -340,9 +340,9 @@ def test_ruta_necunoscuta(server):
|
|||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def server_cu_prefix(server, state_dir):
|
def server_cu_prefix(server, state_dir):
|
||||||
"""Acelasi server, dar cu DASHBOARD_PREFIX=/punte in env."""
|
"""Acelasi server, dar cu DASHBOARD_PREFIX=/claude in env."""
|
||||||
(state_dir / "env").write_text(
|
(state_dir / "env").write_text(
|
||||||
"DASHBOARD_TOKEN=secret-de-test\nDASHBOARD_PREFIX=/punte\n", encoding="utf-8")
|
"DASHBOARD_TOKEN=secret-de-test\nDASHBOARD_PREFIX=/claude\n", encoding="utf-8")
|
||||||
config.reload(state_dir)
|
config.reload(state_dir)
|
||||||
return server
|
return server
|
||||||
|
|
||||||
@@ -355,29 +355,29 @@ def test_rutele_merg_si_cu_prefix_si_fara(server_cu_prefix):
|
|||||||
"""Proxy-ul taie prefixul, dar `curl` direct pe localhost nu — merg ambele."""
|
"""Proxy-ul taie prefixul, dar `curl` direct pe localhost nu — merg ambele."""
|
||||||
server_cu_prefix.login()
|
server_cu_prefix.login()
|
||||||
assert server_cu_prefix.call("/api/status")[0] == 200
|
assert server_cu_prefix.call("/api/status")[0] == 200
|
||||||
assert server_cu_prefix.call("/punte/api/status")[0] == 200
|
assert server_cu_prefix.call("/claude/api/status")[0] == 200
|
||||||
|
|
||||||
|
|
||||||
def test_prefixul_gol_nu_taie_nimic(server):
|
def test_prefixul_gol_nu_taie_nimic(server):
|
||||||
server.login()
|
server.login()
|
||||||
assert server.call("/api/status")[0] == 200
|
assert server.call("/api/status")[0] == 200
|
||||||
assert server.call("/punte/api/status")[0] == 404
|
assert server.call("/claude/api/status")[0] == 404
|
||||||
|
|
||||||
|
|
||||||
def test_redirect_de_login_pastreaza_prefixul(server_cu_prefix):
|
def test_redirect_de_login_pastreaza_prefixul(server_cu_prefix):
|
||||||
"""Un `/login.html` absolut ar arunca browserul in radacina hostului."""
|
"""Un `/login.html` absolut ar arunca browserul in radacina hostului."""
|
||||||
status, _, resp = server_cu_prefix.call("/punte/")
|
status, _, resp = server_cu_prefix.call("/claude/")
|
||||||
assert status == 200
|
assert status == 200
|
||||||
assert resp.url.endswith("/punte/login.html")
|
assert resp.url.endswith("/claude/login.html")
|
||||||
|
|
||||||
|
|
||||||
def test_calea_fara_slash_final_e_redirectionata(server_cu_prefix):
|
def test_calea_fara_slash_final_e_redirectionata(server_cu_prefix):
|
||||||
"""`/punte` fara slash ar rezolva `api/status` la radacina hostului."""
|
"""`/claude` fara slash ar rezolva `api/status` la radacina hostului."""
|
||||||
_, _, resp = server_cu_prefix.call("/punte")
|
_, _, resp = server_cu_prefix.call("/claude")
|
||||||
assert resp.url.endswith("/punte/login.html")
|
assert resp.url.endswith("/claude/login.html")
|
||||||
|
|
||||||
|
|
||||||
def test_static_servit_si_sub_prefix(server_cu_prefix):
|
def test_static_servit_si_sub_prefix(server_cu_prefix):
|
||||||
server_cu_prefix.login()
|
server_cu_prefix.login()
|
||||||
status, data, _ = server_cu_prefix.call("/punte/static/app.css")
|
status, data, _ = server_cu_prefix.call("/claude/static/app.css")
|
||||||
assert status == 200 and ".card" in data["_html"]
|
assert status == 200 and ".card" in data["_html"]
|
||||||
|
|||||||
Reference in New Issue
Block a user