Gryt
Build on Gryt

Addon API

Everything on the gryt object a client plugin runs against, generated from the source

Generated from the source and regenerated by CI, so it cannot fall behind the code. Editing this page by hand gets the edit wiped on the next run — change what the generator reads instead.

This is the reference. Addons is the page that teaches the shape, and plugin pairs covers the server half.

A plugin runs in a worker of its own, and gryt is a global in it. There is no window.gryt and no addon id on any call — Gryt already knows which plugin is asking.

What is not there

A worker has no page, and the rest is taken away before your module is imported:

window        // a worker has none
document
localStorage
indexedDB     // deleted off the prototype chain, not just off globalThis
caches
Worker        // no nesting out of it

Your network is not. Whatever you are granted, you can send anywhere, and that is the part worth telling people who install your plugin.

Capabilities

Declared in the manifest and agreed to per addon. Both, or the call rejects and says which is missing.

CapabilityWhat the person reads
statusSet what you are doing, on every server you are on
messagingExchange its own messages with the servers you are on
displayShow its own panel beside the member list
processesSee which of your listed programs are running
mediaSee what your computer's media controls say is playing
activityPut a card on your profile, like "Listening to", on every server you are on

The manifest

manifest.json, in your addon's folder.

FieldTypeWhat it is
idstring
namestring
versionstring
type"plugin" | "theme"
description?string
author?string
banner?string
styles?string[]Theme-only: CSS files to inject
main?stringPlugin-only: JS entry point
requiresReloadOnDisable?booleanPlugin-only: if true, disabling the addon reloads the client
capabilities?string[]Plugin-only: what it says it needs to do. Agreed to per addon before window.gryt will answer; unknown names are dropped, not refused (GRYT-928).
repository?stringWhere the addon is published, as owner/repo on GitHub. Optional, and not free-form: anything but two plain path segments is rejected when it is read.

gryt

version

version: string

theme

theme: ThemeInfo

on()

on(event: "themeChange" | "cleanup", handler: (payload: ThemeInfo | undefined) => void): () => void

Hear about something. themeChange when appearance changes, cleanup when this plugin is turned off — the worker is terminated shortly after.

setActivity()

setActivity(activity: string): Promise<unknown>

Needs status.

Say what the person running this is doing. An empty string clears it, and it rejects rather than resolving quietly when not granted.

gryt.messaging

send()

send(topic: string, data: unknown, host?: string): Promise<unknown>

Needs messaging.

Send to the copy of this plugin on the server.

on()

on(topic: string, handler: (message: unknown) => void): () => void

Hear from it. Needs messaging.

servers()

servers(): Promise<string[]>

Needs messaging.

Which servers run the other half. A round trip, so a promise.

gryt.processes

running()

running(): Promise<string[]>

Needs processes.

Which of the programs the person listed are running. Their list, not their machine. Empty in a browser and until one is listed.

on()

on(handler: (running: string[]) => void): () => void

Hear when that answer changes. Needs processes.

gryt.media

current()

current(): Promise<unknown>

Needs media.

What the media controls say is playing, or null. Desktop only.

on()

on(handler: (playing: unknown) => void): () => void

Hear when it changes, checked every fifteen seconds. Needs media.

gryt.activity

set()

set(card: { type?: string; name: string; details?: string; state?: string; startedAt?: number }): Promise<unknown>

Needs activity.

Put a card on your profile: { type: "listening", name, details, state, startedAt }.

clear()

clear(): Promise<unknown>

Needs activity.

Take the card down.

gryt.ui

panel()

panel(panel: { title: string; rows: { label: string; value?: string }[] }): Promise<unknown>

Needs display.

Draw a panel beside the member list. A title and rows of text, nothing else; calling it again replaces the one panel per plugin.

clear()

clear(): Promise<unknown>

Needs display.

Take it down.

gryt.log

info()

info(message: string)

warn()

warn(message: string)

error()

error(message: string)

On this page