en un clic
en un clic
| name | diffuse-facet |
| description | Create an interface or feature facet for Diffuse |
| user-invocable | true |
| version | 0.2.0 |
Create a Diffuse facet and produce the HTML ready to paste into the create/ page.
Use the read tool to read these files:
docs/architecture.txt — system overview, facet rules, foundation APIdocs/elements.txt — all available custom elements with code examplesdocs/foundation.js — the foundation code mentioned throughout this documentexample/index.html — a representative interface facet to use as a referencedocs/definitions/output/track.json for the track schema)docs/definitions/index.ts — TypeScript types for all data structuresIf the user hasn't described what the facet should do, ask one plain-language question before proceeding.
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.
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.track.tags.*, not at the top level.queue.now, queue.past, queue.future, …) must be called inside effect() to be reactive.await from Worker scripts — it causes RPC messages to be dropped.@param annotations above functions, not inline @type in parameter lists.<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>
<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.
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);
Signals are used for reactivity, see the ~/common/signal.js javascript file for the code. It's based on the alien-signals library.
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.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
~/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.scoped-tracks orchestrator element.Output the complete facet HTML in a code block. Tell the user to open the create/ page in Diffuse, paste it in, and load it.