Files
claude-mem/.claude/plans/cleanup-worker-service-nonsense-logic.md
T
Alex Newman 05323c9db5 Cleanup worker-service.ts: remove dead code and fallback concept (#706)
* refactor(worker): remove dead code from worker-service.ts

Remove ~216 lines of unreachable code:
- Delete `runInteractiveSetup` function (defined but never called)
- Remove unused imports: fs namespace, spawn, homedir, readline,
  existsSync/writeFileSync/readFileSync/mkdirSync
- Clean up CursorHooksInstaller imports (keep only used exports)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(worker): only enable SDK fallback when Claude is configured

Add isConfigured() method to SDKAgent that checks for ANTHROPIC_API_KEY
or claude CLI availability. Worker now only sets SDK agent as fallback
for third-party providers when credentials exist, preventing cascading
failures for users who intentionally use Gemini/OpenRouter without Claude.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(worker): remove misleading re-export indirection

Remove unnecessary re-export of updateCursorContextForProject from
worker-service.ts. ResponseProcessor now imports directly from
CursorHooksInstaller.ts where the function is defined. This eliminates
misleading indirection that suggested a circular dependency existed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(mcp): use build-time injected version instead of hardcoded strings

Replace hardcoded '1.0.0' version strings with __DEFAULT_PACKAGE_VERSION__
constant that esbuild replaces at build time. This ensures MCP server and
client versions stay synchronized with package.json.

- worker-service.ts: MCP client version now uses packageVersion
- ChromaSync.ts: MCP client version now uses packageVersion
- mcp-server.ts: MCP server version now uses packageVersion
- Added clarifying comments for empty MCP capabilities objects

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Implement cleanup and validation plans for worker-service.ts

- Added a comprehensive cleanup plan addressing 23 identified issues in worker-service.ts, focusing on safe deletions, low-risk simplifications, and medium-risk improvements.
- Created an execution plan for validating intentional patterns in worker-service.ts, detailing necessary actions and priorities.
- Generated a report on unjustified logic in worker-service.ts, categorizing issues by severity and providing recommendations for immediate and short-term actions.
- Introduced documentation for recent activity in the mem-search plugin, enhancing traceability and context for changes.

* fix(sdk): remove dangerous ANTHROPIC_API_KEY check from isConfigured

Claude Code uses CLI authentication, not direct API calls. Checking for
ANTHROPIC_API_KEY could accidentally use a user's API key (from other
projects) which costs 20x more than Claude Code's pricing.

Now only checks for claude CLI availability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(worker): remove fallback agent concept entirely

Users who choose Gemini/OpenRouter want those providers, not secret
fallback behavior. Removed setFallbackAgent calls and the unused
isConfigured() method.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 23:30:13 -05:00

9.5 KiB

Plan: Cleanup worker-service.ts Unjustified Logic

Created: 2026-01-13 Source: docs/reports/nonsense-logic.md Target: src/services/worker-service.ts (813 lines) Goal: Address 23 identified issues, prioritizing safe deletions first


Phase 0: Documentation Discovery (COMPLETED)

Evidence Gathered

Exit Code Strategy (CLAUDE.md:44-54):

- Exit 0: Success or graceful shutdown (Windows Terminal closes tabs)
- Exit 1: Non-blocking error
- Exit 2: Blocking error
Philosophy: Exit 0 prevents Windows Terminal tab accumulation

Signal Handler Pattern (ProcessManager.ts:294-317):

  • Uses mutable reference object isShuttingDownRef
  • Factory function createSignalHandler() returns handler with embedded state
  • Current implementation has 3-hop indirection

MCP Client Pattern (worker-service.ts:157-160, ChromaSync.ts:124-136):

this.mcpClient = new Client({
  name: 'worker-search-proxy',
  version: '1.0.0'
}, { capabilities: {} });

