# Web (app.codai.ro) (/ro/docs/apps/web)

Interfața desktop într-un tab de browser — te autentifici cu contul codai, conversezi de oriunde și rulezi agenți pe un desktop conectat cu același cont.

[app.codai.ro](https://app.codai.ro) este **aceeași aplicație ca codai desktop**, construită pentru browser. Același chat, aceleași sesiuni, aceleași setări — dar un browser nu are sistem de fișiere, shell sau terminal, așa că orice are nevoie de ele rulează pe un **host**: unul dintre desktopurile tale cu codai desktop deschis. Până când un host este online, aplicația web este *doar chat*.

Aceeași aplicație este servită și la [chat.codai.ro](https://chat.codai.ro) — o copie identică pe o a doua adresă. Fiecare adresă se autentifică **separat**: browserul păstrează cheia per site, așa că autentificarea pe `app.codai.ro` nu te autentifică pe `chat.codai.ro`, iar fiecare apare ca dispozitiv distinct.

## Ce funcționează în browser [#ce-funcționează-în-browser]

| Funcționează | Are nevoie de un host desktop | Indisponibil pe web |
| --- | --- | --- |
| Chat cu `codai`, selector de model, slider de efort | Unelte de fișiere (citire, editare, revizuire de diff) | Terminal integrat (PTY) |
| Sesiuni partajate: listă, transcript live, send / answer / cancel | Comenzi shell | Tab de browser încorporat |
| Setări, keybindings, skin-uri | Sarcini trimise (dispatch) către un desktop | Controlul computerului (aplicații Windows) |
| Dispozitive, card de cost, browser de memorie | | Modele locale (Ollama, LM Studio) |
| Autentificare și gestionarea cheii | | Actualizator automat (site-ul este mereu curent) |

## Autentificare [#autentificare]

<Steps>
<Step>

### Before you start [#before-you-start]

Accepți Termenii și Politica de confidențialitate. Consimțământul este stocat în acest browser; ștergerea datelor site-ului readuce ecranul.

</Step>
<Step>

### Continue in browser [#continue-in-browser]

Pagina redirecționează **în același tab** către [auth.codai.ro](https://auth.codai.ro) — Google sau e-mail, cu PKCE. Când revii la `app.codai.ro/callback`, contul a emis o cheie `codai_` pentru **acest browser**, etichetată `OAuth · codai app` în hub.

Preferi o cheie pe care o ai deja? **I have an API key** acceptă un `codai_…` din [hub.codai.ro](https://hub.codai.ro) → **Keys**.

</Step>
<Step>

### Unde stă cheia [#unde-stă-cheia]

În `localStorage`-ul acestui browser, limitat la `app.codai.ro`, împreună cu un **id de dispozitiv** stabil pentru acest profil de browser. Este trimisă doar ca header `Authorization` către URL-ul de gateway din Settings (implicit `https://ai.codai.ro`). Nimic altceva de pe pagină nu o citește.

</Step>
</Steps>

### Revocarea cheii browserului [#revocarea-cheii-browserului]

Fiecare profil de browser care s-a autentificat apare ca un dispozitiv. Îl revoci din [hub.codai.ro](https://hub.codai.ro) → **Security → Devices**, sau din orice client autentificat, la **Devices**. **Settings → Sign out** în aplicația web îl revocă și el. Dacă autentificarea s-a încheiat la IdP dar gateway-ul nu a răspuns, aplicația nu salvează nimic și îți spune — cheia nefolosită există totuși în hub și poate fi revocată de acolo.

## Conectezi un desktop — „Run on” [#conectezi-un-desktop--run-on]

<Callout type="info">
**Chat only in the browser** — vezi acest card până când un host este online. *Instalează aplicația desktop pentru a rula agenți local, sau conectează un host — browserul poate conduce un desktop autentificat cu același cont.*
</Callout>

1. Pe un computer, instalezi [codai desktop](./desktop.mdx) și te autentifici cu **același cont**.
2. **Settings → Executor → Serve as a remote host for my phone** — bara de stare arată *Relay: online*.
3. Înapoi în browser, composer-ul primește un selector **Run on** care listează desktopurile tale online (hostname, OS, ultima dată văzut). Alegi unul.

De acum, uneltele de fișiere și shell din acest chat se execută **pe acel desktop**, în folderele lui aprobate, cu cardurile lui de aprobare. Browserul afișează fiecare pas. Dacă host-ul iese offline în mijlocul sarcinii, apelul de unealtă eșuează cu *No host connected — install the desktop app or pick a host.*

Un host trebuie să fi fost văzut în ultimele **45 de secunde** pentru a fi listat. Host-urile sunt per cont: desktopurile altcuiva nu apar niciodată, iar ale tale nu apar nimănui altcuiva. Releul din spate este documentat pe pagina [releu de host-uri](../sessions/hosts.mdx).

## Limitări [#limitări]

- **Fără execuție locală.** Fără host, apelurile de unealtă care ating fișiere sau un shell sunt refuzate; modelului i se spune asta și răspunde în chat.
- **O cheie per profil de browser.** Ferestrele incognito și alte browsere sunt dispozitive separate.
- **Sesiunile urmează contul, setările urmează browserul.** Skin-urile, keybinding-urile și URL-ul de gateway stau în `localStorage`; sesiunile și memoria stau pe gateway.
- **Gateway-urile auto-găzduite** trebuie să permită originea `https://app.codai.ro` pentru `/v1/*` (CORS) și să înregistreze `https://app.codai.ro/callback` ca redirect URI pe IdP.

## Depanare [#depanare]

<Accordions>
<Accordion title="„Signed in, but the gateway is unreachable”">
Contul tău a emis o cheie, dar URL-ul de gateway din Settings nu a răspuns, așa că nu s-a salvat nimic. Verifici **Settings → Gateway URL** (implicit `https://ai.codai.ro`), apoi **Try again** — aplicația reîncearcă cu aceeași cheie în loc să emită alta. Cheia nefolosită poate fi revocată din hub → Security → Devices.
</Accordion>
<Accordion title="„Device id is registered to another account”">
Id-ul de dispozitiv stocat în acest profil de browser a fost înregistrat prima dată sub un alt cont codai — de obicei pentru că două conturi s-au autentificat din același profil de browser (două tab-uri împart `localStorage`). Gateway-ul refuză să re-lege un id de dispozitiv la un al doilea cont. **Sign out nu resetează id-ul de dispozitiv.** Soluție: folosești un profil de browser separat per cont, sau ștergi datele site-ului pentru `app.codai.ro` (asta elimină cheia stocată, setările și id-ul de dispozitiv — vechiul dispozitiv rămâne listat în hub până îl revoci).
</Accordion>
<Accordion title="Niciun host online, deși desktopul rulează">
Pe desktop verifici că **Settings → Executor → Serve as a remote host** este activ și că bara de stare spune *Relay: online*, nu *connecting* sau *retrying*. Ambele trebuie autentificate cu același cont. Un host fără heartbeat 45 s dispare; reîncarci selectorul.
</Accordion>
<Accordion title="Ecranul Before you start revine mereu">
Consimțământul este stocat în datele de site ale acestui browser pentru `app.codai.ro`. Extensiile care șterg storage-ul la închidere, sau protecția strictă anti-tracking, îl șterg la fiecare sesiune. Permiți datele de site pentru `app.codai.ro`.
</Accordion>
<Accordion title="Autentificarea se învârte în buclă sau ajunge pe o pagină de eroare">
Starea PKCE stă în `sessionStorage` și este consumată la prima revenire. Dacă reîmprospătezi pagina de callback, fluxul se reia și eșuează. Pornești din nou de la `app.codai.ro`; dacă un proxy corporativ elimină cookie-urile pentru `auth.codai.ro`, te autentifici din altă rețea sau lipești o cheie.
</Accordion>
</Accordions>

<Cards>
  <Card title="Desktop" href="./desktop.mdx" description="Configurezi partea de host." />
  <Card title="Releu de host-uri" href="../sessions/hosts.mdx" description="Protocolul din spatele lui Run on." />
  <Card title="Fluxul connect" href="../auth/connect-flow.mdx" description="Cum emite IdP-ul o cheie pentru un dispozitiv." />
</Cards>
