release: git-arboretum 3.4.0 (visibilité temps réel, historisation), desktop 0.2.0 (Windows, logo), vscode 0.4.1, site 0.4.0
CI / Build & test (Node 22) (push) Successful in 11m12s
CI / Build & test (Node 24) (push) Successful in 10m14s
CI / No em/en dashes (push) Successful in 3s
Deploy site (production) / build-and-deploy (push) Successful in 19s
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
CI / Build & test (Node 22) (push) Successful in 11m12s
CI / Build & test (Node 24) (push) Successful in 10m14s
CI / No em/en dashes (push) Successful in 3s
Deploy site (production) / build-and-deploy (push) Successful in 19s
CI / Pack & boot smoke (Node 22) (push) Has been cancelled
Tout est additif : PROTOCOL_VERSION inchangé, aucune rupture d'API. Temps réel réellement armé - `pinSession` n'était appelé nulle part : une session vivante épingle désormais le watcher FS de son worktree (`WorktreeManager.syncSessionPin` + `resolveWorktreeForCwd`), donc un worktree où un agent écrit se rafraîchit même si personne ne le regarde (mesuré ~350 ms). - Les abonnements `watch` sortent de `GitPanel`, démonté dès qu'on quitte son onglet, ce qui coupait le seul abonnement de toute l'app : `composables/useWatchedWorktrees.ts` (monté dans App.vue) suit le worktree actif et les dépôts dépliés, borné à 40. - Une coupure WS ne laisse plus l'UI sur des listes périmées : rechargement complet au retour. - `worktree_changes` alimente `worktrees.changeVersion`, consommé par l'arbre de fichiers, le diff (son `:version` était câblé à 0) et l'éditeur, qui recharge un tampon propre ou lève la bannière de conflit avant la sauvegarde au lieu d'attendre le 409. Corrélation session ↔ worktree par contenance (`@arboretum/shared/path-match.ts`) - Un terminal lancé dans un sous-répertoire (« Démarrer le projet ») ou une session de groupe reliée par `--add-dir` apparaissent enfin sous leur worktree ; le worktree le plus spécifique gagne. - Règle unique partagée par le daemon, le web et l'extension. Historisation - `commitLog` / `commitDiff` purs, `GET /repos/:id/worktrees/log` et `diff?commit=` (hash strictement validé, mêmes bornes que les diffs de fichiers). - `CommitHistory.vue` sous le panneau Git : commits, marquage des non poussés, diff déplié sur place. Visibilité - Compteurs git complets sur chaque worktree de l'arbre et du panneau Groupes (ils n'existaient qu'en barre de statut, pour le seul worktree actif), avec upstream et dernier commit en infobulle ; `locked`, `prunable` et un dépôt invalide sont désormais visibles. - Le panneau Groupes montre sa composition réelle (dépôts, worktrees, sessions) et teinte l'explorateur. Polish visuel - Les toasts d'erreur, persistants, s'empilaient derrière les modals : téléportés au-dessus. - Sur mobile, ouvrir un terminal ou changer d'activité n'avait aucun effet visible. - Tailles de panneaux clampées sur la fenêtre, barres d'onglets sans scrollbar parasite, états de chargement et d'erreur dans les trois panneaux, accessibilité des 11 modals centralisée dans ModalHost, splitters au clavier, numéros de diff collants, `window.confirm` remplacé. Windows (daemon et packaging) - `where.exe`, PowerShell comme shell de lancement, askpass `.cmd` (clone/push HTTPS par PAT), `taskkill /T`, `%APPDATA%`, `arboretum install` via tâche planifiée. - Scripts de build exécutables sur un hôte Windows (`npm.cmd`, extraction sans `unzip` ni `bash`). - Job CI `windows-latest` conditionné par ENABLE_WINDOWS_BUILD ; procédure runner dans docs/CI_RUNNERS.md. Logo Debian : cause racine - Une icône unique de 895×895 atterrissait dans `hicolor/895x895`, répertoire absent d'`index.theme` donc ignoré par la spécification freedesktop ; et `executableName` dérivait du nom scopé du paquet (`@arboretumdesktop`). Jeu d'icônes standard généré + `executableName: arboretum`, plus `deb.synopsis` (description courte vide dans apt) et `Section: devel`. - Runtime Node embarqué élagué : 205 → 118 Mo. - Auto-update réparé : la release flottante `desktop-latest` que les binaires interrogent n'existait pas. Doc et vitrine - README/README.fr : installation par plateforme, mode serveur web (nginx, LAN), dépannage, variables d'environnement, flags manquants. - Doc in-app réécrite (elle renvoyait aux pages Worktrees et Sessions supprimées). - Section « Accès distant » dans les Réglages ; le 403 BAD_ORIGIN nomme le flag à ajouter. - Site : prérequis et registre npm privé (le `npx` affiché renvoyait un 404), téléchargements réels par plateforme, section « trois façons de l'utiliser », navigation complétée, 16 clés i18n mortes purgées. Vérifications : 483 tests unitaires, 14 acceptances E2E vertes (dont p14/p15 nouvelles), captures de rendu sans erreur console (nouveau `verify-ui.mjs`), .deb reconstruit et contrôlé (icônes aux tailles standard, entrée .desktop valide).
This commit is contained in:
@@ -129,6 +129,19 @@ Prefer a native app to the daemon-in-a-terminal? Arboretum ships an **Electron d
|
||||
|
||||
The desktop app is just a shell around the same daemon and web UI, so everything below (workspace, git, sessions) works identically.
|
||||
|
||||
### Installing per platform
|
||||
|
||||
| Platform | Artifact | Notes |
|
||||
|---|---|---|
|
||||
| **Debian / Ubuntu** | `Arboretum-<version>-amd64.deb` | `sudo apt install ./Arboretum-*.deb`. Pulls in `git`. Preferred over the AppImage on Debian: it installs the launcher entry and its icons. |
|
||||
| **Other Linux** | `Arboretum-<version>-x86_64.AppImage` | `chmod +x` then run. No desktop entry unless you use a tool like `appimaged`. |
|
||||
| **Windows** | `Arboretum-<version>-x64.exe` (NSIS) or the portable build | Not code-signed: SmartScreen shows "unknown publisher", choose **More info → Run anyway**. Needs Windows 10 1809+ (ConPTY). |
|
||||
| **macOS** | `Arboretum-<version>.dmg` | Not signed or notarized: right-click the app → **Open**, or `xattr -dr com.apple.quarantine /Applications/Arboretum.app`. Built on demand, see `packages/desktop/README.md`. |
|
||||
|
||||
Windows also needs the `claude` CLI on your PATH like any other platform; if the app cannot find it,
|
||||
set its path in **Settings → Claude CLI**. Running the daemon at logon is supported there too
|
||||
(`arboretum install` registers a scheduled task).
|
||||
|
||||
## Using Arboretum
|
||||
|
||||
1. **Add a repository.** From the dashboard, register a local git repo by its path. Optionally configure **post-create hooks** (e.g. `npm ci`, `cp ../.env .env`) that run automatically every time you create a new worktree for that repo.
|
||||
@@ -164,10 +177,10 @@ It is distributed as a **private VSIX**. Build and package it from the monorepo:
|
||||
|
||||
```bash
|
||||
npm run build:vscode
|
||||
cd packages/vscode && npx @vscode/vsce package --no-dependencies # → git-arboretum-0.3.0.vsix
|
||||
cd packages/vscode && npx @vscode/vsce package --no-dependencies # → git-arboretum-<version>.vsix
|
||||
```
|
||||
|
||||
Then install it via **Extensions: Install from VSIX…** (or `code --install-extension git-arboretum-0.3.0.vsix`), run **Arboretum: Sign In** and paste a token. Full details in [`packages/vscode/README.md`](packages/vscode/README.md).
|
||||
Then install it via **Extensions: Install from VSIX…** (or `code --install-extension git-arboretum-<version>.vsix`), run **Arboretum: Sign In** and paste a token. Full details in [`packages/vscode/README.md`](packages/vscode/README.md).
|
||||
|
||||
## Remote access from your phone
|
||||
|
||||
@@ -188,6 +201,47 @@ Open `https://<machine>.<tailnet>.ts.net` from any device on your tailnet. **Web
|
||||
|
||||
> ⚠️ A web terminal is remote code execution **by design**. Never expose Arboretum directly to the public internet.
|
||||
|
||||
### Web server mode (LAN, reverse proxy)
|
||||
|
||||
Whatever front you put in place, remember the rule that trips everyone up first: **the daemon rejects any
|
||||
request whose `Origin` it does not know**, with `403 BAD_ORIGIN`. The address you type in the browser must
|
||||
be passed with `--allow-origin` (repeatable). Settings → **Remote access** shows the current origin, the
|
||||
allowed list, and the exact command to add one.
|
||||
|
||||
**Behind a reverse proxy** (nginx, Caddy, Traefik), terminating TLS on your own domain:
|
||||
|
||||
```nginx
|
||||
# nginx: the WebSocket upgrade and X-Forwarded-Proto are both required
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:7317;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme; # makes the session cookie Secure
|
||||
proxy_read_timeout 3600s; # long-lived terminals
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
npx @johanleroy/git-arboretum --allow-origin https://arboretum.example.com
|
||||
```
|
||||
|
||||
`X-Forwarded-Proto: https` is what tells Arboretum to mark its session cookie `Secure`; without it the
|
||||
cookie stays non-Secure behind your HTTPS front. Keep the proxy read timeout generous, a terminal
|
||||
WebSocket is idle for long stretches.
|
||||
|
||||
**On the LAN, without a proxy** (least recommended: plain HTTP, no Web Push, no PWA install):
|
||||
|
||||
```bash
|
||||
npx @johanleroy/git-arboretum \
|
||||
--bind 0.0.0.0 --i-know-this-exposes-a-terminal \
|
||||
--allow-origin http://192.168.1.42:7317
|
||||
```
|
||||
|
||||
The acknowledgement flag is mandatory and never added for you: binding beyond loopback must be a
|
||||
deliberate act. Restrict access at the network level (firewall, VPN) and prefer Tailscale.
|
||||
|
||||
## Running it as a background service
|
||||
|
||||
The quickest way to run Arboretum as a service that survives logout and restarts on boot is the built-in installer. Install a pinned version globally, then run `install`. It detects your OS, writes the service file, starts it, and prints the one-time token:
|
||||
@@ -197,7 +251,7 @@ npm i -g @johanleroy/git-arboretum
|
||||
arboretum install --allow-origin https://MACHINE.TAILNET.ts.net
|
||||
```
|
||||
|
||||
This sets up a **systemd user service** on Linux (`~/.config/systemd/user/arboretum.service`) or a **launchd LaunchAgent** on macOS (`~/Library/LaunchAgents/fr.lidge.arboretum.plist`). Every daemon flag (`--port`, `--allow-origin`, `--db`, …) is propagated to the service. Manage it with:
|
||||
This sets up a **systemd user service** on Linux (`~/.config/systemd/user/arboretum.service`), a **launchd LaunchAgent** on macOS (`~/Library/LaunchAgents/fr.lidge.arboretum.plist`), or a **scheduled task** on Windows (`Arboretum`, triggered at logon, registered with `schtasks`). Always as your user, never as root or SYSTEM. Every daemon flag (`--port`, `--allow-origin`, `--db`, …) is propagated to the service. Manage it with:
|
||||
|
||||
```bash
|
||||
arboretum status # service status (+ where to read logs)
|
||||
@@ -253,7 +307,9 @@ Daemon options are CLI flags:
|
||||
| `--allow-origin <url>` | none | Additional allowed `Origin` (repeatable). Needed for Tailscale/HTTPS access. |
|
||||
| `--db <path>` | `<data>/arboretum.db` | SQLite database path. |
|
||||
| `--vapid-contact <mailto/url>` | `mailto:arboretum@localhost` | VAPID contact subject for Web Push. |
|
||||
| `--print-token` | `false` | Hint about token re-printing (tokens are hashed and cannot be re-shown). |
|
||||
| `--print-token` | `false` | Print the access token on start (bootstraps one if the database has none). |
|
||||
| `--claude-home <path>` | `~/.claude` | Override the Claude install root (session registry and transcripts). |
|
||||
| `--no-discover` | `false` | Disable repository auto-discovery (start-up scan and periodic re-scan). |
|
||||
| `--i-know-this-exposes-a-terminal` | `false` | Acknowledge binding to a non-loopback address. **Avoid**: prefer Tailscale Serve. |
|
||||
|
||||
`arboretum install` accepts every daemon flag above (propagated verbatim to the service) plus:
|
||||
@@ -265,7 +321,18 @@ Daemon options are CLI flags:
|
||||
| `--dry-run` | Print the unit/plist and commands without applying anything. |
|
||||
| `--no-enable` | Write the service file but do not enable/start it. |
|
||||
|
||||
State (the SQLite database) lives in `$XDG_DATA_HOME/arboretum` (default `~/.local/share/arboretum`).
|
||||
State (the SQLite database) lives in `$XDG_DATA_HOME/arboretum`, defaulting to
|
||||
`~/.local/share/arboretum` on Linux and macOS and `%APPDATA%\arboretum` on Windows.
|
||||
|
||||
Environment variables:
|
||||
|
||||
| Variable | Used by | Description |
|
||||
|---|---|---|
|
||||
| `ARBORETUM_LOG` | daemon | Log level (`fatal`, `error`, `warn`, `info`, `debug`, `trace`). Default `info`. |
|
||||
| `ARBORETUM_SECRET_KEY` | daemon | 32-byte key (base64 or hex) encrypting stored git credentials. Generated and stored in the database when absent. |
|
||||
| `ARBORETUM_EMIT_TOKEN_FD` | daemon | Write the access token to this file descriptor at start-up. Used by the desktop app to sign itself in; not meant for manual use. |
|
||||
| `XDG_DATA_HOME` | daemon | Root of the data directory (see above). |
|
||||
| `ARBORETUM_SHELL` | daemon (Windows) | Shell used to run project commands. Default `powershell.exe`. |
|
||||
|
||||
Settings beyond CLI flags (the directories Arboretum scans for repos and how often, the `claude` binary path and home, and the session retention / purge windows) live in **Settings** in the UI. They are broadcast over the WebSocket, so every connected browser reflects a change in real time, no reload needed.
|
||||
|
||||
@@ -291,6 +358,19 @@ Tailscale Serve is **the** way to reach Arboretum from other devices, not just a
|
||||
|
||||
See [`SECURITY.md`](SECURITY.md) for the full threat model and [`docs/ENTERPRISE_DEPLOYMENT.md`](docs/ENTERPRISE_DEPLOYMENT.md) for hardening in regulated environments.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause & fix |
|
||||
|---|---|
|
||||
| `npm error 404 Not Found @johanleroy/git-arboretum` | The package lives on a private registry. Add the scope to your `~/.npmrc`: `@johanleroy:registry=https://git.lidge.fr/api/packages/johanleroy/npm/` |
|
||||
| `403 BAD_ORIGIN` in the browser console, blank UI | The address you are using is not in the allowed list. Restart with `--allow-origin <that exact origin>` (scheme, host and port must match). |
|
||||
| `ERR_UNKNOWN_BUILTIN_MODULE node:sqlite` or a crash on start | Node is older than 22.16. Check with `node --version`; `node:sqlite` is only stable from there. The desktop app bundles its own runtime and is immune. |
|
||||
| "Claude Code CLI not found in PATH" | The daemon runs with a minimal PATH (typical under systemd/launchd). Set the binary path in **Settings → Claude CLI**, or reinstall the service with `arboretum install`, which freezes your interactive PATH. |
|
||||
| Notifications cannot be enabled | Web Push requires HTTPS. Use Tailscale Serve or a reverse proxy; on iOS, install the PWA first. |
|
||||
| The app launcher shows a generic icon (Linux) | Fixed in desktop 0.2.0: earlier packages installed a single non-standard icon size that the freedesktop spec ignores. Upgrade the `.deb`; if the icon persists, run `gtk-update-icon-cache -f /usr/share/icons/hicolor` or log out and back in. |
|
||||
| SmartScreen or Gatekeeper blocks the app | Expected: the binaries are not signed. See the per-platform table above. |
|
||||
| A terminal stays blank after "Start project" | The command was typed into a login shell that failed to start. Check the tab: the shell survives the failure on purpose, so the error is visible in it. |
|
||||
|
||||
## What makes it different
|
||||
|
||||
| | Arboretum | GitKraken Agent Mode / Conductor / Nimbalyst | Happy / CloudCLI | Anthropic Remote Control |
|
||||
@@ -334,8 +414,17 @@ node packages/server/scripts/acceptance-p9.mjs # advanced commit/push: selecti
|
||||
node packages/server/scripts/acceptance-p10.mjs # automatic session archival
|
||||
node packages/server/scripts/acceptance-p11.mjs # real-time settings sync
|
||||
node packages/server/scripts/acceptance-p12.mjs # remote git services + HTTPS clone
|
||||
node packages/server/scripts/acceptance-p13.mjs # start the project: launch commands & multi-terminal
|
||||
node packages/server/scripts/acceptance-p14.mjs # armed real-time: session-pinned watcher, cwd correlation
|
||||
node packages/server/scripts/acceptance-p15.mjs # history: commit log & per-commit diff
|
||||
```
|
||||
|
||||
Rendering check (headless Chromium over CDP, no Playwright): after `npm run build`, run
|
||||
`node packages/server/scripts/copy-web.mjs` then
|
||||
`node packages/server/scripts/verify-ui.mjs [outdir]`. It starts an isolated daemon, seeds a demo repo,
|
||||
and writes screenshots of the IDE in both themes at desktop and mobile widths, failing on any console
|
||||
error.
|
||||
|
||||
The protocol grew (additively, no version bump) to carry the new surface: client `watch` / `unwatch` messages and the targeted `worktree_changes` signal (P7), plus `session_archived` (P10), `settings_update` (P11) and `clone_update` (P12) broadcasts. Server-side, the work is backed by `core/git.ts` (the pure git engine), `core/fs-watcher.ts` (chokidar), `core/git-credentials.ts` + `core/clone-manager.ts` (encrypted credentials & clone), and the session-archive and settings services.
|
||||
|
||||
## Support
|
||||
|
||||
Reference in New Issue
Block a user