# Officer Setup Flow Analysis ## Overview The setup.sh script installs all dependencies for Officer, but there are several issues that can cause problems, especially with nvm Node.js environments. ## Setup Flow ``` 1. Detect package manager (apt/pacman/brew) ↓ 2. Install core system packages (git, zip, curl, zsh, build-essential, etc.) ↓ 3. Install archive utilities (7z, unrar) ↓ 4. Install ffmpeg ↓ 5. Configure sudoers for service user ↓ 6. Install Node.js 22 (or warn if not found) ↓ 7. Configure npm global prefix (~/.npm-global) ↓ 8. Install Bun ↓ 9. Install Go 1.23.6 ↓ 10. Install Rust ↓ 11. Install PulseAudio (for audio) ↓ 12. Build cliamp from source (Go music player) ↓ 13. Install Neovim ↓ 14. Install terminal tools (starship, oh-my-zsh, eza, lazygit) ↓ 15. Install yt-dlp (optional) ↓ 16. Install npm global packages (Pi, Claude Code, pm2) ↓ 17. Run bun install (project dependencies) ↓ 18. Setup remote desktop (XFCE + VNC) ↓ 19. Setup PTY sidecar (systemd service) ↓ 20. Verification ``` ## Issues Found ### 1. **nvm Node.js Not Properly Documented** **Location:** `scripts/setup.sh` (line ~238) **Problem:** ```bash if has node; then NODE_VER=$(node -v 2>/dev/null | tr -d 'v') NODE_MAJOR=$(echo "$NODE_VER" | cut -d. -f1) if [ "$NODE_MAJOR" = "22" ]; then skip "node v$NODE_VER" else warn "Node $NODE_VER found but v22 is required" warn "Use nvm: nvm install 22 && nvm use 22" fi else warn "Node.js not found — install v22 via nvm:" warn " curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash" warn " nvm install 22" fi ``` **Issue:** - Only warns about nvm but doesn't ensure it's sourced in the current shell - When installing pm2 and other npm global packages, nvm might not be available - When services (pm2, systemd) later run, they won't have nvm initialized **Impact:** - Users install nvm, run setup.sh in that shell, but when pm2/systemd runs later, it uses the wrong node or no node --- ### 2. **PTY Sidecar Service Uses Unbounded `which node`** **Location:** `scripts/setup-pty-sidecar.sh` (line ~16) **Problem:** ```bash NODE_BIN="$(which node)" ``` **Issue:** - If nvm is not sourced in the current shell, `which node` returns nothing or the system node - The systemd service will run with the wrong node binary - When systemd runs, nvm environment is not available anyway **Impact:** - PTY sidecar service fails to start or runs with wrong node - Terminal functionality breaks in Officer --- ### 3. **PM2/Ecosystem Config Doesn't Handle nvm** **Location:** `ecosystem.config.cjs` **Problem:** ```javascript module.exports = { apps: [ { name: 'officer', script: 'bun', args: 'start', watch: false, }, ], }; ``` **Issue:** - No environment setup for nvm - PM2 runs with whatever node is in system PATH - If user installed node via nvm, PM2 won't find it - This is why you had to restart the server after installing nvm **Impact:** - Officer server fails to start after fresh nvm installation - No clear error message about nvm not being available --- ### 4. **No Documentation on Node Installation Methods** **Location:** `scripts/setup.sh` (lines 238-250) **Problem:** - Script warns about nvm but doesn't explain the workflow - No mention of snap node incompatibility - No mention of system apt/NodeSource installation - No guidance on which method to use when **Impact:** - Users can choose any installation method - Some methods (snap) don't work with Officer - New issues arise from incompatible setups --- ### 5. **Pi Installation Doesn't Validate nvm Environment** **Location:** `scripts/setup.sh` (lines ~408-420) **Problem:** ```bash if has pi; then skip "pi (@mariozechner/pi-coding-agent)" else npm install -g @mariozechner/pi-coding-agent if has pi; then ok "pi installed"; else warn "pi install failed"; fi fi ``` **Issue:** - Installs pi with `npm install -g`, but npm might be different than later shells - No validation that pi works (should test `pi --list-models`) - No check that Pi was installed to the right npm location **Impact:** - Pi appears installed but fails at runtime when shell environment differs --- ## Fixes Required ### Fix 1: Source nvm Before Installing Global Packages ```bash # At the start of setup.sh, after detecting package manager echo "" echo "── Node.js Environment ──" # Check if nvm needs to be sourced if [ -s "$HOME/.nvm/nvm.sh" ]; then source "$HOME/.nvm/nvm.sh" nvm use 22 || nvm install 22 ok "nvm activated: $(node -v)" elif ! has node; then fail "Node.js not found and nvm not installed" fail "Install nvm first: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash" exit 1 fi ``` ### Fix 2: Update PTY Sidecar Setup to Use Correct Node ```bash # In scripts/setup-pty-sidecar.sh if [ -s "$HOME/.nvm/nvm.sh" ]; then source "$HOME/.nvm/nvm.sh" nvm use 22 2>/dev/null || true fi NODE_BIN="$(which node)" if [ ! -f "$NODE_BIN" ]; then echo "ERROR: Node.js not found in PATH" exit 1 fi ``` ### Fix 3: Update PM2 Ecosystem Config ```javascript module.exports = { apps: [ { name: 'officer', script: 'bun', args: 'start', watch: false, // Source nvm before running exec_mode: 'cluster', instances: 1, env: { NODE_ENV: 'production', // This helps systemd find the right node NVM_DIR: '$HOME/.nvm', }, // For systemd service, use a wrapper script }, ], }; ``` Or better: Create a wrapper script for PM2: ```bash #!/bin/bash # bin/start.sh set -euo pipefail # Source nvm if available if [ -s "$HOME/.nvm/nvm.sh" ]; then source "$HOME/.nvm/nvm.sh" fi # Now start Officer NODE_ENV=production bun src/server.tsx ``` Then in ecosystem.config.cjs: ```javascript { name: 'officer', script: 'bin/start.sh', // ... } ``` ### Fix 4: Validate Pi Installation ```bash # After installing Pi if has pi; then if pi --list-models > /dev/null 2>&1; then ok "pi installed and working" else warn "pi installed but --list-models failed" warn "Try: nvm use && npm install -g @mariozechner/pi-coding-agent" fi else warn "pi install failed" fi ``` ### Fix 5: Add Setup Documentation Create `SETUP_GUIDE.md` with clear instructions on: 1. Choose ONE Node installation method (recommend nvm) 2. Source nvm in shell before running setup.sh 3. Setup.sh will validate node and npm are available 4. Services (PM2, systemd) will inherit nvm environment --- ## Recommendations 1. **Make nvm sourcing automatic** at the start of setup.sh 2. **Add environment wrapper script** for PM2 that sources nvm 3. **Document the three Node installation options** with pros/cons: - nvm (recommended, flexible versions) - NodeSource (system package, simple) - apt (if available in repo) - ❌ snap (broken, don't use) 4. **Validate Pi works** before marking setup complete 5. **Create a post-setup check script** that verifies everything works --- ## Current Workaround If setup.sh already ran with snap node: 1. Remove snap: `sudo snap remove node` 2. Install nvm: `curl -o- ... | bash` (reload shell) 3. Install node: `nvm install 22 && nvm use 22` 4. Reinstall pm2 packages: `npm install -g pm2` 5. Restart pm2/officer This is what you just did!