01 // Plugins

Make it yours.

Holo Intelligence UI changes when you ask. Describe a panel, a theme or a routine and your assistant builds it. Or write a plugin yourself: one folder, one page.

02 // What a plugin can be

Four kinds. Two levels.

A plugin is a folder with a manifest that says what it is and what it may see. Settings plugins never run code. Code plugins run in a sandbox.

kind · panelLevel 2 · code

Panel

A new glass panel on any screen: your GPU as rings, your next three events, anything a page can draw from live data.

kind · bodyLevel 2 · code

Body

A new body style for your assistant. It’s code, so like a panel it’s one page with an entry file, run in the sandbox.

kind · themeLevel 1 · settings

Theme

Colours, glow, motion and font. Settings only, never code, so any capable model can make one.

kind · routineLevel 1 · settings

Routine

Something it does on its own, in plain words: “every weekday at 8am give me a briefing.” Settings only.

Level 1 · settings

Changes it can make at once

Themes, colours, text size, motion, its name, personality and voice, screen layouts and routines from templates. Applied straight away, and Ctrl+Shift+Z takes any of it back. Any model rated “can customize” can do it, and the common requests work with no model at all.

Level 2 · code

New things, built for you

New panels and features, written as a plugin by a model rated “can build plugins” or by Claude Code. You see it running in a live preview first, then pick the screen it goes on. Every install keeps the version before it.

03 // Ask the builder

Say it. It builds it.

“Build me a panel that shows my GPU temperature as rings.” Your assistant writes the plugin, checks it, and shows it to you running. Nothing is installed until you say so.

  1. 01
    You askSay it, press Enter on any screen and type it, or use the studio’s Build tab (T).
  2. 02
    It sorts the requestLevel 1 or level 2, and which of your models can do it, before it starts.
  3. 03
    It writes the pluginA manifest and one page, in a build folder of their own.
  4. 04
    It checks itOutside scripts, fetch, XMLHttpRequest, WebSocket and import are rejected, and the manifest has to pass.
  5. 05
    You try itA live preview, fed the same data a screen would get.
  6. 06
    You approveInstall it on the screen you pick. Or don’t.
  7. 07
    Changed your mind?“Go back a version” in the Plugins tab, or turn it off.

An illustration of the studio’s Build tab. The preview is a real plugin running on this page, fed made-up readings.

The intelligence check5 tasks

Only capable models write code

Press Check intelligence on any model you connect: five small coding tasks with hidden tests, run in a separate process. Answers that try to touch your PC fail. The score decides what that model may change.

  • Can build plugins4 or 5 passed: new panels and other code (level 2).
  • Can customize2 or 3 passed: themes, layouts, settings and routines (level 1).
  • Chat only0 or 1 passed: it talks, and never edits.

The tasks Roman numerals · reading durations · merging intervals · fitting a panel on a grid · shading a colour

Who builds itYour choice

Pick the builder

  • The best model I haveThe model routed for building, if it passed the check.
  • Any model that passedEvery model rated “can build plugins” is offered by name.
  • Claude CodeWrites the plugin on your own Claude plan, working only inside its build folder.

In local-AI mode only models on your PC build. Ask out loud and it builds in the background, then the studio holds it until you’ve tried it.

04 // In the box

Plenty before you build a thing.

It comes with all of this, and every piece follows the theme you pick. The plugin guide adds a working example to learn from.

Themes8

Eight themes

Daylightin the app
High contrastin the app

Pick one of the first six and this website changes too. In the app: custom colours, glow, motion, four fonts, and a theme made from any picture.

Body styles5

Five bodies

  • CoreA dotted shell around a glowing wireframe heart.
  • WaveRings of sound that ripple when it talks.
  • SwarmParticles orbiting a bright centre; busier when it thinks.
  • LatticeA slowly turning geodesic sphere of light.
  • FaceA wireframe face with a voice line that speaks.
Agent crews6 ready-made

