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)出馬修正這個問題。
第一次修完的長相是這樣,已經比原本好一點:

叫它修第二次就成功了,亂碼總算消失。(我忘了截圖,反正出現一根 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 7(pwsh.exe)。
| 特性 | PowerShell 5.1(powershell.exe) | PowerShell 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,重開終端後生效。
改了哪些檔案?
settings.json—command把powershell換成pwshcustom_status.ps1— 開頭加入方法 B 的kernel32.dll呼叫- PowerShell Profile(
Documents\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
之後又出現亂碼怎麼辦?
依序檢查:
- 確認用的是 pwsh:
$PSVersionTable.PSVersion應該顯示 7.x - 確認 settings.json 用的是 pwsh 不是 powershell:
(Get-Content "$env:USERPROFILE\.gemini\antigravity-cli\settings.json" | ConvertFrom-Json).statusLine.command - 確認 ANSI 有正確顯示:
應該顯示綠色文字,不是Write-Host "`e[32m綠色文字`e[0m 正常文字"ESC[32m綠色文字ESC[0m - 舊版 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_percent或context_percent - 實際上 Antigravity CLI 把數據放在
context_window.used_percentage(例如21.4992,是百分比數值,不是 0~1 的比例) - 讀不到預期欄位 → 腳本觸發 fallback,直接把數值寫死成
$percent = 45
5h / 7d 額度解析錯誤
- 腳本自己用本地檔案實作了一套 mock 機制去「推算」使用量
- 但 Antigravity CLI 其實已經在 JSON 裡直接給了精準額度,放在
quota物件:- Claude 等第三方模型 →
3p-5h、3p-weekly - Gemini 模型 →
gemini-5h、gemini-weekly - 都附帶
remaining_fraction(剩餘比例)跟reset_time(重置時間)
- Claude 等第三方模型 →
- 腳本完全沒用官方給的精準數據,顯示的是本地算出來的不準確固定值
怎麼修:重寫 custom_status.ps1
- 動態判斷模型與額度來源:檢查
$data.model.id,含 “gemini” 就讀quota."gemini-5h",否則讀quota."3p-5h",確保額度永遠對應目前在用的模型 - 正確換算使用量百分比:
used_percentage = (1 - remaining_fraction) * 100 - 正確讀取 Context 資訊:改讀
context_window.used_percentage、context_window.total_input_tokens、context_window.context_window_size - 加上 5h / 7d 進度條:把進度條渲染邏輯抽成共用的
Render-Bar函式,套用在 Session Context、5h Usage、7d Usage 三個指標上,都能顯示綠 → 黃 → 紅的 TrueColor 漸層進度條

雖然還沒做到跟 Claude 一樣漂亮,但起碼數據終於正常跳動了😁…要做到跟 Claude 一樣漂亮,改天再研究還有什麼參數可以調。
結論
我覺得一開始應該只是 ANSI 亂碼的問題而已,但我懶得再回去測試了,那跟我工控人無關(我沒興趣研究),後面我覺得腳本 JSON 欄位對上,應該就是對了,不過我覺得最終還要自己去上網找腳本貼給它才懂挺煩人了,使用 CLAUDE 改 status line 的過程就很順。不過這次的問題也算是個經驗了,至少知道了亂碼的根本原因是什麼,以後遇到類似問題就知道怎麼解了。
半桶水的
留言區
載入中...
發表留言