feat: Claude usage API + multi-account dashboard display
- Replace expect/CLI hack with direct HTTP API call (GET api.anthropic.com/api/oauth/usage with OAuth token) - Add fetchAllClaudeUsage() for per-token usage fetching - Export getAllTokens() from token-rotation for usage queries - Dashboard shows each account separately (Claude1⚡, Claude2) with ⚡ for active token, 🚫 for rate-limited
This commit is contained in:
@@ -1,53 +1,28 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { parseClaudeUsagePanel } from './claude-usage.js';
|
||||
import type { ClaudeUsageData } from './claude-usage.js';
|
||||
|
||||
describe('parseClaudeUsagePanel', () => {
|
||||
it('parses session and weekly usage from Claude CLI panel output', () => {
|
||||
const sample = `
|
||||
Settings: Status Config Usage
|
||||
Loading usage data...
|
||||
describe('ClaudeUsageData', () => {
|
||||
it('represents the API response structure correctly', () => {
|
||||
const data: ClaudeUsageData = {
|
||||
five_hour: { utilization: 45.2, resets_at: '2026-03-23T17:00:00Z' },
|
||||
seven_day: { utilization: 72.1, resets_at: '2026-03-29T00:00:00Z' },
|
||||
seven_day_sonnet: { utilization: 60.0, resets_at: '2026-03-29T00:00:00Z' },
|
||||
seven_day_opus: { utilization: 80.0, resets_at: '2026-03-29T00:00:00Z' },
|
||||
};
|
||||
|
||||
Current session
|
||||
████ 4% used
|
||||
Resets in 8m (Asia/Seoul)
|
||||
|
||||
Current week (all models)
|
||||
███████████████████████████████████████ 78% used
|
||||
Resets Mar 17 at 10pm (Asia/Seoul)
|
||||
|
||||
Current week (Sonnet only)
|
||||
███ 6% used
|
||||
Resets Mar 17 at 11pm (Asia/Seoul)
|
||||
|
||||
Extra usage
|
||||
Extra usage not enabled • /extra-usage to enable
|
||||
`;
|
||||
|
||||
expect(parseClaudeUsagePanel(sample)).toEqual({
|
||||
five_hour: {
|
||||
utilization: 4,
|
||||
resets_at: 'Resets in 8m (Asia/Seoul)',
|
||||
},
|
||||
seven_day: {
|
||||
utilization: 78,
|
||||
resets_at: 'Resets Mar 17 at 10pm (Asia/Seoul)',
|
||||
},
|
||||
});
|
||||
expect(data.five_hour?.utilization).toBe(45.2);
|
||||
expect(data.seven_day?.utilization).toBe(72.1);
|
||||
expect(data.seven_day_sonnet?.utilization).toBe(60.0);
|
||||
expect(data.seven_day_opus?.utilization).toBe(80.0);
|
||||
});
|
||||
|
||||
it('converts percent left into used percent', () => {
|
||||
const sample = `
|
||||
Current session
|
||||
60% left
|
||||
Resets in 1h
|
||||
`;
|
||||
it('allows partial data (only five_hour)', () => {
|
||||
const data: ClaudeUsageData = {
|
||||
five_hour: { utilization: 10, resets_at: '2026-03-23T17:00:00Z' },
|
||||
};
|
||||
|
||||
expect(parseClaudeUsagePanel(sample)).toEqual({
|
||||
five_hour: {
|
||||
utilization: 40,
|
||||
resets_at: 'Resets in 1h',
|
||||
},
|
||||
});
|
||||
expect(data.five_hour?.utilization).toBe(10);
|
||||
expect(data.seven_day).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user