refactor: land PATHFINDER Plan 07 — dead code sweep

ts-prune-driven sweep across the tree after Plans 01-06 landed.
Deleted unused exports, orphan helpers, and one fully orphaned
file. Earlier-plan deletions verified.

Deleted:
- src/utils/bun-path.ts (entire file — getBunPath, getBunPathOrThrow,
  isBunAvailable: zero importers)
- bun-resolver.getBunVersionString: zero callers
- PendingMessageStore.retryMessage / resetProcessingToPending /
  abortMessage: superseded by transitionMessagesTo (Plan 06 Phase 9)
- EnvManager.MANAGED_CREDENTIAL_KEYS, EnvManager.setCredential:
  zero callers
- CodexCliInstaller.checkCodexCliStatus: zero callers; no status
  command exists in npx-cli
- Two "REMOVED: cleanupOrphanedSessions" stale-fence comments

Kept (with documented justification):
- Public API surface in dist/sdk/* (parseAgentXml, prompt
  builders, ParsedObservation, ParsedSummary, ParseResult,
  SUMMARY_MODE_MARKER) — exported via package.json sdk path.
- generateContext / loadContextConfig / token utilities — used
  via dynamic await import('../../../context-generator.js') in
  worker SearchRoutes.
- MCP_IDE_INSTALLERS, install/uninstall functions for codex/goose
  — used via dynamic await import in npx-cli/install.ts +
  uninstall.ts (ts-prune cannot trace dynamic imports).
- getExistingChromaIds — active caller in
  ChromaSync.backfillMissingSyncs (Plan 04 narrowed scope).
- processPendingQueues / getSessionsWithPendingMessages — active
  orphan-recovery caller in worker-service.ts plus
  zombie-prevention test coverage.
- StoreAndMarkCompleteResult legacy alias — return-type annotation
  in same file.
- All Database.ts barrel re-exports — used downstream.

Earlier-plan verification:
- Plan 03 Phase 9: VERIFIED — src/utils/transcript-parser.ts
  is gone; TranscriptParser has 0 references in src/.
- Plan 01 Phase 8: VERIFIED — migration 19 no-op absorbed.
- SessionStore.ts:52-70 consolidation NOT executed (deferred):
  the methods are not thin wrappers but ~900 LoC of bodies, and
  two methods are documented as intentional mirrors so the
  context-generator.cjs bundle stays schema-consistent without
  pulling MigrationRunner. Deserves its own plan, not a sweep.

Verification: TranscriptParser → 0; transcript-parser.ts → gone;
no commented-out code markers remain. bun run build succeeds.
bun test → 1393 pass / 28 fail / 7 skip — EXACT match to
baseline. Zero regressions.

Plan: PATHFINDER-2026-04-22/07-dead-code.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-23 03:10:58 -07:00
parent e7c03123d9
commit 89ec1cc35d
9 changed files with 3 additions and 253 deletions

View File

@@ -158,6 +158,7 @@
"tree-sitter-scss": "^1.0.0",
"tree-sitter-swift": "^0.7.1",
"tree-sitter-typescript": "^0.23.2",
"ts-prune": "^0.10.3",
"tsx": "^4.20.6",
"typescript": "^5.3.0"
},

View File

@@ -760,15 +760,7 @@ Please see the 3.x to 4.x migration guide for details on how to update your app.
SELECT * FROM pending_messages
WHERE session_db_id = ? AND status = 'pending'
ORDER BY id ASC
`).all(e)}retryMessage(e){return this.db.prepare(`
UPDATE pending_messages
SET status = 'pending', worker_pid = NULL
WHERE id = ? AND status IN ('pending', 'processing', 'failed')
`).run(e).changes>0}resetProcessingToPending(e){return this.db.prepare(`
UPDATE pending_messages
SET status = 'pending', worker_pid = NULL
WHERE session_db_id = ? AND status = 'processing'
`).run(e).changes}transitionMessagesTo(e,r){let n=Date.now(),s=e==="failed"?"status = 'processing'":"status IN ('pending', 'processing')";return r.sessionDbId===void 0?this.db.prepare(`
`).all(e)}transitionMessagesTo(e,r){let n=Date.now(),s=e==="failed"?"status = 'processing'":"status IN ('pending', 'processing')";return r.sessionDbId===void 0?this.db.prepare(`
UPDATE pending_messages
SET status = 'failed', failed_at_epoch = ?
WHERE ${s}
@@ -776,7 +768,7 @@ Please see the 3.x to 4.x migration guide for details on how to update your app.
UPDATE pending_messages
SET status = 'failed', failed_at_epoch = ?
WHERE session_db_id = ? AND ${s}
`).run(n,r.sessionDbId).changes}abortMessage(e){return this.db.prepare("DELETE FROM pending_messages WHERE id = ?").run(e).changes>0}markFailed(e){let r=Date.now(),n=this.db.prepare("SELECT retry_count FROM pending_messages WHERE id = ?").get(e);n&&(n.retry_count<this.maxRetries?this.db.prepare(`
`).run(n,r.sessionDbId).changes}markFailed(e){let r=Date.now(),n=this.db.prepare("SELECT retry_count FROM pending_messages WHERE id = ?").get(e);n&&(n.retry_count<this.maxRetries?this.db.prepare(`
UPDATE pending_messages
SET status = 'pending', retry_count = retry_count + 1, worker_pid = NULL
WHERE id = ?

View File

@@ -64,23 +64,3 @@ export function resolveBunBinaryPath(): string | null {
return null;
}
/**
* Get the installed Bun version string (e.g. `"1.2.3"`), or `null`
* if Bun is not available.
*/
export function getBunVersionString(): string | null {
const bunPath = resolveBunBinaryPath();
if (!bunPath) return null;
try {
const result = spawnSync(bunPath, ['--version'], {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
shell: IS_WINDOWS,
});
return result.status === 0 ? result.stdout.trim() : null;
} catch (error: unknown) {
console.error('[bun-resolver] Failed to get Bun version:', error instanceof Error ? error.message : String(error));
return null;
}
}

