The command-center token endpoint accepts groupBy=task, but the
dimension was never wired through: TokenGroupBy did not include "task",
groupKeyFor had no task case, VALID_GROUP_BY rejected it, and
groupAttributes emitted no attribute. As a result groupBy=task silently
fell back to ungrouped totals — the per-task rollup returned zero groups
even though tasks.tokenUsage* is populated per task.
Thread "task" through all four enumeration sites (the union type makes
the two switches compiler-exhaustive). Task rows group by task id; chat
rows have no task and return null, mirroring the existing node case.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>