Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,28 @@
> Expect breaking changes between releases: keys that move, screens that get redrawn, features that come and go
> without notice. If it's close to what you want, fork or clone it and bend it into what you need it to be.

Headset-Testbegleitung für die gesamte Spielsession: [Einrichtung und Bedienung](docs/xr-playtests.md). Der globale Einstieg liegt oben in der Playtest-Checkliste; passende Tests folgen dem tatsächlichen Spielmodus und Solo/Koop-Kontext.

<div align="center">

*"Whatever you do, work heartily, as for the Lord and not for men."* — Colossians 3:23 (ESV)

# 🏢 Agent Office

Playtest-Vorbereitung direkt im Browser: **Playtest-Checkliste → XR Operator & Dev-APK** prüft die installierte APK per SHA-256, aktualisiert bei Bedarf auf die neueste erfolgreiche Dev-APK und startet die sessionweite Begleitung über USB. Der Operator ist im instrumentierten Dev-Build enthalten. [Ablauf](docs/xr-playtests.md) · [Prompt für externe Reviews und getrennte Übergabe von Tasks, Entscheidungen und Playtests](docs/external-review-prompt.md).

APKs für entfernte Tester: **☰ → APK** bietet getrennte Quest-Development- und signierte Store-Builds. Beide Varianten haben ihren eigenen neuesten erfolgreichen Download hinter dem Office-Login, auch über den bestehenden HTTPS-Tunnel. [Einrichtung und Bedienung](docs/dev-apk.md).

Direkt auf die Quest installieren: Im APK-Fenster **Quest verbinden** wählen. Chrome oder Edge verbindet sich per USB mit der Quest am Rechner des jeweiligen Testers. Die neueste Dev-/Store-APK oder eine ausgewählte Datei lässt sich mit Fortschrittsanzeige installieren und anschließend starten. [Browser-Installation](docs/quest-browser-install.md).

**A 3D office your team shares with its coding agents.**

**Personal playtests:** the rolling checklist board and **☰ → Playtest checklist** organize checks by
Allgemein, RB, RIFT, Rooftop, Safe Zone and Gas Station, with play-style filters and build-specific results.
Use **Issues aussortieren** in the checklist or Issue agent terminal to preview transferring human checks
out of open issues. Implementation and documentation stay in issues; manual checks do not block workers
or merges. See [Playtest checklist](docs/playtests.md).

Sit **Claude Code**, **Codex**, **OpenCode**, **Grok**, **Muse**, **DeepSeek Harness** and **Cursor** workers at desks, watch each one's terminal on the laptop in front of it,
and jump into any of them together. Every GitHub repo is a floor of the building.

Expand Down Expand Up @@ -420,3 +434,5 @@ Every change to the app that lands on `main` is published as a GitHub release by
## License

[MIT](LICENSE)

The [XR playtest plan](docs/xr-playtest-plan.md) describes session-wide Quest assistance. The [session guide](docs/xr-playtests.md) covers the global checklist entry, local Quest bridge, headset hints and evidence, including the required development game build.
23 changes: 23 additions & 0 deletions bin/office-playtests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env node
// Human test handoffs, deliberately separate from office-queue.
const usage = 'office-playtests list | office-playtests add (JSON on stdin: title, steps, expected, category, source)';
async function main() {
const cmd = process.argv[2];
if (!cmd || cmd === '--help') { console.log(usage); return; }
if (!['list', 'add'].includes(cmd) || process.argv.length > 3) throw new Error(usage);
const { AGENT_OFFICE_HOOK_URL: base, AGENT_OFFICE_WORKER_ID: worker, AGENT_OFFICE_HOOK_TOKEN: token } = process.env;
if (!base || !worker || !token) throw new Error('Run this from an existing Office worker terminal');
const url = new URL('/office/playtests', base); url.searchParams.set('worker', worker);
const headers = { authorization: `Bearer ${token}`, 'content-type': 'application/json' };
let body;
if (cmd === 'add') {
let input = '';
for await (const chunk of process.stdin) { input += chunk; if (input.length > 24000) throw new Error('Test too large'); }
body = JSON.stringify({ action: 'add', test: JSON.parse(input.replace(/^\uFEFF/, '')) });
}
const r = await fetch(url, { method: cmd === 'list' ? 'GET' : 'POST', headers, body, signal: AbortSignal.timeout(15000) });
const result = await r.json();
if (!r.ok) throw new Error(result.error ?? `Office returned ${r.status}`);
console.log(JSON.stringify(result, null, 2));
}
main().catch(e => { console.error(e.message); process.exitCode = 1; });
2 changes: 2 additions & 0 deletions bin/office-xr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
import('../dist/server/server/xr-playtests/bridge-cli.js').then(m => m.runBridge()).catch(err => { console.error(err.message); process.exitCode = 1; });
4 changes: 4 additions & 0 deletions docs/code-layout.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Code layout

