Commit Graph

7 Commits

Author SHA1 Message Date
Claude Agent
22628fb178 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
2026-08-30 13:30:43 +00:00
Claude Agent
dd7fa28fa5 feat(discord-bridge): dashboard publicat in tailnet prin tailscale serve
https://claude-agent.tailf7372d.ts.net/punte — acelasi tipar ca /echo de pe
moltbot: procesul ramane legat de 127.0.0.1, tailscaled il proxeaza si pune HTTPS.

Montarea sub prefix a cerut doua schimbari:

- toate URL-urile din pagini sunt acum relative, fiindca --set-path TAIE prefixul
  inainte de a proxa (serverul vede /api/status, browserul cere /punte/api/status).
  DASHBOARD_PREFIX ramane necesar doar pentru redirectul de login, si e acceptat
  si intact pe intrare, ca sa mearga si curl direct pe localhost.
- adresa fara slash final (/punte) primeste 301 catre /punte/: altfel URL-urile
  relative s-ar rezolva la radacina hostului, unde proxy-ul nu trimite nimic
  incoace, si panoul ar arata gol fara nicio eroare vizibila.

ops/install.sh configureaza serve-ul daca sudo permite; altfel spune comanda.
Sase teste noi pentru montarea sub prefix (31 in total pe dashboard).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 13:27:59 +00:00
Claude Agent
7abefa2b46 feat(discord-bridge): dashboard de control si restart, dupa modelul agentului echo
Panou web pe 127.0.0.1:18790, unit systemd separat de al puntii. Server stdlib
(fara dependinte noi), tokenii de design si tiparul de endpoint-uri preluate din
/home/moltbot/echo-core/dashboard (handlers/eco.py) de pe LXC 110.

Arata: starea unitatii (uptime, PID, memoria cgroup, restarturi), firele din
state.json cu tur in zbor si cost, costul zilei fata de plafon, confirmarile
PreToolUse in asteptare (aprobabile direct din pagina), bot.log / infra.log si
opt verificari de diagnostic.

Face: start / stop / restart pe punte, cautarea si curatarea orfanilor prin
cleanup.py, repornirea propriului serviciu.

Garantii, cu teste:
- unitatea controlata e fixa in cod; un {"unit": "ssh.service"} in cerere nu
  schimba nimic, altfel panoul ar fi systemctl remote fara parola;
- stop/restart intorc 409 cu lista firelor active si cer force explicit, fiindca
  KillMode=control-group taie tururile in desfasurare;
- state.json se citeste fara lock: panoul nu are voie sa blocheze botul;
- diagnosticul pica daca reapare Bash(ssh:*) in deny (regresia de azi).

Uptime-ul se calculeaza din time.monotonic(), nu din /proc/uptime: in LXC acela
e virtualizat de lxcfs si da diferenta negativa fata de monotonic-ul systemd.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 13:18:38 +00:00
Claude Agent
c8a5d418f3 fix(discord-bridge): /cleanup urmareste descendentii, dar STRICT in cgroup-ul serviciului
Doua defecte, al doilea gasit la verificarea primului.

1. Procesul `claude` al unui fir isi porneste serverele MCP (npm/sh/node pentru
   playwright), care nu se numesc `claude` si scapau cautarii. Masurat pe firul viu:
   claude 300 MB + MCP 137 MB = ~440 MB per fir, nu 300. find_orphans merge acum pe
   arbore, iar kill_orphans opreste copiii inaintea parintilor (altfel se reparenteaza
   si scapa).

2. PERICULOS: definitia initiala a orfanului ("orice `claude` absent din state.json")
   prindea sesiunile Claude interactive de pe container. Rularea seaca propunea 25 de
   procese / ~3864 MB — sesiunile de lucru din tmux, inclusiv cea din care ar fi fost
   data comanda. `/cleanup force:True` din Discord si-ar fi omorat propria sesiune.
   Apartenenta la cgroup-ul `claude-discord.service` devine conditie necesara pentru
   toate familiile, fail-closed la cgroup necitibil. Dupa fix: zero procese raportate.

   Test de regresie pe instantaneul real (doua sesiuni in tmux-spawn-*.scope, una in
   claude-discord.service): se raporteaza doar a treia. Verificat prin mutant ca testul
   musca — cu filtrul scos pica 3 teste.

