Zum Artikel springen
HB CodeDocsApp herunterladen

HandbuchiOS-App

iOS: Pakete, Start und die Relay-Verbindung

Wie die iPhone-App in Swift-Pakete aufgeteilt ist, warum der Start auf den Schlüsselbund wartet, wie ihr Network.framework-Socket sich registriert, Zeitlimits einhält, sich erholt und Live-Events filtert, und wie sie Agent-Limits liest.

Gegen den Quellcode geprüft am 5. Oktober 2026

Auf dieser Seite

Drei Swift-Pakete und ein schlankes App-Target

Das Xcode-Projekt hat zwei Targets: die HBCode-App und ein VibeUITests-Bundle, das in ihr gehostet läuft. Das App-Target enthält drei Swift-Dateien: den SwiftUI-Einstiegspunkt, den App-Delegate und eine Delegate-Erweiterung für das Timeline-Interesse. Es bindet Core und VibeUI direkt ein, und sein Delegate ruft Core für Push, den Hintergrund und die Wiederherstellung auf. Alles andere liegt in drei lokalen Swift-Paketen, gebaut mit Swift 6.3 für iOS 18.

Target oder PaketWas es enthältHängt ab von
App-TargetDrei Swift-Dateien: der SwiftUI-Einstiegspunkt, der App-Delegate für Start, Push und Hintergrund sowie seine Erweiterung für das Timeline-Interesse.Core und VibeUI.
VibeUIJeder Bildschirm, die UIKit-Chat-Collection, die Code- und Dokumentbetrachter, der Review Mode und die gebündelte mermaid.min.js.Core, VibeUIFormatting, Runestone mit 37 Tree-sitter-Grammatiken, swift-syntax, swift-cmark, MarkdownUI und SwiftMath.
CoreEin Library-Target aus Sources/Core und Sources/Security: der Relay-Client, Anmeldung und Tokens, der RPC-Command-Router, Datendienste, StoreKit, Push, Sprache und die Schlüsselbund-Wrapper. Ein Target CoreTests testet es.KeychainAccess.
VibeUIFormattingMarkdown-Texthelfer: der Pfadklassifizierer, der Linkifier für Inline-Referenzen und der Normalisierer für nummerierte Listen.Nichts.
VibeUITestsDas Test-Bundle, gehostet in der App.Core, VibeUI, VibeUIFormatting, Runestone und MarkdownUI.

Core kann VibeUI nicht importieren, deshalb bauen und testen Relay-Client, Anmeldung und Datendienste ohne einen einzigen Bildschirm.

Pfad vom Repository-StammverzeichnisBeginnen Sie hier für
mobile/ios/App/Start, Push-Registrierung und die Übergänge zwischen Hintergrund und Vordergrund.
mobile/ios/Core/Sources/Core/Connectivity/Der Relay-Socket, die Registrierung, Wiederherstellungsepochen und das Timeline-Interesse-Lease.
mobile/ios/Core/Sources/Core/Data/Manager/Ingress/Annahme von Relay-Events vor dem Main Actor.
mobile/ios/VibeUI/Sources/VibeUI/Features/Workspace/Chat/Chat-Hosts, die Collection-View, die Outbox und Chat-Vorschauen.
mobile/ios/VibeUI/Sources/VibeUI/Features/Workspace/ReviewMode/Aufnahme, Transkription und Videokomposition im Review Mode.

Der Start wartet auf den Schlüsselbund