Verification Results:

  • runInteractiveSetup (lines 439-639): NEVER CALLED - grep shows only definition
  • import * as fs from 'fs' (line 13): UNUSED - no fs. usage found
  • import { spawn } from 'child_process' (line 14): UNUSED - no spawn( calls
  • homedir (line 15): Only used in runInteractiveSetup (dead code)
  • processPendingQueues default = 10: Never used, all callers pass explicit args

Phase 1: Safe Deletions (Dead Code & Unused Imports)

1.1 Delete runInteractiveSetup Function

What: Delete lines 435-639 (~201 lines) Why: Function is defined but never called. Setup happens via handleCursorCommand(). Evidence: grep -n "runInteractiveSetup" src/services/worker-service.ts returns only definition

Pattern to follow: N/A - straight deletion

Steps:

  1. Read worker-service.ts lines 435-650
  2. Delete the entire function including section comment (lines 435-639)
  3. Run npm run build to verify no compile errors

Verification:

  • grep "runInteractiveSetup" src/ returns nothing
  • Build succeeds

1.2 Remove Unused Imports

What: Delete lines 13, 14, 17

Current (delete these):

import * as fs from 'fs';           // Line 13 - UNUSED
import { spawn } from 'child_process';  // Line 14 - UNUSED
import * as readline from 'readline';   // Line 17 - Only in dead code

Keep:

import { homedir } from 'os';  // Line 15 - DELETE (only in dead code)
import { existsSync, writeFileSync, readFileSync, mkdirSync } from 'fs';  // Line 16 - CHECK USAGE

Steps:

  1. After deleting runInteractiveSetup, grep for remaining usages:
    • grep "homedir" src/services/worker-service.ts
    • grep "readline" src/services/worker-service.ts
    • grep "detectClaudeCode\|findCursorHooksDir\|installCursorHooks\|configureCursorMcp" src/services/worker-service.ts
  2. Delete imports with zero usages
  3. Run npm run build

Verification:

  • No TypeScript unused import warnings
  • Build succeeds

1.3 Clean Up Cursor Integration Imports

After deleting runInteractiveSetup, some CursorHooksInstaller imports become unused:

  • detectClaudeCode - only in runInteractiveSetup
  • findCursorHooksDir - only in runInteractiveSetup
  • installCursorHooks - only in runInteractiveSetup
  • configureCursorMcp - only in runInteractiveSetup

Steps:

  1. Grep each import after dead code removal
  2. Remove any that are now unused
  3. Keep updateCursorContextForProject (re-exported) and handleCursorCommand (used in main)

Verification:

  • grep "detectClaudeCode\|findCursorHooksDir\|installCursorHooks\|configureCursorMcp" src/services/worker-service.ts returns nothing
  • Build succeeds

Phase 2: Low-Risk Simplifications

2.1 Remove Unused Default Parameter

What: Line 350 - async processPendingQueues(sessionLimit: number = 10) Why: Default never used. All callers pass explicit args (50 in startup, dynamic in HTTP)

Change from:

async processPendingQueues(sessionLimit: number = 10): Promise<{...}>

Change to:

async processPendingQueues(sessionLimit: number): Promise<{...}>

Verification:

  • Build succeeds
  • All call sites provide explicit values

2.2 Simplify onRestart Callback

Location: Lines 395-396 (approximate, find exact) Issue: onShutdown and onRestart both call this.shutdown()

Find pattern:

onShutdown: () => this.shutdown(),
onRestart: () => this.shutdown()

Options:

  1. Keep as-is if restart semantically differs from shutdown (future-proofing)
  2. Add comment explaining intentional parity
  3. Remove onRestart if never used differently

Investigation needed: Grep for onRestart usage in Server.ts to understand contract

Steps:

  1. Grep onRestart in src/services/server/
  2. If Server.ts treats them identically, add clarifying comment
  3. If different, document why both map to shutdown

2.3 Fix Over-Commented Lines (Sample Only)

Strategy: Do NOT strip all comments. Only remove comments that describe obvious code.

Anti-pattern (remove):

// WHAT: Imports centralized logging utility with structured output
// WHY: All worker logs go through this for consistent formatting
import { logger } from '../utils/logger.js';

Pattern to follow: Remove WHAT/WHY on simple imports. Keep architectural comments.

Scope: Sample 5-10 obvious comment removals to demonstrate approach, not exhaustive


Phase 3: Medium-Risk Improvements

3.1 Simplify Signal Handler Pattern

Current (worker-service.ts:180-192 + ProcessManager.ts:294-317):

// 3-hop indirection with mutable reference
const shutdownRef = { value: this.isShuttingDown };
const handler = createSignalHandler(() => this.shutdown(), shutdownRef);
process.on('SIGTERM', () => {
  this.isShuttingDown = shutdownRef.value;  // Sync back
  handler('SIGTERM');
});

Simplified approach:

private registerSignalHandlers(): void {
  const handler = async (signal: string) => {
    if (this.isShuttingDown) {
      logger.warn('SYSTEM', `Received ${signal} but shutdown already in progress`);
      return;
    }
    this.isShuttingDown = true;
    logger.info('SYSTEM', `Received ${signal}, shutting down...`);
    try {
      await this.shutdown();
      process.exit(0);
    } catch (error) {
      logger.error('SYSTEM', 'Error during shutdown', {}, error as Error);
      process.exit(0);
    }
  };

  process.on('SIGTERM', () => handler('SIGTERM'));
  process.on('SIGINT', () => handler('SIGINT'));
}

Decision needed: Does createSignalHandler serve other callers? If yes, keep factory but simplify worker usage.

Steps:

  1. Grep createSignalHandler usage across codebase
  2. If only worker-service uses it, inline and simplify
  3. If shared, simplify worker's usage while keeping factory

3.2 Unify Dual Initialization Tracking

Current (lines 111, 129-130):

private initializationCompleteFlag: boolean = false;
private initializationComplete: Promise<void>;

Recommendation: Keep both but add clarifying comments:

  • Promise: For async waiters (HTTP handlers)
  • Flag: For sync checks (status endpoints)

Alternative: Use Promise with inspection pattern:

private initializationComplete = false;
private initializationPromise: Promise<void>;
// Flag derived from promise state via finally() callback

Steps:

  1. Add documentation comment explaining dual tracking purpose
  2. Consider if flag can be derived from promise state instead

3.3 Reduce 5-Minute Timeout

Location: Lines 464-478 (approximate) Current: const timeoutMs = 300000; // 5 minutes Recommendation: Reduce to 30-60 seconds for HTTP handler, keep 5min for MCP init

Caution: MCP initialization can legitimately be slow (ChromaDB, model loading). May need different timeouts per use case.

Steps:

  1. Find exact line for context inject timeout
  2. Verify this is separate from MCP init timeout
  3. Reduce HTTP handler timeout to 30-60 seconds
  4. Keep MCP init timeout at 5 minutes

Phase 4: Deferred / Low Priority

These items are noted but NOT part of this cleanup:

Issue Reason to Defer
Exit code 0 always Documented Windows Terminal workaround - intentional
Re-export for circular import Works correctly, architectural fix is separate work
Fallback agent verification Behavioral change, needs feature design
MCP version hardcoding Low impact, separate version management issue
Empty capabilities Documentation issue only
Unsafe as Error casts Common TS pattern, low risk

Phase 5: Verification

5.1 Build Verification

npm run build

Expected: No errors

5.2 Test Suite

npm test

Expected: All tests pass

5.3 Grep for Anti-patterns

# Verify dead code removed
grep -r "runInteractiveSetup" src/

# Verify unused imports removed
grep "import \* as fs from 'fs'" src/services/worker-service.ts
grep "import { spawn }" src/services/worker-service.ts

Expected: No matches

5.4 Runtime Check

npm run build-and-sync
# Start worker and verify basic operation

Summary

Phase Items Estimated Reduction
Phase 1 Dead code + unused imports ~210 lines
Phase 2 Low-risk simplifications ~5 lines + clarity
Phase 3 Medium-risk improvements ~30 lines
Total ~245 lines (~30% reduction)

Execution Order: Phase 1 → Phase 2 → Phase 3 → Phase 5 (verification after each)