run_start
runId | string |
agentId | string |
parentIdoptional | string |
prompt | string |
provideroptional | string |
attachmentsoptional | AttachmentRef[] |
ts | number |
the reference
A spectroscope tells you what light is made of without touching the source. This reference works the same way: every section below is extracted straight from the source tree, and each one names the file it came from. The RunEvents are the spectral lines, a run is the light they add up to, and the JSONL file on disk is the plate it is recorded on.
Extracted from Spectro.java; the example is the owner-frozen wording from SPECTRO-API.md.
var agent = Spectro.agent()
.model(Anthropic.opus())
.tools(Tools.readFile(), Tools.runCommand())
.workspace(Path.of("/tmp/scratch"));
for (RunEvent event : agent.run("Write hello.py and run it")) {
System.out.println(event); // the stream IS the observability
}agent = (Spectro.agent()
.model(Anthropic.opus())
.tools(Tools.read_file(), Tools.run_command())
.workspace("/tmp/scratch"))
for event in agent.run("Write hello.py and run it"):
print(event) # the stream IS the observabilitythe Python port is in design. The JSONL wire is the contract, so a stream recorded by either edition replays in the other.
agent() | Agent | The five-lines facade — spectroscope's front door. |
panel() | FleetPanel | The fleet path — several agents, one merged spectrum — in exactly the facade's shape. |
model(LlmProvider provider) | Agent | One configured agent: setters chain, #run streams. |
tools(Tool... tools) | Agent | The tool belt the model may call. |
workspace(Path workspace) | Agent | The directory the file tools resolve and sandbox against. |
systemPrompt(String systemPrompt) | Agent | Replaces the default unattended system prompt entirely. |
run(String prompt) | EventStream | Runs one prompt against the agent and hands back the live stream. |
The wire contract. Extracted verbatim from spectro-web/src/events.ts — the same union the TypeScript edition and the JSONL files share. The server additionally announces workspace_info on the socket (SessionConnection.java); consumers skip unknown types by contract.
run_startrunId | string |
agentId | string |
parentIdoptional | string |
prompt | string |
provideroptional | string |
attachmentsoptional | AttachmentRef[] |
ts | number |
turn_startagentId | string |
turn | number |
ts | number |
text_deltaagentId | string |
text | string |
ts | number |
thinking_deltaagentId | string |
text | string |
ts | number |
tool_callagentId | string |
callId | string |
name | string |
input | unknown |
ts | number |
permission_requestagentId | string |
callId | string |
name | string |
input | unknown |
ts | number |
permission_decisioncallId | string |
allowed | boolean |
ts | number |
tool_resultagentId | string |
callId | string |
output | string |
isError | boolean |
durationMs | number |
ts | number |
agent_spawnagentId | string |
parentId | string |
task | string |
ts | number |
compactionagentId | string |
removedTurns | number |
summaryChars | number |
ts | number |
usageagentId | string |
inputTokens | number |
outputTokens | number |
cacheReadTokensoptional | number |
cacheCreationTokensoptional | number |
ts | number |
run_endrunId | string |
stopReason | string |
ts | number |
erroragentIdoptional | string |
message | string |
ts | number |
image_generatedagentId | string |
callId | string |
prompt | string |
provider | string |
model | string |
mediaType | string |
blobPath | string |
sha256 | string |
ts | number |
context_infoagentId | string |
turn | number |
messages | number |
estimatedTokens | number |
threshold | number |
parts | { label: string; chars: number; estTokens: number }[] |
ts | number |
agent_messagefrom | string |
to | string |
role | string |
state | string |
text | string |
labeloptional | string |
ts | number |
planagentId | string |
steps | { text: string; status: string }[] |
ts | number |
Client → server messages on /ws. The server sends nothing but RunEvent JSON in the other direction.
user_messagetext | string |
attachmentsoptional | { mediaType: string; dataBase64: string }[] |
permission_responsecallId | string |
allowed | boolean |
rememberoptional | boolean |
persistoptional | boolean |
abortset_image_providerprovider | string |
set_thinkingenabled | boolean |
set_providerprovider | string |
modeloptional | string |
set_workspacepath | string |
set_permission_modemode | string |
Extracted from the @GetMapping/@PostMapping/@DeleteMapping annotations in spectro-server.
/api/claude/transcriptsRead-only browser for the Claude Code transcript store under ~/.claude/projects.
ClaudeTranscriptsController.java
/api/claude/transcripts/contentOne transcript's raw JSONL — the client runs it through detectAndLoad.
ClaudeTranscriptsController.java
/api/configThe active LLM backend for the header + the Lab map: the boot config's provider and model (the same layers the socket builds its agent from).
SessionsController.java
/api/contextWhat goes to the LLM BEFORE any user message — the main agent's assembled system prompt, tools, skills, MCP servers and the subagent role profiles.
SessionsController.java
/api/fileThe tree/content root for a request: without a session parameter, the boot root (unchanged behaviour); with one, THAT session's workspace — a per-session pin (the folder the user picked, shared state with the socket side) wins, else the config/auto rules via {@link WorkspaceResolver#locate} (no directory is ever created by a GET).
WorkspaceController.java
/api/filesPhase 5: the workspace panel's backend — a read-only, sandboxed view of the agent's working directory.
WorkspaceController.java
/api/healthThe health probe the desktop shell polls before loading the UI.
SessionsController.java
/api/images/copy-to-workspaceCopies a generated image from the global content-addressed store (~/.spectro/images/.) into a session's workspace — the gallery's "copy to workspace" button.
ImageCopyController.java
/api/images/{file}A dedicated client for the model-list probes with FINITE connect + read timeouts.
SessionsController.java
/api/jobs/stateThe scheduler's job-state map (the same data `spectroscope cron status` prints).
SessionsController.java
/api/modelsCurated fallbacks — used when the live model APIs are unreachable.
SessionsController.java
/api/pick-workspaceOpens the NATIVE folder chooser on the machine spectroscope runs on and returns the picked absolute path.
WorkspacePickController.java
/api/sessionsThe REST endpoints alongside the socket.
SessionsController.java
/api/sessions/{id}Session ids as the store mints them (yyyyMMdd-HHmmss-uuid8) plus the test/CLI-friendly general shape — never a path, never a dot.
SessionsController.java
/api/sessions/{id}/eventsThe events of one session as JSON — the graph tab replays exactly this.
SessionsController.java
/api/settingsThe settings API — the read side.
SettingsController.java
/api/transcribeThe web face of voice input: the browser records with MediaRecorder and POSTs the webm/opus bytes here; the server converts them to 16 kHz mono WAV (an ffmpeg child process) and runs the SAME {@link Transcriber} the CLI uses.
TranscribeController.java
From settings.gradle.kts, plus the two npm toolchains.
spectro-core gradle moduleThe harness SDK: agents, tools, the permission gate, the typed RunEvent stream. Plain Java 21; Spring appears only as its HTTP client.
spectro-cli gradle moduleThe ./spectro launcher's engine: run, REPL, doctor, cron, sessions, resume (picocli).
spectro-server gradle moduleOne Spring Boot app: WebSocket + REST faces, serves the built web UI from its jar.
spectro-mcp-notes gradle moduleA worked MCP server example (stdio JSON-RPC) to copy from.
spectro-orchestrator gradle moduleThe fleet: BusEnvelope choreography over one bus, every lane a full core agent, one merged EventStream.
spectro-web npm toolchainThe browser cockpit (React 19 + Vite): chat, Spectrum, trace, graph, text and Lab over one WebSocket; builds into the server's static resources.
spectro-desktop npm toolchainThe Electron shell: supervises the boot jar as a child process (not a gradle module).
The public catalog on the Tools facade (Tools.java), wire names cross-checked against StandardTools.java; the permission gate fronts every one of them.
Tools.readFile() | read_file | Tool factories that read as plain names — the frozen facade's tool vocabulary: .tools(Tools.readFile(), Tools.runCommand()). |
Tools.writeFile() | write_file | @return write_file — create or overwrite a workspace file |
Tools.editFile() | edit_file | @return edit_file — exact-match replacement inside a workspace file |
Tools.listDir() | list_dir | @return list_dir — a workspace directory listing |
Tools.glob() | glob | @return glob — filename patterns over the workspace |
Tools.grep() | grep | @return grep — content search over the workspace |
Tools.runCommand() | run_command | @return run_command — a shell command in the workspace (permission-gated) |
Tools.viewImage() | view_image | @return view_image — shows the model an image from the workspace |
Tools.viewFile() | view_file | @return view_file — shows the model a document from the workspace |
Tools.all() | @return the full standard belt, in registration order |
SPECTRO_* keys found in spectro-core. Precedence: defaults < env < user settings < project settings < workspace settings < flags.
SPECTRO_BASE_URL | Override the provider endpoint (local proxies, compat servers). |
SPECTRO_CHROME | Path to the Chrome binary the vision tools drive. |
SPECTRO_IMAGE_MODEL | Image generation backend override. |
SPECTRO_IMAGE_PROVIDER | see the SpectroConfig javadoc |
SPECTRO_LOG_LEVEL | Wire logging: info by default. |
SPECTRO_MAX_RETRIES | Provider retry budget. |
SPECTRO_MODEL | Model name for the selected provider. |
SPECTRO_PROMPT_CACHING | see the SpectroConfig javadoc |
SPECTRO_PROVIDER | LLM backend: anthropic, ollama or any OpenAI-compatible server. |
SPECTRO_STT_MODEL | Speech-to-text model for /voice. |
SPECTRO_THINKING | see the SpectroConfig javadoc |
SPECTRO_TOOL_INPUT | see the SpectroConfig javadoc |
SPECTRO_TOOL_NAME | see the SpectroConfig javadoc |
SPECTRO_TOOL_RESULT | see the SpectroConfig javadoc |
SPECTRO_WORKSPACE | see the SpectroConfig javadoc |