Ein gesperrtes Telefon kann die Geräte-ID nach dem ersten Entsperren lesen, das App-JWT aber nicht
Ein gesperrtes Telefon kann die Geräte-ID nach dem ersten Entsperren lesen, das App-JWT aber nichtVier Momente nacheinander, nicht maßstäblich: ein Neustart, das erste Entsperren, das Sperren des Telefons und das erneute Entsperren. Die Geräte-ID ist bis zum ersten Entsperren nicht lesbar und bleibt danach lesbar, auch während das Telefon gesperrt ist. Das App-JWT und die Resume-Tokens sind nur lesbar, solange das Telefon entsperrt ist. Ein Start vor dem ersten Entsperren wartet auf dem Ladebildschirm, bis geschützte Daten verfügbar werden. Ein Start bei gesperrtem Telefon liest die Geräte-ID und startet Core, behält die gespeicherte Anmeldung, weil das JWT nicht lesbar ist, und prüft sie nach dem Entsperren erneut.
Neustart
erstes Entsperren
gesperrt
entsperrt
Geräte-IDIdentität des Telefons
App-JWTund Resume-Tokens
AppStart, Anmeldung
nicht lesbar
lesbar, auch im gesperrten Zustand
nicht lesbar
lesbar
nicht lesbar
lesbar
Start wartet: keine Geräte-ID, Ladebildschirm bleibt
Geräte-ID lesbar, Core startet, Anmeldung geprüft
Start im gesperrten Zustand: Core startet, JWT nicht lesbar, Anmeldung bleibt
Entsperren: Anmeldung erneut geprüft
  • Geräte-IDAfterFirstUnlockThisDeviceOnly

    Die Identität des Telefons für die Geräteliste und das Relay. Sie wird nie mit iCloud synchronisiert. Die Plattform hält diese Klasse lesbar, während das Telefon gesperrt ist, aber nicht vor dem ersten Entsperren nach einem Neustart.

  • App-JWT und Resume-TokensWhenUnlockedThisDeviceOnly

    Der Standard für die Schlüsselbundeinträge der App. Die Plattform macht diese Klasse nur lesbar, solange das Telefon entsperrt ist.

  • StartprotectedDataDidBecomeAvailable

    Der App-Delegate und AppView lesen die Geräte-ID abseits des Main Threads. Solange sie nicht lesbar ist, startet Core nicht, und AppView behält seinen Ladebildschirm. Beide versuchen es erneut, wenn geschützte Daten verfügbar werden oder die App in den Vordergrund zurückkehrt.

  • AnmeldeprüfungcheckStoredToken

    Ist das App-JWT nicht lesbar, weil das Telefon gesperrt ist, bleibt die gespeicherte Anmeldung erhalten. Die Prüfung läuft erneut, wenn geschützte Daten verfügbar werden oder die App aktiv wird.

Die Geräte-ID ist die Identität des Telefons für die Geräteliste und das Relay, deshalb startet nichts, was mit dem Netzwerk spricht, ohne sie. Sie ist ein Schlüsselbundeintrag mit der Zugänglichkeit AfterFirstUnlockThisDeviceOnly, der nie mit iCloud synchronisiert wird. Das App-JWT, sein Ablaufzeitpunkt und die Relay-Resume-Tokens verwenden den Standard für die Einträge der App, WhenUnlockedThisDeviceOnly.

Der App-Delegate liest die Geräte-ID in einer Hintergrundaufgabe, bevor er Core initialisiert, und AppView löst die Identität ebenfalls abseits des Main Threads auf. Bei einem Start im Hintergrund vor dem ersten Entsperren bleibt AppView auf dem Ladebildschirm und versucht es erneut, sobald das System protectedDataDidBecomeAvailable meldet. Während das Telefon gesperrt ist, hält die Plattform die Geräte-ID lesbar, das App-JWT aber nicht, deshalb behält ein Start in diesem Zustand die gespeicherte Anmeldung und prüft sie erneut, sobald geschützte Daten verfügbar sind oder die App aktiv wird. Ein Eintrag, der sich gar nicht lesen lässt, bietet Reset Device Identity an.

Die Anmeldung braucht keine Callback-URL. ASWebAuthenticationSession öffnet /auth/auth0/initiate-login mit callbackURLScheme auf nil, und die App fragt /auth0/poll-status alle 2 Sekunden ab, bis zu 60 Mal, bevor sie den Code mit ihrem PKCE-Verifier eintauscht und die Anmeldung abschließt. Es läuft immer nur eine Erneuerung des App-JWT. Ihr Timer feuert 300 Sekunden vor dem Ablauf, frühestens aber in 5 Sekunden, und ein 401 oder 403 vom Erneuerungsendpunkt beendet die Anmeldung.

Die gewählte Region wird in UserDefaults gespeichert. Ihre Basis-URL, https://api-us.hbcode.ai oder https://api-eu.hbcode.ai, bestimmt sowohl den REST-Client als auch den /ws/device-link-Socket. iOS speichert die gewählte Region, bevor es den Navigationszustand veröffentlicht, und bindet jeden Registrierungsversuch an den Ursprung, den er verwendet hat.

Ein WebSocket auf Network.framework

