feat(operations): show real claude.ai subscription usage % on /operations
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
Surfaces the 5-hour / weekly / weekly-Opus utilization the Claude Code status bar shows — the authoritative number, not a token estimate. Design approved via the Claude Design gate (card 02c-operations-usage.html). Three layers: - court-fetch-service (host bridge): new GET /usage reads the OAuth token from ~/.claude/.credentials.json and proxies /api/oauth/usage with the required claude-code User-Agent. Read-only, no auth (like /pm2). Host-only — the token never enters the container. - web/app.py: _ops_subscription_usage() proxies the bridge /usage; the /api/operations snapshot gains a `subscription_usage` field (null when the undocumented endpoint is unreachable). - web-ui: SubscriptionUsagePanel renders three meters (label · % · bar · reset) at the top of /operations; bar turns amber >75% / red >90%; hidden when usage is null. Types added to operations.ts (hand-maintained snapshot type). Also fixes a pre-existing react/no-unescaped-entities lint error in learning-panel.tsx (escaped a `"` in Hebrew text — renders identically). tsc --noEmit passes; lint error count 0. (Full next build is blocked only by the manual-worktree node_modules symlink — the Docker build has real node_modules.) Invariants: G2 (usage surfaced through the existing host bridge + /api/operations snapshot — no parallel control path). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,9 +42,26 @@ export type PipelineStats = {
|
||||
by_status: Record<string, number>; // raw counts, for the curious
|
||||
};
|
||||
|
||||
/** One claude.ai usage window (5-hour / weekly / weekly-per-model). */
|
||||
export type UsageWindow = {
|
||||
utilization: number | null; // 0-100; null when the window is inactive
|
||||
resets_at: string | null;
|
||||
};
|
||||
|
||||
/** claude.ai subscription usage — the same %s the Claude Code status bar shows,
|
||||
* via the (undocumented) OAuth usage endpoint proxied by the host bridge.
|
||||
* null when the endpoint is unreachable. */
|
||||
export type SubscriptionUsage = {
|
||||
five_hour?: UsageWindow | null;
|
||||
seven_day?: UsageWindow | null;
|
||||
seven_day_opus?: UsageWindow | null;
|
||||
seven_day_sonnet?: UsageWindow | null;
|
||||
} | null;
|
||||
|
||||
export type OperationsSnapshot = {
|
||||
services: OpsService[];
|
||||
services_error: string | null;
|
||||
subscription_usage: SubscriptionUsage;
|
||||
pipelines: {
|
||||
court_fetch: PipelineStats & { recent: CourtFetchJob[] };
|
||||
metadata_extraction: PipelineStats;
|
||||
|
||||
Reference in New Issue
Block a user