refactor: Complete rewrite of worker-utils.ts and cleanup of worker-service.ts

- Removed fragile PM2 string parsing and replaced with direct PM2 restart logic.
- Eliminated silent error handling in worker-utils.ts for better error visibility.
- Extracted duplicated session auto-creation logic into a new helper method getOrCreateSession() in worker-service.ts.
- Centralized configuration values and replaced magic numbers with named constants.
- Updated health check logic to ensure worker is restarted if unhealthy.
- Removed unnecessary getWorkerPort() wrapper function.
- Improved overall code quality and maintainability by applying DRY and YAGNI principles.
This commit is contained in:
Alex Newman
2025-11-06 22:00:07 -05:00
parent f8dc7f940f
commit 3030f518b5
18 changed files with 2454 additions and 346 deletions
+2 -1
View File
@@ -5,6 +5,7 @@
import { stdin } from 'process';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { getWorkerPort } from '../shared/worker-utils.js';
export interface SessionEndInput {
session_id: string;
@@ -71,7 +72,7 @@ async function cleanupHook(input?: SessionEndInput): Promise<void> {
// Tell worker to stop spinner
try {
const workerPort = session.worker_port || 37777;
const workerPort = session.worker_port || getWorkerPort();
await fetch(`http://127.0.0.1:${workerPort}/sessions/${session.id}/complete`, {
method: 'POST',
signal: AbortSignal.timeout(1000)
+3 -4
View File
@@ -7,7 +7,7 @@ import path from 'path';
import { stdin } from 'process';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { createHookResponse } from './hook-response.js';
import { ensureWorkerRunning } from '../shared/worker-utils.js';
import { ensureWorkerRunning, getWorkerPort } from '../shared/worker-utils.js';
export interface UserPromptSubmitInput {
session_id: string;
@@ -43,12 +43,11 @@ async function newHook(input?: UserPromptSubmitInput): Promise<void> {
db.close();
// Use fixed worker port
const FIXED_PORT = parseInt(process.env.CLAUDE_MEM_WORKER_PORT || '37777', 10);
const port = getWorkerPort();
try {
// Initialize session via HTTP
const response = await fetch(`http://127.0.0.1:${FIXED_PORT}/sessions/${sessionDbId}/init`, {
const response = await fetch(`http://127.0.0.1:${port}/sessions/${sessionDbId}/init`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ project, userPrompt: prompt }),
+4 -5
View File
@@ -7,7 +7,7 @@ import { stdin } from 'process';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { createHookResponse } from './hook-response.js';
import { logger } from '../utils/logger.js';
import { ensureWorkerRunning } from '../shared/worker-utils.js';
import { ensureWorkerRunning, getWorkerPort } from '../shared/worker-utils.js';
export interface PostToolUseInput {
session_id: string;
@@ -50,16 +50,15 @@ async function saveHook(input?: PostToolUseInput): Promise<void> {
const toolStr = logger.formatTool(tool_name, tool_input);
// Use fixed worker port
const FIXED_PORT = parseInt(process.env.CLAUDE_MEM_WORKER_PORT || '37777', 10);
const port = getWorkerPort();
logger.dataIn('HOOK', `PostToolUse: ${toolStr}`, {
sessionId: sessionDbId,
workerPort: FIXED_PORT
workerPort: port
});
try {
const response = await fetch(`http://127.0.0.1:${FIXED_PORT}/sessions/${sessionDbId}/observations`, {
const response = await fetch(`http://127.0.0.1:${port}/sessions/${sessionDbId}/observations`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
+4 -5
View File
@@ -7,7 +7,7 @@ import { stdin } from 'process';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { createHookResponse } from './hook-response.js';
import { logger } from '../utils/logger.js';
import { ensureWorkerRunning } from '../shared/worker-utils.js';
import { ensureWorkerRunning, getWorkerPort } from '../shared/worker-utils.js';
export interface StopInput {
session_id: string;
@@ -35,17 +35,16 @@ async function summaryHook(input?: StopInput): Promise<void> {
const promptNumber = db.getPromptCounter(sessionDbId);
db.close();
// Use fixed worker port
const FIXED_PORT = parseInt(process.env.CLAUDE_MEM_WORKER_PORT || '37777', 10);
const port = getWorkerPort();
logger.dataIn('HOOK', 'Stop: Requesting summary', {
sessionId: sessionDbId,
workerPort: FIXED_PORT,
workerPort: port,
promptNumber
});
try {
const response = await fetch(`http://127.0.0.1:${FIXED_PORT}/sessions/${sessionDbId}/summarize`, {
const response = await fetch(`http://127.0.0.1:${port}/sessions/${sessionDbId}/summarize`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt_number: promptNumber }),
+3 -1
View File
@@ -10,6 +10,7 @@ import { execSync } from "child_process";
import { join } from "path";
import { homedir } from "os";
import { existsSync } from "fs";
import { getWorkerPort } from "../shared/worker-utils.js";
// Check if node_modules exists - if not, this is first run
const pluginDir = join(homedir(), '.claude', 'plugins', 'marketplaces', 'thedotmack');
@@ -46,11 +47,12 @@ try {
encoding: 'utf8'
});
const port = getWorkerPort();
console.error(
"\n\n📝 Claude-Mem Context Loaded\n" +
" ️ Note: This appears as stderr but is informational only\n\n" +
output +
"\n\n📺 Watch live in browser http://localhost:37777/ (New! v5.1)\n"
`\n\n📺 Watch live in browser http://localhost:${port}/ (New! v5.1)\n`
);
} catch (error) {