Antigravity CLI(Gemini CLI)Status Line 亂碼修復

TL;DR

Status line 亂碼的根本原因是 settings.json 裡呼叫的是舊版 powershell.exe(PowerShell 5.1),它不支援 ANSI 顏色碼,亂碼就是 ANSI Escape Code 被直接印出來的樣子。 解法:把指令改成 pwsh.exe(PowerShell 7),再加上強制啟用 ANSI 的保險機制。 隔天還發現另一個更深的坑:Session Context 卡在 45% 不會動,是因為腳本解析的 JSON 欄位跟 Antigravity CLI 實際送出的格式不一樣,詳情看文末。

平常我主要都是用 Claude 搭配 Codex,但最近 token 燒得有點兇,又不想花錢升級,只好先用 Gemini CLI 頂著。

把它更新成 Antigravity CLI 之後,我想叫出下方那條 status line 看用量,結果 /statusline 叫出來整排都是亂碼(可惜忘記截圖)。我請 Gemini 自己修,試了好幾次它說改好了,畫面還是亂一堆亂碼。後來我突然想到:是不是要切換 強到一點的模型?

切過去一看,居然有 Sonnet 跟 Opus 可以選。我馬上叫我的好夥伴(也就是 Claude)出馬修正這個問題。

第一次修完的長相是這樣,已經比原本好一點:

antigravity-cli-statusline-01.png

叫它修第二次就成功了,亂碼總算消失。(我忘了截圖,反正出現一根 Bar 條跟 usage 數字就對了)

⚠️ 這不是最終答案,我隔天就發現有問題了,但我還是把這份紀錄留起來,給遇到一樣問題的人參考完整除錯過程。

為什麼會出現亂碼?

