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
7.3 KiB
7.3 KiB
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:
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:
NODE_BIN="$(which node)"
Issue:
- If nvm is not sourced in the current shell,
which nodereturns 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:
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:
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
# 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
# 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
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:
#!/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:
{
name: 'officer',
script: 'bin/start.sh',
// ...
}
Fix 4: Validate Pi Installation
# 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:
- Choose ONE Node installation method (recommend nvm)
- Source nvm in shell before running setup.sh
- Setup.sh will validate node and npm are available
- Services (PM2, systemd) will inherit nvm environment
Recommendations
- Make nvm sourcing automatic at the start of setup.sh
- Add environment wrapper script for PM2 that sources nvm
- 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)
- Validate Pi works before marking setup complete
- Create a post-setup check script that verifies everything works
Current Workaround
If setup.sh already ran with snap node:
- Remove snap:
sudo snap remove node - Install nvm:
curl -o- ... | bash(reload shell) - Install node:
nvm install 22 && nvm use 22 - Reinstall pm2 packages:
npm install -g pm2 - Restart pm2/officer
This is what you just did!