Skip to content
View spectroscope's full-sized avatar

Block or report spectroscope

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
spectroscope/README.md

spectroscope, agent orchestrator. spawn in five lines. watch every line.

the agent orchestrator you can watch. every event is like a spectral line, every agent a lane on the screen.

gate: the full test suites on every push maven central github release code license MIT images CC BY 4.0 macOS app signed and notarized java 21+

website · user guide · dev docs · gallery · releases · release notes

the spectrum tab: four agents reviewing a pull request in parallel, each one a lane of colored event ticks

the spectrum · four agents review a pull request in parallel; every event is a tick on its agent's lane

watch deeper

spectroscope is a JVM agent harness and fleet orchestrator. One Java core drives every face: a terminal REPL, headless runs, a Spring Boot web UI, a signed macOS desktop app, an MCP example server, and a fleet of agents on a shared bus.

Everything an agent does lands in one stream of typed JSONL RunEvents, the same wire format on every face. The UI reads that stream the way a spectroscope reads light: watch it live, store it as plain files, replay it step by step, lens it for reasoning and timing, and answer permission gates while the run waits. There is no separate telemetry stack to deploy; the session file is the record.

spectroscope began as the reference harness of a build-an-agent-harness workshop and grew into its own product.

five lines to an agent

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 same style scales to a fleet: Spectro.panel() runs several lanes as full agents on a shared bus and hands you one merged event stream. Both artifacts are on Maven Central:

implementation("dev.spectroscope:spectro-core:0.5.0")
implementation("dev.spectroscope:spectro-orchestrator:0.5.0")   // fleets

the tour

the trace tab with the reasoning lens open
the trace · every frame with its causal chain, a reasoning lens, and a replay scrubber
a run paused at the permission gate
the gate · writes and commands wait for allow or deny; every decision lands in the stream
the fleet canvas with spawn edges between agent nodes
the fleet canvas · spawn edges and per-node spectral lines, live from the bus
the machine room: a composed system diagram of a running fleet
the machine room · a running fleet as one composed system diagram, scrubbable in time
chat with the model's thinking streaming live
thinking, live · the model's self-report streams next to what it then did
the text feed with the explain panel open
explain · an LLM reading of the whole run, honestly labeled as a reading
the leveling intro on a fresh home: grow into it, or open everything now
grow into it · a fresh home starts small and asks; an existing home is never asked and never locked
the leveling progress panel: criteria with ticks and receipts, the spectrum strip filling per level
the tutorial · levels tick from observed usage, every tick with a receipt into the session it happened in
the built-in model chooser: five local models with tool badges, sizes and a machine-fit line per row
no key, no cloud · pick a local model, see whether your machine holds it, download once — tools included

More in the gallery and the user guide, both in light and dark.

install

Four routes to 0.5.0, each with the platform it covers. Every asset is on the release page, where SHA256SUMS.linux covers the two Linux kits.

Homebrew — macOS on Apple silicon.

brew install --cask spectroscope/tap/spectroscope

The signed and notarized desktop kit, which brings its own Java runtime and its own llama-server. Uninstalling leaves ~/.spectro alone: that is where your sessions live, and the CLI and the server jar share it. Apple silicon only, there is no Intel build.

The disk image — macOS on Apple silicon. spectroscope-0.5.0-arm64.dmg from the release page is the same kit without the tap.

apt — Debian 12 and Ubuntu 24.04, x86_64.

curl -fsSL https://apt.spectroscope.dev/spectroscope.asc | sudo gpg --dearmor -o /usr/share/keyrings/spectroscope.gpg
echo "deb [signed-by=/usr/share/keyrings/spectroscope.gpg] https://apt.spectroscope.dev stable main" | sudo tee /etc/apt/sources.list.d/spectroscope.list
sudo apt update && sudo apt install spectroscope

The index is GPG-signed and pinned to that one key with signed-by; there is no trusted=yes and no allow-insecure switch. x86_64 only, so on arm64 apt takes the source and then finds nothing to install. For x86_64 distributions that do not use apt, spectroscope-0.5.0-x86_64.AppImage is the same kit as one file. Neither Linux kit is signed, because Linux has no equivalent gate to pass. Both are covered by SHA256SUMS.linux on the release page, so the check to run on a download is:

sha256sum -c SHA256SUMS.linux --ignore-missing

From source. Clone this repository and use the ./spectro launcher below.

Everywhere else — arm64 Linux, Windows, anything with a JVM. There is no desktop kit, and no macOS route will help. Take spectro-0.5.0.zip (the CLI) or spectro-server-0.5.0.jar and run them on a JDK 21; that is the smallest way in, and the only way onto a platform with no kit. Two things the kits carry are missing there: a bundled llama-server for the built-in models, which you supply yourself (brew install llama.cpp, or your package manager), and the spectro-pty helper the Files tab terminal needs, which is POSIX-only either way. The bundled example MCP server ships separately as spectro-mcp-notes-0.5.0.zip.

run it

The desktop kits open the cockpit themselves. From a clone, the ./spectro launcher resolves a JDK 21+ for you and loads the gitignored ./.env:

./spectro web start   # web UI → http://127.0.0.1:8080, in the background
./spectro web         # what the web group can do, and whether it is running
./spectro repl        # terminal REPL
./spectro run -p ""  # headless run
./spectro desktop     # Electron desktop app
./spectro doctor      # environment check
./spectro tour        # guided feature tour

It also knows node, cron, sessions, resume <id>, level and mcp-notes. Raw Gradle works too (JDK 21+ as JAVA_HOME):

./gradlew build                                  # everything + all tests
./gradlew :spectro-server:bootRun                # the web face
(cd spectro-web && npm install && npm run build) # rebuild the UI into the server jar

