developer portal

build on the stream.

Everything in spectroscope hangs off one idea: an agent run is a typed stream of RunEvents, and that stream is at once the API, the storage format, the UI protocol, and the audit log. This page gets you from zero to reading the stream.

the complete user guide

Every surface in one book, from the thirty-second start to the fleet reference. Every screenshot is a real capture of the running app, reshot per release in both editions.

quickstart

an agent in five lines

The facade below is frozen: it already runs in the codebase exactly as written, and it is pinned by tests so it stays this way. v0.1.0 ships under the Maven coordinates shown; the artifact is not on Maven Central yet. The source is public at github.com/spectroscope/spectroscope.

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
}

the Python port is in design: the JSONL wire is the contract, so the stream reads the same in both

maven

<dependency>
  <groupId>dev.spectroscope</groupId>
  <artifactId>spectro-core</artifactId>
  <version>0.1.0</version>
</dependency>

cli

$ spectro run "write hello.py and run it"
$ spectro replay run.jsonl  # byte for byte
$ spectro web               # the whole cockpit
$ spectro doctor            # checks your setup

plain Java 21 on virtual threads · no reactive DSL · no container · tools sit behind a permission gate, because tool inputs are model output and therefore untrusted

the contract

one JSONL file is the whole truth

A finished run lands as newline-delimited JSON: ordered, complete, byte-stable. The wire format is the compatibility contract of the project, so a trace recorded on one machine replays on any other. These lines are abridged from the bundled review fan-out scenario:

{"type":"run_start","runId":"fanout-main","agentId":"main","prompt":"Review the open PR…"}
{"type":"thinking_delta","agentId":"main","text":"I fan out into three parallel reviewers."}
{"type":"tool_call","agentId":"main","name":"review","input":{"areas":["bugs","perf","security"]}}
{"type":"agent_spawn","agentId":"bugs","parentId":"main","task":"Find bugs in the diff"}

watching is passive: the web views, the explain layer and every exporter only read the stream; the one write path back into a live run is the permission gate, and that answer comes from you

Architecture: the agent emits one typed RunEvent stream; JSONL, the web UI, spectro-explain and exporters all read the same stream

the modules

small parts on one backbone

The RunEvent stream is the only contract between them.

spectro-core

The harness SDK: agents, tools, the permission gate, the typed event stream.

spectro-cli

The spectro launcher: run, replay, doctor.

spectro-server + web

The local cockpit: chat, Spectrum, Trace, graph, text feed and the Lab over one WebSocket.

spectro-orchestrator

Small agents on one bus, exchanging task, status and result messages.

spectro-explain

The why layer: gate explanations and causal chains, computed from the stream.

spectro-mcp-notes

A worked MCP server example to copy from.

Module map: core, cli, server and web, orchestrator, explain and the mcp example on one RunEvent backbone

the stack

runs on Spring. almost nothing else.

spectro-core is a plain Java 21 library: you instantiate agents with new, and Spring appears in the core only as its HTTP client. The server face is one ordinary Spring Boot app that serves the web UI from its own jar. The full dependency list is Jackson, Spring's web client, the Anthropic SDK, a cron parser and slf4j; the CLI adds picocli, the faces add logback. There is no agent framework underneath and no vector database to feed.

An observability tool should be observable itself: five small Gradle modules, one typed stream, and every run on disk as JSONL you can open in an editor.

spectro web

the cockpit, in one capture

This is the Trace tab replaying a bundled demo scenario, with the reasoning lens active: thinking events in the foreground, everything else dimmed, and each thought pinned to the tool call that followed it. Read the thinking for what it is: the model's self-report, not a window into the weights. Scenarios are scripted runs, so you can explore every surface of the app before you connect a model.

The trace tab of spectro web: 46 numbered frames of a review fan-out run with the reasoning lens active, one thinking frame opened with its causal chain and insight view.
trace · reasoning lens · the chain reads prompt → turn → thinking → tool call

more captures from the same scripted scenario: spectroscope.ai

status

where the project stands

spectroscope is pre-release. The harness, the CLI, the web cockpit and the scenario player exist and are under test (532 JUnit and 310 vitest checks at the current baseline); the the source is public on GitHub today; the Maven artifact lands with v0.1.0. Everything ships under the MIT license, which permits commercial use and closed-source forks.