#!/usr/bin/env node import { spawnSync, spawn } from 'child_process'; import { existsSync, readFileSync, mkdirSync, appendFileSync, writeFileSync } from 'fs'; import { join, dirname, resolve } from 'path'; import { homedir } from 'os'; import { fileURLToPath } from 'url'; const IS_WINDOWS = process.platform === 'win32'; const __bun_runner_dirname = dirname(fileURLToPath(import.meta.url)); const RESOLVED_PLUGIN_ROOT = process.env.CLAUDE_PLUGIN_ROOT || resolve(__bun_runner_dirname, '..'); function fixBrokenScriptPath(argPath) { if (argPath.startsWith('/scripts/') && !existsSync(argPath)) { const fixedPath = join(RESOLVED_PLUGIN_ROOT, argPath); if (existsSync(fixedPath)) { return fixedPath; } } return argPath; } function findBun() { const pathCheck = IS_WINDOWS ? spawnSync('where bun', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], shell: true }) : spawnSync('which', ['bun'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }); if (pathCheck.status === 0 && pathCheck.stdout.trim()) { if (IS_WINDOWS) { const bunCmdPath = pathCheck.stdout.split('\n').find(line => line.trim().endsWith('bun.cmd')); if (bunCmdPath) { return bunCmdPath.trim(); } } return 'bun'; } const bunPaths = IS_WINDOWS ? [join(homedir(), '.bun', 'bin', 'bun.exe')] : [ join(homedir(), '.bun', 'bin', 'bun'), '/usr/local/bin/bun', '/opt/homebrew/bin/bun', '/home/linuxbrew/.linuxbrew/bin/bun' ]; for (const bunPath of bunPaths) { if (existsSync(bunPath)) { return bunPath; } } return null; } function isPluginDisabledInClaudeSettings() { try { const configDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude'); const settingsPath = join(configDir, 'settings.json'); if (!existsSync(settingsPath)) return false; const settings = JSON.parse(readFileSync(settingsPath, 'utf-8')); return settings?.enabledPlugins?.['claude-mem@thedotmack'] === false; } catch { return false; } } if (isPluginDisabledInClaudeSettings()) { process.exit(0); } const args = process.argv.slice(2); if (args.length === 0) { console.error('Usage: node bun-runner.js