ANSI Escape Code 是終端機用來顯示顏色、粗體、底線等樣式的特殊字元序列,例如 ESC[38;2;2;223;130m 代表把文字設成綠色。

支援 ANSI 的終端機看到這串碼,會直接把文字顯示成對應顏色。但如果終端機不支援 ANSI,就會把控制碼原封不動印出來,變成你看到的亂碼:

??([char]27)[38;2;2;223;130m??([char]27)[0m

其中 ESC 是 ASCII 第 27 號字元([char]27)。在 PowerShell 裡要插入這個字元,寫法是:

"$([char]27)[0m"    # 產生 ESC 字元 + "[0m"

真正的問題出在哪?

問題出在 settings.json 這個設定檔(路徑:C:\Users\<你的使用者名稱>\.gemini\antigravity-cli\settings.json):

"statusLine": {
  "type": "command",
  "command": "powershell -ExecutionPolicy Bypass -File C:/Users/.../antigravity-cli/scratch/custom_status.ps1",
  "enabled": true
}

custom_status.ps1 腳本會產生帶顏色的漂亮 status bar,但這裡呼叫的是 powershell.exe,也就是 Windows PowerShell 5.1(舊版),而不是 PowerShell 7pwsh.exe)。

特性PowerShell 5.1(powershell.exePowerShell 7(pwsh.exe
預設 ANSI 支援❌ 不支援✅ 原生支援
$PSStyle 變數❌ 沒有✅ 有
TrueColor 支援

PowerShell 5.1 執行腳本時,ANSI Escape Code 不會被正確解析,而是以原始字元印出來,這就是亂碼的源頭。


三種解法,我全用上了

方法 A:把 powershell 換成 pwsh

最直接的修法,改 settings.json 裡的指令:

"command": "pwsh -ExecutionPolicy Bypass -File C:/Users/.../antigravity-cli/scratch/custom_status.ps1"

PowerShell 7 原生支援 ANSI,問題就解決了。

方法 B:腳本裡強制啟用 ANSI(雙重保險)

即使換成 pwsh,某些舊版 Windows Console Host(conhost.exe)環境裡 ANSI 仍可能沒被啟用。所以在 custom_status.ps1 開頭加一段直接呼叫 kernel32.dll 的 API:

# 強制啟用 ANSI VirtualTerminalProcessing
try {
    $kernel32 = Add-Type -MemberDefinition @'
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr GetStdHandle(int nStdHandle);
'@ -Name 'Kernel32VT' -Namespace 'Win32Status' -PassThru -ErrorAction SilentlyContinue
    if ($kernel32) {
        $hOut = [Win32Status.Kernel32VT]::GetStdHandle(-11)
        $mode = 0
        [Win32Status.Kernel32VT]::GetConsoleMode($hOut, [ref]$mode) | Out-Null
        # ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
        [Win32Status.Kernel32VT]::SetConsoleMode($hOut, ($mode -bor 0x0004)) | Out-Null
    }
} catch {}

這段強制開啟 ENABLE_VIRTUAL_TERMINAL_PROCESSING(Flag 值 0x0004),確保 ANSI 一定能用。

方法 C:在登錄檔設定全域啟用

Set-ItemProperty -Path "HKCU:\Console" -Name "VirtualTerminalLevel" -Value 1 -Type DWord

這讓所有用舊版 Console Host 開啟的視窗都預設啟用 ANSI,重開終端後生效。


改了哪些檔案?

  1. settings.jsoncommandpowershell 換成 pwsh
  2. custom_status.ps1 — 開頭加入方法 B 的 kernel32.dll 呼叫
  3. PowerShell ProfileDocuments\PowerShell\Microsoft.PowerShell_profile.ps1)— 加入同樣的 SetConsoleMode 呼叫,讓每次開終端都自動啟用 ANSI

怎麼驗證有沒有修好?

開啟 PowerShell 7 終端,執行:

echo '{"token_count":25000,"token_limit":100000,"token_percent":0.25}' | pwsh -ExecutionPolicy Bypass -File "你的 custom_status.ps1 路徑"

如果輸出類似下面這樣,而且進度條有顏色,就代表修復成功:

Session Context: █████░░░░░░░░░░░░░░░ 25% (25k/100k) | 5h Usage: 68k | 7d Usage: 883k

之後又出現亂碼怎麼辦?

依序檢查:

  1. 確認用的是 pwsh$PSVersionTable.PSVersion 應該顯示 7.x
  2. 確認 settings.json 用的是 pwsh 不是 powershell
    (Get-Content "$env:USERPROFILE\.gemini\antigravity-cli\settings.json" | ConvertFrom-Json).statusLine.command
  3. 確認 ANSI 有正確顯示
    Write-Host "`e[32m綠色文字`e[0m 正常文字"
    應該顯示綠色文字,不是 ESC[32m綠色文字ESC[0m
  4. 舊版 CMD/conhost 環境:手動跑一次方法 C 的登錄檔設定,重開終端後生效

整體概念,一張圖看懂

ANSI Escape Code 正常運作需要:
  ┌─────────────────────────────────────────┐
  │  腳本產生 ESC 字元($([char]27))        │
  │            ↓                            │
  │  透過支援 ANSI 的 shell 執行             │
  │  (pwsh 7 ✅ / powershell 5.1 ❌)       │
  │            ↓                            │
  │  輸出到支援 VT100 的終端機               │
  │  (Windows Terminal / VTLevel=1 ✅)    │
  └─────────────────────────────────────────┘
任何一個環節不支援,就會顯示亂碼。

到這邊我以為大功告成了,結果隔天就發現這個 status line 根本是「假的」——不管我怎麼用,數據看起來都長一樣。上網查了一下,發現有人遇過一樣的問題,我把官方文件直接餵給 Gemini(一樣切到 Sonnet 跑),這次才真正解決。

以下是隔天的修復紀錄:數據卡死跟進度條不會動

新問題:Session Context 永遠卡 45%

亂碼問題解決後,我發現 status line 上的數據完全不會動:

  • Session Context 永遠停在 45%
  • 5h 跟 7d Usage 顯示固定數值,沒有進度條

根本原因:JSON 欄位對不上

腳本是照 Claude Code 預期的 JSON 格式寫的,但 Antigravity CLI 送出的 JSON 結構完全不一樣。

Context 解析錯誤

  • 腳本預期讀取 token_percentcontext_percent
  • 實際上 Antigravity CLI 把數據放在 context_window.used_percentage(例如 21.4992,是百分比數值,不是 0~1 的比例)
  • 讀不到預期欄位 → 腳本觸發 fallback,直接把數值寫死成 $percent = 45

5h / 7d 額度解析錯誤

  • 腳本自己用本地檔案實作了一套 mock 機制去「推算」使用量
  • 但 Antigravity CLI 其實已經在 JSON 裡直接給了精準額度,放在 quota 物件:
    • Claude 等第三方模型 → 3p-5h3p-weekly
    • Gemini 模型 → gemini-5hgemini-weekly
    • 都附帶 remaining_fraction(剩餘比例)跟 reset_time(重置時間)
  • 腳本完全沒用官方給的精準數據,顯示的是本地算出來的不準確固定值

怎麼修:重寫 custom_status.ps1

  1. 動態判斷模型與額度來源:檢查 $data.model.id,含 “gemini” 就讀 quota."gemini-5h",否則讀 quota."3p-5h",確保額度永遠對應目前在用的模型
  2. 正確換算使用量百分比used_percentage = (1 - remaining_fraction) * 100
  3. 正確讀取 Context 資訊:改讀 context_window.used_percentagecontext_window.total_input_tokenscontext_window.context_window_size
  4. 加上 5h / 7d 進度條:把進度條渲染邏輯抽成共用的 Render-Bar 函式,套用在 Session Context、5h Usage、7d Usage 三個指標上,都能顯示綠 → 黃 → 紅的 TrueColor 漸層進度條

antigravity-cli-statusline-02.png

雖然還沒做到跟 Claude 一樣漂亮,但起碼數據終於正常跳動了😁…要做到跟 Claude 一樣漂亮,改天再研究還有什麼參數可以調。

結論

我覺得一開始應該只是 ANSI 亂碼的問題而已,但我懶得再回去測試了,那跟我工控人無關(我沒興趣研究),後面我覺得腳本 JSON 欄位對上,應該就是對了,不過我覺得最終還要自己去上網找腳本貼給它才懂挺煩人了,使用 CLAUDE 改 status line 的過程就很順。不過這次的問題也算是個經驗了,至少知道了亂碼的根本原因是什麼,以後遇到類似問題就知道怎麼解了。

留言區

載入中...

發表留言