#!/usr/bin/env node // ponytail — shared configuration resolver // // Resolution order for default mode: // 1. PONYTAIL_DEFAULT_MODE environment variable // 2. Config file defaultMode field: // - $XDG_CONFIG_HOME/ponytail/config.json (any platform, if set) // - ~/.config/ponytail/config.json (macOS / Linux fallback) // - %APPDATA%\ponytail\config.json (Windows fallback) // 3. 'full' const fs = require('fs'); const path = require('path'); const os = require('os'); const DEFAULT_MODE = 'full'; const VALID_MODES = ['off', 'lite', 'full', 'ultra', 'review']; const RUNTIME_MODES = ['off', 'lite', 'full', 'ultra']; function normalizeMode(mode) { if (typeof mode !== 'string') return null; const normalized = mode.trim().toLowerCase(); return RUNTIME_MODES.includes(normalized) ? normalized : null; } function normalizeConfigMode(mode) { if (typeof mode !== 'string') return null; const normalized = mode.trim().toLowerCase(); return VALID_MODES.includes(normalized) ? normalized : null; } function normalizePersistedMode(mode) { return normalizeMode(mode) || normalizeConfigMode(mode); } function getConfigDir() { if (process.env.XDG_CONFIG_HOME) { return path.join(process.env.XDG_CONFIG_HOME, 'ponytail'); } if (process.platform === 'win32') { return path.join( process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), 'ponytail' ); } return path.join(os.homedir(), '.config', 'ponytail'); } function getConfigPath() { return path.join(getConfigDir(), 'config.json'); } function getClaudeDir() { // ponytail: CLAUDE_CONFIG_DIR overrides ~/.claude, matching Claude Code. return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude'); } function getDefaultMode() { // 1. Environment variable (highest priority) const envMode = process.env.PONYTAIL_DEFAULT_MODE; if (envMode && VALID_MODES.includes(envMode.toLowerCase())) { return envMode.toLowerCase(); } // 2. Config file try { const configPath = getConfigPath(); const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); if (config.defaultMode && VALID_MODES.includes(config.defaultMode.toLowerCase())) { return config.defaultMode.toLowerCase(); } } catch (e) { // Config file doesn't exist or is invalid — fall through } // 3. Default return DEFAULT_MODE; } function writeDefaultMode(mode) { const normalized = normalizeConfigMode(mode); if (!normalized) return null; const configPath = getConfigPath(); fs.mkdirSync(path.dirname(configPath), { recursive: true }); fs.writeFileSync(configPath, JSON.stringify({ defaultMode: normalized }, null, 2), 'utf8'); return normalized; } module.exports = { DEFAULT_MODE, VALID_MODES, RUNTIME_MODES, getDefaultMode, getConfigDir, getConfigPath, getClaudeDir, normalizeMode, normalizeConfigMode, normalizePersistedMode, writeDefaultMode, };