Developers

manifest.json

{
  "id": "com.yourname.myplugin",
  "name": "My Plugin",
  "version": "1.0.0",
  "author": "Your Name",
  "summary": "One line describing what this does.",
  "entry": "index.html",
  "mode": "session",
  "permissions": ["voice", "eyes"],
  "minAppBuild": 17,
  "files": ["index.html", "plugin.js"]
}
Field Required Notes
id yes Reverse-DNS, globally unique. This is your identity — installs, permissions and updates are keyed on it. Changing it makes a different plugin.
name yes Shown in the gallery and the plugin list.
version yes Semver. Bump it for every published change.
author no Shown to the user.
summary no One line, shown in the gallery. Write it for someone deciding whether to install.
entry no Defaults to index.html.
mode no session (default) or ambient. See below.
permissions no Array of strings — see permissions.md. Empty means your plugin is pure web content.
minAppBuild no Refuse to install on older builds. Use it when you depend on a newer API.
files yes Every file the plugin needs, as a path relative to the manifest.

files

There is no zip anywhere in the pipeline — not in the upload, not on the device. The app fetches each path in files individually.

So files is the definition of your plugin. A file you upload but don't list is not installed, and a file you list but don't upload is a blocking error at upload time. A stylesheet missing from the list is the most common way a plugin works locally and ships blank.

mode

session — full screen, opened and closed by the user. Your page owns the display; the robot's face is not visible while you run.

ambient — replaces the idle face on the dock. Good for clocks, ambient visuals, a custom face.

One thing to know about ambient: it yields the moment the robot leaves idle. If the user speaks to it, your plugin gives up the screen until the conversation ends. Deep idle also always wins, for battery. Do not build an ambient plugin that depends on running continuously.

Unknown fields and permissions

Unknown permission strings are dropped, not rejected — a plugin built against a newer SDK still runs on an older app, with the subset that build understands. Combine that with minAppBuild and feature detection to decide what "still runs" should mean for you.

← Previous Overview Next → The hairobo API
Preorder Deskmate dock

Reserve your dock.

Drop your details and we'll email you the moment it ships, with early-bird pricing.