# Install Strategy ## Goal A one-liner installer that sets up the companion server beside an existing Hermes Agent install. Target UX: ```bash curl -fsSL https://hermes-mobile.molberg.cloud/install.sh | bash ``` or from Gitea release/raw if accessible without auth: ```bash curl -fsSL https://git.molberg.cloud/bonzi/hermes-mobile/raw/branch/main/install.sh | bash ``` Because Zeb's Gitea raw URLs may require auth, release assets or a mirrored static install URL are safer for the public one-liner. ## Installer Responsibilities 1. Detect OS/package manager. 2. Detect Hermes Agent: - `command -v hermes` - `~/.hermes/config.yaml` - optional `HERMES_HOME` 3. Check Node.js version or install bundled binary/runtime. 4. Download latest Hermes Mobile companion release. 5. Create config. 6. Create data directories. 7. Install systemd service. 8. Start service. 9. Print pairing URL and one-time code. ## Installation Modes ### System mode (default for servers) Paths: ```text /opt/hermes-mobile/ app bundle /etc/hermes-mobile/config.yaml config /var/lib/hermes-mobile/ DB/uploads/cache /var/log/hermes-mobile/ logs if not journald-only ``` Service: ```text hermes-mobile-companion.service ``` Run user: - Option A: current user/root if Hermes is root-installed. - Option B: `hermes-mobile` user with group/read permissions to Hermes paths. For Zeb's box, same user/root is simplest initially because Hermes files live under `/root/.hermes`. ### User mode ```bash curl ... | bash -s -- --user ``` Paths: ```text ~/.local/opt/hermes-mobile/ ~/.config/hermes-mobile/config.yaml ~/.local/share/hermes-mobile/ ~/.config/systemd/user/hermes-mobile-companion.service ``` ## Service Unit Draft ```ini [Unit] Description=Hermes Mobile Companion Server After=network-online.target Wants=network-online.target [Service] Type=simple User=root WorkingDirectory=/opt/hermes-mobile Environment=NODE_ENV=production Environment=HERMES_MOBILE_CONFIG=/etc/hermes-mobile/config.yaml ExecStart=/usr/bin/node /opt/hermes-mobile/server/index.js Restart=always RestartSec=3 [Install] WantedBy=multi-user.target ``` ## Config Generation Installer should write: ```yaml server: host: 0.0.0.0 port: 8787 public_url: "" hermes: home: /root/.hermes cli_bin: /root/.local/bin/hermes mode: python api_base_url: http://127.0.0.1:18793/v1 storage: data_dir: /var/lib/hermes-mobile max_upload_mb: 512 auth: pairing_enabled: true notifications: provider: webpush ``` ## Pairing Output After start: ```text Hermes Mobile installed. Open this on your phone: http://SERVER-IP:8787/pair?code=123-456 Pairing code: 123-456 Service: systemctl status hermes-mobile-companion Logs: journalctl -u hermes-mobile-companion -f ``` ## Update ```bash curl -fsSL https://hermes-mobile.molberg.cloud/install.sh | bash -s -- --update ``` Should: - Download latest release. - Preserve config and data. - Restart service. - Run DB migrations. ## Uninstall ```bash curl -fsSL https://hermes-mobile.molberg.cloud/install.sh | bash -s -- --uninstall ``` Should ask/flag whether to keep data: - `--keep-data` - `--purge` ## Release Layout Build artifact: ```text hermes-mobile-linux-x64.tar.gz server/ index.js package.json node_modules/ or bundled single executable public/ PWA assets scripts/ hermes_worker.py migrations/ ``` Better later: - single static binary via Bun/Node SEA if stable enough. - Docker image optional but not the primary install path. ## One-liner Safety Installer should: - Show what it will do. - Avoid deleting data unless explicitly asked. - Not overwrite existing config without backup. - Use `set -euo pipefail`. - Log to temp file. - Verify download checksum if release metadata supports it. ## Development Install From cloned repo: ```bash pnpm install pnpm dev ``` Companion dev server: ```bash pnpm --filter companion dev ``` Mobile dev server: ```bash pnpm --filter mobile dev --host 0.0.0.0 ``` ## Future Cloudflare/Tailscale Expose options: - Tailscale only: bind to `100.x` IP or localhost behind `tailscale serve`. - Cloudflare Tunnel: companion prints local port and expected reverse proxy config. - Nginx/Caddy snippets generated by installer.