The global playtest toolbar registers browser setup in `client/ui/xr-browser`. It reuses the APK USB adapter, exposes only the fixed on-device Operator endpoint, and shares the bounded MCP client in `shared/xr-operator.ts` with the optional PC bridge. `xr-browser.ts` in the HTTP registry validates the signed-in run owner, origin and per-run token before accepting browser telemetry.

The APK dialog mounts its extensions through `src/client/ui/dev-apk/extensions.ts`. Browser-to-Quest installation lives in `src/client/ui/quest-install/`: source streaming, bounded APK manifest parsing, USB adapter, installation lifecycle and UI stay separate. It requires no server-side ADB endpoint and does not add device state to the shared office store.

Back to the [README](../README.md).

Where the code lives, and where a new feature's pieces go. The office used to grow by adding to the middle of a few big files: the server's message switch, the page's key handler, its frame loop and its store. Each of those is a registry now, and a feature is a folder of its own plus one line in each list it joins. If a change has you editing the middle of `main.ts`, `server.ts`, the store or `protocol.ts`, it probably belongs somewhere else.
Expand Down
66 changes: 66 additions & 0 deletions docs/dev-apk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# APK bauen und herunterladen

Im Office: **☰ → APK**. Über **Dev-APK** oder **Store-APK** wählst du die Variante. Jede hat ihren eigenen Build-Button, letzten erfolgreichen Download und teilbaren Link. Bestehende Pins bleiben gültig. Der Eintrag lässt sich oben anheften. Er gehört zum gesamten Projekt, nicht zu einem einzelnen Playtest. Der Tester braucht zuhause kein Unity.

## Ablauf

1. Ein freigeschalteter Nutzer drückt **Dev-APK bauen** oder **Store-APK bauen**. Der Server startet `Tools/Build-Quest.ps1 -Development` beziehungsweise `-Store` auf dem Build-PC. Store nutzt den vorhandenen Release-Ablauf einschließlich Signierung und Versionsnummer. Der Button veröffentlicht nichts bei Meta.
2. Läuft bereits ein Unity-Build oder Test, wartet der Auftrag auf denselben globalen Build-Platz. Status und Protokoll sind sichtbar. Ein zweiter Office-Build wird währenddessen abgelehnt.
3. Der konfigurierte Branch wird frisch abgerufen und auf einen Commit festgelegt. Der gemeinsame Arbeitscheckout wird weder zurückgesetzt noch umgeschaltet. Gebaut wird im vorbereiteten Build-Ordner.
4. Erst nach erfolgreichem Build, vollständiger Kopie und SHA-256-Berechnung wird der Download veröffentlicht. Ein Fehlschlag lässt die letzte erfolgreiche APK unverändert.
5. **APK herunterladen** lädt genau die angezeigte Version. **Download-Link kopieren** liefert einen dauerhaften Link auf die neueste erfolgreiche APK. Der Empfänger benötigt seinen Office-Login.

Der eigene Hintergrundprozess läuft auch bei geschlossenem Browser oder Office-Neustart weiter. Stirbt er, wird der Auftrag als unterbrochen angezeigt. Ein möglicherweise noch laufendes Unity wird nicht beendet; der nächste Build wartet weiterhin auf den gemeinsamen Mutex.

## Einrichtung auf dem Windows-Build-PC

Im Office-Datenordner (`<Office-Home>/.agent-office`, passend zu `--home`) die Datei `dev-apk.json` anlegen. Die Konfiguration wird bei jedem Aufruf neu gelesen und ausschließlich auf dem Server bearbeitet. Browser können keine Befehle, Ordner oder Branches vorgeben.

```json
{
"projects": [{
"repo": "KajoVanBuyten/zombie-reality-breach",
"sourceDir": "E:/source/Unity/zombie-reality-breach",
"buildDir": "E:/source/Unity/zrb-build",
"ref": "origin/main",
"apkName": "ZombieRealityBreach-dev.apk",
"storeApkName": "ZombieRealityBreach.apk",
"launcher": "C:/Users/gp/KaMaStudios/tools/unity-hidden.ps1",
"builders": []
}]
}
```

