Befehlsausgabe, Dokumente und Vorschauen
Wie Befehlsausgabe erfasst und in Bereichen gelesen wird, wie HTML-Dokumente auf drei Plattformen in einem abgeschotteten Ursprung laufen, wie Webseiten zu Markdown werden und wie Dateien in Blöcken übertragen werden.
Gegen den Quellcode geprüft am 17. September 2026
Auf dieser Seite
Befehlsausgabe als Artefakt
- Live-ZeilecommandOutput.artifact
Der Desktop hängt jedes Ausgabe-Delta an sein Artefakt an, bevor sich die Zeile ändert, und sendet dann runId, byteLength, generation, complete und sourceIncomplete höchstens alle 100 ms pro Befehl. Kein Ausgabe-Byte gelangt in die Timeline.
- Bereichslesenrun.codexChatCommandOutputRead
Nur ein offener Betrachter liest, 1 Byte bis 256 KiB pro Anfrage, und appSessionId bindet den Lesezugriff an die besitzende Basis-Session. Eine Generation, die das Artefakt nicht mehr hält, wird mit einem Konflikt beantwortet, und der Betrachter aktualisiert die Zeile, bevor er erneut liest. Telefone rufen ihn über das Relay auf, der Betrachter auf dem Desktop ruft denselben Lesezugriff direkt auf.
- Abschlussitem/completed
Der Desktop vergleicht seine Bytes mit dem aggregatedOutput von Codex, den Codex auf 1 MiB begrenzt. Identische Bytes markieren das Artefakt nur als vollständig. Abweichende Bytes ersetzen es als nächste Generation, und eine bekannte Kürzungsmarke in diesem Text setzt sourceIncomplete.
- Abgeschlossene ZeileprotocolOutput
Sobald thread/items/list den Befehl liefert, zeigt die Zeile auf die Mitschnittdatei, die Codex während des Laufs geschrieben hat, und ein offener Betrachter auf dem Desktop folgt ihr über die unveränderte Block-ID. Der Desktop leitet Lesezugriffe als thread/commandOutput/read weiter und prüft die zurückgegebene Identität. capturedComplete ist false, wenn Codex keinen vollständigen Mitschnitt behalten hat.
HTML-Dokumente in einer Sandbox
- Ressourcenwurzelopen_html_preview_command
Der Projektordner, wenn er das Dokument enthält, sonst der eigene Ordner des Dokuments. Der Aufrufer erzeugt die Vorschau-UUID, und der Desktop weigert sich, diese ID an ein zweites Dokument zu binden.
- Pfadprüfungptc-document://<preview-id>.localhost/<path>
Der Handler weist einen dekodierten Pfad mit .., einem Backslash, einem Doppelpunkt oder NUL ab, liefert für einen Ordner index.html und antwortet mit 404, wenn der kanonische Pfad fehlt oder die Wurzel verlässt.
- Sandboxsandbox allow-scripts
Skripte, Module und fetch laufen in einem opaken Ursprung ohne Zugriff auf die Seite oder den Speicher der App. Eine Nachricht plantocode.html.open oder plantocode.html.ready aus diesem Frame ist das Einzige, worauf die App reagiert, und nur für eine Datei unter der Wurzel oder eine http(s)-Seite.
- Telefonefiles.readHtmlPreviewResource
Die iPhone-App unter ptc-document://<preview-id>.localhost und die Android-App unter https://ptc-<preview-id>.invalid lösen dieselben Pfade über den Desktop auf, in geprüften Blöcken von bis zu 4 MiB und ohne Skriptbrücke in die App.
Das Protokoll antwortet auf OPTIONS mit 204, bedient nur GET und HEAD, setzt Cache-Control no-store und X-Content-Type-Options nosniff und hängt navigation.js nach dem Dokumentende an, ohne die Datei zu berühren; dieses Skript sendet plantocode.html.open an den Elternteil und blockiert jedes Schema außer ptc-document und http(s). Lokale Links in einem Dokument gehen deshalb in den Vorschauverlauf ein, Weblinks öffnen sich in der Webvorschau, und Neu laden oder eine Dateiänderung aktualisiert die Darstellung.
Webseiten als Markdown
Ein Weblink öffnet sich als Markdown-Darstellung statt als Live-Seite. Die WebView extrahiert den Artikelinhalt und wandelt ihn mit einer GFM-fähigen Turndown-Pipeline um, die Rust-Seite wandelt mit quick_html2md für Inhalte um, die die WebView nie erreichen, und die Browser Bridge hat einen dritten, handgeschriebenen DOM-zu-Markdown-Renderer, dessen Ausgabe der Desktop als capturedBrowserMarkdown speichert und mit derselben Titelkopfzeile umschließt. Drei Konverter, ein Zielformat.
Dateizugriffe und Übertragungen
files.readContent liefert ein Textdokument von höchstens 2 MiB; eine größere Datei scheitert mit „Text preview is too large“. Die Anfrage trägt projectDirectory, path sowie optional encoding und allowExternalFile, wobei encoding akzeptiert, aber ignoriert wird; sie hat keine Block-Offset- oder Medienfelder, weil Text- und Binäranfragen getrennt bleiben. files.readBinary und files.readMediaRendition lesen sequenzielle Blöcke ab Offset null. Jede Antwort trägt offset, nextOffset (null am Dateiende), dataBase64, byteCount, contentVersion, modifiedAt und mimeType, und Renditionen ergänzen originalByteCount. Benachbarte Grenzen: Medienrenditionsquellen bis 1 GiB, Stream-Transkodierungen bis 256 MiB mit 40-Sekunden-Timeouts, Medienbereichslesezugriffe von 1 MiB und Chat-Anhang-Uploads in 1-MiB-Blöcken, höchstens 2.048 davon.
- Blocklesenfiles.readBinary
Jede Anfrage nennt den Pfad und einen Offset. Der Desktop öffnet die Datei, liest dort bis zu 4 MiB und antwortet mit dem nächsten Offset, dem gesamten byteCount und einer contentVersion. Ressourcen der HTML-Vorschau und Medienrenditionen nutzen denselben Leser.
- Festgehaltene VersioncontentVersion
Bei files.readBinary ist sie ein Hash aus Pfad, Größe und Änderungszeit, gebildet bei jedem Öffnen der Datei. Beide Telefone behalten Version und Größe der ersten Antwort und verwerfen den ganzen Lesevorgang, wenn eine spätere Antwort abweicht. Eine Datei, die unter den Offset geschrumpft ist, erhält dieselbe Meldung vom Desktop.
- Relay-FrameDEVICE_LINK_MAX_FRAME_BYTES
Ein Block von 4 MiB ergibt etwa 5,3 MiB base64, daher bleibt jede Antwort weit unter der Frame-Grenze des Relays von 32 MiB, und die Datei selbst hat keine Größengrenze.
Syntaxhervorhebung
Quellvorschauen auf dem Desktop nutzen Shiki-Grammatiken, und jede Telefon-App hebt mit ihrer eigenen Engine hervor.