Skip to main content

diffuse-facet

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

소스 정보

저장소
icidasset/diffuse
최근 소스 활동
2026년 8월 31일 22:10
감지된 SKILL.md 언어
영어
스타
874
포크
70

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
2 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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.
GitHub에서 보기