The web build writes into spectro-server/src/main/resources/static/, where the committed bundle lives, so rebuilding it dirties tracked files by design. Web development wants Node 20+.

observability, built in

The core has a tracing seam, and two sinks ship with it: the JSONL session file (always on, the source of truth) and an OTLP exporter that maps sessions to GenAI-semconv spans. Point it at Langfuse, Jaeger, or any OTLP endpoint under settings, observability; spectro doctor probes the endpoint with an empty batch and tells you whether it answers. Details in docs/OBSERVABILITY.md.

how it is built

architecture overview: one core, five faces
module what it is
spectro-core the agent loop, providers, tools, permission gate, sessions, tracing seam
spectro-cli terminal face: REPL, headless runs, doctor, tour, scheduler
spectro-server Spring Boot web face: WebSocket stream + REST, serves the built UI
spectro-web the React UI (Vite): chat, spectrum, trace, graph, text, lab
spectro-desktop Electron shell that spawns and supervises the server jar
spectro-mcp-notes bundled example MCP server (notes search/add over stdio)
spectro-orchestrator the fleet: lanes as full agents on a shared bus, one merged stream

Runs on Spring and almost nothing else. Twenty-one hand-built architecture diagrams live in docs/diagrams/, each in both themes; docs/ARCHITECTURE.md and docs/WEB-UI.md go deep.

providers

Seven chat providers, switchable mid-session from the header picker with history intact:

provider runs needs
built-in local, via llama-server nothing with the desktop kits, which bundle one; with the server jar, brew install llama.cpp
anthropic cloud ANTHROPIC_API_KEY
ollama local a running Ollama
openai api.openai.com or any compatible server OPENAI_API_KEY (optional for local servers)
lmstudio local LM Studio's server
openrouter cloud OPENROUTER_API_KEY
gemini cloud GEMINI_API_KEY

The built-in provider is the no-setup path: the app offers a small catalogue of open models (Qwen3 1.7B/4B/8B, Qwen2.5 Coder 7B, VibeThinker 3B), says which of them can drive the agent's tools and whether your machine has the memory and disk for each, then downloads your pick sha256-pinned — four of them from Qwen's own repository, VibeThinker from a community requantization of WeiboAI's model. Each row links its licence and its source. The desktop kits carry their own llama-server, so nothing else needs installing; with the server jar you bring your own (brew install llama.cpp) and the chooser says so when it is missing. No key and no account, and the model itself runs on your machine.

Keys are set once, in the UI (masked, written to ~/.spectro/.env with mode 0600) or via CLI set-key; one Gemini or OpenAI key serves chat and the generate_image tool alike. Config layers from env up to per-workspace settings files; spectro doctor names anything shadowed.

Beyond that, the tool belt covers files, shell, sandboxed grep and glob, web fetch, tiered web search, JS-capable page browsing through the system Chrome, image generation, subagents, skills, and MCP servers, all behind the same permission gate.

tested

The v0.5.0 gate: 1166 JUnit tests and 1841 vitest tests across 130 files, no failures, measured on the release tree with the build cache and the up-to-date checks disabled. The suites run without any API key; provider wire mappings are tested against scripted local servers, and the one live contract check skips itself unless a key is set. Concurrency suites (bus, hub, fleet) pass three consecutive runs before a release.

docs

  • user guide, 120+ pages, HTML and PDF, light and dark editions, real captured screens
  • dev portal with a generated, searchable reference extracted from this source tree
  • samples/ — eight numbered examples, six of them standalone Gradle projects that resolve spectroscope from Maven Central rather than from this tree: the five lines, a fleet, recording a run for spectro web, a fleet across processes, OTel export, and a LangChain4j provider
  • docs/ARCHITECTURE.md, docs/WEB-UI.md, docs/OBSERVABILITY.md, docs/INTEROP.md
  • docs/WEB-BUNDLE.md — why the built UI is a tracked file, and the one command that resolves it when two branches collide in it
  • release-notes/ for what each version brought

Found a bug or a rough edge? Open an issue; the project is young and moves fast.

license and credit

Two licenses, one rule: the name stays attached.

Code: MIT, copyright Christopher Ezell. Use it, fork it, ship it, sell with it; the one thing the license asks is that the copyright notice travels with copies of the code. Stripping it ends the license.

Images: CC BY 4.0 for the screenshots, the architecture diagrams and the banner. Reuse them in posts, talks, papers or products, commercially too, as long as visible attribution stays with them: "spectroscope — Christopher Ezell, github.com/spectroscope/spectroscope, CC BY 4.0". The spectroscope logo and wordmark are the exception: fine for referring to the project, not for branding something else — LICENSE-ASSETS.md has the exact terms.

If spectroscope shows up in your product or your research, a mention with a link back is very welcome. GitHub reads CITATION.cff, so "cite this repository" in the sidebar gives you a ready-made reference.

Popular repositories Loading

  1. spectroscope spectroscope Public

    the agent orchestrator you can watch

    TypeScript 1

  2. spectroscope-edu spectroscope-edu Public

    Standalone teaching app for spectroscope: interactive edu lessons + a backend-free agent-harness simulator (map · spectrum · trace). React 19 + Vite + React Flow; deploys to Cloudflare Workers. MIT.

    TypeScript

  3. homebrew-tap homebrew-tap Public

    Homebrew tap for spectroscope — the agent orchestrator you can watch

    Ruby

  4. apt apt Public

    The spectroscope apt repository — signed Debian/Ubuntu packages for the agent orchestrator you can watch

    HTML

  5. blog blog Public

    The spectroscope development blog — what the measurements found, told from the record

    HTML