Skip to main content

diffuse-facet

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

Informations de source

Dépôt
icidasset/diffuse
Dernière activité de la source
31 août 2026 à 22:10
Langue détectée de SKILL.md
anglais
Étoiles
874
Forks
70

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
2 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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.
Voir sur GitHub