* 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>
9.0 KiB
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
## 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)
// 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:
// 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)
this.geminiAgent.setFallbackAgent(this.sdkAgent);
this.openRouterAgent.setFallbackAgent(this.sdkAgent);
Fallback Trigger Logic
// 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
- User chooses Gemini because they don't have Claude credentials
- Gemini encounters transient error (429 rate limit, 503 server error)
- Code attempts fallback to Claude SDK
- Claude SDK fails (no credentials) → cascading failure
- 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:
// 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
// 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
{ 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:
// 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:
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
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
-
Exit code 0: Is the Windows Terminal workaround acceptable, or should we exit non-zero and document that users need to parse JSON status?
-
Circular import: Should we remove the re-export (cleaner) or update the comment to reflect the real reason?
-
Fallback agent: Should we:
- A) Add initialization-time verification
- B) Document the limitation and keep as-is
- C) Allow users to disable fallback behavior
-
MCP version: Worth updating all 3 instances, or leave as cosmetic debt?