Der Relay-Socket ist eine NWConnection mit NWProtocolWebSocket: Version 13, automatische Antworten auf Pings und 32 MiB maximale Nachrichtengröße. Die Parameter erlauben teure und eingeschränkte Pfade und verwenden den Multipath-Dienst handover, sodass die Verbindung zwischen WLAN und Mobilfunk wechseln kann. Nur wss-URLs werden akzeptiert. Die Upgrade-Anfrage trägt das App-JWT als Bearer-Token, X-Device-ID und X-Token-Binding mit der Geräte-ID, X-Client-Type: mobile und X-Target-Desktop-Device-ID für den gewählten Desktop.

Jeder Socket erhält eine Transportgeneration. Das Zustandsobjekt, das einen Socket installiert, führt unter derselben Sperre auch Sendungen aus, die an eine Generation gebunden sind, deshalb kann eine für einen früheren Socket vorbereitete Sendung nie dessen Nachfolger erreichen. Zustands-Callbacks einer Verbindung, die nicht mehr aktuell ist, werden ignoriert.

Nach dem Upgrade sendet der Client register mit der Geräte-ID, dem Gerätenamen, relayProtocolVersion 1.7, dem Zieldesktop sowie der Relay-Session-ID und dem Resume-Token, wenn er sie hat. Der Handshake läuft nach 10 Sekunden ab, und eine Sendung, die aus einem vorübergehenden Grund scheitert, wird nach min(0.25 × attempt, 1.5) Sekunden wiederholt. Nach der Registrierung sendet der Client alle 5 Sekunden eine eigene heartbeat-Nachricht, und ein Watchdog lässt die Verbindung nach 15 Sekunden ohne eingehenden Verkehr scheitern.

Resume-Tokens liegen pro Paar aus Telefon und Desktop im Schlüsselbund, unter dem Schlüssel <device ID>::<desktop ID>. Ein serieller Speicher gibt jedem Relay-Client eine Besitzgeneration für seinen Schlüssel und weist Schreibvorgänge eines Clients ab, dem er nicht mehr gehört, sodass ein veralteter Client kein neueres Token überschreiben kann. Ein invalidResume-Fehler lässt den Client sich nach 0,2 Sekunden ohne Token neu registrieren. Drei ungültige Resumes innerhalb von rollierenden 30 Sekunden beenden die Schleife mit invalidResumeLoop.

Anfragen, Zeitlimits und Trace-Kontext

RpcMethod listet 69 Methoden: 10 im Namensraum system, 23 für Dateien, 15 für Sessions und 21 für Runs. 24 davon sind Mutationen, die einen Idempotenzschlüssel verlangen. Der Client weist eine unbekannte Methode oder eine Mutation ohne Schlüssel ab, bevor etwas gesendet wird, und der ausgehende Encoder wirft einen Fehler, sobald er irgendwo in einer Payload einen snake_case-Schlüssel findet. Ausstehende Aufrufe sind nach Anfrage-ID zusammen mit einem Besitz-Token geordnet. Eine zweite laufende Anfrage mit derselben ID wird abgewiesen, und das Aufräumen eines alten Aufrufs kann keinen neueren entfernen.

Standard-ZeitlimitMethoden
8 Sekundenfiles.readContent.
90 SekundenDateibäume, Run-Liste und -Abruf, Codex-Nutzungslimits und -Auth-Profile, Claude-Konten, der Wechsel des Codex-Profils und des Claude-Kontos, Nutzungsverlauf der Agents, Sprachvokabular und -kontext sowie Verlaufszustand.
60 SekundenSession- und Projektlisten, Abruf und Aktualisierung einer Session, Reihenfolge von Projekten und Sessions, Wiederherstellung fehlender Workspaces, Abgleich, Projekt-Skills, Workspaces, bestehende Sessions, Abbrechen und Löschen, Diffs, Befehlsausgabe, Webseiten als Markdown, Binär- und Medienlesevorgänge sowie Anhang-Uploads.
30 SekundenJede andere Methode.
115, 60 und 20 SekundenChat-Richtlinie: die erste Timeline, eine ältere Seite und die Outbox-Bestätigung.
60 SekundenChat-Richtlinie: run.chatOutboxStopAndSendNow.

Jede Anfrage trägt einen W3C-traceparent, und eine Antwort wird abgewiesen, wenn ihre Trace-ID nicht zu der der Anfrage passt. Ein Zeitlimit lässt diesen Aufruf scheitern und verbindet die Socket-Generation neu, die ihn gesendet hat. Wurde dieser Socket bereits ersetzt, berührt das Zeitlimit nichts anderes.

