UNPKG

claude-statusline-powerline

Version:

Beautiful powerline-style statusline for Claude Code with git integration, session tracking, and cost monitoring

104 lines 4.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OrgSegment = void 0; const token_formatting_1 = require("../utils/token-formatting"); const base_1 = require("./base"); class OrgSegment extends base_1.BaseSegment { constructor() { super(...arguments); this.name = 'org'; this.priority = 35; // Between session (40) and git (30) this.cache = null; this.cache_expiry = null; this.cache_duration_ms = 5 * 60 * 1000; // 5 minutes this.fetch_initiated = false; } build(data, config) { // Check if admin API key is available via environment variable const admin_api_key = process.env.ANTHROPIC_ADMIN_KEY; if (!admin_api_key) { return null; // Hide segment if no API key configured } // Use cached data if available and not expired if (this.cache && this.cache_expiry && new Date() < this.cache_expiry) { return this.render_segment(this.cache, config); } // Try to fetch fresh data (async, won't block rendering) if (!this.fetch_initiated) { this.fetch_initiated = true; this.fetch_usage_data(admin_api_key).catch(() => { // Silently fail - segment will be hidden on error }); } // Return cached data if available, otherwise show loading state if (this.cache) { return this.render_segment(this.cache, config); } // Show loading indicator on first run return this.render_loading_segment(config); } render_segment(usage, config) { const total_tokens = usage.total_input_tokens + usage.total_output_tokens; const cost_str = usage.total_cost < 0.01 ? '< $0.01' : `$${usage.total_cost.toFixed(2)}`; const { style_override, get_icon } = this.setup_segment(config); const theme = config.current_theme?.segments.org; const org_icon = get_icon('organization'); const content = `${org_icon} ${(0, token_formatting_1.format_tokens)(total_tokens)}${cost_str} ${usage.period}`; return this.create_segment_with_fallback(content, theme, 'org', config.separators.org, style_override); } render_loading_segment(config) { const { style_override, get_icon } = this.setup_segment(config); const theme = config.current_theme?.segments.org; const org_icon = get_icon('organization'); const content = `${org_icon} Loading...`; return this.create_segment_with_fallback(content, theme, 'org', config.separators.org, style_override); } async fetch_usage_data(admin_api_key) { try { // Get usage for last 24 hours const starting_at = new Date(Date.now() - 24 * 60 * 60 * 1000); const iso_date = starting_at.toISOString(); const response = await fetch(`https://api.anthropic.com/v1/organizations/usage_report/messages?starting_at=${iso_date}&group_by[]=model`, { headers: { 'x-api-key': admin_api_key, 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01', }, }); if (!response.ok) { throw new Error(`API request failed: ${response.status}`); } const data = await response.json(); // Aggregate usage across all models let total_input_tokens = 0; let total_output_tokens = 0; for (const entry of data.data) { total_input_tokens += entry.input_tokens || 0; total_output_tokens += entry.output_tokens || 0; } // Estimate cost using average pricing (simplified for now) const avg_input_rate = 3; // per million tokens const avg_output_rate = 15; // per million tokens const input_cost = (total_input_tokens / 1000000) * avg_input_rate; const output_cost = (total_output_tokens / 1000000) * avg_output_rate; const total_cost = input_cost + output_cost; // Update cache this.cache = { total_input_tokens, total_output_tokens, total_cost, period: '24h', last_updated: new Date(), }; this.cache_expiry = new Date(Date.now() + this.cache_duration_ms); } catch (error) { // Silently fail - cache remains unchanged console.error('Failed to fetch organizational usage:', error); } } } exports.OrgSegment = OrgSegment; //# sourceMappingURL=org.js.map