Quickstart

This guide gets Diminuendo running on your local machine in dev mode — authentication bypassed, SQLite databases auto-created, and the gateway listening on port 8080. You will connect a client, create a session, and receive your first state snapshot.

Prerequisites

Bun 1.0+

Diminuendo runs on Bun, a fast JavaScript runtime with native WebSocket and SQLite support. Install it with curl -fsSL https://bun.sh/install | bash or via your system package manager.

Clone and Install

The repository uses git submodules for its backend service dependencies (Podium, Ensemble, Chronicle). Clone with --recurse-submodules to pull them in a single step:
git clone --recurse-submodules https://github.com/iGentAI/diminuendo.git
cd diminuendo
bun install
If you already cloned without --recurse-submodules, initialize them after the fact:
git submodule update --init --recursive

Start in Dev Mode

bun run --watch src/main.ts
You should see output similar to:
[info] Config: dev mode enabled
[info] Auth: Dev mode enabled — all requests authenticated as developer@example.com
[info] Gateway listening on 0.0.0.0:8080 (dev mode — auth bypassed)
In dev mode, every WebSocket connection is automatically authenticated as developer@example.com in the dev tenant. No Auth0 configuration, no JWT tokens, no environment variables required.
The gateway creates a ./data directory on first run containing SQLite databases for tenant registries and session data. This directory is gitignored. Delete it at any time to reset all state.

Connect with a WebSocket Client

Any WebSocket client will work. Here is the sequence using wscat:
# Install wscat if you don't have it
npm install -g wscat

# Connect to the gateway
wscat -c ws://localhost:8080/ws
Upon connection, the gateway immediately sends three messages:
{"type":"welcome","protocolVersion":1,"requiresAuth":false}
{"type":"connected","clientId":"a1b2c3d4-...","heartbeatIntervalMs":30000,"ts":1709312400000}
{"type":"authenticated","identity":{"userId":"dev-user-001","email":"developer@example.com","tenantId":"dev"}}
In production, the welcome message will have requiresAuth: true. You must send an authenticate message with a valid JWT before the gateway will accept any other messages. In dev mode, this step is skipped entirely.

Your First Session

With the connection authenticated, create a session, join it, and receive a state snapshot — the three-step handshake for any Diminuendo interaction:
1

Create a session

Send:
{"type":"create_session","agentType":"coding-agent","name":"My First Session"}
Receive:
{
  "type": "session_created",
  "session": {
    "id": "f47ac10b-...",
    "tenantId": "dev",
    "name": "My First Session",
    "agentType": "coding-agent",
    "status": "inactive",
    "archived": false,
    "createdAt": 1709312400000,
    "updatedAt": 1709312400000,
    "lastActivityAt": null
  }
}
2

Join the session

Send (using the id from the previous response):
{"type":"join_session","sessionId":"f47ac10b-..."}
Receive a state snapshot — the complete current state of the session:
{
  "type": "state_snapshot",
  "sessionId": "f47ac10b-...",
  "session": { "id": "f47ac10b-...", "status": "inactive", "..." : "..." },
  "currentTurn": null,
  "recentHistory": [],
  "subscriberCount": 1,
  "sandbox": null
}
3

Subscribe to events

After joining, your client is automatically subscribed to all events for that session. When another client (or the agent itself) produces events, they will stream to your connection in real time.

Using the TypeScript SDK

The @igentai/diminuendo-client SDK wraps the raw WebSocket protocol into a typed, promise-based API. Here is the same sequence using the SDK:
import { DiminuendoClient } from "@igentai/diminuendo-client"

const client = new DiminuendoClient({
  url: "ws://localhost:8080/ws",
  // No token needed in dev mode
})

await client.connect()
console.log("Authenticated as:", client.identity)

// Create a session
const session = await client.createSession("coding-agent", "My First Session")
console.log("Created session:", session.id)

// Join and get current state
const snapshot = await client.joinSession(session.id)
console.log("Session status:", snapshot.session.status)
console.log("Recent history:", snapshot.recentHistory.length, "messages")

// Listen for streaming events
client.on("text_delta", (event) => {
  process.stdout.write(event.text)
})

client.on("turn_complete", (event) => {
  console.log("\n--- Turn complete ---")
  console.log("Final text:", event.finalText.slice(0, 100) + "...")
})

client.on("tool_call", (event) => {
  console.log(`Tool call: ${event.toolName}(${JSON.stringify(event.args)})`)
})

// Start a turn (requires a running Podium agent backend)
// client.runTurn(session.id, "Explain this codebase's architecture")

Run the Test Suite

The gateway includes 9 integration tests that validate protocol handling, session lifecycle, event mapping, and error paths:
bun test
The full repository includes 690 tests across the gateway and four SDKs. For SDK test commands and methodology, see Testing Methodology.

Full Dev Stack

bun dev starts the gateway only. It expects PODIUM_URL and ENSEMBLE_URL in your .env (typically pointing at staging services) and does not build Podium, Ensemble, or Chronicle locally. To run the full stack on your machine, follow the README’s Full Development Stack instructions and build the Rust/Go services separately.
bun dev
ServicePortPurpose
Diminuendo8080WebSocket gateway (this project)
Podium Coordinator5082Agent orchestration
Ensemble5180LLM inference and routing
Chronicle(local-sync)Workspace filesystem (APFS/ext4 files)
Valkey (Redis-compatible)6379Podium state and pub/sub
MinIO9000S3-compatible object storage

Other SDKs

Next Steps