Six crews of AI helpers

A small team takes turns on one job. Each member sees the goal and what the others wrote.

  • Research teamResearcherAnalystWriter
  • Writing roomDrafterEditorFinisher
  • Code review crewReviewerTesterLead
  • Decision boardOptimistSkepticChair
  • Planning crewPlannerCheckerOrganiser
  • Idea labGeneratorCriticBuilder

Make your own with up to six members. The code review crew reads a project folder and changes nothing.

Sound packs4

Sound packs

Small cues for notifications, approvals, focus, listening and undo, made on the spot with no sound files. Press one to hear the real notes.

  • HoloGlassy chimes
  • Retro8-bit blips
  • SoftQuiet and low
  • OffSilenceNo cues at all. A volume slider sets the rest.
Routine templates5

Routines to start from

  • Morning briefing“Every weekday at 8am give me a morning briefing: the weather, my calendar and anything important.”
  • Welcome home“When I get home, say welcome back and tell me anything I missed.”
  • Wind down“Every day at 11pm switch to the sleep scene.”
  • Hourly stretch“Every 60 minutes say time to stand up and stretch.”
  • Weekly recap“Every Sunday at 6pm tell me how my week went.”
Example plugin · to learn fromcpu-ring

CPU Ring

How busy each computer’s processor is, as glowing rings. A complete panel plugin in one short page, and the best place to start reading.

  • kind · panel
  • level 2 · code
  • reads telemetry.*
  • one page · under 50 lines

Watch it run

05 // Live demo

A real plugin, running here.

This is the example plugin from the plugin guide, unchanged, in the same kind of sandboxed frame the app uses. This page plays the part of the screen: it sends the theme, then made-up readings every second.

CPU Ring

plugin
  • sandbox="allow-scripts"
  • reads telemetry.*
  • no same-origin: no cookies, storage or page access
Messages sent to the plugin0
  1. The feed starts when the plugin loads.

Play the screen

Change the theme: the plugin gets a new theme message

The readings are made up. In the app they come from your computers, and this is the name the app gives the PC it’s installed on. The plugin draws a ring for each computer it hears about.

The files manifest.json panel.html

06 // Make your own

One folder. One page.

Most people never write a plugin by hand: they ask, and the builder writes it. This is for anyone who wants to, or wants to know what the builder makes.

01The folder

A plugin is a folder holding a manifest.json and its files. For a panel, that’s one page:

Folder
cpu-ring/
  manifest.json
  panel.html
cpu-ring/manifest.json
{
  "id": "cpu-ring",
  "name": "CPU Ring",
  "version": "1.0.0",
  "kind": "panel",
  "level": 2,
  "entry": "panel.html",
  "reads": ["telemetry.*"],
  "description": "How busy each computer's processor is, as glowing rings.",
  "author": "you"
}

02Manifest fields

FieldNeededWhat it means
idYes2 to 41 lower-case letters, digits or dashes. Unique: installing the same id again updates it, and keeps the version before.
nameYesWhat the studio calls it.
versionShown in the Plugins tab, for example 1.0.0.
kindYespanel or body (code, level 2), theme or routine (settings only, level 1).
level1 is settings only, 2 is code. Themes and routines must be level 1. A level 2 plugin built by a model needs a model that passed the intelligence check.
entryPanels, bodiesThe page that’s shown: an .html file in the folder.
readsThe live topics the plugin is given. This is its whole permission list: it receives nothing else. * matches one part, as in telemetry.*.
descriptionOne sentence, shown before anyone installs it.
authorWho made it.
Never readable

A plugin may never read config.settings, approvals or pair.code. The manifest check refuses it, and the clipboard, meeting, Holo Link and developer topics are off limits too.

03Messages

The plugin runs in a sandboxed frame with scripts allowed and nothing else. It can’t reach the interface’s page, its key, cookies or storage. The screen sends it messages instead:

