繁體中文

新功能

Grok CLI 也有自己的用量狀態列了

Grok CLI 支援跟 Claude Code 一樣的狀態列(statusLine,顯示在終端機最底下的資訊列)機制,所以 usage_statusline_grok.py 加進了既有的安裝/移除/自癒流程,用的是本來就跟 Claude Code 和 Antigravity 共用的那個開關。Grok 從標準輸入送進來的資料裡沒有用量摘要,官方文件明講了,所以腳本改去讀 ~/.grok/logs/unified.jsonl 裡的 creditUsagePercent 與 currentPeriod.end;兩者都讀不到就整段不顯示,不會印出佔位符號。只顯示週的軸線。Grok 沒有 5 小時視窗,也不回報快取命中率,兩者都不會拿去推估。

新功能

狀態列第二行看得到快取命中率與到期倒數

Claude Code 2.1.251 在狀態列掛鉤從標準輸入收到的資料裡加了一個 prompt_cache 物件,usage 本來就把整包資料存進 usage-status.json,只是沒去讀它。現在第二行會顯示快取(cache,把算過的結果暫存起來直接用)命中率與到期倒數。新的 color_by_pct_inverted() 把配色門檻反過來,91% 的命中率讀起來是好事,不會借用額度那套紅色。caching_observed 不是 True 或比率讀不到時整段跳過,舊版 Claude Code 就安靜地不顯示;expires_at 過期只掉倒數、留下長條。終端機太窄還會再降兩級:先拿掉倒數,再整段收起來。

新功能

狀態列只把數字點亮,其餘壓暗

空的進度格、脈絡視窗總量和 | 分隔線以前都是純白,比數字本身還亮。現在它們改成灰 240/暗色,用量成為唯一被點亮的元素。第二行是次要資訊,所以快取命中率在 80% 以上時採用那一行的靜音紫,低於 80% 才轉橘、低於 50% 才轉紅——好消息不需要發光。同一批也調了快取倒數的措辭:原本是把冷熱狀態直譯出來,讀起來沒有明確意思,現在改用既有的 remaining_prefix,英文顯示成 (59min left),跟前面兩段的 5 小時與 7 天寫法一致。只用在一個地方的 cache_cold_suffix 被移除,五種語言不必再各自為它想一個詞。

問題修復

別人的同名狀態列腳本不再被當成自己的接管

判斷一個掛鉤是不是自家的,以前靠 "usage-statusline" in cmd 這種部分比對,所以別人的 usage-statusline-pro.py 被當成 usage 裝的:沒備份就被接管,解除安裝時連他的設定一起刪掉。現在比對完整檔名,這個名字從 HOOK_TARGET.name 與同層檔案推出來,不再寫死字串,並要求名字兩側是路徑分隔符號、引號、空白或字串邊界。它刻意不比對完整路徑——指令字串會隨直譯器位置、引號寫法和 Windows 的反斜線改變,拿路徑比對反而會讓 usage 認不出自己。

問題修復

狀態列的檔案鎖改成等一段時間就放行

你每送出一則訊息,狀態列就卡住不動——因為有另一個處理程序抓著同一把鎖不放。_exclusive_lock() 的 POSIX 分支用的是 flock(LOCK_EX),會一直等下去;Windows 分支早就有 10 秒的 _LOCK_TIMEOUT_S 保護。現在 POSIX 分支改用 LOCK_EX | LOCK_NB 輪詢,等超時就走 msvcrt 那條路:不拿鎖,直接做原子寫入。

新功能

已安裝的狀態列副本真的會跟著更新了

needs_update() 拿 ~/.claude/usage-statusline.py 裡的 __version__ 跟 HOOK_VERSION 比,兩邊一樣就跳過複製。所以出貨時沒有跟著調版本號的畫面改動,永遠傳不到你已安裝的那份副本,而且過程無聲無息、不報任何錯。現在兩個常數都調高了,也補上一個偏移測試——Token Saver 掛鉤本來就有這道防護,只有狀態列漏了。

新功能

報表多了一項「一次過關率」,各模型分開比