Wiederherstellungsepochen, Netzwerkwechsel und der Hintergrund

Relay und Telefon geben einem getrennten Desktop dieselbe Frist von 90 Sekunden
Relay und Telefon geben einem getrennten Desktop dieselbe Frist von 90 SekundenIn diesem Beispiel schließt sich die Verbindung des Desktops zum Relay bei 0 Sekunden. Das Relay hält den Platz des Desktops 90 Sekunden lang frei, meldet dem Telefon reconnecting zusammen mit dieser Frist und beantwortet jeden Ping an ihn mit -32011. Das Telefon öffnet eine Epoche der Wiederherstellung, die zum selben Zeitpunkt endet, und pingt mit Backoff: vier Versuche in etwa 2 Sekunden, danach einer alle 2,5 bis 5 Sekunden. Bei 30 Sekunden registriert sich der Desktop erneut, das Relay sendet online, das Telefon pingt sofort, und sobald der Desktop selbst antwortet, gilt er als verbunden. Wäre der Desktop weggeblieben, hätte das Relay bei 90 Sekunden disconnected gesendet und das Telefon ihn als offline angezeigt.
DesktopBeispiel: 30 s weg
RelaySchonfrist
TelefonWiederherstellung
nicht verbunden
jeder Ping: -32011
Schonfrist liefe weiter
pingt mit Backoff
Epoche liefe weiter
reconnecting, Frist in 90 s
registriert sich neu
online
Desktop beantwortet den Ping
verbunden
4 Versuche in etwa 2 s, danach einer alle 2,5 bis 5 s
Versucheerste 6 s, vergrößert
disconnected
offline
0 s
15 s
30 s
45 s
60 s
75 s
90 s
  • Epoche der WiederherstellungdesktopReconnectGraceSeconds = 90

    Eine pro Desktop. Sie endet zur reconnectDeadline, die das Relay geschickt hat, oder ohne sie 90 Sekunden, nachdem das Telefon den Verlust bemerkt hat. Stille, ein RPC-Zeitlimit oder ein verlorener Pfad innerhalb der Epoche behalten diese Frist.

  • Prüfungsystem.ping

    Vor jedem erneuten Versuch wartet das Telefon eine zufällige Zeit zwischen der Hälfte und dem Ganzen einer Obergrenze, die sich ab 0,25 s verdoppelt und bei 5 s endet, nie über die Frist hinaus. Ein Versuch ohne Socket öffnet zuerst einen, und dieser registriert sich mit seinem Resume-Token.

  • SchonfristDESKTOP_RECONNECT_GRACE_SECS = 90

    Schließt sich der Socket eines Desktops, sendet das Relay reconnecting mit einer reconnectDeadline und beantwortet Anfragen an diesen Desktop mit -32011. Es sendet online, wenn sich der Desktop erneut registriert, und disconnected, wenn die Frist verstreicht.

  • ErgebniscanSendDesktopRPC

    Der Desktop gilt erst als verbunden, wenn er selbst auf system.ping antwortet. Das Telefon zeigt ihn als offline an, wenn die Frist verstreicht, sofort bei disconnected oder wenn die Prüfung mangels Netzwerkpfad endet.

Die Wiederherstellung läuft in Epochen, eine pro Desktop, jede mit einer Frist. Innerhalb einer Epoche prüft die App den Desktop mit system.ping und Backoff, und sendet das Relay online, pingt sie sofort. Ein Desktop, der bis zur Frist nicht geantwortet hat oder den das Relay als disconnected meldet, wird als vorübergehend offline angezeigt. Ebenso einer, dessen Prüfung endet, weil das Telefon keinen Netzwerkpfad hat.

NWPathMonitor meldet verlorene Pfade und Schnittstellenwechsel. Ein verlorener Pfad schließt jedes verbundene Relay, lässt dessen ausstehende Aufrufe scheitern und öffnet eine Epoche. Ein Wechsel zwischen WLAN und Mobilfunk schließt das alte Relay und lässt laufende Aufrufe scheitern, bevor die Wiederherstellung genau einen Ersatz öffnet, denn ein migrierter Socket kann weiter Sendungen annehmen, ohne je auf eine Registrierung zu antworten. Der Wechsel verwirft die aktuelle Epoche, deshalb bekommt der Ersatz ein neues Fenster von 90 Sekunden.