panel.html · listening
window.addEventListener('message', (e) => {
  const {topic, data} = e.data || {};
  if (topic === 'theme') { /* the interface's colours */ }
  if (topic && topic.startsWith('telemetry.')) { /* a computer's live readings */ }
});

First comes a theme message with the current theme’s colours and font. Use them and your plugin follows every theme the user picks. Then each topic in reads arrives whenever it changes.

What arrivesExample
// first: the theme
{topic: 'theme', data: {'--void': '#050102', '--ember': '#ff2b2b', '--glow': '#ffb0a4',
                        '--hot': '#ffe0d8', '--muted': '#c4473f', '--font-ui': '"Rajdhani", …'}}
// then each topic it reads, whenever it changes
{topic: 'telemetry.this', data: {cpu: {pct: 37, count: 16}, mem: {used: …, total: …, pct: 41},
                                 gpu: [{name: …, util: 22, temp: 58, …}], net: {down: …, up: …}}}

04Topics

TopicWhat’s in it
telemetry.<machine>cpu {pct, count}, mem {used, total, pct}, gpu [{name, util, temp, mem_used, mem_total}], net {down, up} (bytes a second), disk {drives [{mount, pct}]}, battery
music.nowtrack, artist, playing, device {name}
weather.nowtemp, unit, text, high, low, tomorrow
calendar.upcomingevents [{title, start, end, all_day}]
claude.<machine>sessions [{title, state, doing, tokens {in, out}, context {used, window, pct}}]
ai.modelsmodels [{title, where, plain, badges}]
presencestate: present, away or asleep

05Rules

  • One self-contained HTML file. Plain JavaScript: no outside scripts, and no fetch, XMLHttpRequest, WebSocket or import. The builder rejects them.
  • A transparent background, so it sits on the glass panels.
  • Any size. People resize panels in edit mode (E).
  • A friendly “waiting for data” until the first message arrives.

06A starter

A whole panel in about fifty lines: each graphics card’s temperature as a ring. It’s the one running in the builder preview above. Copy it, or download the folder’s two files, and change it into yours.

gpu-rings/panel.html
<!doctype html>
<!-- A starter panel plugin for Holo Intelligence UI: each graphics card's temperature as a ring.
     One self-contained page. The screen sends it a "theme" message, then each topic its manifest reads. -->