報表的使用習慣區塊新增一張卡,量的是這段期間你有多少比例的回合沒被打斷、也沒有被擋下的工具呼叫,並依模型分開列。這是品質面向,不是又一個額度數字。兩個訊號都從 ~/.claude/projects 讀出來:使用者那幾行的 interruptedMessageId,以及 tool_result 裡的權限拒絕字串,沒有任何語意上的推測。分母取使用者回合而不是助理訊息,因為一次來回會吐出十來則助理訊息,會把每個模型壓到 99.5% 以上。同一回合裡多次打斷只算一次。<synthetic> 這類角括號標記排除在外。被打斷的助理訊息常常還沒寫進磁碟就中止,查不出歸屬的訊號進未歸屬桶、不顯示,不硬塞給某個模型。最高與最低模型差距超過 15 分時,才會寫出那句洞察。

新功能

報表加了逐日曲線,列印出來也讀得下去

報表標題早就寫著這段期間的高峰日,你卻沒有任何圖可以對照——daily_trend 裡放著 30 天的資料,沒有任何圖表用到它。現在週彙總上方多了一條逐日的面積線,標出最高的那一天,並且只標期間的第一天與最後一天。樣式表也加了一段 @media print:各區塊避免在內部斷頁、互動控制項隱藏、陰影與位移移除,顏色反轉成白底深字,這樣讀者開著深色模式時列印的 PDF 仍然讀得下去。

新功能

報表的表格、圖表與區塊層次都補上了

最重的五個工作階段本來是報表裡唯一純文字的表格,現在權杖那一欄多了一條細長條,比例以這五個裡最大的為基準,顏色沿用模型表格那套供應商配色。作息時段圖以前只有小時標籤,現在會在右下角用低調的字標出尖峰值,沒有另外加格線或 Y 軸。十個區塊本來長得一模一樣,現在洞察與熱圖採用較重的陰影,近期工作與工具兩區則較輕、用 --faint 邊框——只動陰影與邊框,因為人物誌那區放了兩張卡,改背景會讓它們的高度差變得刺眼。

新功能

報表的專案與模型列多了佔比條

十列疊在一起比較時,以前只能一個個讀數字。現在每個名稱下方有一條 4px 的實心比例條——選實心而不是漸層,免得顏色被誤讀成帶有其他意思。甜甜圈的「其他」那一塊以前畫的是配色裡的第七個顏色,看起來跟第一個綠色幾乎一樣;現在改成中性的 #8b8577,並且在 _donut_svg 裡由一個合成旗標挑出來,不再靠它排第幾個去猜。

問題修復

還沒過完的一週不再拿去跟完整的一週比

週趨勢以前拿還沒過完的本週跟上一整週比,在 2026-08-31 那個星期一就產出「W36 ↘ −97%」,結論說本週輕了 97%。現在最後一週的星期日若落在 date_to 之後就標成進行中(新的 trend_week_in_progress 鍵,五語都加了),不顯示百分比,而 _trend_summary() 改比最近兩個完整的週。

問題修復

Antigravity 的模型名不再兩種語言混寫,選單列標題也縮短

Antigravity 的 display_name 結尾本來就帶英文的強度後綴,例如 (High),usage 又在後面接一個在地化的,同一個層級被寫了兩次、兩種語言。現在英文後綴會被拿掉,只留在地化的標籤;display_name 裡沒有強度欄位時,被拿掉的那個後綴就成為來源。選單列標題也收緊了:間隔號拿掉,因為供應商圖示本來就把數字分開了,圖示間距也縮成兩個空格。另外,五份 README 都在即時可見度那節補上快取健康度的說明,註明它需要 Claude Code 2.1.251 或更新版本;網站上關於 AI Tool Update Digest 的描述也移除了,那個報表區塊已經不存在。

新功能

移除時會把 Grok 原本的狀態列放回去

unsetup() 以前只處理 Claude Code 和 Codex,跳過了 Grok。所以你跑完 --unsetup 之後,~/.grok/config.toml 還指著一支 usage 的腳本,而且沒有任何正規方式回到你自己原本的 [ui.status_line]。這個情況現在修好了,移除時會把 Grok 原本的狀態列還原。會漏掉是因為舊的測試只走私有的 _unsetup_grok(),新的測試改從公開的 unsetup() 進去。

新功能

週燃燒趨勢的長條改用 CSS 漸層畫

