メニューバーのステータスロジック

表示内容

  • 現在のエージェント作業状態をメニューバーアイコンとメニューの最初のステータス行に表示。
  • 作業がアクティブな間、ヘルスステータスは非表示。すべてのセッションがアイドルになると復帰。
  • メニューの「Nodes」ブロックにはデバイスのみがリストされます(node.list経由のペアリング済みノード)。クライアント/プレゼンスエントリは表示されません。
  • プロバイダ使用状況のスナップショットが利用可能な場合、Contextの下に「Usage」セクションが表示。

状態モデル

  • セッション:イベントはペイロード内にrunId(実行ごと)とsessionKeyを含んで到着。「main」セッションのキーはmain。不在の場合は最後に更新されたセッションにフォールバック。
  • 優先度:mainが常に優先。mainがアクティブならその状態を即座に表示。mainがアイドルなら最後にアクティブだった非mainセッションを表示。アクティビティ中に切り替えは行わず、現在のセッションがアイドルになるかmainがアクティブになった場合のみ切り替え。
  • アクティビティの種類:
    • job:高レベルのコマンド実行(state: started|streaming|done|error)。
    • toolphase: start|resulttoolNamemeta/argsを含む。

IconState列挙型(Swift)

  • idle
  • workingMain(ActivityKind)
  • workingOther(ActivityKind)
  • overridden(ActivityKind)(デバッグオーバーライド)

ActivityKind → グリフ

  • exec → 💻
  • read → 📄
  • write → ✍️
  • edit → 📝
  • attach → 📎
  • デフォルト → 🛠️

視覚マッピング

  • idle:通常のキャラクター。
  • workingMain:グリフ付きバッジ、フルティント、脚の「作業中」アニメーション。
  • workingOther:グリフ付きバッジ、控えめなティント、パタパタなし。
  • overridden:アクティビティに関係なく選択されたグリフ/ティントを使用。

ステータス行テキスト(メニュー)

  • 作業がアクティブな間:<セッションロール> · <アクティビティラベル>
    • 例:Main · exec: pnpm testOther · read: apps/macos/Sources/OpenClaw/AppState.swift
  • アイドル時:ヘルスサマリーにフォールバック。

イベント取り込み

  • ソース:コントロールチャネルのagentイベント(ControlChannel.handleAgentEvent)。
  • パースされるフィールド:
    • stream: "job" with data.state(開始/停止)。
    • stream: "tool" with data.phasename、オプションのmeta/args
  • ラベル:
    • execargs.commandの最初の行。
    • read/write:短縮されたパス。
    • edit:パスに加えてmeta/差分カウントから推測された変更種類。
    • フォールバック:ツール名。

デバッグオーバーライド

  • 設定 → Debug → 「Icon override」ピッカー:
    • System (auto)(デフォルト)
    • Working: main(ツール種類ごと)
    • Working: other(ツール種類ごと)
    • Idle
  • @AppStorage("iconOverride")経由で保存。IconState.overriddenにマッピング。

テストチェックリスト

  • mainセッションのジョブをトリガー:アイコンが即座に切り替わり、ステータス行にmainのラベルが表示されることを確認。
  • mainがアイドル中に非mainセッションのジョブをトリガー:アイコン/ステータスに非mainが表示され、終了まで安定していることを確認。
  • 他がアクティブ中にmainを開始:アイコンが即座にmainに切り替わることを確認。
  • 高速なツールバースト:バッジがちらつかないことを確認(ツール結果にTTL猶予あり)。
  • すべてのセッションがアイドルになるとヘルス行が再表示されることを確認。