Voraussetzungen: Node, Git, Windows PowerShell, Unity/Android und der funktionierende ZRB-Build-Ablauf inklusive `Tools/BuildLock.ps1`. `sourceDir` ist ein vertrauenswürdiger Projektcheckout mit den erforderlichen Assets; `buildDir` ist ausschließlich ein wegwerfbarer Build-Checkout, niemals ein Arbeitscheckout. Der Office-Prozess muss Zugriff darauf haben. Der vorhandene Build-Ablauf kopiert seine Ausgabe nach `sourceDir/Builds/Quest`; die Download-Kopie wird noch unter demselben Build-Mutex erstellt.

Für Store muss `storeApkName` den vom Build-Script erzeugten Release-Dateinamen angeben; er muss sich vom Dev-Dateinamen unterscheiden. Fehlt das Feld, bleibt Dev nutzbar und Store-Bauen deaktiviert. Die Release-Signierung bleibt ausschließlich auf dem Build-PC in der vom Spiel verwendeten Signing-Konfiguration. Keine Schlüssel oder Passwörter in die Office-Konfiguration eintragen. Die ZRB-Release-Versionsnummer kommt derzeit aus `yyMMddHH`; mehrere Builds innerhalb derselben Stunde erhalten dieselbe Nummer und sind daher nicht automatisch aufeinanderfolgende Meta-Uploads.

Admins und Nutzer des gemeinsamen Office-Passworts dürfen Builds starten. Für weitere Co-Devs deren **Office-Konto-ID** in `builders` eintragen. Alle angemeldeten Office-Nutzer dürfen herunterladen. Keine Issues oder Worker/Queue-Einträge werden erzeugt.

Der Branch ist in der Oberfläche sichtbar. Für XR-Playtest-Werkzeuge muss der gewählte Stand den Spiel-PR #361 enthalten. Ein Development-Build fügt keine noch nicht integrierten Änderungen hinzu.

## Tunnel und Downloads

Die APK liegt unter derselben Office-Adresse: beispielsweise `https://studios.zombierealitybreach.com/api/dev-apk/download?floor=<Etagen-ID>`. Der vorhandene HTTPS-/SSH-Tunnel transportiert den authentifizierten HTTP-Download. Kein zusätzlicher Port oder lokaler `agent-office tunnel`-Helfer ist nötig.

Die vorhandenen API-Pfade und der Datenordner behalten zur Kompatibilität ihren Namen `dev-apk`. Für Store an Status-, Build- und Download-URL `&kind=store` anhängen. Ohne `kind` oder mit `kind=development` gilt weiterhin Dev, auch für ältere Jobs und Links. Eine Store-Anfrage liefert niemals ersatzweise die Dev-APK.

GET/HEAD, Dateigröße, ETag, Range und If-Range ermöglichen fortsetzbare Downloads. Dateien werden gestreamt. Versionierte Links bleiben während neuer Builds unverändert; If-Range verhindert beim Fortsetzen des „neueste“-Links das Vermischen verschiedener Versionen.

Der Proxy muss Cookies und Range-Header weiterleiten, die API darf nicht öffentlich gecacht werden. `X-Accel-Buffering: no` wird gesendet. Bei nginx gegebenenfalls `proxy_buffering off` und ausreichend langen `proxy_read_timeout` für den Download-Pfad konfigurieren. `client_max_body_size` begrenzt Uploads, nicht diese Downloads. Build-PC und Tunnel müssen online bleiben.

## Installation beim Tester

Im APK-Fenster **Quest verbinden** wählen, das USB-Gerät auswählen und USB-Debugging im Headset bestätigen. Anschließend die neueste Dev-/Store-APK oder eine zuvor heruntergeladene Datei installieren. **Spiel starten** wird nach bestätigter Installation freigeschaltet. Das funktioniert am Rechner des Testers auch über das entfernte Office. Voraussetzungen und Fehlerhilfe: [Auf Quest installieren](quest-browser-install.md).

Alternativ bleibt die Installation mit **Meta Quest Developer Hub** oder `adb install -r <Datei.apk>` möglich. Unity ist nicht nötig. Der Quest-Browser selbst installiert eine heruntergeladene APK nicht automatisch.

Bei anderer Signatur als der Store-Version kann Android das Update ablehnen. Nicht automatisch deinstallieren: Lokale Spieldaten könnten verloren gehen.