Wird die App inaktiv, setzt sie das Timeline-Interesse aus. Geht sie in den Hintergrund, trennt sie jedes Relay innerhalb einer GracefulDisconnect-Hintergrundaufgabe, außer desktopgestützte Medien spielen, was der Audio-Hintergrundmodus erlaubt. Zurück im Vordergrund startet die Wiederherstellung für den aktiven Desktop 1,5 Sekunden später, und ein bestehender Socket bleibt nur, wenn ein Ping innerhalb von 3 Sekunden antwortet. Ein stiller desktop_online-Push startet dieselbe Wiederherstellung sofort.

Event-Annahme vor dem Main Actor

Ein wartender Snapshot kann ersetzt werden, und die Lease wird bei der Zustellung geprüft
Ein wartender Snapshot kann ersetzt werden, und die Lease wird bei der Zustellung geprüftEin Beispiel mit fünf Relay-Events innerhalb von 260 Millisekunden, während Sie den Chat wechseln. Snapshot T1 für Chat T wird sofort zugestellt. T2 kommt in der Pause von 100 Millisekunden nach dieser Zustellung an und wartet, bis T3 ihn ersetzt. Ein run:status-changed-Event wartet nicht und wird vor T3 zugestellt. Sie öffnen Chat S bei 105 Millisekunden, deshalb hält die Session von T3 bei dessen Zustellung bei 150 Millisekunden keine Lease mehr, und der Main Actor verwirft ihn vor dem Dekodieren. S1 für Chat S kommt später an, hält die Lease und wird dekodiert und angewendet.
kommt anNetzwerk-Queue
wartetRelayEventIngress
LeaseInteresse-Koordinator
zugestelltMain Actor
Lease: Chat T
Lease: Chat S
Wechsel zu Chat S
T1
T2
T3
S1
run:status-changed
wartet nicht
durch T3 ersetzt
T1 gezeigt
T3 verworfen: keine Lease, nie dekodiert
S1 gezeigt
100 ms Pause
0 ms
100 ms
200 ms
300 ms
  • Snapshot-Platzchat:timeline-updated · event: blocks

    Ein Warteplatz pro Session, Run und Thread, und ein neuerer Snapshot ersetzt den wartenden. Über 128 Plätze hinaus wird der älteste verworfen. Snapshots gehen einzeln hinaus, mit 100 ms Pause nach jeder Zustellung.

  • Steuer-Eventsrun:status-changed · device-status

    Jedes andere Relay-Event wartet in Ankunftsreihenfolge und wird ohne Pause zugestellt, deshalb kann es einen wartenden Snapshot überholen.

  • Lease-PrüfungWorkspaceTimelineRelayEventAuthorization

    Läuft auf dem Main Actor, wenn ein Timeline-Event zugestellt wird, und verwirft das Event vor dem Dekodieren, wenn sein Desktop und seine Session keine aktuelle Lease halten. Die Prüfung läuft erneut, direkt bevor sich das View-Model ändert.

  • Überlastung32 MiB · 64 MiB · 256 Events

    Ein Event über 32 MiB, mehr als 64 MiB wartend oder mehr als 256 wartende Steuer-Events verwerfen den Rest dieser Abonnementgeneration. Das Telefon abonniert dann neu und startet die Wiederherstellung des Desktops.

RelayEventIngress nimmt Relay-Events an, bevor irgendeine Arbeit den Main Actor erreicht. Steuer-Events behalten ihre Ankunftsreihenfolge und warten nie hinter Snapshots. Block-Snapshots aus chat:timeline-updated sind UI-Zustand nach bestem Bemühen. Ein neuerer Snapshot für dieselbe Session, denselben Run und Thread ersetzt einen noch wartenden, und Snapshots gehen einzeln hinaus. Die Lease wird geprüft, wenn ein Snapshot auf dem Main Actor zugestellt wird, bevor seine Payload dekodiert ist, deshalb erreichen Inhalte eines Chats, den Sie verlassen haben, nie die Aufbereitung.

