<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Statusline on Tarragon</title><link>https://tarrragon.github.io/blog/tags/statusline/</link><description>Recent content in Statusline on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 13 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/statusline/index.xml" rel="self" type="application/rss+xml"/><item><title>Codex 與 Claude Code Statusline 相容設計方法</title><link>https://tarrragon.github.io/blog/record/codex-%E8%88%87-claude-code-statusline-%E7%9B%B8%E5%AE%B9%E8%A8%AD%E8%A8%88%E6%96%B9%E6%B3%95/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/codex-%E8%88%87-claude-code-statusline-%E7%9B%B8%E5%AE%B9%E8%A8%AD%E8%A8%88%E6%96%B9%E6%B3%95/</guid><description>&lt;h2 id="問題錨點">問題錨點&lt;/h2>
&lt;p>Statusline 相容設計的核心責任是把「資料輸入契約」和「畫面渲染邏輯」分開。Claude Code 已經提供 command-backed statusline，會把 session JSON 丟進命令的 stdin；Codex 目前公開的設定則是 &lt;code>tui.status_line&lt;/code> 字串項目陣列，契約停在內建 footer item 的排列與選擇。&lt;/p>
&lt;p>這個差異讓「同一個 statusline 工具同時支援兩邊」要從輸入契約對齊開始。真正要做的是先建立一層輸入正規化：Claude JSON、Codex 既有或未來 JSON、手動測試 JSON 都先轉成同一個內部狀態，再交給同一套 renderer。&lt;/p>
&lt;h2 id="case-first-觀察">Case-first 觀察&lt;/h2>
&lt;p>Case-first 查詢的目的，是先看社群實際卡在哪裡，再決定要改工具還是改使用方式。本次查詢到的案例集中在 OpenAI Codex repo issue 與官方文件，顯示需求已經存在，但 Codex 的 command-backed statusline 仍屬提案或缺口。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Case&lt;/th>
 &lt;th>觀察&lt;/th>
 &lt;th>判讀&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://code.claude.com/docs/en/statusline">Claude Code status line 官方文件&lt;/a>&lt;/td>
 &lt;td>Claude Code 的 statusline command 會從 stdin 收到 JSON，stdout 的每一行會顯示成 status area。&lt;/td>
 &lt;td>Claude 端是穩定可用的 producer，工具可依賴 &lt;code>model&lt;/code>、&lt;code>workspace&lt;/code>、&lt;code>context_window&lt;/code>、&lt;code>rate_limits&lt;/code> 這類欄位。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://developers.openai.com/codex/config-reference">OpenAI Codex config reference&lt;/a>&lt;/td>
 &lt;td>&lt;code>tui.status_line&lt;/code> 的型別是 &lt;code>array&amp;lt;string&amp;gt;&lt;/code> 或 &lt;code>null&lt;/code>，用途是排列 footer status-line item identifiers。&lt;/td>
 &lt;td>Codex 端目前公開契約屬於內建項目清單。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://github.com/openai/codex/issues/17827">openai/codex #17827&lt;/a>&lt;/td>
 &lt;td>使用者明確要求 Codex 加入類似 Claude Code 的 &lt;code>statusLine.command&lt;/code>。&lt;/td>
 &lt;td>社群已把 Claude Code statusline 當成對照基準，混用痛點是真實需求。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://github.com/openai/codex/issues/20043">openai/codex #20043&lt;/a>&lt;/td>
 &lt;td>提案列出 Codex 既有 &lt;code>status_line&lt;/code> picker，並要求外部 command 模式、ANSI 顏色與 stdin JSON。&lt;/td>
 &lt;td>未來若 Codex 採納此類設計，statusline 工具需要同時支援 Codex 風格 JSON 與 Claude 欄位。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://github.com/openai/codex/issues/20244">openai/codex #20244&lt;/a>&lt;/td>
 &lt;td>另一個使用者提出 command-backed item 或 persistent banner，並被標為 #17827 的 duplicate。&lt;/td>
 &lt;td>重複 issue 表示需求已經多次出現；相容設計應預留 Codex command input，讓後續定案只需要調整 mapper。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://github.com/openai/codex/issues/21324">openai/codex #21324&lt;/a>&lt;/td>
 &lt;td>使用者在 local branch 實作 context/token usage 狀態項目與進度條。&lt;/td>
 &lt;td>Codex 社群也在補足使用量可視化，但路徑偏向內建 item，和 Claude 的外部 renderer 是兩種不同擴充模型。&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="wrap-判讀">WRAP 判讀&lt;/h2>
