Consume Huginn .cc fixture as Eve DSL

This commit is contained in:
Meta Vens 2026-06-01 22:15:40 +01:00
commit 44cebda1e0
4 changed files with 49 additions and 2 deletions

View file

@ -174,6 +174,9 @@ Open `http://127.0.0.1:8891/`. The page can spawn:
- `Sai VN Surface`, a fixture for visual-novel scenes exported as
`gamecult.eve.surface.v1`, including embedded Norn and TeX surfaces placed
diegetically inside the scene.
- `Huginn .cc`, a read-only `.eve` fixture emitted by CultCache/Huginn for
`.cc` files: source witness, schema catalog, persisted records, payload byte
counts, and decode status. Huginn emits Eve DSL; Eve compiles and renders it.
- `Reactive DSL`, a browser-reference fixture that compiles a small `.eve`
composition language into the same surface contract and binds UI controls to
live CultMesh-shaped vars, collections, and derived fields.

View file

@ -0,0 +1,30 @@
# Huginn emits Eve DSL. Renderers compile and lower it.
surface cultcache.huginn.inspector "Huginn .cc Inspector"
version 1
collection huginn.catalog.entries
item huginn.catalog.entries "gamecult.persona_state | gamecult.persona_state.v0 | sha256:persona-state | 12 members"
item huginn.catalog.entries "voidbot.moderation_cursor | voidbot.moderation_cursor.v1 | sha256:moderation-cursor | 4 members"
item huginn.catalog.entries "voidbot.face_affect | voidbot.face_affect.v1 | sha256:face-affect | 7 members"
collection huginn.records.entries
item huginn.records.entries "persona:huginn | gamecult.persona_state | 2026-05-31T22:14:12.000Z | 2048 bytes | decoded"
item huginn.records.entries "cursor:moderation | voidbot.moderation_cursor | 2026-05-31T22:12:03.000Z | 640 bytes | decoded"
item huginn.records.entries "affect:face | voidbot.face_affect | 2026-05-31T22:13:44.000Z | 768 bytes | decoded"
card source "Source Witness"
text "file: E:\\Projects\\CultCacheTS\\.voidbot\\state\\huginn.cc"
text "format: cultcache.store.v1"
text "bytes: 3456"
text ".cc bytes are authority; Huginn only emits Eve DSL."
end
card catalog "Schema Catalog"
text "schemas: 3"
list "Catalog Entries" bind huginn.catalog.entries
end
card records "Persisted Records"
text "records: 3"
list "Record Entries" bind huginn.records.entries
end

View file

@ -23,6 +23,7 @@
<button id="voidbot-tab" class="active" type="button">VoidBot Live</button>
<button id="fensalir-tab" type="button">Fensalir Direct2D</button>
<button id="sai-tab" type="button">Sai VN Surface</button>
<button id="huginn-tab" type="button">Huginn .cc</button>
<button id="dsl-tab" type="button">Reactive DSL</button>
</nav>

View file

@ -7,6 +7,7 @@ const surfaceVersion = document.querySelector("#surface-version");
const voidBotTab = document.querySelector("#voidbot-tab");
const fensalirTab = document.querySelector("#fensalir-tab");
const saiTab = document.querySelector("#sai-tab");
const huginnTab = document.querySelector("#huginn-tab");
const dslTab = document.querySelector("#dsl-tab");
let socket;
@ -30,6 +31,13 @@ saiTab.addEventListener("click", async () => {
renderSurface(await response.json(), "fixture");
});
huginnTab.addEventListener("click", async () => {
setActiveTab(huginnTab);
closeSocket();
const response = await fetch("./fixtures/huginn-cc-surface.eve");
renderSurface(compileEveDsl(await response.text()), "dsl");
});
dslTab.addEventListener("click", async () => {
setActiveTab(dslTab);
closeSocket();
@ -40,7 +48,7 @@ dslTab.addEventListener("click", async () => {
openVoidBot();
function setActiveTab(tab) {
for (const button of [voidBotTab, fensalirTab, saiTab, dslTab]) {
for (const button of [voidBotTab, fensalirTab, saiTab, huginnTab, dslTab]) {
button.classList.toggle("active", button === tab);
}
}
@ -52,20 +60,25 @@ function openVoidBot() {
const url = `${scheme}//${host}:8795/eve/deck`;
statusEl.textContent = `connecting ${url}`;
socket = new WebSocket(url);
const activeSocket = socket;
socket.addEventListener("open", () => {
if (socket !== activeSocket) return;
statusEl.textContent = "connected to Mimir Eve broker";
socket.send(JSON.stringify({ type: "open-provider", providerId: "voidbot.swarm" }));
activeSocket.send(JSON.stringify({ type: "open-provider", providerId: "voidbot.swarm" }));
});
socket.addEventListener("message", event => {
if (socket !== activeSocket) return;
const state = JSON.parse(event.data);
if (state.providerId === "voidbot.swarm") {
renderSurface(state, "live");
}
});
socket.addEventListener("close", () => {
if (socket !== activeSocket) return;
statusEl.textContent = "Mimir broker disconnected";
});
socket.addEventListener("error", () => {
if (socket !== activeSocket) return;
statusEl.textContent = "Mimir broker error; is port 8795 running?";
});
}