# dsh-mobile-upgrade

[English](../../README.md) | [简体中文](../zh-Hans/README.md) | [繁體中文](../zh-Hant/README.md) | [日本語](../ja/README.md) | [한국어](../ko/README.md) | [Español](../es/README.md) | [Français](../fr/README.md) | Deutsch | [Русский](../ru/README.md)

Mobilfreundliche Verbesserungen für das Web-Profil von [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`), ausgeliefert als ein einzelnes Plugin. Fast alles rendert über die eigenen Slots und Zustandssignale des Hosts — keine Layout-Übernahme, kein DOM-Polling des Chats. Einige Overlays sind absichtlich fest positioniertes reines DOM — der Verbindungschip/die Verbindungskarte unten links, das Selbstaktualisierungs-Banner, der gemeinsame Toast: Sie müssen gerade dann überleben, wenn der React-Baum des Hosts eingefroren ist.

## Was Sie bekommen

- **Neustart-Zeile** — ein Eintrag „Dienst neu starten" unter Einstellungen → Allgemein. Fragt zuerst nach, startet den `dsh`-Prozess neu und lädt die Seite automatisch neu, sobald der Dienst wieder antwortet.
- **Drawer für schmale Bildschirme** — unter 1024px wird die eingeklappte Seitenleiste vollständig außerhalb des Bildschirms geparkt, und der eingeklappte Look gehört zum eigenen schwebenden Button des Plugins: ein reines-DOM-Element, rund, halbtransparent, 56px — nicht die Seitenleiste (der alte Chip war die Seitenleiste selbst, verkleinert — er brach bei Host-Rebuilds und Skin-Restyles). Er trägt sein eigenes Icon — den Wal des Hosts, geklont und von Stil-Hooks befreit — in einer fixierten Größe, die keine Skin ändern kann. Ein Tippen lässt das Plugin den Rail des Hosts zum Ausklappen treiben und die Seitenleiste in voller Höhe von der Button-Seite hereingleiten, sobald der ausgeklappte Inhalt gemountet ist; der Button blendet aus, solange der Drawer steht, und ein Schließen-Tipp (Scrim, Sitzungszeile oder Umschalter im Drawer-Kopf) schiebt ihn im selben Frame wieder heraus. Die Breite des Panels ändert sich nie mehr, das Slide ist reines transform und kann nicht auf halbem Weg einfrieren; der ausgeklappte Drawer erhält weiterhin eine opake Fläche aus den eigenen Seitenleisten-Tokens des Themas, die eine Glas-Skin nicht transparent machen kann. Der Button bleibt an jeden Rand ziehbar; der Drawer öffnet von der Seite, an der er hängt.
- **Scrollbare Fragekarte** — unter 1024px kann eine offene Frage ihre eigenen Optionen nicht mehr aus dem Bild drängen: Die Frage bekommt einen eigenen, höhenbegrenzten Scrollbereich, sodass eine lange Frage an Ort und Stelle scrollt, während die Optionsliste darunter den verbleibenden Platz behält und die Optionen, die Sendezeile und die Schaltflächen zum Minimieren und Schließen auf dem Bildschirm bleiben und erreichbar sind. Eine kurze Frage bleibt unangetastet, und die Karte umschließt weiterhin ihren Inhalt.
- **Sturmsichere Reaktivität** — die Drawer-/Menü-Beobachter und der Settings-Poller reagieren auf einen Burst von Streaming-Nachrichten mit gedrosselter Rate und gehen in Backoff, solange der Host nicht erreichbar ist; ein Rail-Remount während einer Wiederverbindung hält den Drawer-Zustand statt ihn flackern zu lassen, und Drawer-Schließen-Tipps wiederholen sich durch einen Remount, statt auf einem veralteten Umschalter zu landen: viele gleichzeitig streamende Sitzungen frieren die Eingabe nicht mehr ein und zucken die Seitenleiste nicht mehr unklickbar — ob offen oder geschlossen.
- **Guard für den Subagenten-Katalog** — der Host dient den Subagenten-Katalog, indem er pro Anfrage das gesamte Sitzungskorpus aufzählt (~1s bei langer Historie), und sein Client fragt bei jeder Auswahl, jedem Chip-Hover und jedem Membership-Ereignis nach. Das Plugin wrappt diesen Refresh: Ein Eltern-Agent ohne Kinder in der Live-Sitzungsliste wird nie gefragt, ein Eltern-Agent wird höchstens einmal pro 2,5s erneut gefragt, und Refresh-Starts werden zeitlich versetzt — ein Subagenten-Fan-Out hungert den Host nicht mehr mit Full-Corpus-Scans aus.
- **Per Klick öffnende Lineage-Chips** — auf dem Desktop öffnen sich die Subagenten-Chips („N subagents" und der Subagenten-Titel-Umschalter) im aktuellen Host nur beim Hover; ein Klick tut nichts. Das Plugin übersetzt einen Klick auf einen Chip in das Hover-Ereignispaar, das der Host bereits versteht, sodass ein Klick den Baum öffnet und schließt (Crumbs der Vorfahren behalten ihr Navigate-on-Click).
- **Header-Collector auf schmalen Bildschirmen** — unter 1024px sind die Chips des Sitzungs-Headers (Lineage, Jobs, Preset) breiter als das Telefon und nur per Hover bedienbar. Sie falten sich zu einem Pill (`≡ Titel · N agents · M jobs`); ein Tip darauf öffnet ein Sheet in voller Breite mit der Session-Lineage (jeder Vorfahr antippbar, jeder mit seiner Nachfahrenzahl), dem am Familien-Root verwurzelten Subagenten-Baum — Zeilen rendern aus der Live-Sitzungsliste, Zweige holen ihren Katalog on demand über den bewachten Refresh — und den Hintergrund-Jobs dieser Sitzung. Auf dem Desktop ändert sich nichts.
- **Selbst-Update** — das Client-Bundle wird pro Revision unveränderlich ausgeliefert, daher kann ein Telefon-Tag tagelang einen älteren Build weiterlaufen lassen. Die Seite vergleicht die Revision, mit der sie gebootet hat, mit der, die der Server jetzt veröffentlicht, und lädt sich selbst neu, sobald die Seite idle ist (nie, während ein Entwurf getippt wird), oder bietet ein antippbares Banner an.
- **Render-Drossel der Sitzungsliste** — der Host sendet für jede Projektionsänderung jeder angehängten Sitzung ein Ganzwert-Frame, und die Timing-Ansicht eines laufenden Subagenten ändert sich mit jedem committeten Event — eine beschäftigte Hintergrund-Flotte streamt also 50-150 Frames/s in die Seite. Jedes Frame renderte bisher die gesamte Sitzungsliste neu (ein Rebuild läuft über jede Summary plus einen O(n²)-Cache-Sweep — gemessen als der Großteil der Main-Thread-Zeit; die Seite fror bis zum Neuladen). Das Plugin fasst diese Re-Renders auf ein adaptives Trailing-Intervall zusammen, während die Werte unverändert weiter in die Per-Sitzungs-Stores fließen — Hintergrund-Streaming friert die Seite nicht mehr ein, egal welche Sitzung offen ist.
- **Verbindungskarte** — das Verbindungssteuerelement unten links im Host reagiert auf einen Klick mit nichts Beobachtbarem: Die angeforderte Neuverbindung taucht zurück in denselben verklemmten Transport, die Wiederherstellungsanzeige ist ein nicht klickbares div, das nach einem Timer verschwindet, und die schmale Rail/Drawer-Seitenleiste rendert es ohnehin nicht. Dieses Plugin verankert den Status mit einem reinen-DOM-Chip in dieser Ecke (lebendig sogar, wenn der React-Baum des Hosts eingefroren ist) und lässt darüber eine semi-permanente Karte aufploppen: Sie bleibt, solange der Zeiger darin ist, blendet sich sonst automatisch aus und führt die beiden Aktionen mit, die wirklich wirken — eine sofortige Neuverbindung über den Verbindungsdienst und ein vollständiges manuelles Neuladen der Seite. Hängende oder fehlgeschlagene `/api/`-Anfragen erscheinen am selben Ort: ein Badge mit Zähler auf dem Chip, in der Karte eine Anfragenliste samt Lebenszeichen-Probe — so viele Anfragen auch hängen oder scheitern, neben den Composer-Steuerungen erscheint künftig keine Warnung mehr.
- **Schalter pro Funktion** — das Plugin installiert einen Abschnitt `dsh-mobile-upgrade` unter Einstellungen → Plugins mit einem Schalter pro Funktion.

## Screenshots

Schwebender Button, Session-Drawer, Einstellungen als Tabs auf schmalen Bildschirmen und der Header-Collector (mit Beschriftung):

| | |
|---|---|
| ![Schwebender Button](../../res/shot-floating-chip.png) | ![Session-Drawer](../../res/shot-drawer.png) |
| ![Einstellungen-Tabs](../../res/shot-settings-tabs.png) | ![Header-Collector](../../res/shot-header-collector.png) |

## Installation

```sh
dsh plugin --profile web add dsh-mobile-upgrade
```

Starten Sie `dsh web` neu und öffnen Sie das Web-Profil auf dem Telefon: Die Neustart-Zeile findet sich unter Einstellungen → Allgemein und die Funktionsschalter unter Einstellungen → Plugins → dsh-mobile-upgrade. Anhänge kommen aus dem eigenen Anhang-System des Composer des Hosts.

Erfordert `dsh` 0.2.0-rc.2 oder neuer (das eingebaute Anhang-System des Hosts hat die Upload-Funktion dieses Plugins ersetzt).

## Konfiguration

Die Einstellungskarte des Plugins listet einen Schalter pro Funktion (siehe Funktionsschalter); `restartEnabled` steuert zusätzlich die Neustart-Route:

| Schlüssel | Standard | Bedeutung |
|---|---|---|
| `restartEnabled` | `true` | Neustart-Zeile und ihre Route anbieten |

## Funktionsschalter

Jede der obigen Funktionen lässt sich unter Einstellungen → Plugins → dsh-mobile-upgrade umschalten (wirksam beim nächsten Laden der Seite) oder pro Gerät mit einem `localStorage`-Schlüssel überschreiben — `mfx-restart`, `mfx-drawer`, `mfx-net`, `mfx-questions`, `mfx-selfupdate`, `mfx-agents`, `mfx-header`, `mfx-listthrottle`, `mfx-conn` — wobei der Wert `"0"` die Funktion ausschaltet.

## Bekannte Einschränkungen

- Der Client hängt sich über gehashte CSS-Klassennamen an bestimmte Elemente der Host-Oberfläche (Menü, Drawer-Umschalter, Provider-Editor, Sitzungs-Header-Chips). Benennt ein Host-Build diese um, degradieren die betroffenen Funktionen, bis dieses Plugin nachzieht; alles andere funktioniert weiter. Der Fragebereich der Fragekarte wird stattdessen über deren eigenen Hook `data-question-key` gefunden, sodass er auch dann weiter funktioniert, wenn ein Host-Neubau lediglich seine CSS-Module neu hasht.
- Der Header-Collector und der Lineage-Klick-Shim reiten auf den eigenen Daten des Hosts (der Live-Sitzungsliste und ihren Subagenten-Katalogen); sie fügen außer den bewachten Zweig-Fetches keine Requests hinzu, und ein Tap auf eine Zeile, deren Modus noch lädt, vervollständigt sich von selbst, sobald der Katalog eintrifft.
- Eingabemodalitäts-Schalter können nur Provider-Routen patchen, die Sie selbst angepasst haben; reine Katalogrouten sind absichtlich nur lesend, weil eine erfundene Katalogsektion das Modellverzeichnis zum Einsturz bringt.

## Sicherheitshinweise

Die HTTP-Routen des Plugins (Neustart, Einstellungsänderungen) nehmen keine eigene Authentifizierung vor — sie vertrauen der `dsh`-Web-Oberfläche, in die sie geladen werden. Bevor Sie die Bereitstellung über localhost hinaus freigeben, stellen Sie sie hinter dieselbe Schranke wie den Rest der Oberfläche (Reverse-Proxy-Auth, Loopback-Bindung).

## Community-Links

- [Linux.Do](https://linux.do) — Eine Community zum Teilen und Diskutieren von Technik.

## Lizenz

Vertrieben unter der [Synthetic Source License (SySL), Version 1.0](LICENSE).

> HINWEIS: Diese Software enthält von künstlicher Intelligenz generierten Code. Siehe die LICENSE-Datei für die Bedingungen der Synthetic Source License, einschließlich der Anforderungen zur Modelloffenlegung.