Meta verlangt auch für Alpha/Beta/RC die Release-Verpackungsregeln. Für unsere debuggable Dev-APK nutzen wir Sideloading; signierte Release-Builds können über Meta-Testkanäle verteilt werden. Quellen: [Release-Kanäle](https://developers.meta.com/horizon/resources/publish-release-channels/) und [Manifest-Regeln](https://developers.meta.com/horizon/resources/publish-mobile-manifest/).

## Speicherung und Prüfung

Unter `<Office-Datenordner>/dev-apk/` liegen Aufträge, Protokolle und APKs. Pro Variante bleiben die letzten drei erfolgreichen APKs erhalten. Store-Veröffentlichungen löschen keine Dev-APKs und umgekehrt. Ältere APK-Dateien werden nach erfolgreicher Veröffentlichung entfernt; Metadaten und Logs bleiben bestehen. Partielle oder fehlgeschlagene Builds ersetzen niemals den neuesten erfolgreichen Download.

Prüfung: `npm run typecheck`, `npm test`, `npm run build`; gezielt `node --import tsx --test tests/dev-apk.test.ts tests/size.test.ts`; Browser-Abnahme `node --import tsx tests/dev-apk-browser.mjs`. HTTP-/Browser-Tests mit Testdateien sind getrennt von echten Unity-Builds, öffentlichen Tunnel-Downloads und Headset-Installation zu berichten.
48 changes: 48 additions & 0 deletions docs/external-review-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Externe Code-Review und Übergabe an das Office

Dieser Prompt ist für Claude außerhalb des Office gedacht. Gib ihm Zugriff auf das Spiel-Repository und seine GitHub-Issues/PRs. Vorhandene Playtests und Entscheidungen zusätzlich aus dem Office exportieren beziehungsweise bereitstellen, damit auch dort keine Duplikate entstehen. Die Worker-Hook-Befehle funktionieren nur in einer autorisierten Office-Worker-Sitzung; keine internen Worker-Tokens an den externen Reviewer weitergeben.

## Kopierbarer Prompt

Prüfe den aktuellen Stand dieses Repositories gründlich und gleiche deine Befunde mit den vorhandenen Issues und Pull Requests ab. Arbeite als Reviewer: keine Implementierung, keine Merges, keine Queue-Änderungen und keine Worker starten. Änderungen anderer Personen bleiben unberührt.

1. Ermittle den tatsächlich geprüften Commit und lies die Repository-Regeln. Lade die offenen Issues inklusive Beschreibung, Labels und relevanter Kommentare sowie offene und kürzlich gemergte PRs. Prüfe bei vermeintlichen Duplikaten auch geschlossene Issues. Berücksichtige die bereitgestellten Playtest- und Entscheidungslisten. Wenn dir etwas davon fehlt, kennzeichne den Abgleich dort als unvollständig.
2. Suche zuerst konkrete Fehler, Regressionen und fehlende Anforderungen. Belege jeden Befund mit Datei/Funktion, genauer Fundstelle, Auslöser, tatsächlichem und erwartetem Verhalten sowie praktischer Auswirkung. Kennzeichne Hypothesen und ungetestete Hardware-Annahmen. Behaupte keine Quest-, Koop- oder LAN-Verifikation ohne tatsächlichen Test.
3. Ergänzungsideen separat als Vorschläge kennzeichnen. Eine Geschmackssache ist kein Bug. Beschreibe Nutzen, Umfang, Aufwand/Risiko und mögliche Abhängigkeiten. Erfinde keine Anforderung, um ein Issue zu rechtfertigen.
4. Vergleiche vor dem Anlegen jeden Befund semantisch mit bestehenden Issues/PRs. Bei gleichem Problem ein bestehendes Issue mit neuen Belegen ergänzen statt ein Duplikat anzulegen. Bereits implementierte und gemergte Lösungen nicht erneut als offene Entwicklungsarbeit melden.
5. Trenne die Ergebnisse nach Zuständigkeit:
- **Worker-Task → GitHub-Issue:** konkrete Code-, Asset-, Build-, Dokumentations- oder automatisierte Testarbeit. Neue Bugs und eigenständige, begründete Erweiterungsvorschläge dürfen als Issues angelegt werden. Ein Issue enthält Problem/Nutzen, Belege, abgegrenzten Arbeitsumfang, technische Akzeptanzkriterien und Abhängigkeiten. Vorhandene Label-Konvention verwenden. Bloße manuelle Nachprüfung ist kein technisches Akzeptanzhindernis.
- **Entscheidung → Entscheidungspool:** eine echte Produkt-/Design-/Prioritätsfrage an den Eigentümer. Frage, Kontext, zwei oder mehr Optionen mit Auswirkungen, Empfehlung, Kategorie, Tags und betroffene Issue-Nummern liefern. Nur dann als blockierend kennzeichnen, wenn konkrete Entwicklungsarbeit ohne Antwort tatsächlich nicht sinnvoll fortgesetzt werden kann; genau diese Arbeit und den Grund nennen. Routine-Implementierungsdetails nicht unnötig eskalieren. Eine Entscheidung niemals selbst als beantwortet markieren.
- **Playtest → persönliche Playtest-Checkliste:** manuelle Quest-, Sicht-, Spielgefühl-, Hardware- und Mehrspielerprüfungen. Titel, Vorbereitung, konkrete Schritte, erwartetes Ergebnis, Kategorie, Modus, Spielweise und Quell-Issue/PR angeben. Offen lassen. Ein Playtest bleibt auch nach einem Merge offen, bis der Mensch den tatsächlich geprüften Build und das Ergebnis erfasst.
6. Bei gemischten Befunden den umsetzbaren Teil als Issue behalten und Entscheidung/Playtest separat mit gegenseitigen Verweisen übergeben. Ein reproduzierter Fehler aus einem Playtest bekommt ein Bug-Issue; der Test selbst bleibt in der Checkliste. Keine zusätzlichen GitHub-Issues allein als Ablage für Entscheidungen oder manuelle Tests anlegen.
7. **Ausschließlich der Eigentümer entscheidet, welche Issues wann in die Queue kommen.** Nichts einreihen, requeuen, einem Worker zuweisen oder durch Queue-/In-progress-Labels aktivieren. Keine bestehenden Prioritäten oder Bearbeitungszustände ungefragt ändern.
8. Wenn du direkten autorisierten Office-Zugriff hast, nutze dessen jeweiligen Entscheidungspool und Playtest-Checkliste. Ohne diesen Zugriff liefere zusätzlich `office-review-handoff.json` zur Übernahme durch den Issue-Agent. Behaupte nicht, diese Einträge bereits im Office erstellt zu haben. Die JSON-Datei ist eine Übergabe, kein bereits vorhandener automatischer Importer.

Format für `office-review-handoff.json`:

```json
{
"reviewedCommit": "vollstaendiger Commit-SHA",
"workerIssues": [{"url": "https://github.com/OWNER/REPO/issues/123", "action": "created-or-updated"}],
"decisions": [{
"title": "Kurzer Titel", "question": "Konkrete Frage?", "context": "Befund und Auswirkungen",
"options": ["Option A: Auswirkung", "Option B: Auswirkung"], "recommendation": "Empfehlung mit Grund",
"category": "Design & UX", "tags": ["menue"], "issues": [123],
"blocking": false, "blockingReason": ""
}],
"playtests": [{
"title": "Konkreter manueller Test", "setup": "Voraussetzungen und Build",
"steps": "1. Schritt\n2. Schritt", "expected": "Beobachtbares Soll-Ergebnis",
"category": "Menü", "modes": ["RIFT"], "playStyles": ["solo"],
"source": "https://github.com/OWNER/REPO/issues/123"
}]
}
```

Zulässige Entscheidungskategorien: Spielablauf, Design & UX, Technik, Assets, Release, Organisation, Sonstiges. Playtest-Modi: Allgemein, RB, RIFT, Rooftop, Safe Zone, Gas Station. Spielweisen: solo, local-coop, online-coop; leere Liste bedeutet alle. Mehrere Modi nur angeben, wenn der Test tatsächlich für sie gilt. Reality Breach/RB nicht mit RIFT verwechseln.

Abschluss: geprüften Commit, gefundene Probleme nach Schwere, angelegte/ergänzte Issues mit Links, vermiedene Duplikate, Entscheidungen, Playtests und nicht verifizierte Annahmen auflisten. Queue bleibt unverändert.

## Übergabe an den Issue-Agent

Die JSON-Datei bereitstellen und den Issue-Agent anweisen: „Gleiche diese Review-Übergabe mit den vorhandenen Issues, Entscheidungen und Playtests ab. Übernimm fehlende Entscheidungen in den Entscheidungspool und manuelle Tests als offen in die Playtest-Checkliste. Ergänze gegenseitige Links. Erstelle keine redundanten Issues, starte keine Worker und ändere die Queue nicht. Berichte anschließend die tatsächlich gespeicherten Einträge.“
Loading