Introduction
claude-spt is the Spacetime (spt) adapter for
Claude Code. You install one Claude Code plugin — sptc — and get three things at once:
- Agent messaging and live agents inside Claude Code: send messages between agents, run a
reachable “perch,” and drive long-lived live-agent sessions, all delegated to the
sptbinary. - An invisible
spt-coreinstaller. The first time the plugin loads, it installsspt-corefor you if it is missing. No separate setup step. - A casual on-ramp to spt-core. The plugin is the friendly front door to the wider Spacetime agent ecosystem — subnets, terminal hosting, seamless self-update — without leaving your editor.
Mental model
Claude Code provides the harness (hooks, skills, your prompt). The spt binary provides the
core (messaging, lifecycle, networking). claude-spt is the thin adapter between them: it
maps Claude Code’s hook events to the spt binary’s harness-contract entry points and surfaces
delivered messages back into your session.
Claude Code ──hook events──▶ sptc adapter ──spt api──▶ spt-core
(the harness) (this project) (messaging,
▲ thin glue live agents,
└────── additionalContext / skills ◀── renders ◀──── networking)
Two ideas follow from that picture, and they shape everything else in these docs:
- The adapter is thin by design. Logic and skill instructions live in the
sptbinary and its adapter manifest (conducted by spt-core), not in the plugin. The plugin ships skeletons; the operative content is delivered at run time. See Harness contract. - It is built against
spt-core’s public surface only — the publishedspt-releasesbinary, install scripts, and docs. That constraint is the point: it proves the adapter contract is buildable by anyone, from the published surface alone.
Status
This is an early, skeleton-honest build. Skills surface under the /sptc:* namespace; surfaces
that are not yet operative say so in place. Start with the Quickstart.
Quickstart
Goal: install the sptc plugin, watch it bring up spt-core for you, and confirm your session is
reachable — in under ten minutes. You need Claude Code and a shell (bash on macOS/Linux, Git Bash
on Windows).
1. Add the marketplace and install the plugin
From Claude Code:
/plugin marketplace add SaberMage/cplugs
/plugin install sptc@cplugs
Then restart the Claude Code session so the plugin’s SessionStart hook runs and populates the
session environment.
2. Let it install spt-core for you
On that first start, the plugin’s bootstrap installs spt-core if it is not already present —
this is the invisible-installer step, nothing for you to run. Confirm it landed:
spt --version
If spt is not yet on your PATH in this shell, it was installed to ~/.local/bin/spt (macOS /
Linux) or %LOCALAPPDATA%\spt-core\bin\spt.exe (Windows); open a fresh shell and try again.
3. Confirm your session is reachable
Each Claude Code session resolves its own agent identity. Check it:
spt whoami
That prints this session’s perch id (resolved from $OWL_SESSION_ID / $SPT_AGENT_ID). A printed
id means the adapter wired your session into Spacetime’s messaging fabric.
What works today, and what is coming
This is an early build. The plumbing above — install, invisible spt-core bootstrap, identity —
is operative now. The /sptc:* skills (send, ready, live, commune, and the rest) ship as
skeletons: their operative instructions are delivered by the adapter at invocation time rather
than baked into the plugin, and some are still being wired. Each skill says in place whether it is
operative yet.
Next, read Harness contract to see exactly how Claude Code hook
events map onto the spt binary.
Harness contract
claude-spt is glue: it maps Claude Code hook events to the spt binary’s harness-contract
inbound surface (spt api --adapter claude-spt <verb>). The binary is harness-agnostic; this
adapter is the Claude-Code-shaped edge of it.
The authoritative contract lives on spt-core’s published surface — the
harness-contract + CLI reference. This page documents
the adapter’s wiring: which Claude Code hook drives which spt api verb.
Hook → spt api mapping
| Claude Code hook | sptc wrapper | spt api verb | Purpose |
|---|---|---|---|
SessionStart | hooks/session-start.sh | seed / bind / boundary | Bootstrap spt-core, register the perch (bind spt-hosted · seed harness-hosted · boundary on clear/compact), then relay an agent-facing brief (see below); non-blocking — never listen. |
UserPromptSubmit | hooks/user-prompt-submit.sh | poll | Drain delivered messages and surface them to the prompt as additionalContext. |
Stop | hooks/stop.sh | state (idle) | Mark the agent idle when a turn ends. |
SessionEnd | hooks/session-end.sh | session-end | Tear down session state cleanly. |
SubagentStart | hooks/subagent-start.sh | worker-* | Track a spawned subagent. |
SubagentStop | hooks/subagent-stop.sh | worker-* | Track subagent completion. |
Two invariants the wrappers hold
- Payload comes from stdin, never from a
/-leading argument. On Windows under Git Bash / MSYS, any argument beginning with/is silently rewritten to a Windows path. The wrappers read the Claude Code hook payload as JSON from stdin, so a/sptc:…token is never corrupted. - Messages are self-delimiting
<EVENT>envelopes.polloutput is rendered by splitting on the canonical<EVENT type="msg" from="…">body</EVENT>envelope, so a multi-message drain parses cleanly and each message keeps its sender for reply-correlation.
Identity
Every session resolves its own perch id via spt whoami, off $OWL_SESSION_ID / $SPT_AGENT_ID.
A session with no perch (never made reachable) simply delivers nothing — the per-prompt drain
no-ops rather than erroring.
SessionStart briefs
SessionStart also relays an agent-facing brief as additionalContext, composed from the
adapter’s [strings.briefs] (same file-backed/inline machinery as [strings.skills]). The hook
only selects + composes + {id}-substitutes — it never authors the prose.
| session state | trigger | brief |
|---|---|---|
| has a perch | bind ($SPT_ENDPOINT_ID) or boundary (clear/compact) | identity brief — who it is ({id}), that its perch is already live (don’t re-arm → COLLISION), and how to message (spt send + reply + the spt endpoint list roster). |
| no perch, node has subnet peers | seed / fresh startup | ring brief — how to reach other agents without a perch (spt ring <target> --timeout 60) + the roster. |
no perch and no peers · subagent (agent_type set) | — | nothing. |
The brief is liveness-agnostic (no live-vs-ready distinction) pending a published machine-readable
liveness query on the spt surface. The peer gate is a line-count presence check on spt subnet status — it never parses the human-formatted column values.
The operative skill instructions are not in this plugin. They are delivered by the adapter manifest (conducted by spt-core) at invocation time; the
/sptc:*SKILL.mdfiles are deliberately thin skeletons. This split keeps the marketplace artifact low-churn while logic and instructions update through spt-core’s signed adapter-update channel.