# Bauen, testen und beitragen

> Dieses Kapitel zeigt, wie Sie aus einem Quellcode-Checkout bauen, eine Änderung vornehmen und die Prüfungen für jede Grenze ausführen.

Handbuch / Mitwirken · Gegen den Quellcode geprüft am 2026-10-05 · https://www.hbcode.ai/de/docs/contributing

## Starten Sie nur die Komponenten, die Ihre Änderung braucht

Verwenden Sie einen Quell-Checkout mit seinen Lockfiles und lesen Sie AGENTS.md für den aktuellen Repository-Vertrag. Der Paketmanager im Stammverzeichnis ist pnpm 10.34.5, und die package.json im Stammverzeichnis pinnt verwundbare transitive Versionen über pnpm-Overrides und gepatchte Abhängigkeiten, weshalb --frozen-lockfile nach einer Abhängigkeitsänderung scheitert, bis das Lockfile neu erzeugt ist. Installieren Sie eine kompatible Node-Laufzeit, stabiles Rust für native Arbeit und die nativen Compiler-Tools der Zielplattform. iOS-Arbeit erfordert macOS und Xcode. Kein Stammbefehl startet alle Komponenten zusammen. Starten Sie nur die Oberflächen, die Ihre Änderung braucht.

JavaScript-Abhängigkeiten aus dem Repository-Root installieren:

```
pnpm install --frozen-lockfile
```

| Aufgabe | Startbefehl oder Projekt und was es beweist |
| --- | --- |
| Website | pnpm dev:website. Dokumentations- und Marketing-UI in einem Browser. |
| Desktop-Frontend | pnpm -C desktop dev. React-Layout und Frontend-Verhalten. Native Aufrufe erfordern eine Tauri-Laufzeitumgebung. |
| Nativer Desktop | pnpm -C desktop tauri:dev. Die eigentliche WebView, Rust-Befehle, Sidecar und lokale Dateien. |
| Claude-Agent-Host | pnpm -C desktop/agent-host build. Der TypeScript-Host wird nach desktop/agent-host/dist kompiliert. tauri dev führt diesen Build aus, bevor das Frontend startet. |
| Server | pnpm dev:server nach lokalem Setup. Konfiguriertes HTTP- und Relay-Dienstverhalten. |
| iOS | mobile/ios/HBCode.xcodeproj, HBCode-Scheme. Native Companion-UI und, mit einem konfigurierten Desktop, Fernsteuerung. |
| Android | mobile/android in Android Studio. Die Compose-Begleit-App und, mit einem konfigurierten Desktop, Fernsteuerung. |

Der Claude-Agent-Host ist das pnpm-Workspace-Paket @hbcode/claude-host in desktop/agent-host. Es legt das Claude Agent SDK auf 0.3.283 fest. Ein Debug-Build des Desktops startet node aus dem PATH mit desktop/agent-host/dist/src/entry.js und nimmt die claude-Binärdatei aus dem Plattformpaket des SDK in node_modules. Ohne das installierte Paket schlägt die Claude-Laufzeit mit „Install the Claude host dependencies before running desktop“ fehl. Ein Release-Build führt zuerst pnpm -C agent-host package-runtime aus und liest node, host/entry.mjs und claude aus dem Ordner claude der App-Ressourcen. Fehlt das Host-Skript oder die claude-Binärdatei, lautet der Fehler „The Claude runtime is not packaged“.