同一頁上的甜甜圈、熱圖與作息時段圖都是畫出來的圖形,只有週趨勢的長條是用 █ 這個字元排出來的,看起來像另一份文件貼過來的。現在這些長條改用 CSS 漸層繪製。四欄的版面與終端機風格都沒變,只是繪製的程式碼搬進新的 ui/report_charts.py。

問題修復

熱圖不再漏標月份,甜甜圈的百分比跟表格對得上

熱圖每一欄的月份以前就是從星期一取的,跨月的那一週被算給它幾乎沒沾到的舊月份,而被間距規則壓下去的標籤還會永久消失——真實輸出整個掉了九月。現在月份改從該欄的星期四讀出來,並跟上一個真正標出來的月份比對,被壓掉的月份會在下一個符合間距的欄位重新出現。另外,專案甜甜圈以前拿前十個專案的總和當分母,下方表格的百分比卻用總權杖數,所以同一個專案在圖上是 42.5%、在表格是 36.1%,中央那個數字也不是它看起來宣稱的總數。現在分母改成 summary.total_tokens,沒被列出來的部分(包含前十名以外的專案)併成一塊「其他」,沿用既有的 report_chart_other 字串。

問題修復

沒有模型名稱的打斷與被擋工具不再被丟掉

帶著 message.id 卻沒有 message.model 的訊息,會被編成一個空字串,但後面的檢查只測 model is None。所以這些事件既沒有被歸給任何模型,也沒有被算進未歸屬那一桶,上一張卡講的那個一次過關率因此把打斷數算少了。這次修好了。

新功能

完全沒有用量時,報表會顯示乾淨的空狀態

用量為零時,敘述句會把零和佔位符號一起填進去,變成 ---- -- -- was the peak (0/day), main LLM 未知,下方七個區塊全都只寫著「nothing here yet」——新使用者第一次打開看到的正是這個。現在 total_tokens 與 messages 都是零時,敘述改成 report_empty_state_hint,這個鍵五種語言都加了,並且只渲染標題、統計卡與贊助區塊。有資料時的輸出逐位元組相同,沒被動過的 full_zh_tw 與 full_en 快照就是證明。

English

FEATURE

Grok CLI gets its own usage status line

Grok CLI supports the same command-style status line mechanism as Claude Code, so usage_statusline_grok.py joins the existing install / remove / self-heal flow behind the switch already shared with Claude Code and Antigravity. Grok's stdin payload carries no rate-limit summary — its documentation says so explicitly — so the script tails ~/.grok/logs/unified.jsonl for creditUsagePercent and currentPeriod.end; when neither can be read the segment is omitted rather than printed as placeholder characters. Only the weekly axis is shown, since Grok has no 5-hour window and reports no cache hit ratio, and neither is estimated.

FEATURE

The status line's second row shows cache hit rate and a countdown

Claude Code 2.1.251 added a prompt_cache object to the status line hook's stdin JSON, and usage was already storing the whole payload in usage-status.json without reading it. The second row now shows the prompt cache hit rate and a countdown to expiry. A new color_by_pct_inverted() mirrors the thresholds, so a 91% hit rate reads as good instead of borrowing the quota palette's red, and progress_bar() takes an optional color_func, leaving existing callers unchanged. The segment is skipped entirely when caching_observed is not True or the ratio is unavailable, so older Claude Code versions silently omit it; an expired expires_at drops only the countdown and keeps the bar. Narrow terminals degrade in two further steps: the countdown goes first, then the whole segment.

FEATURE

The status line lights up the numbers and dims everything else

Empty progress cells, the context window total, and the | separators were pure white and brighter than the figures themselves; they are now grey 240 / dim, leaving usage as the only lit element. The second row is secondary information, so a cache hit rate of 80% or better takes that row's muted purple and only turns orange below 80% and red below 50% — good news does not need to glow. The same batch reworded the cache countdown. The previous wording was a literal rendering of warm/cold that read as nothing in particular; it now reuses the existing remaining_prefix, giving (59min left) in English alongside the two segments before it. cache_cold_suffix, used in exactly one place, was removed, so five languages no longer need a separate word for it.

BUGFIX

A third-party status line with a similar name is no longer taken over