Timeline-Inhalte erreichen das Telefon nur, solange ein Chat sichtbar ist. Jede sichtbare Chat-Ansicht hält einen Anspruch, und der Interesse-Koordinator hält eine Lease pro Desktop, für die Basis-Session des neuesten Anspruchs. Ansprüche halten die Übergabe zwischen einem Eltern-Chat und einem Subagent-Viewer sicher, solange beide Ansichten kurz nebeneinander existieren, und ein Anspruch zählt nur für die Vordergrundgeneration, in der seine Ansicht zuletzt ihre Sichtbarkeit bestätigt hat, sodass die Rückkehr in den Vordergrund keine verschwundene Ansicht wiederbeleben kann. Die Lease wird als chat:timeline-interest mit der appSessionId und einem active-Flag gesendet, alle 20 Sekunden erneuert und nach der Registrierung beim Relay erneut ausgestellt. Eine gescheiterte Zustellung wird bis zu 4 Mal versucht, beginnend bei 0,25 Sekunden, mit höchstens 2 Sekunden zwischen den Versuchen und 20 Prozent Jitter.

Relay-EreignisGeht an
device-status, device-unlinkedDie Desktop-Präsenz mit der Wiederherstellungsepoche und das Entfernen eines Desktops, dessen Verknüpfung aufgehoben wurde.
project-directory-updatedDas Projektverzeichnis dieses Desktops.
session-created, session-updated, session-deleted, session-snapshot, history-state-changedDer Session-Dienst.
chat:timeline-updatedDer sichtbare Chat, nach der Lease-Prüfung. Dasselbe Event aktualisiert auch die Run-Zusammenfassungen.
chat:outbox-updatedEine Benachrichtigung chatOutboxUpdated, die der offene Chat beobachtet.
run:created, run:deleted, run:list-invalidated, run:status-changed, run:tokens-updated, run:cost-updated, run:finalized, run:stream-progress, run:error-detailsDie Run-Zusammenfassungen in JobsDataService.

Die Aktivitätsanzeige einer Session stammt aus den Run-Zusammenfassungen. Ein Event chat:timeline-updated mit dem Event started oder blocks markiert seinen Run als laufend. Die Events completed, failed und aborted markieren ihn als abgeschlossen, gescheitert und abgebrochen und setzen die Endzeit. Ein Event ohne Run-Metadaten wird mit einer Warnung verworfen, und eines ohne Run-ID ändert nichts.

Agent-Limits und Kontowechsel

Die zwei Limit-Kacheln teilen sich eine Aktualisierung alle 60 Sekunden, aber nicht ihre Abfragen
Die zwei Limit-Kacheln teilen sich eine Aktualisierung alle 60 Sekunden, aber nicht ihre AbfragenEin Beispiel mit drei Momenten, nicht maßstäblich. Wenn Sie die Projektliste öffnen, zeigen beide Kacheln „Checking…“. Die Codex-Kachel liest Limits und Profile parallel, und die Claude-Kachel liest die Kontoliste. Alle 60 Sekunden läuft die Aktualisierung: Codex liest nur die Limits, und Claude liest die Konten erneut. Dann wechseln Sie das Codex-Profil. Das Telefon sendet eine Wechselanfrage mit Schlüssel und danach beide Codex-Abfragen noch einmal, also zeigt die Kachel die Limits des anderen Profils. Die Claude-Kachel bleibt unberührt. Unten: Ein Desktop ohne aktives Codex-Profil zeigt „Not set up“, und die Aktualisierung liest dann nur die Profilliste.
Sie öffnen die Projektliste
Alle 60 s: die Aktualisierung
Sie wechseln das Codex-Profil
Codex-KachelProjektliste
Desktop
Claude-KachelProjektliste
Checking…
5h 76% left · Weekly 58% left
5h 100% left · Weekly 91% left
Checking…
5h 40% left · Weekly 74% left
Limits und Profile, parallel
nur die Limits
eine Wechsel­anfrage mit Schlüssel
dann beide Abfragen erneut
Kontoliste
Kontoliste erneut
Ohne aktives Codex-Profil zeigt die Kachel „Not set up“, und die Aktualisierung liest nur die Profilliste, bis eines aktiv ist.
  • Codex-Abfragensystem.codexUsageLimits · system.codexAuthProfiles

    Ein vollständiges Laden sendet beide parallel. Eine Profilliste ohne aktives Profil bedeutet „Not set up“, und die gescheiterte Limit-Abfrage bleibt verborgen.

  • Claude-Abfragesystem.claudeAccounts

    Eine Abfrage liefert jedes Konto mit seinen Nutzungsfenstern. Eine gescheiterte Abfrage behält die letzten Konten, und die Konten eines anderen Desktops werden vor dem Laden geleert.

  • AktualisierunglimitRefreshIntervalSeconds = 60

    Läuft, solange die Projektliste auf dem Bildschirm ist. Codex liest nur die Limits erneut. Claude liest die Kontoliste erneut.

  • Wechselsystem.activateCodexAuthProfile · system.activateClaudeAccount

    Eine Anfrage mit Schlüssel pro Tippen, mit einer neuen UUID im Schlüssel. Es läuft immer nur ein Wechsel. Die Antwort ist die neue Liste. Codex lädt danach neu, weil die Limits zum aktiven Abonnement gehören.

