Introduce a client for fetching subscription data from the claude.ai web
API, enabling rate-limit monitoring and overage tracking in the dashboard.
New package internal/claudeai:
- Client authenticates via session cookie (sk-ant-sid... prefix validated)
- FetchAll() retrieves orgs, usage windows, and overage in one call,
returning partial data when individual requests fail
- FetchOrganizations/FetchUsage/FetchOverageLimit for granular access
- Defensive utilization parsing handles polymorphic API responses: int
(75), float (0.75 or 75.0), and string ("75%" or "0.75"), normalizing
all to 0.0-1.0 range
- 10s request timeout, 1MB body limit, proper status code handling
(401/403 -> ErrUnauthorized, 429 -> ErrRateLimited)
Types (claudeai/types.go):
- Organization, UsageResponse, UsageWindow (raw), OverageLimit
- SubscriptionData (TUI-ready aggregate), ParsedUsage, ParsedWindow
Config changes (config/config.go):
- Add ClaudeAIConfig struct with session_key and org_id fields
- Add GetSessionKey() with CLAUDE_SESSION_KEY env var fallback
- Fix directory permissions 0o755 -> 0o750 (gosec G301)
- Fix Save() to propagate encoder errors before closing file
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package claudeai
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// Organization represents a claude.ai organization.
|
|
type Organization struct {
|
|
UUID string `json:"uuid"`
|
|
Name string `json:"name"`
|
|
Capabilities []string `json:"capabilities"`
|
|
}
|
|
|
|
// UsageResponse is the raw API response from the usage endpoint.
|
|
type UsageResponse struct {
|
|
FiveHour *UsageWindow `json:"five_hour"`
|
|
SevenDay *UsageWindow `json:"seven_day"`
|
|
SevenDayOpus *UsageWindow `json:"seven_day_opus"`
|
|
SevenDaySonnet *UsageWindow `json:"seven_day_sonnet"`
|
|
}
|
|
|
|
// UsageWindow is a single rate-limit window from the API.
|
|
// Utilization can be int, float, or string — kept as raw JSON for defensive parsing.
|
|
type UsageWindow struct {
|
|
Utilization json.RawMessage `json:"utilization"`
|
|
ResetsAt *string `json:"resets_at"`
|
|
}
|
|
|
|
// OverageLimit is the raw API response from the overage spend limit endpoint.
|
|
type OverageLimit struct {
|
|
IsEnabled bool `json:"isEnabled"`
|
|
UsedCredits float64 `json:"usedCredits"`
|
|
MonthlyCreditLimit float64 `json:"monthlyCreditLimit"`
|
|
Currency string `json:"currency"`
|
|
}
|
|
|
|
// SubscriptionData is the parsed, TUI-ready aggregate of all claude.ai API data.
|
|
type SubscriptionData struct {
|
|
Org Organization
|
|
Usage *ParsedUsage
|
|
Overage *OverageLimit
|
|
FetchedAt time.Time
|
|
Error error
|
|
}
|
|
|
|
// ParsedUsage holds normalized usage windows.
|
|
type ParsedUsage struct {
|
|
FiveHour *ParsedWindow
|
|
SevenDay *ParsedWindow
|
|
SevenDayOpus *ParsedWindow
|
|
SevenDaySonnet *ParsedWindow
|
|
}
|
|
|
|
// ParsedWindow is a single rate-limit window, normalized for display.
|
|
type ParsedWindow struct {
|
|
Pct float64 // 0.0-1.0
|
|
ResetsAt time.Time
|
|
}
|