View File

@@ -281,83 +281,3 @@ export function uninstallCodexCli(): number {
return 0;
}
// ---------------------------------------------------------------------------
// Public API: Status Check
// ---------------------------------------------------------------------------
/**
* Check Codex CLI integration status.
*
* @returns 0 always (informational)
*/
export function checkCodexCliStatus(): number {
console.log('\nClaude-Mem Codex CLI Integration Status\n');
// Check transcript-watch.json
if (!existsSync(DEFAULT_CONFIG_PATH)) {
console.log('Status: Not installed');
console.log(` No transcript watch config at ${DEFAULT_CONFIG_PATH}`);
console.log('\nRun: npx claude-mem install --ide codex-cli\n');
return 0;
}
let config: TranscriptWatchConfig;
try {
config = loadExistingTranscriptWatchConfig();
} catch (error) {
if (error instanceof Error) {
logger.error('WORKER', 'Could not parse transcript-watch.json', { path: DEFAULT_CONFIG_PATH }, error);
} else {
logger.error('WORKER', 'Could not parse transcript-watch.json', { path: DEFAULT_CONFIG_PATH }, new Error(String(error)));
}
console.log('Status: Unknown');
console.log(' Could not parse transcript-watch.json.');
console.log('');
return 0;
}
const codexWatch = config.watches.find(
(w: WatchTarget) => w.name === CODEX_WATCH_NAME,
);
const codexSchema = config.schemas?.[CODEX_WATCH_NAME];
if (!codexWatch) {
console.log('Status: Not installed');
console.log(' transcript-watch.json exists but no codex watch configured.');
console.log('\nRun: npx claude-mem install --ide codex-cli\n');
return 0;
}
console.log('Status: Installed');
console.log(` Config: ${DEFAULT_CONFIG_PATH}`);
console.log(` Watch path: ${codexWatch.path}`);
console.log(` Schema: ${codexSchema ? `codex (v${codexSchema.version ?? '?'})` : 'missing'}`);
console.log(` Start at end: ${codexWatch.startAtEnd ?? false}`);
if (codexWatch.context) {
console.log(` Context mode: ${codexWatch.context.mode}`);
console.log(` Context path: ${codexWatch.context.path ?? '<workspace>/AGENTS.md (default)'}`);
console.log(` Context updates on: ${codexWatch.context.updateOn?.join(', ') ?? 'none'}`);
}
if (existsSync(CODEX_AGENTS_MD_PATH)) {
const mdContent = readFileSync(CODEX_AGENTS_MD_PATH, 'utf-8');
if (mdContent.includes('<claude-mem-context>')) {
console.log(` Legacy global context: Present (${CODEX_AGENTS_MD_PATH})`);
} else {
console.log(` Legacy global context: Not active`);
}
} else {
console.log(` Legacy global context: None`);
}
const sessionsDir = path.join(CODEX_DIR, 'sessions');
if (existsSync(sessionsDir)) {
console.log(` Sessions directory: exists`);
} else {
console.log(` Sessions directory: not yet created (use Codex CLI to generate sessions)`);
}
console.log('');
return 0;
}

View File

