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>
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
# Intentional Patterns Validation Report
|
||||
|
||||
**Generated:** 2026-01-13
|
||||
**Purpose:** Validate whether "intentional" patterns in worker-service.ts are truly justified
|
||||
|
||||
---
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Pattern | Verdict | Evidence Quality | Recommendation |
|
||||
|---------|---------|------------------|----------------|
|
||||
| Exit code 0 always | **JUSTIFIED** | HIGH | Keep (well documented) |
|
||||
| Circular import re-export | **UNNECESSARY** | HIGH | Remove (no actual circular dep) |
|
||||
| Fallback agent without check | **OVERSIGHT** | HIGH | Fix (real bug risk) |
|
||||
| MCP version hardcoded | **COSMETIC** | MEDIUM | Update to match package.json |
|
||||
| Empty MCP capabilities | **INTENTIONAL** | LOW | Add documentation comment |
|
||||
| `as Error` casts | **JUSTIFIED** | HIGH | Keep (documented policy) |
|
||||
|
||||
---
|
||||
|
||||
## Pattern 1: Exit Code 0 Always
|
||||
|
||||
### Evidence
|
||||
|
||||
| Category | Details |
|
||||
|----------|---------|
|
||||
| **Locations** | 8 explicit `process.exit(0)` calls in worker-service.ts |
|
||||
| **Documentation** | CLAUDE.md lines 44-54, CHANGELOG v9.0.2 |
|
||||
| **Git History** | Commit 222a73da (Jan 8, 2026) - detailed explanation |
|
||||
| **Tests** | 23 passing tests in `worker-json-status.test.ts` |
|
||||
| **Comments** | 5 detailed comments at each exit point |
|
||||
|
||||
### Justification
|
||||
|
||||
```markdown
|
||||
## Exit Code Strategy (from CLAUDE.md)
|
||||
|
||||
- **Exit 0**: Success or graceful shutdown (Windows Terminal closes tabs)
|
||||
- **Exit 1**: Non-blocking error (stderr shown to user, continues)
|
||||
- **Exit 2**: Blocking error (stderr fed to Claude for processing)
|
||||
|
||||
**Philosophy**: Worker/hook errors exit with code 0 to prevent Windows Terminal
|
||||
tab accumulation. The wrapper/plugin layer handles restart logic.
|
||||
```
|
||||
|
||||
### Commit Evidence
|
||||
|
||||
```
|
||||
commit 222a73da5dc875e666c3dd2c96c9d178dd7b884d
|
||||
Date: Thu Jan 8 15:02:56 2026 -0500
|
||||
|
||||
fix: graceful exit strategy to prevent Windows Terminal tab accumulation (#625)
|
||||
|
||||
Problem:
|
||||
Windows Terminal keeps tabs open when processes exit with code 1, leading
|
||||
to tab accumulation during worker lifecycle operations.
|
||||
|
||||
Solution:
|
||||
Implemented graceful exit strategy using exit code 0 for all expected failure
|
||||
scenarios. The wrapper and plugin handle restart logic.
|
||||
```
|
||||
|
||||
### Verdict: **JUSTIFIED**
|
||||
|
||||
- Real Windows Terminal behavior documented
|
||||
- Comprehensive test coverage validating pattern
|
||||
- Consistent implementation across all exit points
|
||||
- Error status communicated via JSON, not exit code
|
||||
|
||||
### Risk
|
||||
|
||||
- Breaks Unix convention but trades correctness for UX
|
||||
- Shell scripts calling worker commands won't detect errors via `$?`
|
||||
- Mitigated by JSON status output for programmatic consumers
|
||||
|
||||
---
|
||||
|
||||
## Pattern 2: Circular Import Re-Export
|
||||
|
||||
### The Code (worker-service.ts:77-78)
|
||||
|
||||
```typescript
|
||||
// Re-export updateCursorContextForProject for SDK agents
|
||||
export { updateCursorContextForProject };
|
||||
```
|
||||
|
||||
### Import Chain Analyzed
|
||||
|
||||
```
|
||||
CursorHooksInstaller.ts (defines function)
|
||||
↓
|
||||
worker-service.ts (imports, re-exports)
|
||||
↓
|
||||
ResponseProcessor.ts (imports from worker-service.ts)
|
||||
```
|
||||
|
||||
### Actual Circular Dependency: **NONE EXISTS**
|
||||
|
||||
```
|
||||
CursorHooksInstaller.ts → imports nothing from worker-service.ts ✓
|
||||
ResponseProcessor.ts → only imports the re-exported function ✓
|
||||
```
|
||||
|
||||
ResponseProcessor.ts **could** import directly:
|
||||
|
||||
```typescript
|
||||
// Current (via re-export):
|
||||
import { updateCursorContextForProject } from '../../worker-service.js';
|
||||
|
||||
// Alternative (direct - would work fine):
|
||||
import { updateCursorContextForProject } from '../../integrations/CursorHooksInstaller.js';
|
||||
```
|
||||
|
||||
### Verdict: **UNNECESSARY**
|
||||
|
||||
- Comment claims "avoids circular imports" but no circular dependency exists
|
||||
- Likely a precaution during refactoring that became stale
|
||||
- Harmless but misleading
|
||||
|
||||
### Recommendation
|
||||
|
||||
- **Option A**: Remove re-export, update ResponseProcessor.ts import path
|
||||
- **Option B**: Update comment to explain actual reason (e.g., "API surface simplification")
|
||||
|
||||
---
|
||||
|
||||
## Pattern 3: Fallback Agent Without Verification
|
||||
|
||||
### The Code (worker-service.ts:144-146)
|
||||
|
||||
```typescript
|
||||
this.geminiAgent.setFallbackAgent(this.sdkAgent);
|
||||
this.openRouterAgent.setFallbackAgent(this.sdkAgent);
|
||||
```
|
||||
|
||||
### Fallback Trigger Logic
|
||||
|
||||
```typescript
|
||||
// GeminiAgent.ts:284-294
|
||||
if (shouldFallbackToClaude(error) && this.fallbackAgent) {
|
||||
logger.warn('SDK', 'Gemini API failed, falling back to Claude SDK', {...});
|
||||
return this.fallbackAgent.startSession(session, worker);
|
||||
}
|
||||
```
|
||||
|
||||
### Problem Scenario
|
||||
|
||||
1. User chooses Gemini because they **don't have Claude credentials**
|
||||
2. Gemini encounters transient error (429 rate limit, 503 server error)
|
||||
3. Code attempts fallback to Claude SDK
|
||||
4. Claude SDK fails (no credentials) → **cascading failure**
|
||||
5. User sees cryptic error, session lost
|
||||
|
||||
### What's Checked vs What's NOT
|
||||
|
||||
| Check | Implemented |
|
||||
|-------|-------------|
|
||||
| `this.fallbackAgent` is not null | ✅ Yes |
|
||||
| Fallback agent initialized successfully | ❌ No |
|
||||
| Fallback agent has valid credentials | ❌ No |
|
||||
| Fallback agent can make API calls | ❌ No |
|
||||
|
||||
### Verdict: **OVERSIGHT - Real Bug Risk**
|
||||
|
||||
- Documentation claims "seamless fallback"
|
||||
- No health check verifies fallback is functional
|
||||
- Users without Claude credentials face silent failure mode
|
||||
|
||||
### Recommendation
|
||||
|
||||
Add verification at initialization:
|
||||
|
||||
```typescript
|
||||
// Option 1: Verify fallback can initialize
|
||||
if (this.sdkAgent.isConfigured()) {
|
||||
this.geminiAgent.setFallbackAgent(this.sdkAgent);
|
||||
}
|
||||
|
||||
// Option 2: Log warning when fallback unavailable
|
||||
if (!this.sdkAgent.isConfigured()) {
|
||||
logger.warn('WORKER', 'Claude SDK not configured - Gemini fallback disabled');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 4: Hardcoded MCP Version "1.0.0"
|
||||
|
||||
### Locations (3 instances)
|
||||
|
||||
| File | Line | Version |
|
||||
|------|------|---------|
|
||||
| worker-service.ts | 157-160 | `1.0.0` |
|
||||
| ChromaSync.ts | 126-131 | `1.0.0` |
|
||||
| mcp-server.ts | 236-245 | `1.0.0` |
|
||||
|
||||
### Version Mismatch
|
||||
|
||||
| Source | Version |
|
||||
|--------|---------|
|
||||
| package.json | `9.0.4` |
|
||||
| MCP SDK | `1.25.1` |
|
||||
| MCP Client/Server instances | `1.0.0` |
|
||||
|
||||
### Does It Matter?
|
||||
|
||||
**Investigation found:**
|
||||
- MCP servers do NOT validate client version
|
||||
- Connections succeed regardless of version value
|
||||
- Version appears to be for logging/debugging only (like HTTP User-Agent)
|
||||
|
||||
### Verdict: **COSMETIC - Low Priority**
|
||||
|
||||
- Functionally doesn't matter
|
||||
- Inconsistent with package version is confusing
|
||||
- Should be updated for cleanliness
|
||||
|
||||
### Recommendation
|
||||
|
||||
```typescript
|
||||
// Update to use package version
|
||||
import { version } from '../../package.json' assert { type: 'json' };
|
||||
|
||||
this.mcpClient = new Client({
|
||||
name: 'worker-search-proxy',
|
||||
version: version // Use actual package version
|
||||
}, { capabilities: {} });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 5: Empty MCP Capabilities
|
||||
|
||||
### The Code
|
||||
|
||||
```typescript
|
||||
{ capabilities: {} } // All 3 MCP client instances
|
||||
```
|
||||
|
||||
### Investigation
|
||||
|
||||
- MCP specification: **Servers** declare capabilities (tools, resources, prompts)
|
||||
- MCP specification: **Clients** don't typically declare capabilities
|
||||
- No validation found in any MCP server
|
||||
- Pattern works correctly
|
||||
|
||||
### Verdict: **INTENTIONAL - Documentation Gap**
|
||||
|
||||
- Empty capabilities is likely correct for clients
|
||||
- MCP SDK documentation doesn't clarify this
|
||||
- Works fine in practice
|
||||
|
||||
### Recommendation
|
||||
|
||||
Add clarifying comment:
|
||||
|
||||
```typescript
|
||||
// MCP spec: Clients accept all server capabilities; no declaration needed
|
||||
{ capabilities: {} }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 6: `as Error` Casts
|
||||
|
||||
### Locations (8 in worker-service.ts)
|
||||
|
||||
Lines: 236, 314, 317, 339, 393, 469, 636, 796
|
||||
|
||||
### Why It's Used
|
||||
|
||||
TypeScript 4.0+ catch clauses have `unknown` type:
|
||||
|
||||
```typescript
|
||||
try {
|
||||
// ...
|
||||
} catch (error) { // error: unknown (not Error)
|
||||
logger.error('X', 'msg', {}, error as Error); // Cast needed for logger
|
||||
}
|
||||
```
|
||||
|
||||
### Project Documentation
|
||||
|
||||
**File:** `scripts/anti-pattern-test/CLAUDE.md`
|
||||
|
||||
Establishes explicit error handling policy with:
|
||||
- 5 questions before writing try-catch
|
||||
- Forbidden patterns list
|
||||
- Anti-pattern detection script
|
||||
- Critical paths protection
|
||||
|
||||
### Anti-Pattern Detection
|
||||
|
||||
```bash
|
||||
bun run scripts/anti-pattern-test/detect-error-handling-antipatterns.ts
|
||||
```
|
||||
|
||||
Scans for 7 anti-patterns including:
|
||||
- Empty catch blocks
|
||||
- Catch without logging
|
||||
- Generic error handling
|
||||
|
||||
### Verdict: **JUSTIFIED - Documented Policy**
|
||||
|
||||
- Explicit project convention with tooling support
|
||||
- Alternative (type guards) would add verbosity
|
||||
- Logger requires Error type for stack trace
|
||||
- Pre-commit validation enforces consistency
|
||||
|
||||
---
|
||||
|
||||
## Action Items Summary
|
||||
|
||||
| Pattern | Action | Priority |
|
||||
|---------|--------|----------|
|
||||
| Exit code 0 | Keep as-is | N/A |
|
||||
| Circular import re-export | Remove or fix comment | LOW |
|
||||
| Fallback agent | **Add availability check** | **HIGH** |
|
||||
| MCP version | Update to package.json version | LOW |
|
||||
| Empty capabilities | Add documentation comment | LOW |
|
||||
| `as Error` casts | Keep as-is | N/A |
|
||||
|
||||
---
|
||||
|
||||
## Questions for Your Validation
|
||||
|
||||
1. **Exit code 0**: Is the Windows Terminal workaround acceptable, or should we exit non-zero and document that users need to parse JSON status?
|
||||
|
||||
2. **Circular import**: Should we remove the re-export (cleaner) or update the comment to reflect the real reason?
|
||||
|
||||
3. **Fallback agent**: Should we:
|
||||
- A) Add initialization-time verification
|
||||
- B) Document the limitation and keep as-is
|
||||
- C) Allow users to disable fallback behavior
|
||||
|
||||
4. **MCP version**: Worth updating all 3 instances, or leave as cosmetic debt?
|
||||
@@ -0,0 +1,450 @@
|
||||
# Unjustified Logic Report - worker-service.ts
|
||||
|
||||
**Generated:** 2026-01-13
|
||||
**Source:** `src/services/worker-service.ts` (1445 lines)
|
||||
**Status:** Pending Review
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
23 items identified lacking clear justification. Categorized by severity.
|
||||
|
||||
---
|
||||
|
||||
## HIGH SEVERITY
|
||||
|
||||
### 1. Dead Function: `runInteractiveSetup` (~275 lines)
|
||||
|
||||
**Location:** Lines 837-1111
|
||||
|
||||
```typescript
|
||||
async function runInteractiveSetup(): Promise<number> {
|
||||
// ~275 lines of interactive wizard code
|
||||
}
|
||||
```
|
||||
|
||||
**What it does:** Interactive CLI wizard for Cursor setup.
|
||||
|
||||
**Why it's questionable:** Function is defined but **never called** anywhere. Grep shows only the definition. The `main()` switch handles 'cursor' via `handleCursorCommand`, not this function.
|
||||
|
||||
**Justification status:** No justification found. Appears to be dead code from refactoring.
|
||||
|
||||
---
|
||||
|
||||
## MEDIUM SEVERITY
|
||||
|
||||
### 2. 5-Minute Initialization Timeout
|
||||
|
||||
**Location:** Lines 464-478
|
||||
|
||||
```typescript
|
||||
const timeoutMs = 300000; // 5 minutes
|
||||
await Promise.race([this.initializationComplete, timeoutPromise]);
|
||||
```
|
||||
|
||||
**What it does:** Blocks `/api/context/inject` for up to 5 minutes.
|
||||
|
||||
**Why it's questionable:** HTTP request hanging for 5 minutes is extreme.
|
||||
|
||||
**Justification status:** "5 minutes seems excessive but matches MCP init timeout for consistency" - **circular reasoning**.
|
||||
|
||||
---
|
||||
|
||||
### 3. Redundant Signal Handler Synchronization
|
||||
|
||||
**Location:** Lines 412-434
|
||||
|
||||
```typescript
|
||||
const shutdownRef = { value: this.isShuttingDown };
|
||||
const handler = createSignalHandler(() => this.shutdown(), shutdownRef);
|
||||
process.on('SIGTERM', () => {
|
||||
this.isShuttingDown = shutdownRef.value;
|
||||
handler('SIGTERM');
|
||||
});
|
||||
```
|
||||
|
||||
**What it does:** Creates reference object, passes to handler, copies value back.
|
||||
|
||||
**Why it's questionable:** Overly complex. `this.isShuttingDown` could be used directly via closure.
|
||||
|
||||
**Justification status:** "Signal handler needs mutable reference" - but closure would work.
|
||||
|
||||
---
|
||||
|
||||
### 4. Dual Initialization Tracking (Promise + Flag)
|
||||
|
||||
**Location:** Lines 322-326, 633-634
|
||||
|
||||
```typescript
|
||||
private initializationComplete: Promise<void>;
|
||||
private initializationCompleteFlag: boolean = false;
|
||||
```
|
||||
|
||||
**What it does:** Maintains both Promise and boolean for same state.
|
||||
|
||||
**Why it's questionable:** Two sources of truth. Promise could resolve to boolean, or sync code could use a different pattern.
|
||||
|
||||
**Justification status:** Comments explain separately but not why both needed.
|
||||
|
||||
---
|
||||
|
||||
### 5. Over-Commenting (~40% of file)
|
||||
|
||||
**Location:** Throughout
|
||||
|
||||
```typescript
|
||||
// WHAT: Imports centralized logging utility with structured output
|
||||
// WHY: All worker logs go through this for consistent formatting
|
||||
import { logger } from '../utils/logger.js';
|
||||
```
|
||||
|
||||
**What it does:** WHAT/WHY comments on nearly every line.
|
||||
|
||||
**Why it's questionable:** Many describe obvious code. Creates visual noise. `import { logger }` is self-explanatory.
|
||||
|
||||
**Justification status:** No justification for this density.
|
||||
|
||||
---
|
||||
|
||||
### 6. Exit Code 0 Always (Even on Errors)
|
||||
|
||||
**Location:** Lines 1142, 1272-1287, 1417-1420
|
||||
|
||||
```typescript
|
||||
function exitWithStatus(status: 'ready' | 'error', message?: string): never {
|
||||
console.log(JSON.stringify(output));
|
||||
process.exit(0); // Always 0, even on error
|
||||
}
|
||||
```
|
||||
|
||||
**What it does:** Exits 0 regardless of success/failure.
|
||||
|
||||
**Why it's questionable:** Breaks Unix convention. Hides failures from scripts/monitoring.
|
||||
|
||||
**Justification status:** "Windows Terminal keeps tabs open on non-zero exit" - **trades correctness for UI convenience**.
|
||||
|
||||
---
|
||||
|
||||
### 7. Fallback Agent Without Verification
|
||||
|
||||
**Location:** Lines 357-363
|
||||
|
||||
```typescript
|
||||
this.geminiAgent.setFallbackAgent(this.sdkAgent);
|
||||
this.openRouterAgent.setFallbackAgent(this.sdkAgent);
|
||||
```
|
||||
|
||||
**What it does:** Sets Claude SDK as fallback for alternative providers.
|
||||
|
||||
**Why it's questionable:** User may choose Gemini because they DON'T have Claude subscription. Fallback would fail.
|
||||
|
||||
**Justification status:** "If Gemini fails, falls back to Claude SDK (if available)" - doesn't verify availability.
|
||||
|
||||
---
|
||||
|
||||
### 8. Re-Export to Avoid Circular Import
|
||||
|
||||
**Location:** Line 191
|
||||
|
||||
```typescript
|
||||
export { updateCursorContextForProject };
|
||||
```
|
||||
|
||||
**What it does:** Re-exports imported function.
|
||||
|
||||
**Why it's questionable:** Creates odd import path. Masks architectural issue (circular dependency).
|
||||
|
||||
**Justification status:** "Avoids circular imports" - acknowledges architecture problem.
|
||||
|
||||
---
|
||||
|
||||
## LOW SEVERITY
|
||||
|
||||
### 9. Unused Import: `import * as fs`
|
||||
|
||||
**Location:** Line 22
|
||||
|
||||
```typescript
|
||||
import * as fs from 'fs';
|
||||
```
|
||||
|
||||
**What it does:** Imports fs namespace.
|
||||
|
||||
**Why it's questionable:** Namespace never used. Only specific named imports (line 34) are used.
|
||||
|
||||
**Justification status:** Comment claims "Used for file operations" - **false**.
|
||||
|
||||
---
|
||||
|
||||
### 10. Unused Import: `spawn`
|
||||
|
||||
**Location:** Line 26
|
||||
|
||||
```typescript
|
||||
import { spawn } from 'child_process';
|
||||
```
|
||||
|
||||
**What it does:** Imports spawn function.
|
||||
|
||||
**Why it's questionable:** Never used. MCP spawning uses `StdioClientTransport` internally.
|
||||
|
||||
**Justification status:** Comment claims "Worker spawns MCP server" - **misleading**.
|
||||
|
||||
---
|
||||
|
||||
### 11. `onRestart` = `onShutdown` (Identical Callbacks)
|
||||
|
||||
**Location:** Lines 395-396
|
||||
|
||||
```typescript
|
||||
onShutdown: () => this.shutdown(),
|
||||
onRestart: () => this.shutdown()
|
||||
```
|
||||
|
||||
**What it does:** Both callbacks do the exact same thing.
|
||||
|
||||
**Why it's questionable:** Naming implies different behavior.
|
||||
|
||||
**Justification status:** No justification for why restart just calls shutdown.
|
||||
|
||||
---
|
||||
|
||||
### 12. 100ms Magic Number in Recovery Loop
|
||||
|
||||
**Location:** Line 767
|
||||
|
||||
```typescript
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
```
|
||||
|
||||
**What it does:** 100ms delay between session recovery.
|
||||
|
||||
**Why it's questionable:** Why 100ms specifically? Not 50ms or 200ms?
|
||||
|
||||
**Justification status:** "Prevents thundering herd" - purpose explained, value unexplained.
|
||||
|
||||
---
|
||||
|
||||
### 13. Dynamic Import Already Loaded
|
||||
|
||||
**Location:** Lines 709-710
|
||||
|
||||
```typescript
|
||||
const { PendingMessageStore } = await import('./sqlite/PendingMessageStore.js');
|
||||
```
|
||||
|
||||
**What it does:** Dynamic import in `processPendingQueues`.
|
||||
|
||||
**Why it's questionable:** Same import in `initializeBackground` (line 558). Already loaded by auto-recovery call.
|
||||
|
||||
**Justification status:** "Lazy load because method may not be called often" - **misleading**, always called at startup.
|
||||
|
||||
---
|
||||
|
||||
### 14. Defensive Null Check for Race Condition
|
||||
|
||||
**Location:** Lines 663-669
|
||||
|
||||
```typescript
|
||||
if (!session) return;
|
||||
```
|
||||
|
||||
**What it does:** Early returns if session null.
|
||||
|
||||
**Why it's questionable:** Comment admits "Session could be deleted between queue check and processor start" - hints at design issue.
|
||||
|
||||
**Justification status:** Justified, but suggests architecture problem.
|
||||
|
||||
---
|
||||
|
||||
### 15. Eager Broadcaster Init (Before Server)
|
||||
|
||||
**Location:** Lines 347-349
|
||||
|
||||
```typescript
|
||||
this.sseBroadcaster = new SSEBroadcaster();
|
||||
```
|
||||
|
||||
**What it does:** Creates broadcaster in constructor.
|
||||
|
||||
**Why it's questionable:** Comment says "SSE clients can connect before background init" - but server not started yet.
|
||||
|
||||
**Justification status:** Comment is **technically incorrect**.
|
||||
|
||||
---
|
||||
|
||||
### 16. Hardcoded MCP Version
|
||||
|
||||
**Location:** Lines 385-388
|
||||
|
||||
```typescript
|
||||
this.mcpClient = new Client({
|
||||
name: 'worker-search-proxy',
|
||||
version: '1.0.0' // Hardcoded, doesn't match package.json
|
||||
}, { capabilities: {} });
|
||||
```
|
||||
|
||||
**What it does:** Hardcodes version to 1.0.0.
|
||||
|
||||
**Why it's questionable:** Doesn't match actual package version.
|
||||
|
||||
**Justification status:** No justification for specific version.
|
||||
|
||||
---
|
||||
|
||||
### 17. Nullable SearchRoutes After Init Complete
|
||||
|
||||
**Location:** Lines 314, 479-484
|
||||
|
||||
```typescript
|
||||
private searchRoutes: SearchRoutes | null = null;
|
||||
// After awaiting initializationComplete:
|
||||
if (!this.searchRoutes) {
|
||||
res.status(503).json({ error: 'Search routes not initialized' });
|
||||
}
|
||||
```
|
||||
|
||||
**What it does:** Null check after init should be complete.
|
||||
|
||||
**Why it's questionable:** If init succeeded, should never be null.
|
||||
|
||||
**Justification status:** Explains async nature, not why remains nullable after.
|
||||
|
||||
---
|
||||
|
||||
### 18. Complex ESM/CJS Module Detection
|
||||
|
||||
**Location:** Lines 1433-1439
|
||||
|
||||
```typescript
|
||||
const isMainModule = typeof require !== 'undefined' && typeof module !== 'undefined'
|
||||
? require.main === module || !module.parent
|
||||
: import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith('worker-service');
|
||||
```
|
||||
|
||||
**What it does:** Complex conditional for both module systems.
|
||||
|
||||
**Why it's questionable:** File is ESM-only (uses `import`). CJS checks unnecessary.
|
||||
|
||||
**Justification status:** "Works with both ESM and CommonJS" - but file is ESM-only.
|
||||
|
||||
---
|
||||
|
||||
### 19. Self-Questioning Comment
|
||||
|
||||
**Location:** Line 466
|
||||
|
||||
```typescript
|
||||
// REASON: 5 minutes seems excessive but matches MCP init timeout for consistency
|
||||
```
|
||||
|
||||
**What it does:** Comment admits code is questionable.
|
||||
|
||||
**Why it's questionable:** If author thought excessive when writing, deserves investigation.
|
||||
|
||||
**Justification status:** Self-acknowledged as questionable.
|
||||
|
||||
---
|
||||
|
||||
### 20. `homedir` Import (Only Used in Dead Code)
|
||||
|
||||
**Location:** Line 30
|
||||
|
||||
```typescript
|
||||
import { homedir } from 'os';
|
||||
```
|
||||
|
||||
**What it does:** Imports homedir.
|
||||
|
||||
**Why it's questionable:** Only used in `runInteractiveSetup` (dead code).
|
||||
|
||||
**Justification status:** Unused if dead code removed.
|
||||
|
||||
---
|
||||
|
||||
### 21. Unused Default Parameter
|
||||
|
||||
**Location:** Line 702
|
||||
|
||||
```typescript
|
||||
async processPendingQueues(sessionLimit: number = 10)
|
||||
```
|
||||
|
||||
**What it does:** Default of 10.
|
||||
|
||||
**Why it's questionable:** Only call uses 50 (line 639). Default never used.
|
||||
|
||||
**Justification status:** No justification for 10 vs actual usage of 50.
|
||||
|
||||
---
|
||||
|
||||
### 22. Empty Capabilities Object
|
||||
|
||||
**Location:** Line 388
|
||||
|
||||
```typescript
|
||||
}, { capabilities: {} });
|
||||
```
|
||||
|
||||
**What it does:** Passes empty capabilities to MCP client.
|
||||
|
||||
**Why it's questionable:** No explanation of what capabilities exist or why none needed.
|
||||
|
||||
**Justification status:** No justification found.
|
||||
|
||||
---
|
||||
|
||||
### 23. Unsafe `as Error` Casts
|
||||
|
||||
**Location:** Multiple (lines 513, 651, 771, etc.)
|
||||
|
||||
```typescript
|
||||
}, error as Error);
|
||||
```
|
||||
|
||||
**What it does:** Casts unknown to Error.
|
||||
|
||||
**Why it's questionable:** Caught value might not be Error.
|
||||
|
||||
**Justification status:** Common TypeScript pattern, acceptable but potentially unsafe.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| # | Issue | Severity | Action |
|
||||
|---|-------|----------|--------|
|
||||
| 1 | Dead `runInteractiveSetup` (~275 lines) | HIGH | Delete |
|
||||
| 2 | 5-minute timeout | MEDIUM | Reduce to 30s |
|
||||
| 3 | Redundant signal sync | MEDIUM | Simplify |
|
||||
| 4 | Dual init tracking | MEDIUM | Unify |
|
||||
| 5 | Over-commenting | MEDIUM | Reduce |
|
||||
| 6 | Exit 0 always | MEDIUM | Reconsider |
|
||||
| 7 | Fallback without check | MEDIUM | Verify availability |
|
||||
| 8 | Re-export for circular | MEDIUM | Fix architecture |
|
||||
| 9 | Unused `fs` namespace | LOW | Delete |
|
||||
| 10 | Unused `spawn` | LOW | Delete |
|
||||
| 11 | Identical callbacks | LOW | Clarify/merge |
|
||||
| 12 | 100ms magic number | LOW | Document or configure |
|
||||
| 13 | Redundant dynamic import | LOW | Remove |
|
||||
| 14 | Defensive null (design smell) | LOW | Review architecture |
|
||||
| 15 | Early broadcaster init | LOW | Fix comment |
|
||||
| 16 | Hardcoded MCP version | LOW | Use package.json |
|
||||
| 17 | Nullable after init | LOW | Clarify lifecycle |
|
||||
| 18 | CJS checks in ESM | LOW | Remove |
|
||||
| 19 | Self-questioning comment | LOW | Investigate |
|
||||
| 20 | `homedir` in dead code | LOW | Delete with dead code |
|
||||
| 21 | Unused default param | LOW | Remove or document |
|
||||
| 22 | Empty capabilities | LOW | Document |
|
||||
| 23 | Unsafe error casts | LOW | Add type guards |
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
1. **Immediate:** Delete dead `runInteractiveSetup` function (275 lines, ~19% of file)
|
||||
2. **Immediate:** Remove unused imports (`fs` namespace, `spawn`)
|
||||
3. **Short-term:** Reduce 5-minute timeout to 30 seconds
|
||||
4. **Short-term:** Simplify signal handler pattern
|
||||
5. **Consider:** Reduce comment density to improve readability
|
||||
Reference in New Issue
Block a user