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

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 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:

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:

  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!