jkunz 3d30d6da4b
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
Release / build-and-release (push) Successful in 1m2s
v5.15.3
2026-06-10 17:50:15 +00:00
2026-06-10 17:50:15 +00:00
2026-06-10 17:50:15 +00:00
2025-02-24 23:02:17 +00:00
2025-02-24 23:02:17 +00:00
2026-06-10 17:50:15 +00:00

@git.zone/tspm 🚀

TypeScript Process Manager — A robust, no-fuss process manager built for the modern TypeScript and Node.js ecosystem. Production-ready process management without the bloat.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

🎯 What is TSPM?

TSPM is your production-ready process manager that handles the hard parts of running Node.js applications. Think PM2, but built from scratch for the TypeScript-first ecosystem with better memory management, intelligent logging, a clean daemon architecture, and native ESM support.

Key Features

  • 🧠 Smart Memory Management — Tracks memory across entire process trees (parent + children), enforces limits, and auto-restarts on OOM
  • 💾 Persistent Log Storage — 10MB in-memory ring buffer per process, auto-persists to disk on stop/restart/crash
  • 🔄 Intelligent Auto-Restart — Crashed processes restart with incremental backoff (1s → 10s), auto-stop after 10 consecutive failures
  • 🧾 Persistent Process Configs — Saved process definitions and desired states survive daemon restarts
  • 🌳 Process Tree Tracking — Monitors parent and all child processes as a unit — no orphans, ever
  • 🏗️ Daemon Architecture — Persistent background service that survives terminal sessions via Unix socket IPC
  • 📊 Beautiful CLI — Clean, informative output with table views, real-time log streaming, and search
  • Zero Config — Works out of the box; customize only when you need to
  • 🔌 Systemd Integration — Run as a system service for production deployments with tspm enable
  • 🔍 Crash Log Reports — Detailed crash reports with metadata, memory snapshots, and log history

📦 Installation

Linux Release Binary

For production hosts, install the self-contained release binary instead of a package-manager wrapper:

curl -sSL https://code.foss.global/git.zone/tspm/raw/branch/main/install.sh | sudo bash

The installer downloads the matching Linux x64 or Linux ARM64 release asset, installs it to /opt/tspm, and links /usr/local/bin/tspm. To install a specific version:

curl -sSL https://code.foss.global/git.zone/tspm/raw/branch/main/install.sh | sudo bash -s -- --version v5.x.y

If the smartdaemon_tspm-daemon systemd service is already running, the installer refreshes it with the installed binary so the service command no longer points at an old package-manager wrapper.

Package Install

# Global install (recommended)
pnpm add -g @git.zone/tspm

# Or with npm
npm install -g @git.zone/tspm

# Or as a project dependency
pnpm add --save-dev @git.zone/tspm

🚀 Quick Start

# Start the daemon
tspm daemon start

# Add a process
tspm add "node server.js" --name my-server --memory 1GB

# Start it
tspm start name:my-server

# See what's running
tspm list

# View logs
tspm logs name:my-server

# Stop it
tspm stop name:my-server

📋 CLI Reference

Targeting Processes

Most commands accept flexible process targeting:

Format Example Description
Numeric ID tspm start 1 Direct ID reference
id:N tspm start id:1 Explicit ID prefix
name:LABEL tspm start name:api Target by name

Use tspm search <query> to find processes by name or ID substring.

Process Management

tspm add <command> [options]

Register a new process configuration (without starting it).

Option Description Default
--name <name> Process name command string
--memory <size> Memory limit (e.g. 512MB, 2GB) 512MB
--cwd <path> Working directory current directory
--user <user> POSIX user to run the process as when the TSPM daemon runs as root daemon user
--group <group> POSIX group to run the process as when the TSPM daemon runs as root user's primary/default group
--watch Restart on watched file changes false
--watch-paths <paths> Comma-separated files or directories to watch project directory
--autorestart <bool> Auto-restart on crash (true, false, --no-autorestart) true
--env <KEY=value> Persist an environment variable for the managed process; repeatable
-i, --interactive Enter interactive edit after adding
# Simple Node.js app
tspm add "node server.js" --name api-server

# TypeScript with 2GB memory limit
tspm add "tsx src/index.ts" --name production-api --memory 2GB

# TypeScript entry file (runs through tsx automatically)
tspm add ./src/index.ts --name ts-worker --memory 2GB

# One-shot worker (no auto-restart)
tspm add "node worker.js" --name batch-job --autorestart false

# Persist runtime environment without exposing values in describe output
tspm add "node server.js" --name api --env NODE_ENV=production --env API_URL=https://api.example.com

