framejs
framejs führt ein ES6-JavaScript-Modul im Browser aus. Ein Frame ist die App: Er lebt unter einer stabilen, teilbaren framejs.app/j/<uuid>-URL, deren Inhalt änderbar ist – Sie aktualisieren die App direkt, indem Sie ihre Hash-Parameter per POST senden. Ihre Aufgabe: Die Anfrage des Benutzers in dieses Browser-JavaScript umwandeln und es für Ihre Umgebung korrekt ausliefern.
Wählen Sie Ihren Auslieferungsmodus
Wählen Sie basierend auf Ihren Fähigkeiten – nicht auf der Art der Anfrage:
- Automatisierungsmodus – Sie können eine Shell /
nodeausführen: Generieren Sie das JavaScript, erstellen oder aktualisieren Sie dann den Frame der Sitzung unter framejs.app, geben Sie dessen/j/<uuid>-URL aus und öffnen Sie sie im Browser. Dies ist der Standard, sofern eine Shell verfügbar ist. - Codeblock-Modus – nur Chat/API, keine Shell: Antworten Sie nur mit einem einzelnen abgeschlossenen JavaScript-Codeblock (öffnen Sie ihn mit einem
javascript-Info-String) und sonst nichts – kein umgebender Text, keine Dateien, keine URLs. Der Benutzer fügt ihn in den Editor unter framejs.io ein.
In beiden Modi folgt das von Ihnen geschriebene JavaScript denselben Regeln – lesen Sie references/coding-guide.md.
Was die Anfrage sein kann
- Erstellen aus einer Eingabeaufforderung – „eine Bouncing-Ball-Animation“, „plot y = sin(x)".
- Vorhandene App ändern – Die Anfrage enthält eine Frame-URL. Es kann sich um eine
https://framejs.app/j/<uuid>oder einehttps://framejs.io/j/<uuid>?token=…-URL handeln (die Aktion „Frame für KI-Sitzung kopieren“ kopiert das Laufzeitformular von framejs.io), eine reine 32-Zeichen-Hex-ID oder eine veraltetehttps://framejs.io/j/<sha256>/ 64-Zeichen-ID als Snapshot. Wann immer Sie eine framejs-URL sehen, extrahieren Sie die UUID aus dem/j/<uuid>-Pfad und zielen Sie auf DIESEN Frame ab (übergeben Sie die URL direkt an--id– der Helfer leitet das Update selbst bei einer framejs.io-URL an die App-Ebene weiter). Sie MÜSSEN zuerst den vorhandenen Code abrufen und ihn dann modifizieren – siehe references/short-url-api.md (§ Modifizieren). Wenn die URL einen?token=<key>-Query-Parameter trägt (von der Aktion „Frame für KI-Sitzung kopieren“ der App), übergeben Sie die gesamte URL an--id(oder den Schlüssel an--token): Der Helfer speichert ihn und sendet ihn als Bearer-Anmeldedaten, sodass Ihre Updates auch dann funktionieren, nachdem der Besitzer den Frame beansprucht hat. Die Übergabe der gesamten URL zielt auch auf das Backend ab, das die URL benennt – so aktualisiert eine Entwicklungs- oder selbst gehostete Frame-URL (z. B.https://framejs-app.localhost:13747/j/<uuid>?token=<key>) ihren eigenen Stack ohne vorkonfigurierte Umgebungsvariablen.--app-origin <url>/--io-origin <url>setzen das Backend explizit. Siehe references/short-url-api.md (§ Lokale / Entwicklungs-Origins). - Lokale Dateien visualisieren – Die Anfrage bezieht sich auf Dateipfade (
./data.csv,/tmp/results.json). Laden Sie sie hoch und übergeben Sie sie als Eingaben – siehe references/file-inputs.md.
Automatisierungsmodus – Wie ausliefern
Generieren Sie den Code und verwenden Sie dann den gebündelten Helfer (bevorzugt) oder den Inline-Node-Fallback in references/short-url-api.md:
cat << 'JSCODE' | node scripts/framejs.mjs create --state "${SCRATCHPAD}/framejs-frame.json" --title "<kurzer Titel>" --description "<Ein-Satz-Zusammenfassung>" --screenshot
// Ihr generiertes Browser-JS hier – $vars, Backticks, alle Sonderzeichen sind im Heredoc sicher
JSCODE
Der Helfer gibt (auf stdout) zwei URLs aus – die primäre https://framejs.app/j/<uuid>-Seiten-URL und eine unveränderliche snapshot:-https://framejs.io/j/<sha256>-URL. Außerdem gibt er (auf stderr) einen Share-Link-Lebenszyklus-Hinweis aus, den Sie dem Benutzer MITTEILEN MÜSSEN:
- Die
/j/<uuid>-Seite ist bearbeitbar und wird live aktualisiert, aber ein anonymer (nicht beanspruchter) Frame ist temporär und läuft ab – sagen Sie dem Benutzer, er solle ihn öffnen und beanspruchen (kostenloses Konto), um ihn dauerhaft zu behalten; - Der
/j/<sha256>-Snapshot ist eine unveränderliche Kopie der aktuellen App, die ~30 Tage nach dem letzten Öffnen abläuft – ein guter stabiler Share-/Backup-Link, der aber spätere Bearbeitungen nie widerspiegelt.
Fügen Sie --module <url> für klassische Skripte und --input name=value für Eingaben hinzu.
Ein Frame pro Sitzung, direkt aktualisiert. Übergeben Sie immer --state "<Pfad in Ihrer Ablage>/framejs-frame.json" (jeder beschreibbare Dateipfad). Das erste create erstellt den Frame; führen Sie create erneut mit demselben --state aus, um DENSELBEN Frame zu AKTUALISIEREN – die /j/<uuid>-URL bleibt konstant und jede geöffnete framejs.app-Seite aktualisiert sich live, also geben Sie dem Benutzer die URL einmal. Nur wenn der Benutzer eine separate App in derselben Sitzung wünscht, fügen Sie --new hinzu, um einen neuen Frame zu starten (nachfolgende Updates zielen dann auf diesen neuen). Um einen bestimmten Frame unabhängig vom Status zu aktualisieren, übergeben Sie --id <uuid>. Bei einem solchen direkten Update übernimmt der Helfer die vorhandenen Open-Graph-Daten des Frames automatisch, wenn Sie kein --og/--title/--description übergeben, sodass eine bloße erneute Ausführung niemals Titel/Beschreibung verwirft (und das beibehaltene og.image überspringt einen redundanten erneuten Screenshot). Übergeben Sie --title/--description nur erneut, um den Vorschautext zu ändern.
Der Browser öffnet sich automatisch nur beim ersten Erstellen eines Frames (--no-open, um auch das zu überspringen). Ein späteres Update desselben Frames – gleicher --state oder explizites --id – öffnet den Browser NICHT erneut: Die bereits geöffnete Seite erreicht ihn live über dasselbe Frame-Abonnement, ein erneutes Öffnen würde nur einen redundanten neuen Tab erzeugen.
Wenn ein lokales Entwicklungs-Checkout vorhanden ist, lädt der Helfer automatisch dessen .env und zielt auf die Entwicklungs-Stacks (FRAMEJS_APP_ORIGIN / FRAMEJS_IO_ORIGIN) anstatt auf die Produktion – kein Handlungsbedarf Ihrerseits.
Wenn der Helfer einen out of date-Update-Hinweis ausgibt (auf stderr, höchstens stündlich), geben Sie ihn dem Benutzer einmal wörtlich weiter – seine installierte Skill ist hinter der neuesten zurück und der Hinweis nennt den Befehl zur Aktualisierung.
Übergeben Sie immer --screenshot: Der Helfer rendert die fertige App und speichert die Aufnahme als og:image-Vorschau. Es ist selbstschützend – es erfasst NUR, wenn die App noch kein og.image hat, überschreibt also niemals ein Bild, das ein vorheriger Lauf (oder der Benutzer) bereits gesetzt hat, und fällt stillschweigend auf die URL ohne Bild zurück, wenn kein Renderer verfügbar ist. Die Erfassung bevorzugt Playwright, wenn es importiert werden kann (echtes Network-Idle-Waiting – am besten für Apps, die Eingaben abrufen), und verwendet andernfalls systemweites Headless-Chrome. Playwright ist optional: Installieren Sie es (npm i -g playwright && npx playwright install chromium) für den zuverlässigeren Pfad, oder setzen Sie $FRAMEJS_PLAYWRIGHT auf ein Verzeichnis, dessen node_modules es enthält. Optimieren Sie mit --screenshot-wait <ms> (Standard 6000 – erhöhen Sie es für Apps, die langsam laden) und --screenshot-size <w,h> (Standard 1200,630). Überschreiben Sie die Chrome-Binärdatei mit $CHROME_PATH.
scripts/framejs.mjs wird relativ zum Verzeichnis dieser Skill aufgelöst, nicht zu Ihrem aktuellen Arbeitsverzeichnis – führen Sie es aus dem Skill-Ordner aus oder verwenden Sie seinen absoluten Pfad (Claude Code macht dieses Verzeichnis als ${CLAUDE_SKILL_DIR} verfügbar, also funktioniert ${CLAUDE_SKILL_DIR}/scripts/framejs.mjs immer). Wenn Sie den gebündelten Helfer nicht finden oder ausführen können, verwenden Sie den Inline-Node-Fallback in references/short-url-api.md – dieser benötigt keine Skriptdatei.
Fügen Sie immer Open-Graph-Vorschau-Tags hinzu, damit der Link beim Teilen schön aufgeklappt wird – siehe die OG-Regeln in references/short-url-api.md:
- Neue App: Leiten Sie frischen Text mit
--title/--descriptionab und übergeben Sie--screenshot, um das Vorschaubild aufzunehmen. - Vorhandene App ändern: Die abgerufene App enthält bereits
og(derfetch-Befehl gibt es zurück). Berechnen Sie es NICHT neu – übergeben Sie das abgerufene Objekt direkt mit--og '<das abgerufene og-JSON>'zurück, wodurch jedes Feld (einschließlichimage) erhalten bleibt. Aktualisieren Sie DENSELBEN Frame mit--id <uuid>(oder demselben--state). Setzen Sie nur dann neue--title/--description, wenn der Benutzer ausdrücklich darum gebeten hat, den Vorschautext zu ändern. Sie können weiterhin--screenshotübergeben: Wenn das abgerufeneogbereits einimagehat, bleibt es unberührt; wenn es keines hat, wird eine neue Aufnahme hinzugefügt.
Absolute Regeln (beide Modi)
- Nur Browser-JavaScript – es läuft in einem Iframe, NICHT in Node.js.
- MUSS die ES6-Modul-Syntax verwenden:
export function onInputs(inputs) {}. - NIEMALS HTML-Dateien erstellen. NIEMALS lokale
.js-Dateien schreiben. NIEMALS Ihre eigenen Visualisierungs-/Render-/Widget-Tools verwenden, um das Ergebnis darzustellen. - NIEMALS
root.style.position,root.style.heightoderroot.style.widthändern. - WICHTIG: Die Visualisierung MUSS auf mobilen Geräten gut aussehen und sich an die Bildschirmgröße anpassen – verwenden Sie responsives Layout (lesen Sie die Abmessungen von
root/ hören Sie auf resize), vermeiden Sie feste Pixelbreiten, die überlaufen, und halten Sie Text und Touch-Ziele auf kleinen Bildschirmen lesbar. - Im Automatisierungsmodus NIEMALS einen Codeblock zur manuellen Kopie ausgeben und NIEMALS eine lange Hash-URL von Hand als Liefergegenstand bauen – immer über die Frame-API posten (der
create-Befehl des Helfers). Geben Sie dem Benutzer die/j/<uuid>-Seiten-URL. - Im Codeblock-Modus NUR den einzelnen abgeschlossenen JavaScript-Codeblock ausgeben – sonst nichts.
Referenzen
- references/coding-guide.md – Globals, Exports, Patterns, CDN-Bibliotheken, häufige Fehler.
- references/short-url-api.md – Frame erstellen/aktualisieren (
POST /j/<uuid>.json), Ein-Frame-pro-Sitzung-Zustand, Open-Graph-Tags, API-Tokens (Updates auch nach Frame-Besitzergreifung fortsetzen), Inline-Fallbacks. - references/file-inputs.md – Lokale Dateien hochladen und als Eingaben einbinden.
scripts/framejs.mjs– Node-Helfer:create(stdin JS → framejs.app-Frame),fetch <id>,upload <path>. Origins:FRAMEJS_APP_ORIGIN/FRAMEJS_IO_ORIGIN(automatisch aus einer nahegelegenen.envbei lokaler Entwicklung geladen), oder pro Lauf via--app-origin/--io-originoder der Origin einer vollständigen Frame-URL, die an--id/fetchübergeben wird.