<meta charset="utf-8">
<style>
  html, body { margin: 0; height: 100%; background: transparent; overflow: hidden; }
  body {
    box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4% 8%;
    padding: 4%; font-family: var(--font-ui, sans-serif); color: var(--glow, #ffb0a4);
  }
  .gpu { position: relative; width: min(40%, 78vh); aspect-ratio: 1; }
  .gpu svg { width: 100%; height: 100%; transform: rotate(135deg); }
  .gpu circle { fill: none; stroke: var(--ember, #ff2b2b); stroke-width: 7; }
  .gpu .track { stroke-opacity: 0.18; }
  .gpu .arc { transition: stroke-dasharray 0.6s ease; }
  .read { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
  .read b { font-size: min(9vw, 16vh); line-height: 1; color: var(--hot, #ffe0d8); }
  .read small { margin-top: 0.4em; font-size: min(2.8vw, 5vh); letter-spacing: 0.12em; text-transform: uppercase; }
  .wait { opacity: 0.8; }
  @media (prefers-reduced-motion: reduce) { .gpu .arc { transition: none; } }
</style>
<div class="wait">Waiting for data…</div>
<script>
  // A 270° gauge from 20 °C to 100 °C, on a circle of radius 42.
  const LOW = 20, HIGH = 100, ARC = 0.75 * 2 * Math.PI * 42;
  const rings = {};

  function ring(key, label) {
    if (rings[key]) return rings[key];
    document.querySelector('.wait')?.remove();
    const el = document.createElement('div');
    el.className = 'gpu';
    el.innerHTML = `<svg viewBox="0 0 100 100"><circle class="track" cx="50" cy="50" r="42" stroke-dasharray="${ARC} 999"/>
      <circle class="arc" cx="50" cy="50" r="42" stroke-dasharray="0 999"/></svg>
      <div class="read"><b>–</b><small></small></div>`;
    el.querySelector('small').textContent = label;
    document.body.append(el);
    return (rings[key] = el);
  }

  window.addEventListener('message', (e) => {
    const {topic, data} = e.data || {};
    if (topic === 'theme') {  // the interface's colours: use them, and the plugin follows every theme
      for (const [k, v] of Object.entries(data || {})) document.documentElement.style.setProperty(k, v);
      return;
    }
    if (!topic || !topic.startsWith('telemetry.') || !data || !Array.isArray(data.gpu)) return;
    const machine = topic.split('.')[1];
    data.gpu.forEach((gpu, i) => {
      if (gpu.temp == null) return;  // not every card reports its temperature
      const el = ring(`${machine}.${i}`, `${machine} · ${gpu.name || 'GPU ' + (i + 1)}`);
      const t = Math.max(LOW, Math.min(HIGH, gpu.temp));
      el.querySelector('.arc').setAttribute('stroke-dasharray', `${((t - LOW) / (HIGH - LOW)) * ARC} 999`);
      el.querySelector('b').textContent = `${Math.round(gpu.temp)}°`;
    });
    const wait = document.querySelector('.wait');
    if (wait && data.gpu.length && data.gpu.every((g) => g.temp == null)) wait.textContent = 'This graphics card doesn’t report its temperature.';
  });
</script>

Download manifest.json panel.html

07Test and install

Test it in a browser first. Open your panel.html, press F12, and play the screen from the console:

Browser console
postMessage({topic: 'theme', data: {'--ember': '#2bd4ff', '--hot': '#e2f8ff'}}, '*');
postMessage({topic: 'telemetry.this', data: {gpu: [{name: 'GPU', temp: 64}]}}, '*');
  1. Ask for it. Say or type what you want. The studio’s Build tab shows a live preview, then installs it on the screen you pick.
  2. Or by hand. Copy the folder into %USERPROFILE%\.sarch\plugins\.
  3. Check it was accepted in the studio’s Plugins tab (T). Any problem with the manifest is listed there in plain words.
  4. Put it on a screen with edit mode (E), or from the Build tab.
Undo

Every install keeps the previous version, so “Go back a version” in the Plugins tab undoes an update. Safe mode turns every plugin off at once if something misbehaves.

08Export and import

In the studio’s History tab, Share my look saves your theme, body style, screens and plugins in a .holo file anyone can apply. It holds nothing personal: never your keys, memories or your assistant’s name.

To bring one in, use Restore a backup or apply a shared look on the same tab. It goes through the change history, so it can be undone, and every plugin in it is checked like any install.

07 // The safety model

It can look. It can’t touch.

Every plugin runs under the same rules, whether your assistant built it or a friend sent it.

  • A sandboxed frameScripts run, and nothing else. No access to the interface’s page, its key, cookies or storage.
  • No networkOne self-contained page. The builder rejects outside scripts and network calls, and the gallery checks for them too.
  • “reads” is the whole permission listThe screen sends a plugin only the topics its manifest lists. You see them before you install, and in the Security tab after.
  • Never the private thingsYour settings (config.settings), approvals and pairing codes (pair.code) can’t be read by any plugin. The manifest check refuses it.
  • Only checked models write codeA model has to pass the intelligence check to build a plugin. A weaker one can only change safe things.
  • Rollback and safe modeEvery install keeps the version before it. Turn a plugin off in one click, or switch on safe mode and every plugin stops at once.

08 // Sharing

Pass it on.

Hand a plugin to a friend in a file today. The community gallery is on its way.

Build your first one.

Install it, connect a model that can build, and ask. The setup guide walks you through connecting one.

Launch sale · 25% offOne-time · one key, 3 PCs · Windows 10 and 11