Getting started: a notification shell
The fastest way to understand shells is the shipping one:
spt-shell-notify renders
agent commands and surfaced notifications as native OS notifications
(Windows toast / Linux notify-send). Its manifest plus one small binary are
the only glue to spt-core — no spt-core source, no SDK; the binary speaks
the public spt api surface and nothing else. This page installs it, drives
it, and reads its manifest as the template for your own shell.
1. Install and spawn it
$ git clone https://github.com/SaberMage/spt-shell-notify
$ cd spt-shell-notify
$ cargo install --path . # puts `notify-shell` on PATH
$ spt adapter add . # validates + registers the manifest
ADAPTER_ADD:notify:Shell:Copy (registered)
$ spt shell spawn notify # mints an instance (notify-1) and launches it
spawn mints a new instance identity — notify-1 — and launches the
binary; it’s the creation act, not an on/off switch. The first spawn asks for
approval once (the manifest sets require_approval = "remembered"), and the
grant persists.
2. Drive it from an agent
Two render paths, by design:
Explicit command — an owner agent drives a toast down the durable command channel:
$ spt shell cmd notify-1 notify "build finished" "all 139 tests green"
The resident binary drains its command frames (spt api … poll --link) and
renders. Commands are validated against the manifest’s declared vocabulary —
a verb or arity outside [shell.capabilities] is refused before it ever
reaches the binary.
Surfaced notification — no agent in the loop:
$ spt notify "deploy window opens in 10 minutes"
A subnet-wide notification resolves to the node the user most recently
touched, and spt-core spawns the shell’s [session.notif] template there —
a native toast on the machine you’re actually at.
3. Read the manifest
The complete contract for this shell, annotated:
[adapter]
name = "notify"
kind = "shell"
version = "1.0.0"
min_spt_core_version = "1.0.0"
[shell]
# Broker-launched; the {link_token} is the binary's only credential.
spawn = "notify-shell --link {link_token} --id {id}"
# A display is node-local; discovery never offers it off-node.
broadcast = "same-node"
# Auto-online with the owner: the notification surface should be up
# whenever the user's endpoint is.
persistent = true
# First spawn asks once; the grant is remembered.
require_approval = "remembered"
pre_close = "closing"
close_timeout_ms = 2000
# Offline wake-watcher: reports wake (exit code 86) after a short settle.
wake_command = "notify-shell --wake"
# The whole command vocabulary: one verb, two positional args.
[shell.capabilities.notify]
args = ["title", "body"]
# The notif render seam: spt-core fills the {notif_*} keys and spawns this
# detached when a notification surfaces at an endpoint this shell serves.
[session.notif]
command = 'notify-shell --render-title "{notif_from}" --render-body "{notif_body}"'
detach = true
keys = ["notif_id", "notif_from", "notif_subnet", "notif_body"]
What the binary itself does (three modes, ~one file):
- resident (
--link …): callsapi bind-shell --link <token>to come online, then loopsapi poll --link <token>draining command frames and rendering them. - one-shot render (
--render-title/--render-body): the[session.notif]template — render and exit. - wake watcher (
--wake): run while the instance is offline; exiting with code 86 signals “wake me”.
4. Make your own
A shell is worth building whenever agents should drive something — a desktop widget, a robot, a lamp, a game character, a sensor feed:
- Start from this manifest; change
name,spawn, and the[shell.capabilities]vocabulary to your verbs. - Your binary needs exactly three behaviors: bind with the link token,
drain commands (
api poll --link, or declarecommand_receipt = "http"/"stdin"if those fit better), and optionally emit sensory payloads back (api emit … --type <t> --link <token>— declared in[shell.sensory], delivered only to a live owner session: sensors report the present, never the past). - Pick lifecycle behavior:
persistentfor always-up surfaces,ephemeral = truefor fire-and-forget ones,wake_commandif the surface can wake its owner. spt adapter add .andspt shell spawn <name>.
Field-by-field details: the manifest reference;
the shell-side api calls: the spt api reference.