Was maschinell geprüft ist, steht jetzt namentlich da — Manifest, Berechtigungs-Rahmen, Syntax, Sammel-Logik (12 Tests) und der Transport End-to-End gegen die Live-Instanz (POST → 303 → Einweg-Token → Abholung → zweite Abholung 404). Ungetestet bleibt genau die MV3-Verdrahtung dazwischen: action.onClicked → scripting.executeScript → fetch mit credentials. Die braucht einen echten Browser-Load; eine Automatisierung darf chrome://extensions nicht bedienen. Dafür jetzt eine Anleitung mit erwartetem Verhalten (Golem-Artikel, Cookie-Abfrage wegklicken, Symbol zeigt … dann ✓) und wo im Fehlerfall der Grund steht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.4 KiB
Pageta — Browser-Erweiterung
Ein Klick speichert die geöffnete Seite in die Lese-Liste — mit dem Text, den du siehst.
Wozu, wenn es das Bookmarklet schon gibt
Das Bookmarklet kann dasselbe, aber es muss erst in die Lesezeichenleiste gezogen werden — für die meisten Menschen ist das die Stelle, an der sie aufhören. Die Erweiterung ist ein Symbol in der Leiste.
Beide lösen dasselbe Problem: Quellen wie golem.de antworten auf jede
Anfrage ohne Cookies mit ihrer Zustimmungs-Abfrage statt mit dem Artikel —
auch dann, wenn der Abrufer sich als normaler Browser ausgibt (gemessen
2026-07-27 aus dem Produktions-Container, siehe
docs/EXTRAKTION.md). Serverseitig kommt da
nichts vorbei. Der Artikel existiert nur in deinem Tab.
Wie sie arbeitet
Klick aufs Symbol
→ activeTab erlaubt EINMALIG, diesen einen Tab zu lesen
→ collectPageta() im Tab: Seite 1 + erkannte Folgeseiten, je geleichtert
→ { url, title, pages, missing }
→ POST <instanz>/lese-liste/add/receive (dieselbe Route wie das Bookmarklet)
→ 303 auf /lese-liste/add?pickup=<einweg-token> (2 Minuten gültig)
→ neuer Tab holt das Payload ab und speichert lokal-first über event-sync
Es gibt bewusst einen Eingang für Bookmarklet und Erweiterung. Zwei Transportwege für dieselbe Sache wären zwei Wege, die auseinanderdriften.
Mehrseitige Artikel
Ein Artikel auf drei Seiten liegt komplett hinter derselben Wand — Seite 2
holt der Server genauso wenig wie Seite 1. Also holt sie der Tab: ein
fetch aus der Seite heraus trägt die Sitzung mit.
Folgeseiten findet page-collector.js ohne
quellenspezifische Selektoren — ein Link zählt, wenn seine Adresse sich von
der aktuellen nur in einem Seitenzähler unterscheidet (-2.html,
?page=2, /seite/2/); findet sich keine Seitenliste, folgt es der
rel="next"-Kette. Gedeckelt bei 20 Seiten und 6 MB, mit kurzer Pause
zwischen den Abrufen.
Diese Datei ist eine zeichengleiche Kopie von
apps/web/src/lib/page-collector.js — dieselbe Logik treibt das Bookmarklet
(dort als Quelltext in der javascript:-Adresse). Einen Bundler, der beide
bedient, gibt es nicht; die Erweiterung soll bewusst ohne Build auskommen.
scripts/check.mjs bricht ab, sobald die Kopien auseinanderlaufen.
Was sie nicht tut
- Keine dauerhafte Leseerlaubnis.
activeTabgilt für den Klick, nicht für den Verlauf. Ohne Klick sieht die Erweiterung keine Seite. - Kein API-Schlüssel. Es zählt die Anmeldung, die dein Browser ohnehin hat. Nichts Geheimes liegt in der Erweiterung.
- Keine Telemetrie, keine Fremd-Server, kein Hintergrund-Verkehr. Sie spricht ausschließlich mit deiner Pageta-Instanz, und nur wenn du klickst.
Lokal ausprobieren
Chrome / Edge / Brave
chrome://extensions→ Entwicklermodus an- „Entpackte Erweiterung laden" → diesen Ordner wählen
- Symbol anheften, Artikel öffnen, klicken
Firefox (ab 121)
about:debugging#/runtime/this-firefox- „Temporäres Add-on laden…" →
manifest.jsonwählen
Eine andere Instanz (Selbst-Hosting) stellst du in den Erweiterungs- Einstellungen ein; die Erlaubnis für diese Adresse wird dort abgefragt.
Der erste Klick — was passieren soll
Nimm eine Seite mit Zustimmungs-Abfrage, an der der Server scheitert; ein Golem-Artikel ist der verlässlichste Fall.
- Artikel in einem Tab öffnen, Cookie-Abfrage wegklicken (das ist der Punkt — die Erweiterung nutzt genau diese Zustimmung).
- Auf das Pageta-Symbol klicken.
- Erwartung: Symbol zeigt kurz
…, dann✓; ein neuer Tab öffnet/lese-liste/add?pickup=…und speichert. - In der Lese-Liste steht der Artikel mit echtem Titel und Volltext — nicht mit „Quelle blockiert".
Wenn das Symbol ! zeigt: Rechtsklick → „Verwaltung" → „Service Worker"
öffnet die Konsole der Erweiterung; dort steht der Grund.
Läuft der Klick auf einer internen Seite (chrome://, Store-Seiten) oder
auf Pageta selbst, zeigt das Symbol – und tut bewusst nichts.
Paketieren
pnpm --filter @pageta/extension package # → dist/pageta-extension-<version>.zip
Das Zip ist das, was in den Chrome Web Store bzw. bei addons.mozilla.org hochgeladen wird.
Offene Punkte
- Store-Einreichung ist nicht angestoßen. Chrome Web Store verlangt ein Entwicklerkonto (einmalig 5 USD) und eine Datenschutz-Begründung je Berechtigung; Firefox verlangt Signierung. Beides ist Vereinsarbeit, keine Programmierarbeit — bis dahin ist die Erweiterung über „entpackt laden" nutzbar.
- Kein Kontextmenü-Eintrag („Link in Pageta speichern"). Braucht die
contextMenus-Berechtigung; erst einbauen, wenn jemand danach fragt. - Der Klick-Weg im Browser ist ungetestet. Maschinell geprüft sind:
Manifest, referenzierte Dateien, Berechtigungs-Rahmen, Syntax aller
Skripte (
scripts/check.mjs), die Sammel-Logik (12 Tests inapps/web/src/lib/page-collector.test.ts) und der Transport End-to-End gegen die Live-Instanz: POST → 303 → Einweg-Token → Abholung liefert das Payload → zweite Abholung 404. Was fehlt, ist genau die MV3-Verdrahtung dazwischen —action.onClicked→scripting.executeScript→fetchmitcredentialscross-origin. Die braucht einen echten Browser-Load; eine Automatisierung darfchrome://extensionsnicht bedienen. Anleitung oben, dauert eine Minute.