Hook ownership was decided by the substring test "usage-statusline" in cmd, so someone else's usage-statusline-pro.py was treated as a usage installation: taken over without a backup, and its configuration deleted on uninstall. The comparison now matches the complete filename, derived from HOOK_TARGET.name and its siblings instead of a hardcoded string, requiring a path separator, quote, whitespace, or string boundary on each side. It deliberately does not compare full paths: the command string shifts with interpreter location, quoting, and Windows backslashes, and a path comparison would stop usage recognizing itself.

BUGFIX

The status line's file lock times out instead of hanging

Every message you sent left the status line stalled, because another process was holding the same lock. _exclusive_lock()'s POSIX branch used a plainly blocking flock(LOCK_EX), while the Windows branch already had a 10-second _LOCK_TIMEOUT_S guard. The POSIX branch now polls with LOCK_EX | LOCK_NB and, on timeout, follows the msvcrt path: the atomic write proceeds without the lock.

FEATURE

Installed status line copies actually update now

needs_update() compares __version__ in ~/.claude/usage-statusline.py against HOOK_VERSION and skips the copy when they match, so rendering changes that shipped without a version bump never reached an installed copy, silently and with no error. Both constants were bumped, and a drift test was added: the Token Saver hook had that guard already; the status line was missing it.

FEATURE

The report adds a first-pass rate, compared across models

The report's usage habits section gained a card measuring what share of your turns this period ran without an interruption and without a blocked tool call, split by model — a quality axis rather than another quota count. Both signals are structural, read from ~/.claude/projects: interruptedMessageId on user lines, and permission-denial strings inside tool_result content; nothing is inferred semantically. The denominator is user turns rather than assistant messages, because a single exchange emits a dozen assistant messages and would compress every model above 99.5%. Multiple interruptions inside one turn count once. Angle-bracketed internal markers such as <synthetic> are excluded. Interrupted assistant messages are frequently aborted before reaching disk, so unresolvable signals go to an unattributed bucket and are not shown rather than being assigned to a model. The insight line is written only when the spread between the highest and lowest model exceeds 15 points.

FEATURE

The report draws a day-by-day curve and prints properly

The report's header already named the period's peak day, but you had no chart to check it against: daily_trend held 30 days of data that no chart used. A daily area line now sits above the weekly rollup, marking the highest day and labelling only the period's first and last dates. The stylesheet also gained a @media print block: sections avoid internal page breaks, interactive controls are hidden, shadows and offsets are removed, and colors invert to dark-on-white so a PDF stays readable when the reader is in dark mode.

FEATURE

The report's tables, charts, and section rhythm were filled in

The five heaviest sessions were the report's only all-text table; the tokens column now carries a thin bar scaled against the largest of the five, colored by the same provider palette the model table uses. The active-hours chart, previously hour labels alone, now marks its peak value in muted type in the lower right, with no gridlines or Y axis added. The ten sections shared one identical treatment; insights and the heatmap now carry heavier shadows while the recent-work and tools sections are lighter with --faint borders — shadows and borders only, since the persona section holds two cards and a background change would make their height difference conspicuous.

FEATURE

Project and model rows in the report carry share bars

Comparing ten stacked rows previously meant reading the numbers. Each name now has a 4px solid proportion bar beneath it — solid rather than gradient, so the color is not misread as carrying meaning. The donut's "Other" slice, which used to draw the palette's seventh color and read as nearly the same green as the first, is now a neutral #8b8577, selected inside _donut_svg by a synthetic flag rather than guessed from its index.

BUGFIX

A week still in progress is no longer compared against a complete one

The weekly trend measured the current partial week against the previous full one, which on Monday 2026-08-31 produced "W36 ↘ −97%" and the conclusion that this week was 97% lighter. The final week is now marked in progress when its Sunday falls after date_to (new trend_week_in_progress key, added in all five languages) and shows no percentage, and _trend_summary() compares the last two completed weeks instead.

BUGFIX

The Antigravity model name stops mixing two languages, and the menu bar title tightens