# Root-managed daemon running a process as a dedicated service user
sudo TSPM_DIR=/var/lib/tspm tspm add "/usr/local/bin/my-service" --name my-service --user serviceuser --group serviceuser

# Add + interactive edit
tspm add "node server.js" --name api -i

tspm start <target>

Start a registered process.

tspm start name:my-server
tspm start id:1
tspm start 1          # bare numeric id also works

tspm stop <target>

Gracefully stop a process (SIGTERM → 5s grace → SIGKILL).

tspm stop name:my-server

tspm restart <target>

Stop and restart a process, preserving its configuration.

tspm restart name:my-server

tspm delete <target> / tspm remove <target>

Stop, remove from management, and delete persisted logs.

tspm delete name:old-server
tspm remove id:3

tspm edit <target>

Interactively modify a process configuration (name, command, memory, etc.).

tspm edit name:my-server

tspm search <query>

Search processes by name or ID substring.

tspm search api
# Matches for "api":
#   id:3    name:api-server

Monitoring

tspm list

Display all managed processes with live runtime stats. Use tspm describe <target> for saved command, directory, and full process configuration details.

┌─────────┬─────────────┬───────────┬───────────┬────────────┬────────────┬──────────┬──────────┬─────────┐
│ ID      │ Name        │ Status    │ PID       │ User       │ Group      │ Memory   │ CPU      │ Restarts │
├─────────┼─────────────┼───────────┼───────────┼────────────┼────────────┼──────────┼──────────┼──────────┤
│ 1       │ api         │ online    │ 45123     │ apiuser    │ apiuser    │ 245.3 MB │ 2.1%     │ 0        │
│ 2       │ worker      │ online    │ 45456     │ worker     │ worker     │ 128.7 MB │ 0.5%     │ 2        │
│ 3       │ batch       │ stopped   │ -         │ -          │ -          │ 0 B      │ -        │ 5        │
└─────────┴─────────────┴───────────┴───────────┴────────────┴────────────┴──────────┴──────────┴──────────┘

tspm describe <target>

Detailed information about a specific process.

tspm describe name:my-server

# Process Details: my-server
# ────────────────────────────────────────
# Status:       online
# PID:          45123
# Memory:       245.3 MB
# Uptime:       3600s
# Restarts:     0
#
# Configuration:
# ────────────────────────────────────────
# Command:      node server.js
# Directory:    /home/user/project
# User:         daemon user
# Group:        default group
# Memory Limit: 2 GB
# Auto-restart: true

tspm logs <target> [options]

View and stream process logs.

Option Description Default
--lines <n> Number of lines 50
--since <dur> Time filter (10m, 2h, 1d)
--stderr-only Only stderr
--stdout-only Only stdout
--ndjson Output as newline-delimited JSON
--follow Real-time streaming (like tail -f)
# View last 50 lines
tspm logs name:my-server

# Last 100 lines of stderr only
tspm logs name:my-server --lines 100 --stderr-only

# Stream logs in real time
tspm logs name:my-server --follow

# NDJSON output since 10 minutes ago
tspm logs name:my-server --since 10m --ndjson

Batch Operations

tspm start-all      # Start all saved processes
tspm stop-all       # Stop all running processes
tspm restart-all    # Restart all running processes
tspm restart all    # Alternate all-process restart form
tspm reset          # ⚠️ Stop all + clear all configs (prompts for confirmation)

Daemon Management

The daemon is a persistent background service that manages all processes. Start it explicitly for the current session, or install it as a systemd service for boot startup.

tspm daemon start     # Start the daemon
tspm daemon stop      # Stop daemon + all managed processes
tspm daemon restart   # Restart daemon (preserves processes)
tspm daemon status    # Check daemon health + stats
tspm stats            # Detailed daemon stats + process table

By default TSPM stores its socket, PID file, log files, crash logs, and daemon runtime data below ~/.tspm. Set TSPM_DIR to isolate an environment, for example in tests or local experiments:

TSPM_DIR=/tmp/tspm-dev tspm daemon start

System Service (systemd)

sudo tspm enable      # Install + enable as systemd service (auto-start on boot)
sudo tspm disable     # Remove systemd service

When tspm enable is run through sudo, TSPM targets SUDO_USER by default so the daemon keeps using that user's ~/.tspm runtime directory and saved process config. Override the target explicitly when needed:

sudo tspm enable \
  --user appuser \
  --group appuser \
  --home /home/appuser \
  --path "/home/appuser/.local/share/pnpm:/usr/local/bin:/usr/bin:/bin" \
  --node /usr/bin/node \
  --tspm-dir /home/appuser/.tspm

