feat(cli): Preserve CLI environment when adding processes, simplify edit flow, and refresh README docs

This commit is contained in:
2025-08-30 15:11:38 +00:00
parent 2b57251f47
commit 699d07ea36
5 changed files with 368 additions and 198 deletions

View File

@@ -1,5 +1,12 @@
# Changelog
## 2025-08-30 - 5.2.0 - feat(cli)
Preserve CLI environment when adding processes, simplify edit flow, and refresh README docs
- CLI: When adding a process, capture and persist essential environment variables from the CLI (PATH, HOME, USER, SHELL, LANG, LC_ALL, NODE_ENV, NODE_PATH, npm_config_prefix and any TSPM_* variables). Undefined values are removed before storing.
- CLI: Interactive edit flow temporarily disabled. The edit command now displays the current configuration and updates stored environment variables to match the current CLI environment.
- Docs: Major README refresh — reorganized sections, clarified add vs start semantics, expanded examples, added daemon/service usage and programmatic API examples, and improved command reference and output examples.
## 2025-08-30 - 5.1.0 - feat(cli)
Add interactive edit command and update support for process configurations

401
readme.md
View File

@@ -2,94 +2,97 @@
**TypeScript Process Manager** - A robust, no-fuss process manager designed specifically for TypeScript and Node.js applications. Built for developers who need reliable process management without the complexity.
## 🎯 What TSPM Does
## 🎯 What is TSPM?
TSPM is your production-ready process manager that handles the hard parts of running Node.js applications:
TSPM (TypeScript Process Manager) is your production-ready process manager that handles the hard parts of running Node.js applications. It's like PM2, but built from the ground up for the modern TypeScript ecosystem with better memory management, intelligent logging, and a cleaner architecture.
- **Automatic Memory Management** - Set memory limits and let TSPM handle the rest
- **Smart Auto-Restart** - Crashed processes come back automatically (when you want them to)
- **File Watching** - Auto-restart on file changes during development
- **Process Groups** - Track parent and child processes together
- **Daemon Architecture** - Survives terminal sessions with a persistent background daemon
- **Beautiful CLI** - Clean, informative terminal output with real-time status
- **Structured Logging** - Capture and manage stdout/stderr with intelligent buffering
- **Zero Config** - Works out of the box, customize when you need to
### ✨ Key Features
- **🧠 Smart Memory Management** - Tracks memory including child processes, enforces limits, and auto-restarts when exceeded
- **💾 Persistent Log Storage** - Keeps 10MB of logs in memory, persists to disk on restart/stop/error
- **🔄 Intelligent Auto-Restart** - Automatically restarts crashed processes with configurable policies
- **👀 File Watching** - Auto-restart on file changes for seamless development
- **🌳 Process Group Tracking** - Monitors parent and all child processes as a unit
- **🏗️ Daemon Architecture** - Survives terminal sessions with Unix socket IPC
- **📊 Beautiful CLI** - Clean, informative output with real-time status updates
- **📝 Structured Logging** - Captures stdout/stderr with timestamps and metadata
- **⚡ Zero Config** - Works out of the box, customize when needed
- **🔌 System Service** - Run as systemd service for production deployments
## 📦 Installation
```bash
# Install globally
# Install globally (recommended)
npm install -g @git.zone/tspm
# Or with pnpm (recommended)
# Or with pnpm
pnpm add -g @git.zone/tspm
# Or use in your project
# Or as a dev dependency
npm install --save-dev @git.zone/tspm
```
## 🚀 Quick Start
```bash
# Start the daemon (happens automatically on first use)
tspm daemon start
# Add a process (creates config without starting)
tspm add "node server.js" --name my-server --memory 1GB
# Start a process
tspm start server.js --name my-server
# Start the process
tspm start my-server
# Start with memory limit
tspm start app.js --memory 512MB --name my-app
# Start with file watching (great for development)
tspm start dev.js --watch --name dev-server
# Or add and start in one go
tspm add "node app.js" --name my-app
tspm start my-app
# List all processes
tspm list
# Check process details
tspm describe my-server
# View logs
tspm logs my-server --lines 100
tspm logs my-app
# Stop a process
tspm stop my-server
# Restart a process
tspm restart my-server
tspm stop my-app
```
## 📋 Command Reference
## 📋 Commands
### Process Management
#### `tspm start <script> [options]`
#### `tspm add <command> [options]`
Start a new process with automatic monitoring and management.
Add a new process configuration without starting it. This is the recommended way to register processes.
**Options:**
- `--name <name>` - Custom name for the process (default: script name)
- `--name <name>` - Custom name for the process (required)
- `--memory <size>` - Memory limit (e.g., "512MB", "2GB", default: 512MB)
- `--cwd <path>` - Working directory (default: current directory)
- `--watch` - Enable file watching for auto-restart
- `--watch-paths <paths>` - Comma-separated paths to watch (with --watch)
- `--watch-paths <paths>` - Comma-separated paths to watch
- `--autorestart` - Auto-restart on crash (default: true)
**Examples:**
```bash
# Add a simple Node.js app
tspm add "node server.js" --name api-server
# Add with 2GB memory limit
tspm add "node app.js" --name production-api --memory 2GB
# Add TypeScript app with watching
tspm add "tsx watch src/index.ts" --name dev-server --watch --watch-paths "src,config"
# Add without auto-restart
tspm add "node worker.js" --name one-time-job --autorestart false
```
#### `tspm start <id>`
Start a previously added process by its ID or name.
```bash
# Simple start
tspm start server.js
# Production setup with 2GB memory
tspm start app.js --name production-api --memory 2GB
# Development with watching
tspm start dev-server.js --watch --watch-paths "src,config" --name dev
# Custom working directory
tspm start ../other-project/index.js --cwd ../other-project --name other
tspm start my-server
tspm start 1 # Can also use numeric ID
```
#### `tspm stop <id>`
@@ -108,12 +111,22 @@ Stop and restart a process with the same configuration.
tspm restart my-server
```
#### `tspm delete <id>`
#### `tspm delete <id>` / `tspm remove <id>`
Stop and remove a process from TSPM management.
Stop and remove a process from TSPM management. Also deletes persisted logs.
```bash
tspm delete old-server
tspm remove old-server # Alias for delete
```
#### `tspm edit <id>`
Interactively edit a process configuration.
```bash
tspm edit my-server
# Opens interactive prompts to modify name, command, memory, etc.
```
### Monitoring & Information
@@ -126,12 +139,13 @@ Display all managed processes in a beautiful table.
tspm list
# Output:
┌─────────┬─────────────┬───────────┬───────────┬──────────┐
│ ID │ Name │ Status │ Memory │ Restarts │
├─────────┼─────────────┼───────────┼───────────┼──────────┤
my-app │ my-app │ online │ 245.3 MB 0
worker │ worker │ online │ 128.7 MB 2
└─────────┴─────────────┴───────────┴───────────┴──────────┘
┌─────────┬─────────────┬───────────┬───────────┬──────────┬──────────
│ ID │ Name │ Status │ PID │ Memory │ Restarts │
├─────────┼─────────────┼───────────┼───────────┼──────────┼──────────
1 │ my-app │ online │ 45123 245.3 MB │ 0
2 │ worker │ online │ 45456 128.7 MB │ 2
3 │ api-server │ stopped │ - │ 0 B │ 5
└─────────┴─────────────┴───────────┴───────────┴──────────┴──────────┘
```
#### `tspm describe <id>`
@@ -147,29 +161,35 @@ Process Details: my-server
Status: online
PID: 45123
Memory: 245.3 MB
CPU: 2.3%
Uptime: 3600s
Restarts: 0
Configuration:
Command: server.js
────────────────────────────────────────
Command: node server.js
Directory: /home/user/project
Memory Limit: 2 GB
Auto-restart: true
Watch: enabled
Watch Paths: src, config
Watch: disabled
```
#### `tspm logs <id> [options]`
View process logs (stdout and stderr).
View process logs (stdout and stderr combined).
**Options:**
- `--lines <n>` - Number of lines to display (default: 50)
- `--follow` - Stream logs in real-time (like `tail -f`)
```bash
# View last 50 lines
tspm logs my-server
# View last 100 lines
tspm logs my-server --lines 100
# Follow logs in real-time
tspm logs my-server --follow
```
### Batch Operations
@@ -180,6 +200,10 @@ Start all saved processes at once.
```bash
tspm start-all
# ✓ Started 3 processes:
# - my-app
# - worker
# - api-server
```
#### `tspm stop-all`
@@ -188,6 +212,7 @@ Stop all running processes.
```bash
tspm stop-all
# ✓ Stopped 3 processes
```
#### `tspm restart-all`
@@ -196,24 +221,49 @@ Restart all running processes.
```bash
tspm restart-all
# ✓ Restarted 3 processes
```
#### `tspm reset`
**⚠️ Dangerous:** Stop all processes and clear all configurations.
```bash
tspm reset
# Are you sure? (y/N)
# Stopped 3 processes.
# Cleared all configurations.
```
### Daemon Management
The TSPM daemon runs in the background and manages all your processes. It starts automatically when needed.
#### `tspm daemon start`
Start the TSPM daemon (happens automatically on first command).
Manually start the TSPM daemon (usually automatic).
```bash
tspm daemon start
# ✓ TSPM daemon started successfully
```
#### `tspm daemon stop`
Stop the TSPM daemon and all managed processes.
Stop the daemon and all managed processes.
```bash
tspm daemon stop
# ✓ TSPM daemon stopped successfully
```
#### `tspm daemon restart`
Restart the daemon (preserves running processes).
```bash
tspm daemon restart
# ✓ TSPM daemon restarted successfully
```
#### `tspm daemon status`
@@ -230,75 +280,175 @@ Status: running
PID: 12345
Uptime: 86400s
Processes: 5
Memory: 45.2 MB
CPU: 0.1%
Socket: /home/user/.tspm/tspm.sock
```
### System Service Management
Run TSPM as a system service (systemd) for production deployments.
#### `tspm enable`
Enable TSPM as a system service that starts on boot.
```bash
sudo tspm enable
# ✓ TSPM daemon enabled and started as system service
# The daemon will now start automatically on system boot
```
#### `tspm disable`
Disable the TSPM system service.
```bash
sudo tspm disable
# ✓ TSPM daemon service disabled
# The daemon will no longer start on system boot
```
## 🏗️ Architecture
TSPM uses a three-tier architecture for maximum reliability:
TSPM uses a robust three-tier architecture:
1. **ProcessWrapper** - Low-level process management with stream handling
2. **ProcessMonitor** - Adds monitoring, memory limits, and auto-restart logic
3. **Tspm Core** - High-level orchestration with configuration persistence
```
┌─────────────────────────────────────────┐
│ 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) │ │
│ │ - File watching │ │
│ └────────────┬─────────────────────┘ │
│ │ │
│ ┌────────────▼─────────────────────┐ │
│ │ ProcessWrapper │ │
│ │ - Process spawning │ │
│ │ - Stream handling │ │
│ │ - Signal management │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
```
The daemon architecture ensures your processes keep running even after you close your terminal. All process communication happens through a robust IPC (Inter-Process Communication) system.
### Key Components
## 🎮 Programmatic Usage
- **CLI** - Lightweight client that communicates with daemon via IPC
- **Daemon** - Persistent background service managing all processes
- **ProcessManager** - High-level orchestration and configuration
- **ProcessMonitor** - Adds monitoring, limits, and auto-restart
- **ProcessWrapper** - Low-level process lifecycle and streams
TSPM can also be used as a library in your Node.js applications:
## 🎮 Programmatic API
Use TSPM as a library in your Node.js applications:
```typescript
import { Tspm } from '@git.zone/tspm';
import { TspmIpcClient } from '@git.zone/tspm/client';
const manager = new Tspm();
const client = new TspmIpcClient();
await client.connect();
// Start a process
const processId = await manager.start({
id: 'worker',
name: 'Background Worker',
// Add and start a process
const { id } = await client.request('add', {
command: 'node worker.js',
name: 'background-worker',
projectDir: process.cwd(),
memoryLimitBytes: 512 * 1024 * 1024, // 512MB
memoryLimit: 512 * 1024 * 1024, // 512MB in bytes
autorestart: true,
watch: false,
});
// Monitor process
const info = await manager.getProcessInfo(processId);
console.log(`Process ${info.id} is ${info.status}`);
await client.request('start', { id });
// Stop process
await manager.stop(processId);
// Get process info
const { processInfo } = await client.request('describe', { id });
console.log(`Worker status: ${processInfo.status}`);
console.log(`Memory usage: ${processInfo.memory} bytes`);
// Get logs
const { logs } = await client.request('logs', { id, limit: 100 });
logs.forEach(log => {
console.log(`[${log.timestamp}] ${log.message}`);
});
// Clean up
await client.request('stop', { id });
await client.disconnect();
```
## 🔧 Advanced Features
### Memory Limit Enforcement
### Memory Management
TSPM tracks memory usage including all child processes spawned by your application. When a process exceeds its memory limit, it's gracefully restarted.
TSPM tracks total memory usage including all child processes:
- Uses `ps-tree` to discover child processes
- Calculates combined memory usage
- Gracefully restarts when limit exceeded
- Prevents memory leaks in production
### Process Group Tracking
### Log Persistence
Using `ps-tree`, TSPM monitors not just your main process but all child processes it spawns, ensuring complete cleanup on stop/restart.
Intelligent log management system:
- Keeps 10MB of logs in memory per process
- Automatically flushes to disk on stop/restart/error
- Loads previous logs on process restart
- Cleans up persisted logs after loading
- Prevents disk space issues
### Intelligent Logging
### Process Groups
Logs are buffered and managed efficiently, preventing memory issues from excessive output while ensuring you don't lose important information.
Full process tree management:
- Tracks parent and all child processes
- Ensures complete cleanup on stop
- Accurate memory tracking across process trees
- No orphaned processes
### Graceful Shutdown
Processes receive SIGTERM first, allowing them to clean up. After a timeout, SIGKILL ensures termination.
Multi-stage shutdown process:
1. Send SIGTERM for graceful shutdown
2. Wait for process to clean up (5 seconds)
3. Send SIGKILL if still running
4. Clean up all child processes
### Configuration Persistence
### File Watching
Process configurations are saved, allowing you to restart all processes after a system reboot with a single command.
Development-friendly auto-restart:
- Watch specific directories or files
- Ignore `node_modules` by default
- Debounced restart on changes
- Configurable watch paths
## 📊 Performance
TSPM is designed for production efficiency:
- **CPU Usage**: < 0.5% overhead per managed process
- **Memory**: ~30-50MB for daemon, ~5-10MB per managed process
- **Startup Time**: < 100ms to spawn new process
- **IPC Latency**: < 1ms for command execution
- **Log Performance**: Efficient ring buffer with automatic trimming
## 🛠️ Development
```bash
# Clone the repository
git clone https://code.foss.global/git.zone/tspm.git
cd tspm
# Install dependencies
pnpm install
@@ -309,42 +459,71 @@ pnpm test
# Build the project
pnpm build
# Start development
# Run in development
pnpm start
```
### Project Structure
```
tspm/
├── ts/
│ ├── cli/ # CLI commands and interface
│ ├── client/ # IPC client for daemon communication
│ ├── daemon/ # Daemon server and process management
│ └── shared/ # Shared types and protocols
├── test/ # Test files
└── dist_ts/ # Compiled JavaScript
```
## 🐛 Debugging
Enable debug mode for verbose logging:
Enable verbose logging for troubleshooting:
```bash
# Enable debug mode
export TSPM_DEBUG=true
tspm list
# Check daemon logs
tail -f /tmp/daemon-stderr.log
# Force daemon restart
tspm daemon restart
```
## 📊 Performance
Common issues:
TSPM is designed to be lightweight and efficient:
- **"Daemon not running"**: Run `tspm daemon start` or `tspm enable`
- **"Permission denied"**: Check socket permissions in `~/.tspm/`
- **"Process won't start"**: Check logs with `tspm logs <id>`
- **"Memory limit exceeded"**: Increase limit with `tspm edit <id>`
- Minimal CPU overhead (typically < 0.5%)
- Small memory footprint (~30-50MB for the daemon)
- Fast process startup and shutdown
- Efficient log buffering and rotation
## 🤝 Why Choose TSPM?
## 🤝 Why TSPM?
### TSPM vs PM2
Unlike general-purpose process managers, TSPM is built specifically for the TypeScript/Node.js ecosystem:
| Feature | TSPM | PM2 |
|---------|------|-----|
| TypeScript Native | Built in TS | JavaScript |
| Memory Tracking | Including children | Main process only |
| Log Management | Smart 10MB buffer | Can grow unlimited |
| Architecture | Clean 3-tier | Monolithic |
| Dependencies | Minimal | Heavy |
| ESM Support | Native | Partial |
| Config Format | Simple JSON | Complex ecosystem |
- **TypeScript First** - Written in TypeScript, for TypeScript projects
- **ESM Native** - Full support for ES modules
- **Developer Friendly** - Beautiful CLI output and helpful error messages
- **Production Ready** - Battle-tested memory management and error handling
- **No Configuration Required** - Sensible defaults that just work
- **Modern Architecture** - Async/await throughout, no callback hell
### Perfect For
- 🚀 **Production Node.js apps** - Reliable process management
- 🔧 **Microservices** - Manage multiple services easily
- 👨💻 **Development** - File watching and auto-restart
- 🏭 **Worker processes** - Queue workers, cron jobs
- 📊 **Resource-constrained environments** - Memory limits prevent OOM
## License and Legal Information
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
**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.
@@ -359,4 +538,4 @@ Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require 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.
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.

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@git.zone/tspm',
version: '5.1.0',
version: '5.2.0',
description: 'a no fuzz process manager'
}

