Web UI
The web UI is served by the Hyperspool server itself (locally, it’s at
http://localhost:18753 when you run spool dev). It talks to the same
HTTP API as the spool CLI, so everything it shows is also reachable from
the command line.
Navigation
Section titled “Navigation”The top nav carries six destinations - Inbox, Runs, Workflows, Canvas, Events, Fleet - and a More dropdown holding the rest: schedules, connections, secrets, projects, members and settings, then a link to the docs and Feedback.
Feedback opens a small form: pick what kind of thing it is, write it,
send. It reaches the people running the service with your email and
name, the org and project you were in, the page you were on and the
console build. On a server whose operator has not pointed feedback
anywhere yet the form says so instead of pretending. The same thing from
a terminal is spool feedback.
Two of those names differ from the route behind them, which is worth
knowing when you’re reading a URL rather than clicking: Inbox is
/dashboard, and Fleet is /agents.
/signin
Section titled “/signin”Two ways in, depending on what the server advertises. The page
reads a config endpoint on mount; when oidc_enabled is true it
shows a “Sign in with single sign-on” button that hands off to
the identity provider, with a personal-access-token form tucked
behind a toggle. When OIDC is off, the token form is the primary
path: paste a cspat_… token, optionally override the org/project
slug, and sign in. The token and scope are stored in
The session persists in the browser, so a reload keeps you signed in.
/dashboard
Section titled “/dashboard”The “what needs my attention?” landing page. A stats row over
three sections: Needs you - runs whose substate is
awaiting_signal (YAML approval gates and polyglot
spool wait-signal), stale waits first; Sleeping - self-
resuming durable waits (spool sleep timers and child-workflow
waits), soonest to resume first; Recent failures - failed
runs in the last 24 hours. Clicking a “Needs you” row lands on
the run-detail page with the inline approval form already wired up.
/
Runs list for the active project; it refreshes itself while runs are live. Each row links into the run-detail page; runs that came from a schedule deeplink to the schedule.
Runs that carry source tags (anything triggered off a connected
repo) show a source chip: the repo slug, the ref with a branch
(⑂) or tag (⊚) glyph, and the trigger (push, manual). A
plain manual submit has no source tags and shows no chip.
/runs/:id
Section titled “/runs/:id”Per-run page; it refreshes itself while the run is live. A header, then four tabs - Timeline (the default), Logs, Raw, and the state and artifacts views where a run has them. Things below that name a tab are only on that tab; the fan-out panel in particular lives under Logs, not on the page you land on.
-
The header carries the run id, workflow type, status, a cancel button (live runs) or a rerun button (terminal runs), a manual refresh, and a schedule deeplink where one applies. An approval form appears here when the run is waiting on a signal: its fields come from the YAML approval spec, and a bare polyglot signal falls back to a generic name + payload form. Approve resumes the run with the values given. Reject cancels the run, which is what stops the jobs behind the gate; the cancel reason records which gate it was. Both the cancel button and Reject ask before they act, and Reject re-checks the run first, so a gate answered from elsewhere while the question was open reports that nothing was stopped rather than claiming success. The same form appears inline on the dashboard for a run that needs an answer.
-
On a failed run, a banner at the top of the page names the failing step with its error and a tail of its log.
-
spool annotatenotes render below that as sanitized markdown, sorted by severity with errors first. -
For YAML runs, a job strip shows one chip per job and its status at a glance.
-
Timeline - vertical waterfall of spans derived from the event log: one bar per activity/sleep/wait, sized by duration, with queue-delay and execution segments distinguished.
-
Activities (fan-out) - fan-out view for scripts that call
spool activity-submit. Polyglot fan-out children are tracked separately fromworkflow:child runs, so this panel lists them on their own. Filter chips (all/failed/running/done) and failures-to-top sort. -
Live activity - per-step live output panes while the run executes. The merged live-log stream is split into one pane per activity; the server emits a keepalive every 15s on quiet streams and the page reconnects losslessly while the run is live.
-
The event list reveals structure rather than flattening it: workflow body events render as nested rows, and a child workflow renders inline at its spawn point, a few levels deep before it links out to the child’s own page. Per-step terminal panels show captured stdout with ANSI colors.
/canvas, /canvas/:name
Section titled “/canvas, /canvas/:name”The graph editor. /canvas lists stored graphs; /canvas/:name
opens one for authoring - a node palette, a per-node inspector with
labeled fields and help, live validation, expression autocomplete,
and draft/publish/run controls with a live run overlay. Full guide:
Authoring on the canvas.
Editing one is live in both directions - the canvas, the inspector and the JSON document underneath are the same graph:
/schedules, /schedules/:id
Section titled “/schedules, /schedules/:id”List and detail views for spool schedule-managed recurring
workflows. Both pages carry the same fields, so anything you can edit
you can also start: a script, a YAML pipeline, a stored graph by name,
or a single node kind, with cadence, timezone, overlap, jitter, label
and tags. The detail page also shows what a schedule runs and edits it
in place. An edit keeps the schedule’s id, so its run history stays
attached.
Both pages have Run now, which fires the schedule once and opens the run it started. It leaves the cadence where it is and works on a paused schedule, so it is the way to try a body out without waiting for its next deadline or disturbing it. If runs of that schedule are already going it starts nothing and lists them, with Run alongside to start one anyway.
/events
Section titled “/events”The project event bus: recent events with type, id, emitter, and
payload. Events the platform mints get a muted chip - the built-in
trigger types (push, manual, schedule.tick, spawn) and the lifecycle
types every run emits when it finishes (run.succeeded, run.failed,
run.cancelled). Custom spool emit events and forwarded forge events -
the ones a handler routes on - stand out. Handlers match by event type,
so any of these can be subscribed.
/connections
Section titled “/connections”Four things for the active project:
- Event-hooks - inbound webhooks that emit a bus event per
delivery, which a
spool handleror a graph trigger runs on. Create / list / delete them, and register one on the forge (GitHub / Gitea / Forgejo) given a repo and a forge admin credential, instead of pasting the URL + secret into repo settings. - Connected accounts - identities granted through a provider’s own consent screen, which a node can name where it would name a credential.
- Connector credentials - typed auth (bearer / api-key / basic) that canvas http and connector nodes reference by name. Write-only: values become request headers at dispatch and never come back out.
- Secrets - environment variables every job in the project gets. Names list for anyone who can see the project; replace and delete are admin. Values are write-only: nothing in the console shows one again.
To trigger runs from a repo push, a canvas webhook trigger node provisions its own endpoint; see CI from a repo.
/agents
Section titled “/agents”Fleet, which is where your compute is. Jobs execute on agents you run, so an org with no agent has nowhere to put work: runs sit waiting for a machine that never arrives. On an org that has none, the page says so and gives the two commands that fix it.
Each agent shows when it was last seen and two capability sets, and the difference between them is the thing to read:
- advertised is what the running process reports, so it is what the
agent will actually claim. It comes from its
--capflags, or from$HYPERSPOOL_AGENT_CAPABILITIES(which is what the install script’s--capswrites into the unit’s environment), or the built-inshell,polyglotdefault. - token grant is the ceiling its token allows. An agent that has never claimed anything shows only the grant, because nothing has reported what it advertises yet.
A job’s requires: is matched against the advertised set. With agents
running but none covering it, the run reports unroutable and names
what is missing; with no agents at all it reports waiting_for_agent,
because an empty fleet is indistinguishable from a busy one.
spool agents ls answers the same question from a terminal.
A token that was minted but never used gets its own section, issued but never claimed. That is the usual state of a half-finished setup: the token exists, the process was never started, and nothing will run.
Shutdown asks a running agent to stop after its current job. Forget deletes an agent’s tokens; use it to prune a decommissioned runner, remembering that a process still running with one of those tokens stops being able to authenticate.
See Deploying agents for minting tokens, capabilities, and running one as a service.
/projects
Section titled “/projects”Projects in the org: create one, switch the active project, or delete one. Deletion is destructive - it cascades everything project-scoped, so it’s armed per row and requires re-typing the slug.
/members
Section titled “/members”Manage access by email in two scopes: org-wide members and members of the active project. Each row assigns a role; granting an email that has no account yet creates an invite.
/settings
Section titled “/settings”Manage your personal access tokens: mint a new one (shown once), list existing ones, and revoke.