For production hosts that should behave like Docker, run one root-owned daemon and grant operational access through a dedicated tspm group. Members of this group are effectively root-equivalent because they can ask the daemon to start arbitrary commands as configured users.

sudo groupadd --system tspm
sudo mkdir -p /var/lib/tspm
sudo chown root:tspm /var/lib/tspm
sudo chmod 0750 /var/lib/tspm

sudo tspm enable \
  --user root \
  --group tspm \
  --home /root \
  --path "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
  --node /usr/bin/node \
  --tspm-dir /var/lib/tspm \
  --socket-group tspm \
  --socket-mode 0660

The runtime directory should allow group traversal but not group writes. TSPM stores config, state, and logs as root-owned files; the tspm group controls the daemon through /var/lib/tspm/tspm.sock.

Per-Process User

When the daemon runs as root, each process can declare its own POSIX user and group:

TSPM_DIR=/var/lib/tspm tspm add "/usr/local/bin/dcrouter" \
  --name dcrouter \
  --user centraluser \
  --group centraluser \
  --memory 2GB

TSPM validates the user and group on the daemon side, stores names in the process config, resolves them to uid/gid at start time, and applies the identity through Node's child_process.spawn. Non-root daemons can only run processes as their own user.

Version Check

tspm -v
# tspm CLI: 5.x.y
# Daemon: running v5.x.z (pid 1234)
# Version mismatch detected → optionally refresh the systemd service

Building Release Binaries

Maintainers can build the Linux release binaries locally with:

pnpm run build:binary