&lt;p>Anchor Check：目標是讓 &lt;code>cc-statusline&lt;/code> 的核心能力可被兩種工具共用。使用者真正需要的是少維護一套 statusline 邏輯，並在 Codex 具備 command-backed 入口時保留既有 renderer。&lt;/p>
&lt;p>Step 0 資料充足度：足以做工具內部改造，尚不足以宣稱 Codex TUI 目前能直接執行 &lt;code>cc-statusline&lt;/code>。官方文件只保證 &lt;code>tui.status_line&lt;/code> 是字串陣列；社群 issue 裡的 command JSON 仍是提案階段。&lt;/p>
&lt;p>Widen Options：可選方案有三種。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>選項&lt;/th>
 &lt;th>策略&lt;/th>
 &lt;th>適用條件&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>A：只用 Codex 內建 &lt;code>tui.status_line&lt;/code>&lt;/td>
 &lt;td>不改 &lt;code>cc-statusline&lt;/code>，在 Codex 設定內建項目。&lt;/td>
 &lt;td>只需要模型、目錄、git branch、context 這類內建欄位時可用。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>B：改 &lt;code>cc-statusline&lt;/code> 成雙 schema renderer&lt;/td>
 &lt;td>保留 Claude JSON，新增 Codex / generic JSON normalization。&lt;/td>
 &lt;td>希望同一套 renderer 服務 Claude、未來 Codex command hook、tmux / wrapper 測試時最划算。&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>C：Fork 兩套工具&lt;/td>
 &lt;td>Claude 一套、Codex 一套，各自用不同資料模型。&lt;/td>
 &lt;td>只有在兩邊 UI 契約長期分歧且需求完全不同時才合理。&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Reality Test：目前 Codex 的公開設定停在內建 item 排列，所以 B 的立即價值是讓工具「具備 Codex 相容輸入能力」。反向驗證是：若未來 Codex 最終採用完全不同的 command JSON，B 的 normalization 層仍只需新增一個 mapper，renderer 可維持同一套。&lt;/p></description><content:encoded><![CDATA[<h2 id="問題錨點">問題錨點</h2>
<p>Statusline 相容設計的核心責任是把「資料輸入契約」和「畫面渲染邏輯」分開。Claude Code 已經提供 command-backed statusline，會把 session JSON 丟進命令的 stdin；Codex 目前公開的設定則是 <code>tui.status_line</code> 字串項目陣列，契約停在內建 footer item 的排列與選擇。</p>
<p>這個差異讓「同一個 statusline 工具同時支援兩邊」要從輸入契約對齊開始。真正要做的是先建立一層輸入正規化：Claude JSON、Codex 既有或未來 JSON、手動測試 JSON 都先轉成同一個內部狀態，再交給同一套 renderer。</p>
<h2 id="case-first-觀察">Case-first 觀察</h2>
<p>Case-first 查詢的目的，是先看社群實際卡在哪裡，再決定要改工具還是改使用方式。本次查詢到的案例集中在 OpenAI Codex repo issue 與官方文件，顯示需求已經存在，但 Codex 的 command-backed statusline 仍屬提案或缺口。</p>
<table>
  <thead>
      <tr>
          <th>Case</th>
          <th>觀察</th>
          <th>判讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="https://code.claude.com/docs/en/statusline">Claude Code status line 官方文件</a></td>
          <td>Claude Code 的 statusline command 會從 stdin 收到 JSON，stdout 的每一行會顯示成 status area。</td>
          <td>Claude 端是穩定可用的 producer，工具可依賴 <code>model</code>、<code>workspace</code>、<code>context_window</code>、<code>rate_limits</code> 這類欄位。</td>
      </tr>
      <tr>
          <td><a href="https://developers.openai.com/codex/config-reference">OpenAI Codex config reference</a></td>
          <td><code>tui.status_line</code> 的型別是 <code>array&lt;string&gt;</code> 或 <code>null</code>，用途是排列 footer status-line item identifiers。</td>
          <td>Codex 端目前公開契約屬於內建項目清單。</td>
      </tr>
      <tr>
          <td><a href="https://github.com/openai/codex/issues/17827">openai/codex #17827</a></td>
          <td>使用者明確要求 Codex 加入類似 Claude Code 的 <code>statusLine.command</code>。</td>
          <td>社群已把 Claude Code statusline 當成對照基準，混用痛點是真實需求。</td>
      </tr>
      <tr>
          <td><a href="https://github.com/openai/codex/issues/20043">openai/codex #20043</a></td>
          <td>提案列出 Codex 既有 <code>status_line</code> picker，並要求外部 command 模式、ANSI 顏色與 stdin JSON。</td>
          <td>未來若 Codex 採納此類設計，statusline 工具需要同時支援 Codex 風格 JSON 與 Claude 欄位。</td>
      </tr>
      <tr>
          <td><a href="https://github.com/openai/codex/issues/20244">openai/codex #20244</a></td>
          <td>另一個使用者提出 command-backed item 或 persistent banner，並被標為 #17827 的 duplicate。</td>
          <td>重複 issue 表示需求已經多次出現；相容設計應預留 Codex command input，讓後續定案只需要調整 mapper。</td>
      </tr>
      <tr>
          <td><a href="https://github.com/openai/codex/issues/21324">openai/codex #21324</a></td>
          <td>使用者在 local branch 實作 context/token usage 狀態項目與進度條。</td>
          <td>Codex 社群也在補足使用量可視化，但路徑偏向內建 item，和 Claude 的外部 renderer 是兩種不同擴充模型。</td>
      </tr>
  </tbody>
</table>
<h2 id="wrap-判讀">WRAP 判讀</h2>
<p>Anchor Check：目標是讓 <code>cc-statusline</code> 的核心能力可被兩種工具共用。使用者真正需要的是少維護一套 statusline 邏輯，並在 Codex 具備 command-backed 入口時保留既有 renderer。</p>
<p>Step 0 資料充足度：足以做工具內部改造，尚不足以宣稱 Codex TUI 目前能直接執行 <code>cc-statusline</code>。官方文件只保證 <code>tui.status_line</code> 是字串陣列；社群 issue 裡的 command JSON 仍是提案階段。</p>
<p>Widen Options：可選方案有三種。</p>
<table>
  <thead>
      <tr>
          <th>選項</th>
          <th>策略</th>
          <th>適用條件</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>A：只用 Codex 內建 <code>tui.status_line</code></td>
          <td>不改 <code>cc-statusline</code>，在 Codex 設定內建項目。</td>
          <td>只需要模型、目錄、git branch、context 這類內建欄位時可用。</td>
      </tr>
      <tr>
          <td>B：改 <code>cc-statusline</code> 成雙 schema renderer</td>
          <td>保留 Claude JSON，新增 Codex / generic JSON normalization。</td>
          <td>希望同一套 renderer 服務 Claude、未來 Codex command hook、tmux / wrapper 測試時最划算。</td>
      </tr>
      <tr>
          <td>C：Fork 兩套工具</td>
          <td>Claude 一套、Codex 一套，各自用不同資料模型。</td>
          <td>只有在兩邊 UI 契約長期分歧且需求完全不同時才合理。</td>
      </tr>
  </tbody>
</table>
<p>Reality Test：目前 Codex 的公開設定停在內建 item 排列，所以 B 的立即價值是讓工具「具備 Codex 相容輸入能力」。反向驗證是：若未來 Codex 最終採用完全不同的 command JSON，B 的 normalization 層仍只需新增一個 mapper，renderer 可維持同一套。</p>
<p>Attain Distance：B 的長期成本最低，因為 statusline 最容易變動的是輸入欄位名稱，最穩定的是使用者想看的資訊：專案、環境、輸入法、模型、context、rate limit、git worktree。把欄位差異收斂在 normalization 層，能避免每加入一個工具就複製一次畫面邏輯。</p>
<p>Prepare to be Wrong：若 Codex 不採納外部 command statusline，這次改造仍可用於手動測試、tmux status、其他 wrapper，且不影響 Claude Code 原始入口。若 Codex 採納但欄位名稱不同，新增 mapper 即可。</p>
<p>Tripwire：當 OpenAI Codex 文件把 <code>tui.status_line</code> 從 <code>array&lt;string&gt;</code> 擴充為 command 或 table schema 時，重新檢查 <code>cc-statusline</code> 的 Codex mapper。若 Codex issue #17827 關閉並附帶實作 PR，也應重新校準欄位名稱。</p>
<h2 id="實作策略">實作策略</h2>
<p>相容設計的正確切點是輸入正規化層。<code>cc-statusline</code> 應維持一個內部狀態模型，並接受多種外部 payload：</p>
<table>
  <thead>
      <tr>
          <th>外部 payload</th>
          <th>正規化規則</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Code</td>
          <td>直接讀 <code>model.display_name</code>、<code>workspace.project_dir</code>、<code>context_window.used_percentage</code>、<code>rate_limits</code>。</td>
      </tr>
      <tr>
          <td>Codex proposed / generic</td>
          <td>接受 <code>model</code> 字串、<code>cwd</code> / <code>project_root</code>、<code>context.used_percent</code> / <code>context.remaining_percent</code>、<code>limits.five_hour</code> / <code>limits.weekly</code>。</td>
      </tr>
      <tr>
          <td>手動測試 payload</td>
          <td>只要能提供模型與目錄，就輸出可讀 statusline；缺 rate limit 時自動省略。</td>
      </tr>
  </tbody>
</table>
<p>這個切點保留了 Claude Code 既有功能，因為原本的欄位不需要改名，也不需要改設定檔。新增行為只在非 Claude payload 進來時啟動，屬於向後相容的讀取能力。</p>
<h2 id="操作路由">操作路由</h2>
<p>現在可立即使用的路由是 Claude Code 原設定：在 <code>~/.claude/settings.json</code> 裡設定 <code>statusLine.command</code> 指向 <code>cc-statusline</code>。這條路由使用官方支援的 stdin JSON，適合日常使用。</p>
<p>Codex 目前可立即使用的路由是內建 footer item：在 <code>~/.codex/config.toml</code> 設定 <code>tui.status_line = [...]</code>。這條路由使用 Codex 內建 renderer，能顯示 Codex 已支援的內建狀態。</p>
<p>未來 Codex 若支援 command-backed statusline，路由應該指向同一個 <code>cc-statusline</code> binary。工具端已經能接受 Codex / generic JSON 時，設定層只要補 command 指向，不需要重寫 renderer。</p>
<h2 id="實測記錄2026-05-14">實測記錄（2026-05-14）</h2>
<p>這次排查的核心責任是先確認「工具本身可用」還是「接入路由不對」。先把 binary 行為跟 TUI 設定拆開檢查，才能避免把路由問題誤判成程式 bug。</p>
<h3 id="觀察">觀察</h3>
<ul>
<li><code>cc-statusline</code> 程式已支援 generic/Codex-style payload，手動餵 JSON 可正確輸出模型與 context 資訊。</li>
<li><code>~/.claude/settings.json</code> 使用 <code>statusLine.command</code> 指向 <code>/Users/mac-eric/go/bin/cc-statusline</code>，Claude Code 路由成立。</li>
<li><code>~/.codex/config.toml</code> 的 <code>tui.status_line</code> 是內建 item 陣列，這條路由不會執行外部 binary。</li>
<li>Codex 內建 footer 的實際輸出已觀察到：<code>gpt-5.3-codex medium · Context 100% left · ~/project/blog</code>。</li>
</ul>
<h3 id="判讀">判讀</h3>
<p>Codex 端「沒有生效」的主因是契約邊界：<code>tui.status_line</code> 只負責排列內建欄位，不負責執行 command。<code>cc-statusline</code> 的 renderer 相容能力屬於預留未來入口，不會在現有 Codex 內建 footer 流程自動觸發。</p>
<h3 id="操作">操作</h3>
<p>為了讓 Codex 內建 footer 至少顯示模型與 context 資訊，已調整：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">[</span><span class="nx">tui</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nx">status_line</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;model-with-reasoning&#34;</span><span class="p">,</span> <span class="s2">&#34;context-remaining&#34;</span><span class="p">,</span> <span class="s2">&#34;current-dir&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">status_line_use_colors</span> <span class="p">=</span> <span class="kc">true</span></span></span></code></pre></div><p>這個設定可讓 Codex 使用內建項目顯示 <code>model-with-reasoning</code> 與 context remaining；格式由 Codex 內建 renderer 決定，不等同 <code>cc-statusline</code> 的自訂輸出字串。</p>
<h3 id="驗證指令">驗證指令</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">printf</span> <span class="s1">&#39;%s\n&#39;</span> <span class="s1">&#39;{&#34;model&#34;:&#34;gpt-5.3-codex&#34;,&#34;reasoning_effort&#34;:&#34;medium&#34;,&#34;project_root&#34;:&#34;~/project/blog&#34;,&#34;context&#34;:{&#34;remaining_percent&#34;:100}}&#39;</span> <span class="p">|</span> /Users/mac-eric/go/bin/cc-statusline</span></span></code></pre></div><p>預期結果是主行包含 <code>gpt-5.3-codex medium</code>，context 顯示為 <code>Context 100% left</code>。這一步驗證的是 binary 能力，不是 Codex 內建 footer contract。</p>
<h2 id="檢查清單">檢查清單</h2>
<ul>
<li>Claude Code 原本的 JSON payload 仍能輸出相同欄位。</li>
<li>Codex / generic payload 不造成 parse error。</li>
<li><code>model</code> 同時支援 object 與 string。</li>
<li><code>context</code> 同時支援 used percentage 與 remaining percentage。</li>
<li>rate limit 缺席時只省略對應 segment，不影響專案、模型、git worktree。</li>
<li>README 明確標示 Codex 目前限制，避免讀者以為 Codex 已能直接執行外部 statusline command。</li>
</ul>
]]></content:encoded></item></channel></rss>