Skip to main content

diffuse-facet

Create an interface or feature facet for Diffuse (diffuse.sh)

Quellinformationen

Repository
icidasset/diffuse
Letzte Quellaktivität
31. August 2026 um 22:10
Erkannte Sprache von SKILL.md
Englisch
Sterne
874
Forks
70

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
diffuse-facet
description
Create an interface or feature facet for Diffuse (diffuse.sh)
user-invocable
true
version
0.3.0
Create a [Diffuse](https://diffuse.sh) facet and produce the HTML ready to paste into the `create/` page. ## Step 1 — Read the docs Use the read tool to read these files: - `docs/architecture.txt` — system overview, facet rules, foundation API - `docs/elements.txt` — all available custom elements with code examples - `docs/foundation.js` — the foundation code mentioned throughout this document - `example/index.html` — a representative interface facet to use as a reference - Any specific definition you need (e.g. `docs/definitions/output/track.json` for the track schema) - `docs/definitions/index.ts` — TypeScript types for all data structures ## Step 2 — Clarify intent If the user hasn't described what the facet should do, ask one plain-language question before proceeding. ## Step 3 — Write the facet Facets are HTML fragments (no `<!doctype>`, `<html>`, or `<head>`). The loader injects them into `<div id="container">` and sets a `<base>` pointing at the Diffuse build root, so all relative URLs resolve from there. The import map exposes `~/` as the root alias. ### Mandatory rules - **`foundation.ready()`** must be called on every interface facet — it removes the loading spinner. Omitting it leaves the screen stuck on loading. - **`foundation.setup({ title })`** should be called to set the document title. - Always check the definitions fetched in Step 1 for the exact shape of any data you access — never assume top-level fields exist. For example, track metadata lives under `track.tags.*`, not at the top level. - Signal reader functions (`queue.now`, `queue.past`, `queue.future`, …) must be **called inside `effect()`** to be reactive. - Do **not** import modules with top-level `await` from Worker scripts — it causes RPC messages to be dropped. - Use **`@param` annotations above functions**, not inline `@type` in parameter lists. ### Skeleton ```html <style> @import "./styles/base.css"; @import "./styles/diffuse/facet.css"; @import "./vendor/@phosphor-icons/web/fill/style.css"; /* or /bold/ */ @layer base, diffuse; /* facet-specific styles */ </style> <main> <!-- markup --> </main> <script type="module"> import foundation from "~/common/foundation.js"; import { effect } from "~/common/signal.js"; foundation.setup({ title: "My Facet | Diffuse" }); // wire up elements … foundation.ready(); </script> ``` ### Standard two-column layout ```html <main> <div class="facet__left"> <a href="./dashboard/" class="diffuse-logo-container"> <svg viewBox="0 0 902 134" width="160"> <title>Diffuse</title> <use href="images/diffuse-current.svg#diffuse"></use> </svg> </a> <h1>Title</h1> <p>Description.</p> </div> <div class="facet__right"> <!-- main content --> </div> </main> ``` For a centered or full-screen layout (player, dialog, etc.) override `body` and `main` in the facet's `<style>` block directly. ### Example foundation usage ```js await foundation.orchestrator.queueAudio(); await foundation.orchestrator.mediaSession(); const [audio, ctl, queue] = await Promise.all([ foundation.engine.audio(), foundation.orchestrator.controller(), foundation.engine.queue(), ]); await customElements.whenDefined(ctl.localName); ``` ### Reactivity Signals are used for reactivity, see the `~/common/signal.js` javascript file for the code. It's based on the alien-signals library. ```js effect(() => { const track = ctl.currentTrack(); // computed — call like a fn const isPlaying = ctl.isPlaying(); const audioState = ctl.audio(); // AudioStateReadOnly | undefined if (audioState) { const progress = audioState.progress(); // 0–1 const current = audioState.currentTime(); const duration = audioState.duration(); } const now = queue.now(); // SignalReader — call like a fn const past = queue.past(); const future = queue.future(); }); ``` ### Audio control ```js audio.play({ audioId: queue.now().id }); audio.pause({ audioId: queue.now().id }); audio.seek({ audioId: queue.now().id, percentage: 0.5 }); // 0–1 queue.shift(); // next track queue.unshift(); // previous track ``` ### Additional requirements and notes - When working with track lists, realise that there could be a huge number of tracks that you need to work with (eg. 20000 tracks). Implement a custom virtual scroll (see the winamp or blur browser elements for examples). - Prefer the lit-html library as the templating/rendering engine. It is available from `~/vendor/lit-html/index.js` (among some other libraries such as: `idb-keyval`, `throttle-debounce`, several `@atcute` libraries, and `kmenu-core`). Always make sure to use the `~/vendor/` prefix for libraries, you're not working in an enviroment that bundles code. - Prefer to fetch the tracks from the `scoped-tracks` orchestrator element. - Always prefer to use an orchestrator or another component instead of reimplementing logic yourself. - Be mindful of performance. ## Step 4 — Deliver Output the complete facet HTML in a code block. If the page currently running in the browser exposes WebMCP tools, call the `create-facet` tool with this HTML (plus the name, kind and description) instead of asking the user to paste it in — the tool saves it directly to the user's collection. Otherwise, tell the user to open the `create/` page in Diffuse, paste it in, and load it.
Auf GitHub ansehen