Menüleisten-Statuslogik

Was angezeigt wird

  • Der aktuelle Agent-Arbeitszustand wird im Menüleisten-Icon und in der ersten Statuszeile des Menüs angezeigt.
  • Der Health-Status wird ausgeblendet, während Arbeit aktiv ist; er kehrt zurück, wenn alle Sessions idle sind.
  • Der „Nodes”-Block im Menü listet nur Geräte auf (gepaarte Nodes via node.list), nicht Client/Presence-Einträge.
  • Ein „Usage”-Bereich erscheint unter Context, wenn Provider-Nutzungs-Snapshots verfügbar sind.

Zustandsmodell

  • Sessions: Events kommen mit runId (pro Run) plus sessionKey im Payload. Die „main”-Session ist der Key main; falls nicht vorhanden, fällt es auf die zuletzt aktualisierte Session zurück.
  • Priorität: Main gewinnt immer. Wenn Main aktiv ist, wird sein Zustand sofort angezeigt. Wenn Main idle ist, wird die zuletzt aktive Nicht-Main-Session angezeigt. Wir wechseln nicht hin und her während einer Aktivität; wir wechseln nur, wenn die aktuelle Session idle wird oder Main aktiv wird.
  • Aktivitätsarten:
    • job: übergeordnete Befehlsausführung (state: started|streaming|done|error).
    • tool: phase: start|result mit toolName und meta/args.

IconState Enum (Swift)

  • idle
  • workingMain(ActivityKind)
  • workingOther(ActivityKind)
  • overridden(ActivityKind) (Debug-Override)

ActivityKind → Glyph

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

Visuelle Zuordnung

  • idle: normales Tierchen.
  • workingMain: Badge mit Glyph, voller Tint, Bein-„Arbeits”-Animation.
  • workingOther: Badge mit Glyph, gedämpfter Tint, kein Wuseln.
  • overridden: nutzt den gewählten Glyph/Tint unabhängig von der Aktivität.

Statuszeilen-Text (Menü)

  • Bei aktiver Arbeit: <Session-Rolle> · <Aktivitäts-Label>
    • Beispiele: Main · exec: pnpm test, Other · read: apps/macos/Sources/OpenClaw/AppState.swift.
  • Bei idle: fällt auf die Health-Zusammenfassung zurück.

Event-Verarbeitung

  • Quelle: Control-Channel-agent-Events (ControlChannel.handleAgentEvent).
  • Geparste Felder:
    • stream: "job" mit data.state für Start/Stopp.
    • stream: "tool" mit data.phase, name, optionalem meta/args.
  • Labels:
    • exec: erste Zeile von args.command.
    • read/write: gekürzter Pfad.
    • edit: Pfad plus abgeleitete Änderungsart aus meta/Diff-Counts.
    • Fallback: Tool-Name.

Debug-Override

  • Einstellungen ▸ Debug ▸ „Icon-Override”-Auswahl:
    • System (auto) (Standard)
    • Working: main (pro Tool-Art)
    • Working: other (pro Tool-Art)
    • Idle
  • Gespeichert via @AppStorage("iconOverride"); zugeordnet zu IconState.overridden.

Test-Checkliste

  • Main-Session-Job auslösen: prüfe ob das Icon sofort wechselt und die Statuszeile das Main-Label zeigt.
  • Nicht-Main-Session-Job auslösen während Main idle ist: Icon/Status zeigt Nicht-Main; bleibt stabil bis zum Ende.
  • Main starten während anderer aktiv ist: Icon wechselt sofort zu Main.
  • Schnelle Tool-Bursts: sicherstellen dass das Badge nicht flackert (TTL-Grace bei Tool-Ergebnissen).
  • Health-Zeile erscheint wieder, sobald alle Sessions idle sind.