3. INTERFACES.md cerea pid_start_time in ticks, dar session_store scrie secunde (si
   state.json viu contine secunde). Contractul era imprecis, nu codul: un consumator
   care compara ticks nu s-ar potrivi niciodata, iar cum acea comparatie protejeaza
   turul in desfasurare, esecul ar fi fost tacut si ar fi facut eligibil exact ce
   trebuia protejat. Documentat, cu avertismentul explicit.

Bug colateral prins de agent: raportul cu rezultate de omorare ajungea la 2289 caractere,
peste limita Discord — mesajul ar fi fost respins exact la `/cleanup force:True`. Buget
de caractere adaugat.

Suita: 322 passed cu discord.py, 319 passed + 3 skipped fara. Rulare seaca pe container: curat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 12:47:16 +00:00
Claude Agent
5f34320e3e feat(discord-bridge): comenzi slash in loc de prefixul !
Comenzile devin application commands inregistrate pe guild (sync instantaneu,
spre deosebire de cel global care dureaza ~1h): /new [fork], /cd <cale>,
/model <sonnet|opus> cu Choice, /status, /stop, /cleanup [force], /help.

- allowlist-ul se aplica identic la interactiuni (check_ids comun, ca sa nu
  existe a doua implementare care diverge); refuz efemer, fara executie
- fiecare comanda face defer() inainte de lucru — altfel Discord marcheaza
  interactiunea esuata dupa 3s desi comanda a rulat
- sync tolerant: la esec (lipsa scope applications.commands) botul porneste
  normal si logheaza linkul de reinvitare necesar
- mesajele obisnuite raman neschimbate, inclusiv steering-ul mid-tur
- linkul de invitatie primeste scope=bot%20applications.commands; referintele
  la ! din ops/ si documentatie trecute pe /

Verificat in productie: 7 comenzi inregistrate pe guild, citite inapoi din API.
Suita: 296 passed cu discord.py, 293 passed + 3 skipped fara.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 12:23:33 +00:00
Claude Agent
8c550a2cde docs(discord-bridge): corectii la partea manuala — View Channel lipsea, Add Bot depasit
- permisiunile de invitatie omiteau *View Channel*, fara de care botul nu vede
  canalul deloc, oricat de permis ar fi in allowlist
- link de invitatie gata calculat (permissions=309237763136), fiindca bifele din
  URL Generator sunt greu de nimerit pe telefon
- *Bot -> Add Bot* nu mai exista: portalul creeaza user-ul bot odata cu aplicatia
- MESSAGE CONTENT INTENT are nevoie de *Save Changes*; fara apasare setarea se pierde
- pasii de copiere ID: pe telefon e apasare lunga, nu click dreapta

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 10:55:47 +00:00
Claude Agent
d466f358ce feat(discord-bridge): punte Discord -> Claude Code pe LXC 171
Implementeaza planul claude-master-plan-discord-bridge-20260830 (15 taskuri,
3 lane-uri paralele) — un bot subtire discord.py peste CLI-ul `claude`, cu
proces persistent per fir alimentat pe stdin cu --input-format stream-json.

Nucleu: runner (proces persistent + reaper 20min + respawn --resume), stream
(parser tolerant), session_store (scriere atomica, lock per fir, detectare PID
reuse, recovery), limits (max 4 procese, timeout tur, rate per user, plafon cost
pe zi), render (un loop de editare per canal, interval adaptiv).

Adaptor: allowlist guild/canal/user fail-closed cu respingerea webhook-urilor,
comenzi !new/!cd/!model/!status/!stop/!cleanup, cost si model in subsolul
fiecarui raspuns. Mesajul sosit in timpul unui tur devine steering, nu tur nou.

Securitate: hook PreToolUse fail-closed care cere confirmare in Discord pentru
operatiuni ireversibile, wrapper `infra` cu lista explicita de hosturi. Deny
rules raman strat cosmetic, nu bariera (verificat: /usr/bin/ssh trece pe langa).

Ops: alerte email pe conventia repo-ului, !cleanup pentru orfani, unit systemd
user cu KillMode=control-group si limite de memorie, install.sh idempotent.

Verificat: 275 teste fara retea/Discord/API (10.8s), identic cu si fara
discord.py instalat; e2e pe CLI real confirma steering-ul mid-tur (mesaj la 6s
intr-un tool call de 25s schimba raspunsul final).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
2026-08-30 10:44:39 +00:00