Antigravity's display_name already ends in an English effort suffix such as (High), and usage appended a localized one after it, naming the same level twice in two languages. The English suffix is now stripped and only the localized label is kept; when display_name carries no effort field, the stripped suffix becomes the source. The menu bar title tightened up too: the interpunct separator was removed, since the provider icons already separate the figures, and icon spacing was reduced to two spaces. Separately, prompt cache health was documented in all five READMEs under real-time visibility, noting it needs Claude Code 2.1.251 or newer, and the website's description of the AI Tool Update Digest was removed, a report section that no longer exists.

FEATURE

Uninstalling restores Grok's original status line

unsetup() handled Claude Code and Codex but skipped Grok, so after --unsetup the user's ~/.grok/config.toml still pointed at a usage script with no supported way back to their own [ui.status_line]. Uninstalling now restores Grok's original status line. The old test exercised only the private _unsetup_grok(), which is why this slipped through; the new one enters through the public unsetup().

FEATURE

Weekly burn trend bars are now CSS gradients

The donut, heatmap, and active-hours chart on the same page were all drawn graphics, while the weekly trend drew its bars with █ characters, looking pasted in from another document. Those bars are now CSS gradients. The four-column layout and terminal styling are unchanged; the rendering moved into a new ui/report_charts.py.

BUGFIX

The heatmap stops skipping months, and the donut agrees with the table

A heatmap column's month was taken from its Monday, so a week spanning a month boundary was credited to the old month it barely touched, and a label suppressed by the spacing rule was lost permanently — real output dropped September entirely. The month is now read from the column's Thursday and compared against the last month actually labelled, so a suppressed month reappears at the next column that satisfies the spacing. Separately, the project donut divided by the sum of by_project[:10] while the table's percentage used total tokens, so one project showed 42.5% in the chart and 36.1% in the table, and the center figure read as a total it was not. The denominator is now summary.total_tokens, with everything not shown (including projects outside the top ten) combined into an "Other" slice reusing the existing report_chart_other string.

BUGFIX

Interruptions and denied tools on messages with no model name are no longer dropped

A message carrying message.id but no message.model was indexed as an empty string, while the later check tested only model is None. Those events were therefore neither attributed to a model nor counted as unattributed, undercounting interruptions in the first-pass rate described on the previous card. That is now fixed.

FEATURE

A report with no usage renders a clean empty state

At zero usage the narrative sentence interpolated zeros and placeholders — "---- -- -- was the peak (0/day), main LLM 未知" — above seven sections each saying only "nothing here yet", which is what a new user saw on first open. When both total_tokens and messages are zero the narrative is now replaced by report_empty_state_hint, a key added in all five languages, and only the header, stat cards, and sponsor section render. Output with data is byte-identical; the untouched full_zh_tw and full_en snapshots are the proof.

原始 CHANGELOG

