forked from bots-garden/ori
| ✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme | 1 | # ori-desktop — une coquille de bureau Wails pour ori |
| 2 | ||
| 3 | `ori-desktop` enveloppe le client web [ori](../README.md) dans une fenêtre native construite | |
| 4 | avec [Wails v2](https://wails.io) (Go + la webview de la plateforme). Il ne réimplémente **pas** | |
| 5 | ori : le serveur ori continue de servir la SPA React et les points d'entrée `/ws`, `/api/files`, | |
| 6 | `/ws/terminal`. L'application de bureau se contente de | |
| 7 | ||
| 8 | 1. afficher un petit **écran de connexion** avec l'URL du serveur ori (par défaut | |
| 9 | `http://localhost:8888`), mémorisée d'une exécution à l'autre dans un fichier JSON ; | |
| 10 | 2. vérifier le serveur avec **`GET /healthz`** via une méthode Go exposée au frontend ; | |
| 11 | 3. puis afficher **la webapp ori elle-même** dans la fenêtre. | |
| 12 | ||
| 13 | C'est un module Go séparé (`rickub.com/bots-garden/ori-desktop`) : le `go test ./...` et le | |
| 14 | `make build` du dépôt parent ne sont pas affectés. | |
| 15 | ||
| 16 | ## Prérequis | |
| 17 | ||
| 18 | - Go 1.25+ (exigence de Wails v2.16, reprise par le module). | |
| 19 | - La CLI Wails v2 : `go install github.com/wailsapp/wails/v2/cmd/wails@v2.16.0` | |
| 20 | (puis vérifier que `$(go env GOPATH)/bin` est dans le `PATH`). | |
| 21 | - La chaîne d'outils graphique attendue par Wails — `wails doctor` liste ce qui manque : | |
| 22 | - **Linux** : `gcc`, `pkg-config`, `libgtk-3-dev`, `libwebkit2gtk-4.0-dev` (ou `-4.1-dev` | |
| 23 | avec `-tags webkit2_41`) ; | |
| 24 | - **macOS** : les Xcode command line tools ; | |
| 25 | - **Windows** : le runtime WebView2 (préinstallé sur Windows 10/11) ; NSIS seulement pour | |
| 26 | l'installeur. | |
| 27 | - Un serveur ori en marche. Depuis la racine du dépôt : `make run` ou `make run-mock`. | |
| 28 | ||
| 29 | Aucun Node/npm n'est nécessaire : le frontend est du HTML/CSS/JS pur embarqué tel quel (pas de | |
| 30 | bundler). | |
| 31 | ||
| 32 | ## Lancer en mode développement | |
| 33 | ||
| 34 | ```bash | |
| 35 | cd ori-desktop | |
| 36 | wails dev | |
| 37 | ``` | |
| 38 | ||
| 39 | `wails dev` compile la partie Go, ouvre la fenêtre et recharge le frontend à chaque modification | |
| 40 | sous `frontend/src/` (`assetdir` dans `wails.json`). Il sert aussi l'application sur | |
| 41 | http://localhost:34115 pour l'ouvrir dans un navigateur classique avec les devtools tout en | |
| 42 | appelant les méthodes Go. | |
| 43 | ||
| 44 | ## Construire un binaire distribuable | |
| 45 | ||
| 46 | ```bash | |
| 47 | cd ori-desktop | |
| 48 | wails build # → build/bin/ori-desktop (ou .app / .exe) | |
| 49 | # ou, depuis la racine du dépôt : | |
| 50 | make desktop | |
| 51 | ``` | |
| 52 | ||
| 53 | La compilation croisée vers Windows depuis Linux/macOS fonctionne sans chaîne C : | |
| 54 | `wails build -platform windows/amd64` → `build/bin/ori-desktop.exe`. | |
| 55 | ||
| 56 | ## Tests | |
| 57 | ||
| 58 | La logique de connexion est en Go pur et testée sans aucune dépendance graphique : | |
| 59 | ||
| 60 | ```bash | |
| 61 | cd ori-desktop && go test ./internal/... | |
| 62 | # ou, depuis la racine du dépôt : | |
| 63 | make desktop-test | |
| 64 | ``` | |
| 65 | ||
| 66 | `internal/settings` couvre les allers-retours chargement/sauvegarde, les valeurs par défaut au | |
| 67 | premier lancement, les fichiers invalides et la normalisation d'URL ; `internal/health` couvre | |
| 68 | `/healthz` face à un serveur `httptest` (sain, non-ori, injoignable, contexte annulé). | |
| 69 | ||
| 70 | ## Comment il se connecte à ori | |
| 71 | ||
| 72 | ``` | |
| 🛟 Updated. | 73 | ┌──────────────── ori-desktop (fenêtre Wails) ────────────────┐ |
| ✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme | 74 | │ frontend/src (embarqué, origine wails://) │ |
| 75 | │ écran de connexion ──► window.go.main.App.Connect(url) │ | |
| 76 | │ │ Go : NormalizeURL → GET /healthz → sauvegarde des réglages | |
| 77 | │ ▼ │ | |
| 78 | │ <iframe src="http://localhost:8888/"> ◄── le serveur ori sert la SPA, | |
| 79 | │ la SPA ouvre ws://localhost:8888/ws, /ws/terminal, /api/files comme d'habitude | |
| 80 | └─────────────────────────────────────────────────────────────┘ | |
| 81 | ``` | |
| 82 | ||
| 83 | **Pourquoi une iframe ?** Wails v2 n'offre aucun appel runtime pour faire naviguer la webview | |
| 84 | principale vers une URL externe ; la fenêtre affiche toujours le frontend embarqué | |
| 85 | (`runtime.BrowserOpenURL` ouvre le navigateur système, proposé comme solution de repli « Open in | |
| 86 | browser »). Charger ori dans une `<iframe>` conserve une fine barre native (URL, Reload, Open in | |
| 87 | browser, Disconnect) autour de la SPA ori intacte. Cela fonctionne parce qu'ori n'envoie ni | |
| 88 | en-tête `X-Frame-Options` ni CSP `frame-ancestors`, et parce que la SPA dérive ses URL | |
| 89 | WebSocket de `window.location` — dans l'iframe c'est l'origine ori elle-même, donc le contrôle | |
| 90 | d'origine `localhost:*` des WebSockets d'ori est satisfait. | |
| 91 | ||
| 92 | Sur macOS, `build/darwin/Info.plist` positionne `NSAppTransportSecurity/NSAllowsLocalNetworking` | |
| 93 | pour qu'App Transport Security autorise le chargement HTTP en clair sur la boucle locale. | |
| 94 | ||
| 95 | ### Méthodes Go exposées au frontend (`app.go`) | |
| 96 | ||
| 97 | | Méthode | Rôle | | |
| 98 | | --- | --- | | |
| 99 | | `GetConfig() → settings.Settings` | Réglages mémorisés (valeurs par défaut au premier lancement). | | |
| 100 | | `SaveConfig(settings.Settings)` | Normalise l'URL puis persiste. | | |
| 101 | | `CheckHealth(url) → health.Report` | `GET <url>/healthz` ; ne rejette jamais — `ok`, `statusCode`, `detail`. | | |
| 102 | | `Connect(url) → string` | Normalise, vérifie la santé, mémorise l'URL, renvoie l'URL de base à charger. | | |
| 103 | | `OpenInBrowser(url)` | Repli `runtime.BrowserOpenURL`. | | |
| 104 | | `SettingsPath() → string` | Emplacement du fichier de réglages (affiché à l'écran). | | |
| 105 | ||
| 106 | Le frontend les appelle via `window.go.main.App.<Méthode>()` (Promesses). Les wrappers typés | |
| 107 | générés par `wails dev`/`wails build` sous `frontend/wailsjs/` sont ignorés par git car rien ne | |
| 108 | les importe ; `wails generate module` les régénère si l'on veut les fichiers `.d.ts`. | |
| 109 | ||
| 110 | ### Fichier de réglages | |
| 111 | ||
| 112 | `<répertoire de configuration utilisateur>/ori-desktop/settings.json`, soit | |
| 113 | `~/.config/ori-desktop/settings.json` sous Linux, `~/Library/Application | |
| 114 | Support/ori-desktop/settings.json` sous macOS, `%AppData%\ori-desktop\settings.json` sous | |
| 115 | Windows : | |
| 116 | ||
| 117 | ```json | |
| 118 | { | |
| 119 | "serverUrl": "http://localhost:8888" | |
| 120 | } | |
| 121 | ``` | |
| 122 | ||
| 123 | ## Arborescence | |
| 124 | ||
| 125 | ``` | |
| 126 | ori-desktop/ | |
| 127 | ├── main.go amorçage Wails (options de fenêtre, assets embarqués, bindings) | |
| 128 | ├── app.go méthodes Go exposées au frontend | |
| 129 | ├── wails.json configuration du projet Wails | |
| 130 | ├── internal/settings/ fichier de réglages (chargement/sauvegarde/normalisation) + tests | |
| 131 | ├── internal/health/ sonde GET /healthz + tests | |
| 132 | ├── frontend/src/ index.html, main.css, main.js (module ES embarqué, sans bundler) | |
| 133 | └── build/ assets de build Wails (icône, Info.plist, manifeste Windows) ; build/bin est la sortie | |
| 134 | ``` | |
| 135 | ||
| 136 | ## État / limites connues | |
| 137 | ||
| 138 | - Vérifié à ce jour : tests unitaires, `go vet`, et une compilation croisée Windows | |
| 139 | (`wails build -platform windows/amd64`) depuis un bac à sable Linux sans bibliothèques | |
| 140 | graphiques. La fenêtre elle-même n'a pas encore été lancée (pas de WebKitGTK dans ce bac à | |
| 141 | sable) — voir les notes `.memory/` du dépôt. | |
| 142 | - ori est chargé en HTTP clair ; à réserver à des serveurs locaux ou de confiance. | |
| 143 | - Un ori lancé avec un autre `--addr` que `:8888` se rejoint simplement en saisissant l'URL | |
| 144 | correspondante sur l'écran de connexion. |