UNPKG

@aicodewith/ccstatusline

Version:

AiCodeWith credits display plugin for Claude Code with customizable status line

128 lines (122 loc) 4 kB
import { createRequire } from 'module'; const require = createRequire(import.meta.url); // src/utils/claude-settings.ts import * as fs from "fs"; import * as path from "path"; import * as os from "os"; import { promisify } from "util"; var readFile2 = fs.promises?.readFile || promisify(fs.readFile); var writeFile2 = fs.promises?.writeFile || promisify(fs.writeFile); var mkdir2 = fs.promises?.mkdir || promisify(fs.mkdir); var CLAUDE_SETTINGS_PATH = path.join(os.homedir(), ".claude", "settings.json"); async function loadClaudeSettings() { try { if (!fs.existsSync(CLAUDE_SETTINGS_PATH)) { return {}; } const content = await readFile2(CLAUDE_SETTINGS_PATH, "utf-8"); return JSON.parse(content); } catch (error) { if (fs.existsSync(CLAUDE_SETTINGS_PATH)) { let rawContent = "[Unable to read file content]"; try { rawContent = await readFile2(CLAUDE_SETTINGS_PATH, "utf-8"); } catch { } throw new Error( `Failed to load Claude settings from ~/.claude/settings.json Error: ${error.message} Current file content: ${rawContent} Please fix the file manually or backup it before proceeding.` ); } return {}; } } async function saveClaudeSettings(settings) { const dir = path.dirname(CLAUDE_SETTINGS_PATH); await mkdir2(dir, { recursive: true }); await writeFile2(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2), "utf-8"); } async function isInstalled() { const settings = await loadClaudeSettings(); if (!settings.statusLine) return false; const command = settings.statusLine.command; const isNpmVersion = command === "npx -y @aicodewith/ccstatusline@latest" || command === "npx -y ccstatusline@latest"; const isLocalVersion = command.includes("ccstatusline.js") || command.includes("ccstatusline-main"); return (isNpmVersion || isLocalVersion) && (settings.statusLine.padding === 0 || settings.statusLine.padding === void 0); } async function installStatusLine() { let settings; try { settings = await loadClaudeSettings(); } catch (error) { throw error; } const isNpxRun = process.argv[1]?.includes("npm-cache") || process.argv[1]?.includes("_npx"); let command; if (isNpxRun) { command = "npx -y @aicodewith/ccstatusline@latest"; } else { const projectRoot = process.cwd(); const distPath = path.join(projectRoot, "dist", "ccstatusline.js"); if (!fs.existsSync(distPath)) { throw new Error(`Cannot find dist/ccstatusline.js in ${projectRoot}. Please run 'bun run build' or 'npm run build' first.`); } const absolutePath = path.resolve(distPath); command = `node "${absolutePath}"`; } settings.statusLine = { type: "command", command, padding: 0 }; try { await saveClaudeSettings(settings); } catch (saveError) { const configToSave = JSON.stringify(settings, null, 2); throw new Error( `Failed to save settings: ${saveError.message} You can manually save this to ~/.claude/settings.json: ---------------------------------------- ${configToSave} ----------------------------------------` ); } } async function uninstallStatusLine() { let settings; try { settings = await loadClaudeSettings(); } catch (error) { throw error; } if (settings.statusLine) { delete settings.statusLine; try { await saveClaudeSettings(settings); } catch (saveError) { const configToSave = JSON.stringify(settings, null, 2); throw new Error( `Failed to save settings: ${saveError.message} You can manually save this to ~/.claude/settings.json: ---------------------------------------- ${configToSave} ----------------------------------------` ); } } } async function getExistingStatusLine() { const settings = await loadClaudeSettings(); return settings.statusLine?.command || null; } export { getExistingStatusLine, installStatusLine, isInstalled, loadClaudeSettings, saveClaudeSettings, uninstallStatusLine };