Original changelogGrok CLI 也有自己的用量狀態列了
**Grok CLI now gets its own `usage` status line.** Grok CLI supports the same command-style status line mechanism as Claude Code, so `usage_statusline_grok.py` joins the existing install / remove / self-heal flow behind the switch already shared with Claude Code and Antigravity. Grok's stdin payload carries no rate-limit summary (its documentation says so explicitly), so the script tails `~/.grok/logs/unified.jsonl` for `creditUsagePercent` and `currentPeriod.end`; when neither can be read the segment is omitted rather than printed as placeholder characters. Only the weekly axis is shown — Grok has no 5-hour window and reports no cache hit ratio, and neither is estimated.
Original changelog狀態列第二行看得到快取命中率與到期倒數
**The status line's second row now shows prompt cache hit rate and a countdown to expiry.** Claude Code 2.1.251 added a `prompt_cache` object to the status line hook's stdin JSON; `usage` was already storing the whole payload in `usage-status.json` without reading it. A new `color_by_pct_inverted()` mirrors the thresholds, so a 91% hit rate reads as good instead of borrowing the quota palette's red, and `progress_bar()` takes an optional `color_func` leaving existing callers unchanged. The segment is skipped entirely when `caching_observed` is not `True` or the ratio is unavailable, so older Claude Code versions silently omit it; an expired `expires_at` drops only the countdown and keeps the bar. Narrow terminals degrade in two further steps: the countdown goes first, then the whole segment.
Original changelog狀態列只把數字點亮,其餘壓暗
**The status line dims what isn't the number.** Empty progress cells, the context window total, and the `|` separators were pure white and brighter than the figures themselves; they are now grey 240 / dim, leaving usage as the only lit element. The second row is secondary information, so a cache hit rate of 80% or better takes that row's muted purple and only turns orange below 80% and red below 50% — good news does not need to glow.
**The cache countdown now says "left", matching the 5-hour and 7-day segments.** The previous wording was a literal rendering of warm/cold that read as nothing in particular; it now reuses the existing `remaining_prefix`, giving `(59min left)` in English alongside the two segments before it. `cache_cold_suffix`, used in exactly one place, was removed, so five languages no longer need a separate word for it.
Original changelog別人的同名狀態列腳本不再被當成自己的接管
**A third-party status line with a similar name is no longer mistaken for our own.** Hook ownership was decided by the substring test `"usage-statusline" in cmd`, so someone else's `usage-statusline-pro.py` was treated as a `usage` installation: taken over without a backup, and its configuration deleted on uninstall. The comparison now matches the complete filename, derived from `HOOK_TARGET.name` and its siblings instead of a hardcoded string, requiring a path separator, quote, whitespace, or string boundary on each side. It deliberately does not compare full paths — the command string shifts with interpreter location, quoting, and Windows backslashes, and a path comparison would stop `usage` recognizing itself.
Original changelog狀態列的檔案鎖改成等一段時間就放行
**The status line's file lock now times out instead of hanging a message.** `_exclusive_lock()`'s POSIX branch used a plainly blocking `flock(LOCK_EX)` while the Windows branch already had a 10-second `_LOCK_TIMEOUT_S` guard, so a process holding the lock stalled the status line on every message. The POSIX branch now polls with `LOCK_EX | LOCK_NB` and, on timeout, follows the `msvcrt` path: the atomic write proceeds without the lock.
Original changelog已安裝的狀態列副本真的會跟著更新了
**Installed status line copies now actually update.** `needs_update()` compares `__version__` in `~/.claude/usage-statusline.py` against `HOOK_VERSION` and skips the copy when they match, so rendering changes that shipped without a version bump never reached an installed copy, silently and with no error. Both constants were bumped, and a drift test was added — the Token Saver hook had that guard already; the status line was missing it.
Original changelog報表多了一項「一次過關率」,各模型分開比
**The HTML report's usage habits section now has a first-pass rate, compared across models.** The card measures what share of your turns this period ran without an interruption and without a blocked tool call, split by model — a quality axis rather than another quota count. Both signals are structural, read from `~/.claude/projects`: `interruptedMessageId` on user lines, and permission-denial strings inside `tool_result` content; nothing is inferred semantically. The denominator is user turns rather than assistant messages, because a single exchange emits a dozen assistant messages and would compress every model above 99.5%. Multiple interruptions inside one turn count once. Angle-bracketed internal markers such as `<synthetic>` are excluded. Interrupted assistant messages are frequently aborted before reaching disk, so unresolvable signals go to an unattributed bucket and are not shown rather than being assigned to a model. The insight line is written only when the spread between the highest and lowest model exceeds 15 points.
Original changelog報表加了逐日曲線,列印出來也讀得下去
**The report's trend section now draws a day-by-day curve for the period, and prints properly.** `daily_trend` already held 30 days of data that no chart used, leaving the peak day named in the header with nothing to check it against. A daily area line now sits above the weekly rollup, marking the highest day and labelling only the period's first and last dates. The stylesheet also gained a `@media print` block: sections avoid internal page breaks, interactive controls are hidden, shadows and offsets are removed, and colors invert to dark-on-white so a PDF stays readable when the reader is in dark mode.
Original changelog報表的表格、圖表與區塊層次都補上了
**The report's heaviest-sessions table, active-hours chart, and section rhythm were filled in.** The five heaviest sessions were the report's only all-text table; the tokens column now carries a thin bar scaled against the largest of the five, colored by the same provider palette the model table uses. The active-hours chart, previously hour labels alone, now marks its peak value in muted type in the lower right, with no gridlines or Y axis added. The ten sections shared one identical treatment; insights and the heatmap now carry heavier shadows while the recent-work and tools sections are lighter with `--faint` borders — shadows and borders only, since the persona section holds two cards and a background change would make their height difference conspicuous.
Original changelog報表的專案與模型列多了佔比條
**Project and model rows in the report now carry share bars.** Comparing ten stacked rows previously meant reading the numbers; each name now has a 4px solid proportion bar beneath it — solid rather than gradient, so the color is not misread as carrying meaning. The donut's "Other" slice, which used to draw the palette's seventh color and read as nearly the same green as the first, is now a neutral `#8b8577`, selected inside `_donut_svg` by a synthetic flag rather than guessed from its index.
Original changelog還沒過完的一週不再拿去跟完整的一週比
**A week still in progress is no longer compared against a complete one.** The weekly trend measured the current partial week against the previous full one, which on Monday 2026-08-31 produced "W36 ↘ −97%" and the conclusion that this week was 97% lighter. The final week is now marked in progress when its Sunday falls after `date_to` (new `trend_week_in_progress` key, added in all five languages) and shows no percentage, and `_trend_summary()` compares the last two completed weeks instead.
Original changelogAntigravity 的模型名不再兩種語言混寫,選單列標題也縮短
**The Antigravity model name no longer mixes two languages.** Antigravity's `display_name` already ends in an English effort suffix such as `(High)`, and `usage` appended a localized one after it, naming the same level twice in two languages. The English suffix is now stripped and only the localized label is kept; when `display_name` carries no effort field, the stripped suffix becomes the source.
**The menu bar title tightened up.** The interpunct separator was removed, since the provider icons already separate the figures, and icon spacing was reduced to two spaces.
Documented prompt cache health in all five READMEs under real-time visibility, noting it needs Claude Code 2.1.251 or newer, and removed the website's description of the AI Tool Update Digest, a report section that no longer exists.
Original changelog移除時會把 Grok 原本的狀態列放回去
**Uninstalling now restores Grok's original status line.** `unsetup()` handled Claude Code and Codex but skipped Grok, so after `--unsetup` the user's `~/.grok/config.toml` still pointed at a `usage` script with no supported way back to their own `[ui.status_line]`. The old test exercised only the private `_unsetup_grok()`, which is why this slipped through; the new one enters through the public `unsetup()`.
Original changelog週燃燒趨勢的長條改用 CSS 漸層畫
**Weekly burn trend bars are now CSS gradients.** The weekly trend drew its bars with `█` characters while the donut, heatmap, and active-hours chart on the same page were graphical. The four-column layout and terminal styling are unchanged; the rendering moved into a new `ui/report_charts.py`.
Original changelog熱圖不再漏標月份,甜甜圈的百分比跟表格對得上
**The heatmap's month labels no longer skip or mislabel a month.** A column's month was taken from its Monday, so a week spanning a month boundary was credited to the old month it barely touched, and a label suppressed by the spacing rule was lost permanently — real output dropped September entirely. The month is now read from the column's Thursday and compared against the last month actually labelled, so a suppressed month reappears at the next column that satisfies the spacing.
**The project donut's percentages now agree with the table beneath it.** The donut divided by the sum of `by_project[:10]` while the table's percentage used total tokens, so one project showed 42.5% in the chart and 36.1% in the table, and the center figure read as a total it was not. The denominator is now `summary.total_tokens`, with everything not shown — including projects outside the top ten — combined into an "Other" slice reusing the existing `report_chart_other` string.
Original changelog沒有模型名稱的打斷與被擋工具不再被丟掉
**Interruptions and denied tools on messages with no model name are no longer dropped.** A message carrying `message.id` but no `message.model` was indexed as an empty string, while the later check tested only `model is None` — so those events were neither attributed to a model nor counted as unattributed, undercounting interruptions in the first-pass rate.
Original changelog完全沒有用量時,報表會顯示乾淨的空狀態
**A report with no usage now renders a clean empty state.** At zero usage the narrative sentence interpolated zeros and placeholders — "---- -- -- was the peak (0/day), main LLM 未知" — above seven sections each saying only "nothing here yet", which is what a new user saw on first open. When both `total_tokens` and `messages` are zero the narrative is replaced by `report_empty_state_hint` (added in all five languages) and only the header, stat cards, and sponsor section render. Output with data is byte-identical; the untouched `full_zh_tw` and `full_en` snapshots are the proof.