Repository navigation
v0.3.0 — private reports + WCL resilience
Highlights
Private and guild-stealth reports actually work now
v0.2.0 routed authenticated traffic to /api/v2/user, but the typed encounter analytics still parsed the legacy report.table.entries shape. Live WCL responses use report.table.data.entries (and data.auras for buffs), so report-encounter-damage-source-summary, report-encounter-damage-target-summary, report-encounter-damage-breakdown, and report-encounter-aura-summary were silently returning zero rows on real reports despite passing the fixtures. The parser now drills into the data wrapper and the aura/damage commands return populated rows end-to-end against private reports the user has access to.
view-private-reports is now first-class alongside view-user-profile. auth login, auth pkce-login, auth status, auth token, and doctor decode the access token's JWT body to surface scopes.has_view_private_reports, and the scope_warning message walks you through what to re-auth for. WCL's token response omits the granted-scope list, so reading the JWT is the only reliable way to know what the user actually has — the CLI now uses it.
Tolerant partial-error handling for flaky WCL responses
WCL occasionally returns { "data": ..., "errors": [...] } partials — a non-nullable nested field errors out, the resolver nulls it, and the rest of the payload still resolves. Previously the client raised graphql_error and discarded the otherwise-good payload. Now the client tolerates partial errors with a recursive useful-data check: if any leaf value (or a non-empty list) is populated at any depth, the response flows through with the error list captured as last_warnings. If every leaf is null, the original GraphQL error is raised so users see the real failure rather than a misleading not_found.
Every WCL command surfaces those warnings as notes and graphql_warnings in its JSON output via a centralized _emit(client=client) path, so partial-failure context is no longer hidden from agents that script against the CLI.
Null GraphQL variables are dropped at the wire
WCL's GraphQL endpoint rejects null variable values with Internal server error instead of treating them as omitted. character-rankings ... --spec-name <slug> and similar flag-driven calls were 500'ing whenever the user left an optional flag unset and another was provided. The client now prunes None from the request body before posting, matching WCL's documented behavior of falling back to defaults for omitted variables. Cache keys use the pruned variable set so cache identity stays stable across null/omitted callers.
GuildAttendance no longer trips on Zone.frozen
Zone.frozen was the upstream field nulling out for real guilds (e.g. gn / us-malganis) and tripping the partial-error path. The query no longer selects it; pagination, rosters, and zone identity continue to flow.
report-events hint when a slice resolves to null
When a narrowed slice still returns events.data: null, the CLI now appends a hint that WCL needs --data-type (e.g. casts, damage-done, healing) for non-null event slices. Previously it surfaced a bare null with no indication of the missing flag.
Upgrading
pip install -U -e '.[dev]'
warcraftlogs auth login --scope view-user-profile --scope view-private-reports --redirect-uri http://localhost:8787/callback
Existing tokens issued without view-private-reports continue to work for public queries — auth status will report the missing scope so you know to re-auth before reaching for private data.
Full changelog
- #8 — Unblock private/guild-stealth report access end-to-end
- #9 — Tolerate WCL partial GraphQL errors and prune null variables
🤖 Reviewed by Codex across 4 iterations until clean.