- [Der mitgelieferte Sidecar](https://www.hbcode.ai/de/docs/codex-app-server.md#sidecar): tauri:dev baut zuerst den Codex-Kindprozess aus der mitgelieferten Quelle. Dieser Abschnitt erklärt die Schritte und den Prüfbefehl.
- [Der Claude-Agent-Host](https://www.hbcode.ai/de/docs/claude-agent-sdk.md): Der Host-Prozess, sein Protokoll mit dem Desktop und die Run-Schleife.

## Wo der Desktop-Code liegt

**Die gemeinsame Chat-Schicht erreicht einen Agenten nur über agents/dispatch, und die zwei Adapter importieren einander nie**

Eine Karte von desktop/src-tauri/src, einem einzigen Rust-Crate. Die Tauri-Befehle und die RPC-Handler für die Telefone rufen die Chat-Schicht auf. Die Chat-Schicht ruft agents/dispatch auf, und Dispatch ruft den Codex-Adapter oder den Claude-Adapter auf. Jeder Adapter importiert die Verträge der Chat-Schicht und den gemeinsamen Tool-Katalog in services/agent_tools. Zwischen den zwei Adaptern gibt es keinen Import. Unter dem Crate trennt eine Prozessgrenze zwei Kindprogramme ab: den Codex-app-server und den Claude-Agent-Host, ein eigenes Node-Paket in desktop/agent-host.

- **Gemeinsame Chat-Schicht** (desktop/src-tauri/src/chat): Elf Ordner: approvals, contracts, entrypoints, operation_ledger, outbox, presentation, runs, send, session_messages, sessions und timeline. Ihr einziger Import aus agents ist agents::dispatch.
- **Dispatch** (desktop/src-tauri/src/agents/dispatch): Sechs Module: approvals, conversations, runs, selection, send und timeline. Jede Funktion liest den Agenten der Session und ruft den passenden Adapter auf.
- **Adapter** (agents/codex · agents/claude): Jeder Adapter betreibt einen Agenten und bildet ihn auf die Chat-Verträge ab. Konto- und Nutzungsbefehle in commands und remote_api rufen einen Adapter direkt auf, weil sie zu einem Agenten gehören.
- **Tool-Katalog** (desktop/src-tauri/src/services/agent_tools): Beide Adapter rufen ihn auf, um die Tools aufzulisten und einen Tool-Aufruf auszuführen. Er führt den Erklärvideo-Worker auf dem Agenten der Session aus, mit dem Codex-app-server oder dem Claude-Agent-Host, und nutzt chat::session_messages für Nachrichten zwischen Sessions.
- **Claude-Agent-Host** (desktop/agent-host · @hbcode/claude-host): TypeScript mit dem Claude Agent SDK 0.3.283. Er teilt keinen Code mit dem Crate. Der Claude-Adapter startet ihn als Kindprozess und spricht über stdin und stdout mit ihm.

Die Modulkommentare nennen die Regel. chat/mod.rs bezeichnet die Chat-Schicht als agentenneutral. agents/dispatch/mod.rs sagt, dass die Chat-Schicht agents::codex und agents::claude nur über dieses Modul erreicht. Die Importe halten sich daran: Jeder Verweis von chat auf agents geht an agents::dispatch, und kein Adapter importiert den anderen. Kein Skript in check:quality-boundaries erzwingt diese Regel, daher muss ein Reviewer sie prüfen.

Die ersten sechs Pfade der Tabelle liegen in desktop/src-tauri/src.

| Pfad | Was er besitzt und was er importieren darf |
| --- | --- |
| chat | Sessions, die Outbox, Runs, das Live-Overlay, Timeline-Zeilen und ihre Darstellung, Freigaben, Session-Nachrichten und die Chat-Einstiegspunkte. Darf importieren: agents::dispatch. Nie einen Adapter. |
| agents/dispatch | Die Wahl des Adapters für eine Session: Senden, Runs, Timeline, Freigaben, Unterhaltungen und Modellauswahl. Darf importieren: beide Adapter und chat. |
| agents/codex | Den app-server-Kindprozess, Threads, Turns, Ziele, Verlauf, Codex-Auth-Profile und Nutzungslimits. Darf importieren: chat, services/agent_tools und agents::dispatch für den Session-Eintrag. Nie agents::claude. |
| agents/claude | Den Host-Prozess, Runs, die Verlaufsprojektion, Berechtigungen, Subagenten und Claude-Konten. Darf importieren: chat, services/agent_tools und agents::dispatch für den Session-Eintrag. Nie agents::codex. |
| services/agent_tools | Den Tool-Katalog und die Tool-Handler für beide Agenten. Darf importieren: chat, agents::dispatch für den Session-Datensatz und den Run sowie beide Adapter für die zwei Engines des Worker-Kerns. |
| remote_api | RPC-Handler für die Telefone. Darf importieren: chat und agents::dispatch. Die Handler für Codex-Profile und Nutzungslimits rufen agents::codex auf. |
| desktop/agent-host | Den Claude-Agent-Host in TypeScript mit eigenen Tests. Er importiert keinen Rust-Code. Das Protokoll steht in src/protocol.ts. |

- [Wie sich Codex und Claude eine Chat-Schicht teilen](https://www.hbcode.ai/de/docs/agents.md#layers): Was die Chat-Schicht teilt und was jeder Adapter hinzufügt.

## Die nativen Begleit-Apps bauen

1. iPhone: Öffnen Sie mobile/ios/HBCode.xcodeproj, wählen Sie das Schema HBCode, lösen Sie die lokalen Pakete Core, VibeUI und VibeUIFormatting auf und konfigurieren Sie die Auth0-Werte aus mobile/ios/README.md. Starten Sie auf einem iOS-18-Simulator oder einem Gerät mit Ihrem Signing-Team.
2. Android: Öffnen Sie mobile/android in Android Studio, lassen Sie Gradle synchronisieren und konfigurieren Sie die Auth0- und Firebase-Werte aus mobile/android/README.md. Die App zielt auf Android 8.0 und neuer.
3. Für einen Live-Steuerungstest auf einer der Plattformen verbinden Sie sich mit einem konfigurierten Desktop mit demselben Konto und derselben Region und lesen eine bekannte Datei, bevor Sie eine Mutation versuchen.

Lokale Ziele ermitteln und eines davon für Builds und Tests verwenden:

```
xcodebuild -showdestinations \
  -project mobile/ios/HBCode.xcodeproj \
  -scheme "HB Code"
```

Das Schema „HB Code“ führt VibeUITests über den Testplan mobile/ios/HBCode.xctestplan aus. Der Plan setzt diagnosticCollectionPolicy auf Never, daher sammelt xcodebuild am Ende eines Testlaufs keine Simulator-Diagnosen und wartet nicht auf sie.

Simulatoren und Emulatoren decken Layout, Dekodierung und Zustandsübergänge ab. Sie beweisen nichts über physische Push-Zustellung, Store-Käufe oder die Anbieteranmeldung eines signierten Releases, testen Sie das also mit echten Diensten und einem echten Gerät, bevor Sie ein Release für fertig erklären.

## Einer Operation durch den Code folgen

Beispiel: Die Outbox-Übermittlung vom Contract bis zum Speicher nachverfolgen:

```
rg -n "chatOutboxSubmit" rpc-contract.v1.json desktop/src-tauri/src/remote_api server/src mobile/ios
rg -n "submit_outbox_request" desktop/src-tauri/src/chat/outbox
rg -n "save_workspace_chat_outbox_with_operation_identity" desktop/src-tauri/src
```

1. Beschreiben Sie die Benutzeraktion, das erwartete Ergebnis und einen Fehlerfall vor der Bearbeitung.
2. Finden Sie das Transport-DTO und den Domain-Service, der für die Operation zuständig ist. Lesen Sie beides, denn ein Adapter allein definiert kein Verhalten.
3. Ändern Sie die kleinste zuständige Schicht. Bewahren Sie stabile Identitäten für Operationen, Sessions und Timelines.
4. Ändern Sie einen gemeinsamen RPC, aktualisieren Sie Manifest, Desktop, Server, iOS und Android zusammen. Das Manifest pinnt, was sie teilen: Seitengrößen 12 und 100, 40 Zeilen für ein Fenster mit Anker, Timeouts von 15, 60, 115, 60 und 20 Sekunden, die Wiederholungsrichtlinie der ersten Timeline und die Mutationen, die einen Idempotenzschlüssel verlangen.
5. Fügen Sie einen gezielten Regressionstest an der Fehlergrenze hinzu. Untersuchen Sie bei visuellem oder Lebenszyklus-Verhalten auch die laufende Oberfläche.
6. Aktualisieren Sie das relevante technische Kapitel und seine Quellcode-Referenzen zusammen mit der Codeänderung.

## Wählen Sie Prüfungen aus, die zur Änderung passen

| Geänderte Oberfläche | Repository-Befehle |
| --- | --- |
| Desktop TypeScript | pnpm -C desktop typecheck, pnpm -C desktop lint, pnpm -C desktop test |
| Desktop Rust | pnpm desktop:check, danach gezielte Rust-Tests für den geänderten Service. |
| Claude-Agent-Host | pnpm -C desktop/agent-host typecheck, pnpm -C desktop/agent-host test |
| Server Rust | pnpm server:check, danach gezielte cargo-Tests und konfigurierte Service-Tests nach Bedarf. |
| Shared RPC | pnpm check:rpc-contract, plus die betroffenen Client- und Server-Tests. |
| Codex storage boundary | pnpm check:codex-storage-boundary |
| Website | pnpm -C website typecheck, pnpm -C website lint, pnpm -C website test, pnpm -C website build |
| Größe von Dateien, Funktionen und Ordnern | pnpm check:max-lines, pnpm check:max-function-lines, pnpm check:max-folder-files |
| Ungenutzter Code im Desktop | pnpm check:unused führt knip, cargo machete und clippy mit den Warnungen für toten Code und ungenutzte Elemente aus. Es gehört nicht zu check:all. |
| Grenzübergreifendes Review | pnpm check:quality-boundaries verkettet neun Prüfungen: die drei Größenprüfungen, die Tauri-Befehlsoberfläche, den RPC-Vertrag, die Parität der IntelliJ-Palette, den Skill-Korpus, die Codex-Speichergrenze und einen Duplikat-Scan des geänderten Codes mit mindestens 18 Zeilen. |
| Alles | pnpm check:all führt check:quality-boundaries, server:check, desktop:check, Lint und Formatprüfung des Desktops sowie den Typecheck jedes Workspace-Pakets aus. |

Eine Typprüfung beweist Typkonsistenz. Sie beweist keine korrekte Zustellung, und ein Relay-Unit-Test beweist keine native Anmeldung. Nennen Sie, welche Prüfungen gelaufen sind, welche externe Dienste brauchen und was Sie im laufenden Produkt geprüft haben.

## Machen Sie die Änderung leicht überprüfbar

Behalten Sie einen kanonischen Laufzeitpfad bei. Entfernen Sie veraltete Zweige, statt stilles Kompatibilitätsverhalten hinzuzufügen. Halten Sie Komponenten modular, nutzen Sie die vorhandenen Abhängigkeiten und bewahren Sie fremde Arbeit in einem Checkout mit offenen Änderungen. Das Repository begrenzt Dateien auf 550 Zeilen und Funktionen auf 100 Zeilen. Die Baseline-Dateien .max-lines-baseline und .max-function-lines-baseline halten bestehende Altlasten fest und dürfen nur schrumpfen. AGENTS.md setzt ein Ziel von fünf verfassten Quell- oder Testdateien pro Ordner, und check:max-folder-files schlägt oberhalb von sieben fehl. Teilen Sie einen wachsenden Ordner nach Feature oder Leseraufgabe. Ein Ordner mit Nummer, Buchstabe, part, misc oder more erfüllt die Regel nicht.

Ein Beitrag sollte den Auslöser, das resultierende Verhalten, den betroffenen Vertrag und die Validierungsnachweise erklären, mit einem Screenshot für eine sichtbare Änderung und einer begrenzten Ablaufspur für einen Zustellfehler. Nehmen Sie nie private Session-Transkripte, Auth-Dateien oder maschinenspezifische Pfade auf.
