feat(ProcessManager): add Bun availability check and improve PID file validation

- Implemented a method to check if Bun is available in the system PATH.
- Updated the startWithBun method to return an error if Bun is not found.
- Enhanced PID file parsing to validate required fields and their types.
- Cleaned up stale PID files if the process is no longer alive.

fix(SettingsRoutes): clear port cache after updating settings

- Added a call to clearPortCache after writing updated settings to ensure the application uses the latest configuration.
This commit is contained in:
Alex Newman
2025-12-12 17:48:41 -05:00
parent 9f1745bdec
commit 1491123706
27 changed files with 247 additions and 316 deletions
+3 -3
View File
@@ -109,7 +109,7 @@ npx mintlify dev
- **[Architecture Evolution](https://docs.claude-mem.ai/architecture-evolution)** - The journey from v3 to v5
- **[Hooks Architecture](https://docs.claude-mem.ai/hooks-architecture)** - How Claude-Mem uses lifecycle hooks
- **[Hooks Reference](https://docs.claude-mem.ai/architecture/hooks)** - 7 hook scripts explained
- **[Worker Service](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API & PM2 management
- **[Worker Service](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API & Bun management
- **[Database](https://docs.claude-mem.ai/architecture/database)** - SQLite schema & FTS5 search
- **[Search Architecture](https://docs.claude-mem.ai/architecture/search-architecture)** - Hybrid search with Chroma vector database
@@ -149,7 +149,7 @@ npx mintlify dev
1. **5 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 hook scripts)
2. **Smart Install** - Cached dependency checker (pre-hook script, not a lifecycle hook)
3. **Worker Service** - HTTP API on port 37777 with web viewer UI and 10 search endpoints, managed by PM2
3. **Worker Service** - HTTP API on port 37777 with web viewer UI and 10 search endpoints, managed by Bun
4. **SQLite Database** - Stores sessions, observations, summaries with FTS5 full-text search
5. **mem-search Skill** - Natural language queries with progressive disclosure (~2,250 token savings vs MCP)
6. **Chroma Vector Database** - Hybrid semantic + keyword search for intelligent context retrieval
@@ -263,7 +263,7 @@ See [CHANGELOG.md](CHANGELOG.md) for complete version history.
- **Node.js**: 18.0.0 or higher
- **Claude Code**: Latest version with plugin support
- **PM2**: Process manager (bundled - no global install required)
- **Bun**: JavaScript runtime and process manager (auto-installed if missing)
- **SQLite 3**: For persistent storage (bundled)
---
+11 -11
View File
@@ -34,7 +34,7 @@ isWorkerHealthy() → fetch /health endpoint
└─ [UNHEALTHY] → startWorker()
├─ [Windows] → PowerShell Start-Process (hidden window)
└─ [Unix] → PM2 start ecosystem.config.cjs
└─ [Unix] → Bun start ecosystem.config.cjs
Wait for health check (15 retries × 1000ms)
@@ -116,7 +116,7 @@ spawnSync('powershell.exe', [
**Issues:**
1. **PowerShell Dependency:** Assumes PowerShell is available and in PATH
2. **Command Injection Risk:** Worker script path inserted directly into command string without escaping
3. **Process Monitoring:** Windows approach launches detached process with no PM2 monitoring - harder to debug/restart
3. **Process Monitoring:** Windows approach launches detached process with no Bun monitoring - harder to debug/restart
4. **Health Check Timeout:** Comment says "Windows needs longer timeouts" but timeout is same for all platforms (500ms)
**Edge Cases:**
@@ -127,16 +127,16 @@ spawnSync('powershell.exe', [
**Unix Implementation:**
```typescript
const localPm2Base = path.join(MARKETPLACE_ROOT, 'node_modules', '.bin', 'pm2');
const pm2Command = existsSync(localPm2Base) ? localPm2Base : 'pm2';
const localBunBase = path.join(MARKETPLACE_ROOT, 'node_modules', '.bin', 'bun');
const bunCommand = existsSync(localBunBase) ? localBunBase : 'bun';
```
**Issues:**
1. **PM2 Dependency:** Falls back to global pm2 if local not found, but doesn't verify it exists
2. **Silent Failure:** If PM2 not installed globally, spawnSync will fail with cryptic ENOENT error
1. **Bun Dependency:** Falls back to global bun if local not found, but doesn't verify it exists
2. **Silent Failure:** If Bun not installed globally, spawnSync will fail with cryptic ENOENT error
**Recommendation:**
- Add pm2 existence check before spawn
- Add bun existence check before spawn
- Implement consistent process monitoring across platforms
- Add path escaping for Windows command construction
- Actually implement longer timeout for Windows if needed
@@ -414,7 +414,7 @@ if (!existsSync(join(commandsDir, 'save.md'))) {
### Missing Edge Case Handling ⚠️
1. **curl Failure:** context-hook.ts has no error handling for curl failures
2. **PM2 Not Installed:** worker-utils.ts assumes pm2 exists globally
2. **Bun Not Installed:** worker-utils.ts assumes bun exists globally
3. **PowerShell Restrictions:** worker-utils.ts doesn't check execution policy
4. **Concurrent Worker Starts:** No locking to prevent multiple hooks from starting worker simultaneously
5. **Port Already In Use:** No detection or recovery if worker port is taken
@@ -442,7 +442,7 @@ if (!existsSync(join(commandsDir, 'save.md'))) {
### Medium Priority 🟡
4. **Verify PM2 availability** before attempting to use it
4. **Verify Bun availability** before attempting to use it
- Check existence before spawn
- Provide clear error message if missing
@@ -494,7 +494,7 @@ if (!existsSync(join(commandsDir, 'save.md'))) {
1. **Cold Start:** First run with no existing data
2. **Corrupt Settings:** Invalid JSON in settings.json
3. **Missing Dependencies:** No PM2, no git, no curl
3. **Missing Dependencies:** No Bun, no git, no curl
4. **Port Conflicts:** Worker port already in use
5. **Rapid Hook Invocations:** Multiple hooks trying to start worker simultaneously
6. **Permission Issues:** Read-only filesystem, restricted execution
@@ -525,7 +525,7 @@ if (!existsSync(join(commandsDir, 'save.md'))) {
- Duplicate health endpoints
- curl dependency when fetch available
- PM2 dependency on Unix but not Windows (inconsistent monitoring)
- Bun dependency on Unix but not Windows (inconsistent monitoring)
- First-run detection using node_modules existence
- Hardcoded timeout values
+5 -5
View File
@@ -68,9 +68,9 @@ CLAUDE_MEM_PYTHON_VERSION=3.13 # Python version for chroma-mcp
```bash
npm run build # Compile TypeScript (hooks + worker)
npm run sync-marketplace # Copy to ~/.claude/plugins
npm run worker:restart # Restart PM2 worker
npm run worker:restart # Restart Bun worker
npm run worker:logs # View worker logs
pm2 list # Check worker status
bun list # Check worker status
```
---
@@ -918,8 +918,8 @@ esbuild.build({
npm run watch
# Terminal 2: Check worker status
pm2 list
pm2 logs claude-mem-worker
bun list
bun logs claude-mem-worker
# Terminal 3: Test API manually
curl http://localhost:37777/api/health
@@ -1020,7 +1020,7 @@ describe('Worker Integration', () => {
### Manual Testing Checklist
**Phase 1: Connection & Health**
- [ ] Worker starts successfully (`pm2 list`)
- [ ] Worker starts successfully (`bun list`)
- [ ] Health endpoint responds (`curl http://localhost:37777/api/health`)
- [ ] SSE stream connects (`curl http://localhost:37777/stream`)
+8 -15
View File
@@ -46,22 +46,15 @@ const ThemeProvider = ({ children }) => {
**Why It Matters**: Users working in different lighting conditions can now customize the viewer for comfort.
### v5.1.1: PM2 Windows Fix (November 2025)
### v5.1.1: Worker Startup Fix (November 2025) - Now Deprecated
**The Problem**: PM2 startup failed on Windows with ENOENT error
**Note**: This section describes a historical PM2-based approach that has been replaced with Bun in later versions.
**Root Cause**:
```typescript
// ❌ Failed on Windows - PM2 not in PATH
execSync('pm2 start ecosystem.config.cjs');
```
**The Problem**: Worker startup failed on Windows with ENOENT error when using PM2
**The Fix**:
```typescript
// ✅ Use full path to PM2 binary
const PM2_PATH = join(PLUGIN_ROOT, 'node_modules', '.bin', 'pm2');
execSync(`"${PM2_PATH}" start "${ECOSYSTEM_CONFIG}"`);
```
**Historical Solution**: Used full path to PM2 binary instead of relying on PATH
**Current Approach**: The project now uses Bun for process management, which provides better cross-platform compatibility and eliminates these PATH-related issues.
**Impact**: Cross-platform compatibility restored, Windows users can now use claude-mem without issues.
@@ -203,7 +196,7 @@ async function ensureWorkerHealthy() {
**Key Fixes**:
- Fixed race conditions in observation queue processing
- Improved error handling in SDK worker
- Better cleanup of stale PM2 processes
- Better cleanup of stale worker processes
- Enhanced logging for debugging
### v5.0.0: Hybrid Search Architecture (October 2025)
@@ -520,7 +513,7 @@ const response = query({
**Key change from v3:**
- ✅ Stores raw prompts for search
- ✅ Auto-starts PM2 worker
- ✅ Auto-starts worker service
</Tab>
<Tab title="PostToolUse">
+2 -2
View File
@@ -446,7 +446,7 @@ sequenceDiagram
else Tool allowed
SaveHook->>SaveHook: Strip privacy tags from input/response
SaveHook->>SaveHook: Ensure worker running<br/>(PM2 health check)
SaveHook->>SaveHook: Ensure worker running<br/>(health check)
SaveHook->>Worker: POST /api/sessions/observations<br/>{ claudeSessionId, tool_name, tool_input, tool_response, cwd }<br/>(fire-and-forget, 2s timeout)
@@ -906,7 +906,7 @@ For developers implementing this pattern on other platforms:
### Worker Service
- [ ] HTTP server on configurable port (default 37777)
- [ ] PM2 or equivalent process management
- [ ] Bun runtime for process management
- [ ] 3 core services: SessionManager, SDKAgent, DatabaseManager
### Hook Implementation
+5 -5
View File
@@ -29,7 +29,7 @@ Claude-Mem operates as a Claude Code plugin with five core components:
| **UI Framework** | React + TypeScript |
| **AI SDK** | @anthropic-ai/claude-agent-sdk |
| **Build Tool** | esbuild (bundles TypeScript) |
| **Process Manager** | PM2 |
| **Process Manager** | Bun |
| **Testing** | Node.js built-in test runner |
## Data Flow
@@ -70,7 +70,7 @@ User Query → mem-search Skill Invoked → HTTP API → SessionSearch Service
┌─────────────────────────────────────────────────────────────────┐
│ 1. Session Starts → Context Hook Fires │
│ Starts PM2 worker if needed, injects context from previous │
│ Starts Bun worker if needed, injects context from previous │
│ sessions (configurable observation count) │
└─────────────────────────────────────────────────────────────────┘
@@ -177,13 +177,13 @@ claude-mem/
├── tests/ # Test suite
├── docs/ # Documentation
└── ecosystem.config.cjs # PM2 configuration
└── ecosystem.config.cjs # Process configuration (deprecated)
```
## Component Details
### 1. Plugin Hooks (6 Hooks)
- **context-hook.js** - SessionStart: Starts PM2 worker, injects context
- **context-hook.js** - SessionStart: Starts Bun worker, injects context
- **user-message-hook.js** - UserMessage: Debugging hook
- **new-hook.js** - UserPromptSubmit: Creates session, saves prompt
- **save-hook.js** - PostToolUse: Captures tool executions
@@ -200,7 +200,7 @@ Express.js HTTP server on port 37777 (configurable) with:
- 8 viewer UI HTTP/SSE endpoints
- Async observation processing via Claude Agent SDK
- Real-time updates via Server-Sent Events
- Auto-managed by PM2 process manager
- Auto-managed by Bun
See [Worker Service](/architecture/worker-service) for HTTP API and endpoints.
@@ -415,7 +415,7 @@ Claude translates to appropriate API call.
If searches fail, check worker service:
```bash
pm2 list # Check status
npm run worker:status # Check status
npm run worker:restart # Restart worker
npm run worker:logs # View logs
```
+3 -33
View File
@@ -181,33 +181,9 @@ Claude-Mem supports switching between stable and beta versions via the web viewe
See [Beta Features](beta-features) for details on what's available in beta.
## PM2 Configuration
## Worker Service Management
Worker service is managed by PM2 via `ecosystem.config.cjs`:
```javascript
module.exports = {
apps: [{
name: 'claude-mem-worker',
script: './plugin/scripts/worker-service.cjs',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
FORCE_COLOR: '1'
}
}]
};
```
### PM2 Settings
- **instances**: 1 (single instance)
- **autorestart**: true (auto-restart on crash)
- **watch**: false (no file watching)
- **max_memory_restart**: 1G (restart if memory exceeds 1GB)
Worker service is managed by Bun as a background process. The worker auto-starts on first session and runs continuously in the background.
## Context Injection Configuration
@@ -402,13 +378,7 @@ Recommended values:
### Worker Memory Limit
Modify PM2 memory limit in `ecosystem.config.cjs`:
```javascript
{
max_memory_restart: '2G' // Increase if needed
}
```
The worker service is managed by Bun and will automatically restart if it encounters issues. Memory usage is typically low (~100-200MB).
### Logging Verbosity
+1 -1
View File
@@ -650,7 +650,7 @@ rm -rf plugin/scripts/*.js plugin/scripts/*.cjs
1. Kill existing process:
```bash
pm2 delete claude-mem-worker
npm run worker:stop
```
2. Check port:
+20 -36
View File
@@ -87,7 +87,7 @@ Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-h
- Version changed in package.json
- Critical dependency missing (better-sqlite3)
3. Provides Windows-specific error messages
4. Starts PM2 worker service
4. Starts Bun worker service
**Configuration:**
```json
@@ -215,7 +215,7 @@ Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-h
1. Reads user prompt and session ID from stdin
2. Creates new session record in SQLite
3. Saves raw user prompt for full-text search (v4.2.0+)
4. Starts PM2 worker service if not running
4. Starts Bun worker service if not running
5. Returns immediately (non-blocking)
**Configuration:**
@@ -512,49 +512,33 @@ sequenceDiagram
└─────────────────────────────────────────────────────────┘
```
### PM2 Process Management
### Bun Process Management
**Technology:** PM2 (process manager for Node.js)
**Technology:** Bun (JavaScript runtime and process manager)
**Why PM2:**
**Why Bun:**
- Auto-restart on failure
- Log management
- Process monitoring
- Fast startup and low memory footprint
- Built-in TypeScript support
- Cross-platform (works on macOS, Linux, Windows)
- No systemd/launchd needed
**Configuration:**
```javascript
// ecosystem.config.cjs
module.exports = {
apps: [{
name: 'claude-mem-worker',
script: './plugin/scripts/worker-service.cjs',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '500M',
env: {
NODE_ENV: 'production',
CLAUDE_MEM_WORKER_PORT: 37777
}
}]
};
```
- No separate process manager needed
**Worker lifecycle:**
```bash
# Started by new-hook (if not running)
pm2 start ecosystem.config.cjs
# Started by hooks automatically (if not running)
npm run worker:start
# Status check
pm2 status claude-mem-worker
npm run worker:status
# View logs
pm2 logs claude-mem-worker
npm run worker:logs
# Restart
pm2 restart claude-mem-worker
npm run worker:restart
# Stop
npm run worker:stop
```
### Worker HTTP API
@@ -632,7 +616,7 @@ try {
**Failure modes:**
- Database locked → Skip observation, log error
- Worker crashed → Auto-restart via PM2
- Worker crashed → Auto-restart via Bun
- Network issue → Retry with exponential backoff
- Disk full → Warn user, disable memory
@@ -708,8 +692,8 @@ claude --debug
**Debugging:**
1. Check database: `sqlite3 ~/.claude-mem/claude-mem.db "SELECT * FROM observation_queue"`
2. Verify session exists: `SELECT * FROM sdk_sessions`
3. Check worker status: `pm2 status`
4. View worker logs: `pm2 logs claude-mem-worker`
3. Check worker status: `npm run worker:status`
4. View worker logs: `npm run worker:logs`
</Accordion>
</AccordionGroup>
@@ -761,7 +745,7 @@ claude --debug
**Why smart-install is sometimes slow:**
- First-time: Full npm install (2-5 seconds)
- Cached: Version check only (~10ms)
- Version change: Full npm install + PM2 restart
- Version change: Full npm install + worker restart
**Optimization (v5.0.3):**
- Version caching with `.install-version` marker
+2 -2
View File
@@ -16,7 +16,7 @@ Install Claude-Mem directly from the plugin marketplace:
That's it! The plugin will automatically:
- Download prebuilt binaries (no compilation needed)
- Install all dependencies (including PM2 and SQLite binaries)
- Install all dependencies (including SQLite binaries)
- Configure hooks for session lifecycle management
- Auto-start the worker service on first session
@@ -26,7 +26,7 @@ Start a new Claude Code session and you'll see context from previous sessions au
- **Node.js**: 18.0.0 or higher
- **Claude Code**: Latest version with plugin support
- **PM2**: Process manager (bundled with plugin - no global install required)
- **Bun**: JavaScript runtime and process manager (auto-installed if missing)
- **SQLite 3**: For persistent storage (bundled)
## Advanced Installation
+2 -2
View File
@@ -58,7 +58,7 @@ Restart Claude Code. Context from previous sessions will automatically appear in
**Core Components:**
1. **5 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 hook scripts)
2. **Smart Install** - Cached dependency checker (pre-hook script)
3. **Worker Service** - HTTP API on port 37777 managed by PM2
3. **Worker Service** - HTTP API on port 37777 managed by Bun
4. **SQLite Database** - Stores sessions, observations, summaries with FTS5 search
5. **mem-search Skill** - Query historical context with natural language
6. **Web Viewer UI** - Real-time visualization with SSE and infinite scroll
@@ -69,7 +69,7 @@ See [Architecture Overview](architecture/overview) for details.
- **Node.js**: 18.0.0 or higher
- **Claude Code**: Latest version with plugin support
- **PM2**: Process manager (bundled - no global install required)
- **Bun**: JavaScript runtime and process manager (auto-installed if missing)
- **SQLite 3**: For persistent storage (bundled)
## What's New
+5 -5
View File
@@ -57,9 +57,9 @@ CLAUDE_MEM_PYTHON_VERSION=3.13 # Python version for chroma-mcp
```bash
npm run build # Compile TypeScript (hooks + worker)
npm run sync-marketplace # Copy to ~/.claude/plugins
npm run worker:restart # Restart PM2 worker
npm run worker:restart # Restart worker
npm run worker:logs # View worker logs
pm2 list # Check worker status
npm run worker:status # Check worker status
```
## Worker Architecture
@@ -1132,8 +1132,8 @@ esbuild.build({
</Step>
<Step title="Terminal 2: Check worker status">
```bash
pm2 list
pm2 logs claude-mem-worker
npm run worker:status
npm run worker:logs
```
</Step>
<Step title="Terminal 3: Test API manually">
@@ -1238,7 +1238,7 @@ describe('Worker Integration', () => {
<AccordionGroup>
<Accordion title="Phase 1: Connection & Health">
- [ ] Worker starts successfully (`pm2 list`)
- [ ] Worker starts successfully (`npm run worker:status`)
- [ ] Health endpoint responds (`curl http://localhost:37777/api/health`)
- [ ] SSE stream connects (`curl http://localhost:37777/stream`)
</Accordion>
+24 -55
View File
@@ -10,7 +10,7 @@ description: "Common issues and solutions for Claude-Mem"
Describe any issues you're experiencing to Claude, and the troubleshoot skill will automatically activate to provide diagnosis and fixes.
The troubleshoot skill will:
- ✅ Check PM2 worker status and health
- ✅ Check worker status and health
- ✅ Verify database existence and integrity
- ✅ Test worker service connectivity
- ✅ Validate dependencies installation
@@ -170,39 +170,18 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
4. Restart Claude Code after manual install
### PM2 ENOENT Error on Windows (v5.1.1 Fix)
**Symptoms**: Worker fails to start with "ENOENT" error on Windows.
**Solutions**:
1. This was fixed in v5.1.1 - update to latest version:
```bash
/plugin update claude-mem
```
2. If still experiencing issues, verify PM2 path:
```bash
cd ~/.claude/plugins/marketplaces/thedotmack
dir node_modules\.bin\pm2.cmd
```
3. Manual PM2 install if needed:
```bash
npm install pm2@latest
```
## Worker Service Issues
### Worker Service Not Starting
**Symptoms**: Worker doesn't start, or `pm2 status` shows no processes.
**Symptoms**: Worker doesn't start, or worker status shows it's not running.
**Solutions**:
1. Check if PM2 is running:
1. Check worker status:
```bash
pm2 status
npm run worker:status
```
2. Try starting manually:
@@ -217,14 +196,14 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
4. Full reset:
```bash
pm2 delete claude-mem-worker
npm run worker:stop
npm run worker:start
```
5. Verify PM2 is installed:
5. Verify Bun is installed:
```bash
which pm2
npm list pm2
which bun
bun --version
```
### Port Allocation Failed
@@ -256,7 +235,7 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
### Worker Keeps Crashing
**Symptoms**: Worker restarts repeatedly, PM2 shows high restart count.
**Symptoms**: Worker restarts repeatedly or fails to stay running.
**Solutions**:
@@ -265,23 +244,21 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
npm run worker:logs
```
2. Check memory usage:
2. Check worker status:
```bash
pm2 status
npm run worker:status
```
3. Increase memory limit in `ecosystem.config.cjs`:
```javascript
{
max_memory_restart: '2G' // Increase if needed
}
```
4. Check database for corruption:
3. Check database for corruption:
```bash
sqlite3 ~/.claude-mem/claude-mem.db "PRAGMA integrity_check;"
```
4. Verify Bun installation:
```bash
bun --version
```
### Worker Not Processing Observations
**Symptoms**: Observations saved but not processed, no summaries generated.
@@ -424,7 +401,7 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
1. Close all connections:
```bash
pm2 stop claude-mem-worker
npm run worker:stop
```
2. Check for stale locks:
@@ -656,29 +633,21 @@ The skill includes comprehensive diagnostics, automated repair sequences, and de
### High Memory Usage
**Symptoms**: Worker uses too much memory, frequent restarts.
**Symptoms**: Worker uses too much memory.
**Solutions**:
1. Check current usage:
```bash
pm2 status
npm run worker:status
```
2. Increase memory limit:
```javascript
// In ecosystem.config.cjs
{
max_memory_restart: '2G'
}
```
3. Restart worker:
2. Restart worker:
```bash
npm run worker:restart
```
4. Clean up old data (see "Database Too Large" above)
3. Clean up old data (see "Database Too Large" above)
## Installation Issues
@@ -773,10 +742,10 @@ sqlite3 ~/.claude-mem/claude-mem.db "
```bash
# Check if worker is running
pm2 status
npm run worker:status
# View logs
pm2 logs claude-mem-worker
npm run worker:logs
# Check port file
cat ~/.claude-mem/worker.port
+1 -1
View File
@@ -175,7 +175,7 @@ This design ensures that private content never reaches the database, search indi
1. Verify correct syntax: `<private>content</private>`
2. Check `~/.claude-mem/silent.log` for errors
3. Ensure worker is running: `pm2 list`
3. Ensure worker is running: `npm run worker:status`
4. Restart worker: `npm run worker:restart`
### Partial Content Stored
+1 -1
View File
@@ -364,7 +364,7 @@ search_sessions with query="[YOUR PROJECT NAME]" and orderBy="date_desc"
If search isn't working, check the worker service:
```bash
pm2 list # Check worker status
npm run worker:status # Check worker status
npm run worker:restart # Restart if needed
npm run worker:logs # View logs
```
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+28 -3
View File
@@ -1,7 +1,7 @@
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'fs';
import { createWriteStream } from 'fs';
import { join } from 'path';
import { spawn } from 'child_process';
import { spawn, spawnSync } from 'child_process';
import { homedir } from 'os';
import { DATA_DIR } from '../../shared/paths.js';
@@ -47,7 +47,23 @@ export class ProcessManager {
return this.startWithBun(workerScript, logFile, port);
}
private static isBunAvailable(): boolean {
try {
const result = spawnSync('bun', ['--version'], { stdio: 'pipe', timeout: 5000 });
return result.status === 0;
} catch {
return false;
}
}
private static async startWithBun(script: string, logFile: string, port: number): Promise<{ success: boolean; pid?: number; error?: string }> {
if (!this.isBunAvailable()) {
return {
success: false,
error: 'Bun is required but not found in PATH. Install from https://bun.sh'
};
}
try {
const isWindows = process.platform === 'win32';
@@ -129,7 +145,11 @@ export class ProcessManager {
static async isRunning(): Promise<boolean> {
const info = this.getPidInfo();
if (!info) return false;
return this.isProcessAlive(info.pid);
const alive = this.isProcessAlive(info.pid);
if (!alive) {
this.removePidFile(); // Clean up stale PID file
}
return alive;
}
// Helper methods
@@ -137,7 +157,12 @@ export class ProcessManager {
try {
if (!existsSync(PID_FILE)) return null;
const content = readFileSync(PID_FILE, 'utf-8');
return JSON.parse(content) as PidInfo;
const parsed = JSON.parse(content);
// Validate required fields have correct types
if (typeof parsed.pid !== 'number' || typeof parsed.port !== 'number') {
return null;
}
return parsed as PidInfo;
} catch {
return null;
}
@@ -21,6 +21,7 @@ import {
} from '../../../../constants/observation-metadata.js';
import { BaseRouteHandler } from '../BaseRouteHandler.js';
import { SettingsDefaultsManager } from '../../../../shared/SettingsDefaultsManager.js';
import { clearPortCache } from '../../../../shared/worker-utils.js';
export class SettingsRoutes extends BaseRouteHandler {
constructor(
@@ -162,6 +163,9 @@ export class SettingsRoutes extends BaseRouteHandler {
// Write back
writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
// Clear port cache to force re-reading from updated settings
clearPortCache();
logger.info('WORKER', 'Settings updated');
res.json({ success: true, message: 'Settings updated successfully' });
});