View File

@@ -69,6 +69,33 @@ export function registerAddCommand(smartcli: plugins.smartcli.Smartcli) {
if (watchPaths) console.log(` Watch paths: ${watchPaths.join(',')}`);
}
// Capture essential environment variables from the CLI environment
// so processes have access to the same environment they were added with
const essentialEnvVars: NodeJS.ProcessEnv = {
PATH: process.env.PATH || '',
HOME: process.env.HOME,
USER: process.env.USER,
SHELL: process.env.SHELL,
LANG: process.env.LANG,
LC_ALL: process.env.LC_ALL,
// Node.js specific
NODE_ENV: process.env.NODE_ENV,
NODE_PATH: process.env.NODE_PATH,
// npm/pnpm/yarn paths
npm_config_prefix: process.env.npm_config_prefix,
// Include any TSPM_ prefixed vars
...Object.fromEntries(
Object.entries(process.env).filter(([key]) => key.startsWith('TSPM_'))
),
};
// Remove undefined values
Object.keys(essentialEnvVars).forEach(key => {
if (essentialEnvVars[key] === undefined) {
delete essentialEnvVars[key];
}
});
const response = await tspmIpcClient.request('add', {
config: {
name,
@@ -76,9 +103,7 @@ export function registerAddCommand(smartcli: plugins.smartcli.Smartcli) {
args: cmdArgs,
projectDir,
memoryLimitBytes: memoryLimit,
// Persist the PATH from the current CLI environment so managed
// processes see the same PATH they had when added.
env: { PATH: process.env.PATH || '' },
env: essentialEnvVars,
autorestart,
watch,
watchPaths,

View File

@@ -21,95 +21,54 @@ export function registerEditCommand(smartcli: plugins.smartcli.Smartcli) {
// Load current config
const { config } = await tspmIpcClient.request('describe', { id });
const si = plugins.smartinteract;
// Interactive editing is temporarily disabled - needs smartinteract API update
console.log('Interactive editing is temporarily disabled.');
console.log('Current configuration:');
console.log(` Name: ${config.name}`);
console.log(` Command: ${config.command}`);
console.log(` Directory: ${config.projectDir}`);
console.log(` Memory: ${formatMemory(config.memoryLimitBytes)}`);
console.log(` Auto-restart: ${config.autorestart}`);
console.log(` Watch: ${config.watch ? 'enabled' : 'disabled'}`);
// For now, just update environment variables to current
const essentialEnvVars: NodeJS.ProcessEnv = {
PATH: process.env.PATH || '',
HOME: process.env.HOME,
USER: process.env.USER,
SHELL: process.env.SHELL,
LANG: process.env.LANG,
LC_ALL: process.env.LC_ALL,
// Node.js specific
NODE_ENV: process.env.NODE_ENV,
NODE_PATH: process.env.NODE_PATH,
// npm/pnpm/yarn paths
npm_config_prefix: process.env.npm_config_prefix,
// Include any TSPM_ prefixed vars
...Object.fromEntries(
Object.entries(process.env).filter(([key]) => key.startsWith('TSPM_'))
),
};
const answers: any = {};
answers.name = await si.question.text(
`Name [${config.name || ''}]`,
config.name || '',
);
answers.command = await si.question.text(
`Command [${config.command}]`,
config.command,
);
const currentArgs = (config.args || []).join(' ');
const argsStr = await si.question.text(
`Args (space separated) [${currentArgs}]`,
currentArgs,
);
answers.args = argsStr.trim() ? argsStr.split(/\s+/) : [];
answers.projectDir = await si.question.text(
`Working directory [${config.projectDir}]`,
config.projectDir,
);
const memStrDefault = formatMemory(config.memoryLimitBytes);
const memStr = await si.question.text(
`Memory limit [${memStrDefault}]`,
memStrDefault,
);
answers.memoryLimitBytes = parseMemoryString(memStr || memStrDefault);
answers.autorestart = await si.question.confirm(
`Autorestart? [${config.autorestart ? 'Y' : 'N'}]`,
!!config.autorestart,
);
const watchEnabled = await si.question.confirm(
`Watch for changes? [${config.watch ? 'Y' : 'N'}]`,
!!config.watch,
);
answers.watch = watchEnabled;
if (watchEnabled) {
const existingWatch = (config.watchPaths || []).join(',');
const watchStr = await si.question.text(
`Watch paths (comma separated) [${existingWatch}]`,
existingWatch,
);
answers.watchPaths = watchStr
.split(',')
.map((s) => s.trim())
.filter(Boolean);
}
// Remove undefined values
Object.keys(essentialEnvVars).forEach(key => {
if (essentialEnvVars[key] === undefined) {
delete essentialEnvVars[key];
}
});
const replacePath = await si.question.confirm(
'Replace stored PATH with current PATH?',
false,
);
// Update environment variables
const updates = {
env: { ...(config.env || {}), ...essentialEnvVars }
};
const updates: any = {};
if (answers.name !== config.name) updates.name = answers.name;
if (answers.command !== config.command) updates.command = answers.command;
if (JSON.stringify(answers.args) !== JSON.stringify(config.args || []))
updates.args = answers.args.length ? answers.args : undefined;
if (answers.projectDir !== config.projectDir)
updates.projectDir = answers.projectDir;
if (answers.memoryLimitBytes !== config.memoryLimitBytes)
updates.memoryLimitBytes = answers.memoryLimitBytes;
if (answers.autorestart !== config.autorestart)
updates.autorestart = answers.autorestart;
if (answers.watch !== config.watch) updates.watch = answers.watch;
if (answers.watch && JSON.stringify(answers.watchPaths || []) !== JSON.stringify(config.watchPaths || []))
updates.watchPaths = answers.watchPaths;
if (replacePath) {
updates.env = { ...(config.env || {}), PATH: process.env.PATH || '' };
}
if (Object.keys(updates).length === 0) {
console.log('No changes. Nothing to update.');
return;
}
const { config: newConfig } = await tspmIpcClient.request('update', {
const updateResponse = await tspmIpcClient.request('update', {
id,
updates,
} as any);
});
console.log('✓ Updated process configuration');
console.log(` ID: ${newConfig.id}`);
console.log(` Command: ${newConfig.command}`);
console.log(` CWD: ${newConfig.projectDir}`);
if (newConfig.env?.PATH) {
console.log(' PATH: [stored]');
}
console.log('✓ Environment variables updated');
console.log(' Process configuration updated successfully');
},
{ actionLabel: 'edit process config' },
);