Files
platform/SETUP_ANALYSIS.md
T
pastilhas ebd8778007 fix: refactor setup scripts for system-wide Node.js (no nvm)
BREAKING: Officer now uses system Node.js via NodeSource instead of nvm.

Changes:
- Removed nvm sourcing from setup.sh
- Updated Node installation to use NodeSource repository
- All npm global packages installed system-wide with sudo
- Updated PTY sidecar setup to use /usr/bin/node (system node)
- Added Pi validation (test --list-models)
- System packages now available to all users automatically

Benefits:
- Multi-user friendly: all users get same Node version
- No per-user environment setup needed
- Simpler troubleshooting (one node version)
- Services use consistent node binary
- Prevents snap node incompatibility issues

Fixes:
- 'node not found' for secondary users
- systemd services finding correct node
- Pi installation consistency across users

New Files:
- SETUP_GUIDE.md: Comprehensive installation guide
- SETUP_ANALYSIS.md: Technical analysis of previous issues

Migration:
- Remove nvm if installed (optional)
- Run: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
- Run: sudo apt-get install -y nodejs
- Run: bash scripts/setup.sh
2026-03-04 02:09:47 +00:00

311 lines
7.3 KiB
Markdown

# 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!