Logic Trạng Thái Menu Bar

Những gì được hiển thị

  • Mình hiển thị trạng thái làm việc hiện tại của Agent trong icon menu bar và ở dòng trạng thái đầu tiên của menu.
  • Trạng thái sức khỏe (health status) sẽ bị ẩn khi đang có công việc đang chạy; nó sẽ hiện lại khi tất cả các Session đều idle.
  • Khối “Nodes” trong menu chỉ liệt kê thiết bị (các node đã pairing qua node.list), không bao gồm các entry client/presence.
  • Phần “Usage” sẽ xuất hiện dưới Context khi có snapshot về usage của provider.

Mô hình trạng thái

  • Sessions: các event đến với runId (mỗi lần chạy) cộng với sessionKey trong payload. Session “main” có key là main; nếu không có, ta sẽ fallback về session được cập nhật gần nhất.
  • Độ ưu tiên: main luôn thắng. Nếu main đang active, trạng thái của nó sẽ được hiển thị ngay lập tức. Nếu main đang idle, session non-main active gần nhất sẽ được hiển thị. Mình không chuyển đổi qua lại giữa chừng hoạt động; chỉ chuyển khi session hiện tại chuyển sang idle hoặc main trở nên active.
  • Các loại hoạt động (Activity kinds):
    • job: thực thi lệnh cấp cao (state: started|streaming|done|error).
    • tool: phase: start|result với toolNamemeta/args.

IconState enum (Swift)

  • idle
  • workingMain(ActivityKind)
  • workingOther(ActivityKind)
  • overridden(ActivityKind) (debug override)

ActivityKind → glyph

  • exec → 💻
  • read → 📄
  • write → ✍️
  • edit → 📝
  • attach → 📎
  • default → 🛠️

Visual mapping

  • idle: critter bình thường.
  • workingMain: badge với glyph, tint đầy đủ, animation chân “working”.
  • workingOther: badge với glyph, tint mờ, không có scurry.
  • overridden: sử dụng glyph/tint đã chọn bất kể hoạt động nào.

Text dòng trạng thái (menu)

  • Khi đang có công việc active: <Session role> · <activity label>
    • Ví dụ: Main · exec: pnpm test, Other · read: apps/macos/Sources/OpenClaw/AppState.swift.
  • Khi idle: fallback về health summary.

Xử lý event

  • Nguồn: các event agent từ control-channel (ControlChannel.handleAgentEvent).
  • Các trường được parse:
    • stream: "job" với data.state cho start/stop.
    • stream: "tool" với data.phase, name, meta/args tùy chọn.
  • Labels:
    • exec: dòng đầu tiên của args.command.
    • read/write: đường dẫn rút gọn.
    • edit: đường dẫn cộng với loại thay đổi được suy ra từ meta/diff counts.
    • fallback: tên tool.

Debug override

  • Settings ▸ Debug ▸ “Icon override” picker:
    • System (auto) (mặc định)
    • Working: main (theo từng loại tool)
    • Working: other (theo từng loại tool)
    • Idle
  • Được lưu qua @AppStorage("iconOverride"); map tới IconState.overridden.

Checklist kiểm tra

  • Trigger main session job: kiểm tra icon chuyển ngay lập tức và dòng trạng thái hiển thị label main.
  • Trigger non-main session job khi main đang idle: icon/status hiển thị non-main; giữ ổn định cho đến khi hoàn thành.
  • Start main khi other đang active: icon chuyển sang main ngay lập tức.
  • Rapid tool bursts: đảm bảo badge không bị flicker (TTL grace trên tool results).
  • Dòng health xuất hiện lại khi tất cả các session đều idle.