@@ -236,34 +236,6 @@ export class PendingMessageStore {
return stmt.all(sessionDbId) as PersistentPendingMessage[];
}
/**
* Retry a specific message (reset to pending)
* Works for pending (re-queue), processing (reset stuck), and failed messages
*/
retryMessage(messageId: number): boolean {
const stmt = this.db.prepare(`
UPDATE pending_messages
SET status = 'pending', worker_pid = NULL
WHERE id = ? AND status IN ('pending', 'processing', 'failed')
`);
const result = stmt.run(messageId);
return result.changes > 0;
}
/**
* Reset all processing messages for a session to pending
* Used when force-restarting a stuck session
*/
resetProcessingToPending(sessionDbId: number): number {
const stmt = this.db.prepare(`
UPDATE pending_messages
SET status = 'pending', worker_pid = NULL
WHERE session_db_id = ? AND status = 'processing'
`);
const result = stmt.run(sessionDbId);
return result.changes;
}
/**
* Transition pending_messages rows to a terminal status — PATHFINDER-2026-04-22
* Plan 06 Phase 9. One SQL UPDATE path, one place to add a new terminal status
@@ -313,15 +285,6 @@ export class PendingMessageStore {
return stmt.run(now, filter.sessionDbId).changes;
}
/**
* Abort a specific message (delete from queue)
*/
abortMessage(messageId: number): boolean {
const stmt = this.db.prepare('DELETE FROM pending_messages WHERE id = ?');
const result = stmt.run(messageId);
return result.changes > 0;
}
/**
* Mark message as failed (status: pending -> failed or back to pending for retry)
* If retry_count < maxRetries, moves back to 'pending' for retry

View File

@@ -2208,11 +2208,6 @@ export class SessionStore {
// REMOVED: cleanupOrphanedSessions - violates "EVERYTHING SHOULD SAVE ALWAYS"
// There's no such thing as an "orphaned" session. Sessions are created by hooks
// and managed by Claude Code's lifecycle. Worker restarts don't invalidate them.
// Marking all active sessions as 'failed' on startup destroys the user's current work.
/**
* Get session summaries by IDs (for hybrid Chroma search)
* Returns summaries in specified temporal order

View File

@@ -89,10 +89,6 @@ export class DatabaseManager {
return this.chromaSync;
}
// REMOVED: cleanupOrphanedSessions - violates "EVERYTHING SHOULD SAVE ALWAYS"
// Worker restarts don't make sessions orphaned. Sessions are managed by hooks
// and exist independently of worker state.
/**
* Get session by ID (throws if not found)
*/

View File

@@ -30,13 +30,6 @@ const BLOCKED_ENV_VARS = [
'CLAUDECODE', // Prevent "cannot be launched inside another Claude Code session" error
];
// Credential keys that claude-mem manages
export const MANAGED_CREDENTIAL_KEYS = [
'ANTHROPIC_API_KEY',
'GEMINI_API_KEY',
'OPENROUTER_API_KEY',
];
export interface ClaudeMemEnv {
// Credentials (optional - empty means use CLI billing for Claude)
ANTHROPIC_API_KEY?: string;
@@ -269,16 +262,6 @@ export function getCredential(key: keyof ClaudeMemEnv): string | undefined {
return env[key];
}
/**
* Set a specific credential in claude-mem's .env
* Pass empty string to remove the credential
*/
export function setCredential(key: keyof ClaudeMemEnv, value: string): void {
const env = loadClaudeMemEnv();
env[key] = value || undefined;
saveClaudeMemEnv(env);
}
/**
* Check if claude-mem has an Anthropic API key configured
* If false, it means CLI billing should be used

View File

@@ -1,80 +0,0 @@
/**
* Bun Path Utility
*
* Resolves the Bun executable path for environments where Bun is not in PATH
* (e.g., fish shell users where ~/.config/fish/config.fish isn't read by /bin/sh)
*/
import { spawnSync } from 'child_process';
import { existsSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
import { logger } from './logger.js';
/**
* Get the Bun executable path
* Tries PATH first, then checks common installation locations
* Returns absolute path if found, null otherwise
*/
export function getBunPath(): string | null {
const isWindows = process.platform === 'win32';
// Try PATH first
try {
const result = spawnSync('bun', ['--version'], {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
shell: false // SECURITY: No need for shell, bun is the executable
});
if (result.status === 0) {
return 'bun'; // Available in PATH
}
} catch (e) {
logger.debug('SYSTEM', 'Bun not found in PATH, checking common installation locations', {
error: e instanceof Error ? e.message : String(e)
});
}
// Check common installation paths
const bunPaths = isWindows
? [join(homedir(), '.bun', 'bin', 'bun.exe')]
: [
join(homedir(), '.bun', 'bin', 'bun'),
'/usr/local/bin/bun',
'/opt/homebrew/bin/bun', // Apple Silicon Homebrew
'/home/linuxbrew/.linuxbrew/bin/bun' // Linux Homebrew
];
for (const bunPath of bunPaths) {
if (existsSync(bunPath)) {
return bunPath;
}
}
return null;
}
/**
* Get the Bun executable path or throw an error
* Use this when Bun is required for operation
*/
export function getBunPathOrThrow(): string {
const bunPath = getBunPath();
if (!bunPath) {
const isWindows = process.platform === 'win32';
const installCmd = isWindows
? 'powershell -c "irm bun.sh/install.ps1 | iex"'
: 'curl -fsSL https://bun.sh/install | bash';
throw new Error(
`Bun is required but not found. Install it with:\n ${installCmd}\nThen restart your terminal.`
);
}
return bunPath;
}
/**
* Check if Bun is available (in PATH or common locations)
*/
export function isBunAvailable(): boolean {
return getBunPath() !== null;
}