メニューバーステータスロジック
表示される内容
- メニューバーアイコンとメニューの最初のステータス行に、現在のエージェントの作業状態を表示します。
- ヘルスステータスは作業がアクティブな間は非表示になり、すべてのセッションがアイドル状態になると戻ります。
- メニュー内の「Nodes」ブロックはデバイスのみをリストします(node.list 経由のペアリングされたノード)。クライアント/プレゼンスエントリは含みません。
- プロバイダー使用量スナップショットが利用可能な場合、Context の下に「Usage」セクションが表示されます。
状態モデル
- セッション: イベントはペイロード内の runId(実行ごと)と sessionKey で到着します。「main」セッションはキー main です。存在しない場合は、最も最近更新されたセッションにフォールバックします。
- 優先度: main が常に優先されます。main がアクティブな場合、その状態が即座に表示されます。main がアイドルの場合、最も最近アクティブだった非 main セッションが表示されます。アクティビティ中には切り替わりません。現在のセッションがアイドルになるか、main がアクティブになった場合のみ切り替わります。
- アクティビティの種類:
- job: 高レベルコマンド実行(state: started|streaming|done|error)。
- tool: phase: start|result と toolName および meta/args。
IconState 列挙型(Swift)
- idle
- workingMain(ActivityKind)
- workingOther(ActivityKind)
- overridden(ActivityKind)(デバッグオーバーライド)
ActivityKind → グリフ
- exec → 💻
- read → 📄
- write → ✍️
- edit → 📝
- attach → 📎
- デフォルト → 🛠️
ビジュアルマッピング
- idle: 通常のクリッター。
- workingMain: グリフ付きバッジ、フル色合い、脚の「作業中」アニメーション。
- workingOther: グリフ付きバッジ、ミュート色合い、小走りなし。
- overridden: アクティビティに関係なく選択されたグリフ/色合いを使用。
ステータス行テキスト(メニュー)
- 作業中: <セッションロール> · <アクティビティラベル>
- 例: Main · exec: pnpm test, Other · read: apps/macos/Sources/OpenClaw/AppState.swift
- アイドル時: ヘルスサマリーにフォールバック。
イベント取り込み
- ソース: コントロールチャネル agent イベント(ControlChannel.handleAgentEvent)。
- パースされたフィールド:
- stream: "job" と data.state で開始/停止。
- stream: "tool" と data.phase, name, オプションの meta/args。
- ラベル:
- exec: args.command の最初の行。
- read/write: 短縮されたパス。
- edit: パスと meta/diff カウントから推測された変更種類。
- フォールバック: ツール名。
デバッグオーバーライド
- 設定 ▸ デバッグ ▸ 「アイコンオーバーライド」ピッカー:
- System (auto)(デフォルト)
- Working: main(ツール種類ごと)
- Working: other(ツール種類ごと)
- Idle
- @AppStorage("iconOverride") 経由で保存。IconState.overridden にマッピング。
テストチェックリスト
- メインセッションジョブをトリガー: アイコンが即座に切り替わり、ステータス行にメインラベルが表示されることを確認。
- メインがアイドルの間に非メインセッションジョブをトリガー: アイコン/ステータスが非メインを表示。完了するまで安定を保つ。
- 他がアクティブな間にメインを開始: アイコンが即座にメインに切り替わる。
- 高速ツールバースト: バッジがちらつかないことを確認(ツール結果の TTL 猶予)。
- すべてのセッションがアイドルになるとヘルス行が再表示される。