img-share Skill
Mache Browser-Screenshots oder lokale Bilder zu anklickbaren Großbildern im Chat (Vorschaubild + Vollbild beim Klicken), die auch vom Handy/anderen Geräten aus erreichbar sind. Plattformübergreifend (Linux/macOS/WSL/Windows nativ).
whenToUse (Wann auslösen)
- Der Benutzer möchte einen Screenshot einer bestimmten Website/Seite im Chat haben.
- Ein Bild wird in den Chat eingefügt und soll „auch auf dem Handy sichtbar sein und zum Vergrößern klickbar“ sein.
- Ein Arbeitsbereichsbild soll als klickbares, eingebettetes Großbild im Chat geteilt werden.
Abhängigkeiten
| Abhängigkeit | Zweck | Bezug |
|---|---|---|
| web-access skill | Screenshot (CDP-gesteuerter Browser) | Muss installiert: https://github.com/eze-is/web-access |
| python3/python | Orchestrierung (serve.py) | Systemintegriert |
| cloudflared | Öffentlicher Tunnel als Fallback | Mac: brew install cloudflared; Win: winget install Cloudflare.cloudflared; Linux: siehe offizielles README; oder setze CLOUDFLARED=/Pfad |
| ffmpeg (optional) | Mehrere Bilder zu einem Grid zusammenfügen | Systeminstallation (wird von scripts/montage.sh genutzt) |
Ausführungsschritte
-
Host-Erreichbarkeitsprüfung (zwingend, zuerst) – Bestimmt die Basis-URL der Bilder und ob ein separater öffentlicher Tunnel nötig ist. Die Bildadresse muss der Host-Adresse folgen – es darf nicht eigenständig ein Tunnel mit anderer Herkunft als der Host geöffnet werden, nur weil es „funktioniert“.
Prüfung Ergebnis (Aktion) Host ist bereits getunnelt/öffentlich erreichbar (der Benutzer erreicht die Sitzung genau über diese Adresse) und der Host stellt einen statischen Bildpfad bereit (z. B. /img/*)Bild in das statische Host-Verzeichnis legen und mit der öffentlichen Host-Adresse einbetten. Keinen neuen Tunnel öffnen. Host öffentlich erreichbar, aber ohne statischen Bildpfad Nicht stillschweigend ausweichen: zuerst dem Benutzer mitteilen, dass der Host eine statische Bildzuordnung benötigt; nur mit ausdrücklicher Zustimmung des Benutzers den „expliziten unabhängigen Tunnel-Fallback“ verwenden. Host nur localhost (z. B. DSH_WEB_URL=http://127.0.0.1:*, kein öffentlicher Tunnel)Das Bild wäre nur lokal/lokalnetz erreichbar, das Handy erreicht die Sitzung ohnehin nicht. – Zuerst den Benutzer auffordern, DSH öffentlich zu machen, oder nach Zustimmung den expliziten Fallback verwenden. Es ist verboten, eine localhost-/127.0.0.1-Adresse einzubetten und zu behaupten, das Handy könne sie sehen. Keine Erkennung möglich / unsicher Nicht raten, zuerst den Benutzer fragen: „Welche Adresse verwendest du auf deinem Handy, um auf diese Sitzung zuzugreifen (öffentliche Domain oder localhost)?“ Dann gemäß obiger Tabelle vorgehen. Erkennungsmethode: Umgebungsvariablen lesen (
DSH_WEB_URL,DSH_PUBLIC_BASE,DSH_IMG_BASEusw.), statische Host-Routing-Konfiguration prüfen; falls nichts gefunden wird, gilt der Host als „nicht bereitgestellt“ – gemäß Tabelle „Benutzer fragen/hinweisen“, kein stillschweigendes Öffnen eines anderen Tunnels.Host-Vertrag (vorausschauende Vereinbarung, aktuell vom DSH-Host noch nicht bereitgestellt): Wenn der Host
DSH_PUBLIC_BASE/DSH_IMG_BASEoder eine äquivalente statische Pfaddeklaration bereitstellt, muss der Agent die Bilder vorrangig unter der Host-Domain ablegen; falls nicht bereitgestellt, nicht annehmen, dass es existiert. -
Screenshot (falls nötig): Verwende die web-access-Fähigkeit,
/screenshot, um die Seite als PNG zu rendern.- Falls CDP/Chromium in einer eingeschränkten Umgebung nicht startet (kein Netzwerkzugriff, Prozessabsturz), auf Cloud-Screenshot zurückfallen: thum.io / mshots / microlink usw. mit
?wait=N&width=W; nach Erhalt prüfen, ob „Anteil nicht-weißer Pixel > Schwellwert“ und „Farbcluster-Anzahl > N“; nur wenn nicht leer, verwenden.
- Falls CDP/Chromium in einer eingeschränkten Umgebung nicht startet (kein Netzwerkzugriff, Prozessabsturz), auf Cloud-Screenshot zurückfallen: thum.io / mshots / microlink usw. mit
-
Bild speichern: In das Arbeitsverzeichnis legen (z. B.
img/x.png; Dateiname ASCII/keine Leerzeichen). -
Teilen (je nach Schritt-0-Ergebnis eine von zwei Optionen):
- Host-Pfad (wenn Schritt 0 ergibt, dass der Host wiederverwendet werden kann): Das Bild in das vom Host bereitgestellte statische Verzeichnis legen, einbetten als
https://<Host-Domain>/img/x.png. Keinen unabhängigen Tunnel öffnen. - Expliziter Fallback (wenn Schritt 0 ergibt, dass ein Fallback nötig ist und der Benutzer zugestimmt hat): Nur diese eine Datei teilen, nicht das ganze Verzeichnis öffnen; Bildserver [nur Loopback] + öffentlicher Tunnel, End-to-End-Prüfung, Ausgabe von PUBLIC_BASE:
bash <skill>/scripts/setup.sh <img>/x.png # Unix/WSL python <skill>/scripts/serve.py --share <img>/x.png # Windows nativ
- Host-Pfad (wenn Schritt 0 ergibt, dass der Host wiederverwendet werden kann): Das Bild in das vom Host bereitgestellte statische Verzeichnis legen, einbetten als
-
In Antwort einbetten (Vorschaubild = Original-URL, klicken öffnet Vollbild):
[](https://<Basis>/x.png)Die Basis muss das Ergebnis von Schritt 0 sein (öffentliche Host-Adresse oder vom Benutzer zugestimmte explizite Tunneladresse). Es ist verboten, localhost/127.0.0.1 einzubetten und zu behaupten, das Handy könne es sehen. Teile dem Benutzer mit: Im Chat wird das Vorschaubild angezeigt, bei Klick wird das Original geöffnet; das Handy kann dieselbe öffentliche Adresse verwenden (DSH wurde getestet, um öffentliche Markdown-Bilder darzustellen).
-
Nach dem Teilen → Tunnel abbauen (nur beim expliziten Fallback, um dauerhafte Offenlegung zu vermeiden):
bash <skill>/scripts/teardown.sh # Bildserver+Tunnel+Reinigung stoppen
Fehlerbehandlung
- Host-Erreichbarkeit nicht bestimmbar: Nicht raten, nicht stillschweigend einen anderen Tunnel öffnen; zuerst den Benutzer fragen, welche Adresse er auf dem Handy für die Sitzung verwendet (siehe Schritt 0).
- Host öffentlich, aber kein statischer Bildpfad: Benutzer auffordern, eine statische Zuordnung zu konfigurieren, oder nach Zustimmung den expliziten Fallback verwenden und darauf hinweisen, dass dieser eine andere Herkunft als der Host hat.
- Fehlende Abhängigkeiten: serve.py meldet „cloudflared/python fehlt“; installieren oder
CLOUDFLAREDsetzen; fehlender Screenshot von web-access → Cloud-Screenshot-Fallback (siehe oben) oder Benutzer auffordern, das Bild selbst hochzuladen. - Port belegt: serve.py wählt automatisch einen freien Port.
- Tunnel-Domain nicht abrufbar (langsames Netzwerk/Cloudflare-Verbindungsabbruch): serve.py wiederholt die Abfrage mit Polling; falls immer noch fehlschlägt, dem Benutzer mitteilen „Netzwerk kann keinen Tunnel aufbauen“, zurückfallen auf nur lokal/LAN (lokale Adresse angeben und erklären, dass für das Handy-Szenario der Host/Dienst zuerst öffentlich erreichbar sein muss).
- End-to-End-Prüfung fehlgeschlagen: serve.py führt einen curl auf die tatsächliche Datei durch und prüft auf HTTP 200; bei Fehlschlag sofort abbauen, um eine „scheinbar live, aber tatsächlich 404“-Situation zu vermeiden.
- Domain-Drift: Schnelltunnel ändern beim Neustart die Domain; alte eingebettete URLs werden ungültig; Host-Pfad hat dieses Problem nicht; für langlebige Stabilität im Fallback-Szenario benannte Tunnel/feste Domains verwenden.
Umgebungs-Selbstprüfung (Agent zuerst ausführen)
Vor Beginn prüfen: Kann auf das öffentliche Netz zugegriffen werden (curl auf eine öffentliche Adresse)? Kann ein Browser-Prozess gestartet werden (CDP)? Ist der Host öffentlich erreichbar (siehe Schritt 0)? Weder ausgehendes Netz noch CDP möglich → Cloud-Screenshot + Hinweis, dass höhere Berechtigungen nötig sind; nicht einfach ein Bild ausliefern, das „aussieht, als ob es funktioniert, aber in Wirklichkeit kaputt ist“.
Sicherheit (Standardaktionen, keine Hinweise)
- Nur die angegebene Datei teilen: serve.py kopiert die zu teilende Datei in ein zufällig benanntes Unterverzeichnis und startet dann den Dienst – auf keinen Fall das gesamte
img/-Verzeichnis öffnen (sonst könnte die Tunnel-URL alle Dateien in diesem Verzeichnis auflisten/herunterladen); beim Host-Pfad ebenfalls nur die zu teilende Datei ablegen. - Bildserver bindet nur an 127.0.0.1 (nicht direkt aus dem LAN erreichbar); öffentliche Tunnel-URL ohne Authentifizierung – nach dem Teilen sofort teardown.
- Für höhere Sicherheit: der URL einen zufälligen Token hinzufügen / kurzlebige Tunnel verwenden; keine sensiblen Bilder teilen.
- Nicht alle Bilder öffentlich machen: Nur das/die „diesmal zu teilende(n)“ Bild(er) in einem öffentlich zugänglichen Verzeichnis/Tunnel platzieren.
Host-Tunnel bevorzugen (siehe Schritt 0 der Ausführungsschritte)
- Bildadresse folgt der Host-Adresse: Ist der Host bereits getunnelt/öffentlich, sollen die Bilder unter derselben Domain des Hosts abgelegt werden (z. B. statischer Pfad
/img/*) – der Benutzer lädt sie auf dem Handy in der Sitzung, kein separater Tunnel mit anderer Herkunft nötig und sollte auch nicht geöffnet werden. - Wenn der Host über dsh-trust-proxy o. Ä. eine
/img/-statische Regel bereitstellt, lautet die Bild-URL z. B.https://<DSH-Domain>/img/x.png– geräteübergreifend, ohne zusätzlichen Tunnel. - Der unabhängige cloudflared-Tunnel von serve.py ist nur ein tragbarer Fallback (läuft auf jedem Rechner): Nur in Schritt 0, wenn der Host nicht öffentlich wiederverwendbar ist und der Benutzer zugestimmt hat; dabei die Einschränkungen klar kommunizieren (andere Herkunft als der Host, Schnelltunnel ändern beim Neustart die Domain).
Randbedingungen
- Prozess muss persistent/abbaubar sein: serve.py speichert die PID für teardown; in einer DSH-Sitzung muss der Dienst sitzungsübergreifend sein (mit verwaltetem Hintergrunddienst + explizitem teardown).
- Dateiname: ASCII, keine Leerzeichen; Skripte prüfen auf Datei-Existenz; chinesische Zeichen/Leerzeichen werden durch URL-Kodierung behandelt, aber es wird empfohlen, sie zu vermeiden.
- Unterschiedliche Arbeitsverzeichnisse: Verschiedene Sitzungen haben unterschiedliche Arbeitsverzeichnisse; das Teilen erfolgt relativ zum Sitzungspfad; serve.py verwendet das systemweite temporäre Verzeichnis, unabhängig vom Arbeitsverzeichnis.