The release workflow builds the same targets and uploads the .nogit/release-binaries/* artifacts to the Gitea release for each v* tag. These release binaries are intentionally kept outside the npm package contents.

🏗️ Architecture

TSPM uses a clean three-tier architecture:

┌─────────────────────────────────────────┐
│            CLI Interface                │
│         (tspm commands)                 │
└────────────────┬────────────────────────┘
                 │ Unix Socket IPC
┌────────────────▼────────────────────────┐
│          TSPM Daemon                    │
│     (Background Service)                │
│  ┌──────────────────────────────────┐  │
│  │     ProcessManager               │  │
│  │  - Configuration persistence     │  │
│  │  - Process lifecycle             │  │
│  │  - Desired state management      │  │
│  └────────────┬─────────────────────┘  │
│               │                         │
│  ┌────────────▼─────────────────────┐  │
│  │     ProcessMonitor                │  │
│  │  - Memory tracking & limits      │  │
│  │  - Auto-restart logic            │  │
│  │  - Log persistence (10MB)        │  │
│  │  - Desired state restoration     │  │
│  └────────────┬─────────────────────┘  │
│               │                         │
│  ┌────────────▼─────────────────────┐  │
│  │     ProcessWrapper                │  │
│  │  - Process spawning              │  │
│  │  - Stream handling               │  │
│  │  - Signal management             │  │
│  └──────────────────────────────────┘  │
│                                         │
│  ┌──────────────────────────────────┐  │
│  │     CrashLogManager              │  │
│  │  - Crash report generation       │  │
│  │  - Log rotation (max 100)        │  │
│  └──────────────────────────────────┘  │
└─────────────────────────────────────────┘

Key Components

Component Role
CLI Lightweight client that sends commands to daemon via IPC
Daemon Persistent background service managing all processes
ProcessManager High-level orchestration, config persistence, state management
ProcessMonitor Memory limits, auto-restart with backoff, log persistence, process-tree stats
ProcessWrapper Low-level process lifecycle, stream handling, signal management
CrashLogManager Detailed crash reports with metadata and log history

🎮 Programmatic API

TSPM exposes a typed IPC client for programmatic use:

import { TspmIpcClient } from '@git.zone/tspm/client';

const client = new TspmIpcClient();
await client.connect();

// Add a process configuration
const { id } = await client.request('add', {
  config: {
    command: 'node worker.js',
    name: 'background-worker',
    projectDir: process.cwd(),
    memoryLimitBytes: 512 * 1024 * 1024,
    autorestart: true,
  },
});

// Start it
await client.request('startById', { id });

// Get process info
const { processInfo } = await client.request('describe', { id });
console.log(`Status: ${processInfo.status}, Memory: ${processInfo.memory} bytes`);

// Get logs
const { logs } = await client.request('getLogs', { id, lines: 100 });
logs.forEach(log => console.log(`[${log.timestamp}] [${log.type}] ${log.message}`));

// Stop and remove
await client.request('stop', { id });
await client.request('delete', { id });
await client.disconnect();

Module Exports

Export Path Purpose
@git.zone/tspm Main entry point (re-exports client + daemon)
@git.zone/tspm/client IPC client (TspmIpcClient, TspmServiceManager)
@git.zone/tspm/daemon Daemon entry point (startDaemon)
@git.zone/tspm/protocol IPC type definitions

🔧 Advanced Features

Restart Backoff & Failure Handling

TSPM handles crashed processes with intelligent backoff:

  • Incremental delay: Grows linearly from 1s up to 10s for consecutive restarts
  • Failure threshold: After 10 consecutive failures, the process is marked errored and auto-restart stops
  • Auto-reset: The retry counter resets if no failure occurs for 1 hour
  • Manual recovery: tspm restart id:1 always works, even on errored processes
  • Disabled auto-restart: Crashed processes with autorestart: false are marked errored without respawning; clean exits become stopped
  • Config preservation: Failed starts keep the saved process config so it can be edited and retried

File Watching

When --watch is enabled, TSPM watches the configured paths and restarts the process after file changes. --watch-paths accepts comma-separated files or directories; without it, the process project directory is watched.

tspm add "tsx src/index.ts" --name api --watch --watch-paths src,package.json

Memory Management

Full process tree memory tracking:

  • Discovers all child processes via ps-tree
  • Calculates combined memory usage across the entire tree
  • Gracefully restarts when the limit is exceeded if auto-restart is enabled (SIGTERM → SIGKILL)
  • Prevents memory leaks from taking down production systems

The daemon itself runs with a bounded V8 heap. The release binaries are compiled with --v8-flags=--max-old-space-size=512 baked in — compiled Deno binaries ignore NODE_OPTIONS and DENO_V8_FLAGS at runtime, so the compile-time flag is the only effective cap. Without it, V8 defers major garbage collection almost indefinitely on large hosts and the daemon's RSS can climb to gigabytes under heavy child log throughput. The --daemonHeap option of tspm enable still applies to daemons started from a Node.js install (where NODE_OPTIONS works).

Log Persistence

Smart in-memory log management:

  • 10MB ring buffer per process with automatic trimming
  • Flushes to disk on stop, restart, or crash
  • Reloads persisted logs when process restarts
  • Crash logs stored separately with full metadata (exit code, signal, memory, timestamps)

Graceful Shutdown

Multi-stage shutdown for reliability:

  1. Send SIGTERM for graceful shutdown
  2. Wait 5 seconds for process cleanup
  3. Send SIGKILL if still alive
  4. Clean up all child processes in the tree

TypeScript Entry Files

If tspm add receives a single .ts file, TSPM resolves it through tsx automatically and stores the resolved command plus file argument in the process config. Full command strings are still executed through the shell, so existing node, tsx, pnpm, or custom commands work as expected.

🐛 Debugging

# Check daemon status
tspm daemon status

# View process logs
tspm logs name:my-app --lines 200

# Start with verbose daemon diagnostics
TSPM_DEBUG=true tspm daemon start

# For systemd-managed daemon logs
journalctl -u smartdaemon_tspm-daemon -f

# Force daemon restart
tspm daemon restart

Common issues:

Problem Solution
"Daemon not running" tspm daemon start or sudo tspm enable
"Permission denied" Check socket permissions in ~/.tspm/ or the configured TSPM_DIR
Process won't start Check logs with tspm logs <target>
Memory limit exceeded Increase with tspm edit <target>

The daemon PID file contains TSPM identity metadata. If a stale PID file points at an unrelated process, TSPM removes the stale file instead of treating that process as a daemon. Client and daemon also expose a protocol version through daemon:status so incompatible upgrades can be detected early.

🤝 Why TSPM?

Feature TSPM PM2
TypeScript Native Built in TypeScript JavaScript
Memory Tracking Full process tree ⚠️ Main process only
Log Management Smart 10MB buffer ⚠️ Can grow unbounded
Architecture Clean 3-tier daemon Monolithic
Dependencies Minimal Heavy
ESM Support Native ⚠️ Partial
Crash Reports Detailed with metadata Basic

Perfect For

  • 🚀 Production Node.js apps — Reliable process management with memory guards
  • 🔧 Microservices — Manage multiple services from a single tool
  • 👨‍💻 Development — TypeScript entry files, local workers, and quick daemon lifecycle commands
  • 🏭 Workers & Jobs — Queue workers, cron jobs, background tasks
  • 📊 Resource-constrained environments — Memory limits prevent OOM kills

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

S
Description
no fuzz process manager.
Readme 1.8 MiB
TSPM v5.15.3 Latest
2026-06-10 17:50:16 +00:00
Languages
TypeScript 96.7%
Shell 3%
JavaScript 0.3%