Die Projektliste zeigt eine Kachel pro Agent, und die Einstellungen haben einen Abschnitt Agents mit denselben zwei Statuszeilen. Ein Tippen öffnet den Nutzungsbildschirm dieses Agents. Konten und Profile liegen auf dem Desktop. Das Telefon liest sie über das Relay und kann nur das aktive auswählen. Ein Konto fügen Sie auf dem Desktop hinzu, und dort melden Sie sich auch an.

Text der KachelWann die Codex-Kachel ihn zeigtWann die Claude-Kachel ihn zeigt
Checking…Ein Laden läuft, und keine Limits sind bekannt.Die erste Abfrage dieses Desktops hat noch nicht geantwortet.
Not set upDie Profilliste hat kein aktives Profil, und die Limits werden geleert.Die Kontoliste ist leer, und die Abfrage ist nicht gescheitert.
UnavailableNach dem Laden ist kein Limit-Fenster bekannt.Die Kontoliste ist leer, und die Abfrage ist gescheitert.
AbgemeldetDie Codex-Kachel zeigt ihn nie.Kein Konto ist aktiv, oder das aktive Konto ist abgemeldet.
NutzungszeilenDas primäre und das sekundäre Fenster des aktiven Profils, benannt nach ihrer Länge, 5h und Weekly.Das 5h-Fenster und das Wochenfenster aller Modelle des aktiven Kontos.
Could not read usageDie Codex-Kachel zeigt ihn nie.Das aktive Konto hat keine Nutzungsfenster und eine Fehlermeldung.
Name des Plans oder No plan limitsDie Codex-Kachel zeigt ihn nie.Das aktive Konto hat keine Nutzungsfenster und keinen Fehler.

Eine Nutzungszeile zeigt den Prozentsatz, der übrig ist: 100 minus usedPercent, begrenzt auf 0 bis 100. Die Zeile wechselt bei 25 Prozent oder weniger in die Warnfarbe und bei 10 Prozent oder weniger in die Fehlerfarbe. Der Claude-Nutzungsbildschirm listet auch die Wochenfenster einzelner Modelle, die die Kachel weglässt.

Auf dem Codex-Nutzungsbildschirm sendet ein Tippen auf ein Profil, das authentifiziert und nicht aktiv ist, system.activateCodexAuthProfile. Auf dem Claude-Nutzungsbildschirm sendet ein Tippen auf ein Konto, das angemeldet und nicht aktiv ist, system.activateClaudeAccount, und dieses Konto führt den nächsten Claude-Turn aus. Beide Aufrufe sind Mutationen mit Schlüssel. Der Schlüssel besteht aus der Methode, der ID und einer neuen UUID, also ist jedes Tippen eine eigene Mutation. Ein View-Model führt immer nur einen Wechsel aus. Ein gescheiterter Codex-Wechsel setzt den Ladezustand auf gescheitert, und die Kachel behält die Limits, die sie schon hat. Ein gescheiterter Claude-Wechsel behält die Konten und speichert den Fehler.

Jeder Nutzungsbildschirm liest außerdem system.agentUsageHistory für seinen Agent. Die Wochenlinie entsteht aus weeklySamples. Liegt ein Reset-Zeitpunkt zwischen zwei Messwerten und ist der spätere Messwert niedriger, bekommt die Linie zwei zusätzliche Punkte: den alten Wert eine Sekunde vor dem Reset und null beim Reset. Das Token-Diagramm umfasst immer die letzten 30 lokalen Tage und existiert nur für Codex, weil dailyTokens für Claude null ist. Eine gescheiterte Abfrage behält den Verlauf, der schon auf dem Bildschirm ist.