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
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
# 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!
|
||||
Reference in New Issue
Block a user