AgentStack
SKILL verified MIT Self-run

Pm2

skill-marcfargas-skills-pm2 · by marcfargas

>-

No reviews yet
0 installs
13 views
0.0% view→install

Install

$ agentstack add skill-marcfargas-skills-pm2

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Pm2? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

PM2 — Process Manager

PM2 keeps processes alive, restarts them on crash, and provides monitoring/logging. Use for long-running services, persistent agents, background workers.

> Not for detached terminals — use holdpty when you need PTY output, attach/view, or interactive sessions. > Not for ephemeral tasks — use pi -p > file & for quick fire-and-forget agent runs.

Quick Reference

Start a process

# Simple
pm2 start server.js --name myapp

# With interpreter
pm2 start script.py --interpreter python3 --name worker

# With arguments (use -- to separate pm2 args from script args)
pm2 start app.js --name api -- --port 3000 --env production

# From ecosystem file
pm2 start ecosystem.config.cjs

Manage processes

pm2 list                    # List all processes (table)
pm2 jlist                   # List as JSON (for scripting)
pm2 info           # Detailed process info
pm2 restart    # Restart
pm2 stop       # Stop (keeps in list)
pm2 delete     # Stop + remove from list
pm2 restart  --update-env  # Restart with refreshed env vars

Logs

pm2 logs                     # Tail all logs
pm2 logs  --lines 50   # Tail specific process, last 50 lines
pm2 flush                    # Clear all log files

Log files location: ~/.pm2/logs/-out.log and -error.log.

Monitoring

pm2 monit          # Real-time TUI: CPU, memory, logs
pm2 dash           # Dashboard with monitoring + logs

Ecosystem Config

For reproducible multi-process setups, use an ecosystem.config.cjs file:

// ecosystem.config.cjs
module.exports = {
  apps: [
    {
      name: "api",
      script: "dist/server.js",
      instances: 2,                // cluster mode
      exec_mode: "cluster",
      env: {
        NODE_ENV: "production",
        PORT: 3000,
      },
      max_memory_restart: "500M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
    },
    {
      name: "worker",
      script: "dist/worker.js",
      autorestart: true,
      max_restarts: 10,
      restart_delay: 5000,
      exp_backoff_restart_delay: 100,  // exponential backoff
      watch: false,
    },
  ],
};
pm2 start ecosystem.config.cjs           # Start all apps
pm2 start ecosystem.config.cjs --only api  # Start specific app
pm2 restart ecosystem.config.cjs          # Restart all
pm2 delete ecosystem.config.cjs           # Stop + remove all

Useful ecosystem options

| Option | Type | Description | |--------|------|-------------| | script | string | Script to run (required) | | interpreter | string | Override interpreter (default: node) | | args | string or string[] | Script arguments | | cwd | string | Working directory | | instances | number | Number of instances (cluster mode) | | exec_mode | string | "fork" (default) or "cluster" | | autorestart | boolean | Auto-restart on exit (default: true) | | max_restarts | number | Max consecutive restarts before stopping | | restart_delay | number | Delay between restarts (ms) | | exp_backoff_restart_delay | number | Exponential backoff base (ms) | | max_memory_restart | string | Restart if memory exceeds (e.g. "500M") | | cron_restart | string | Cron-based restart schedule | | watch | boolean or string[] | Watch for file changes | | ignore_watch | string[] | Paths to ignore when watching | | env | object | Environment variables | | log_date_format | string | Timestamp format for logs | | error_file | string | Custom stderr log path | | out_file | string | Custom stdout log path | | merge_logs | boolean | Merge cluster instance logs | | stop_exit_codes | number[] | Exit codes that skip auto-restart |

Persistence

pm2 save               # Save current process list
pm2 resurrect           # Restore saved process list
pm2 startup             # Generate OS startup script (auto-start on boot)
pm2 unstartup           # Remove startup script

After pm2 startup, run the command it outputs (may need admin/sudo). Then pm2 save to snapshot current processes — they'll auto-start on reboot.

Windows Gotchas

.cmd wrapper resolution

PM2 tries to run .cmd files as Node.js scripts. Never start a .cmd shim directly with PM2.

# ❌ WRONG — resolves to pi.cmd, crashes
pm2 start pi -- -p "prompt"

# ✅ CORRECT — point to the actual .js entry point
pm2 start /path/to/cli.js --interpreter node -- -p "prompt"

For npm-installed CLIs, find the real script:

# Find where the .cmd shim points
cat "$(which pi)" | head -5
# → Look for the .js path, then use that with --interpreter node

In ecosystem configs, always use the resolved .js path:

module.exports = {
  apps: [{
    name: "my-agent",
    // Resolve the actual cli.js, not the .cmd wrapper
    script: "C:\\path\\to\\node_modules\\package\\dist\\cli.js",
    interpreter: "node",
    args: ["--mode", "json"],
  }],
};

Log paths

PM2 stores logs at ~/.pm2/logs/. On Windows this is typically C:\Users\\.pm2\logs\.

Daemon

PM2 daemon runs as a background Node.js process. pm2 kill stops the daemon and all managed processes. pm2 ping checks if the daemon is running.

Agent Patterns

Launch a pi agent as a persistent service

First, find the actual cli.js path (see Windows Gotchas above):

# Find pi's real entry point
cat "$(which pi)" | head -5
# e.g. → /path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: "my-agent",
    // Use the resolved cli.js path — NOT the .cmd wrapper
    script: "/path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js",
    interpreter: "node",
    args: ["--mode", "json", "--cwd", "/path/to/project"],
    autorestart: true,
    max_restarts: 10,
    restart_delay: 5000,
  }],
};

> Note: pi -p to non-TTY only outputs final text. Use --mode json for full event streaming to PM2 logs.

Check process health from an agent

# Structured output for parsing
pm2 jlist | node -e "
  const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
  d.forEach(p => console.log(p.name, p.pm2_env.status, 'restarts:', p.pm2_env.restart_time));
"

Rotate logs

pm2 install pm2-logrotate        # Install log rotation module
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5

When NOT to Use PM2

  • Detached terminal sessions → use holdpty (PTY output, attach/view)
  • Ephemeral agent runs → use pi -p > file & (fire-and-forget with output capture)
  • Containers → the container runtime manages lifecycle; PM2 inside Docker is usually redundant
  • Systemd environments → use systemd service units natively on Linux

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.