| name | autotel-terminal |
| description | Use this skill when integrating the autotel-terminal dashboard into a Node.js app or running it as a standalone OTLP receiver — covers renderTerminal(), StreamingSpanProcessor, the CLI, and the AI assistant configuration.
|
autotel-terminal
React-Ink powered terminal dashboard for viewing autotel OpenTelemetry spans in real-time. Two modes: embedded in your Node.js process via renderTerminal(), or standalone OTLP receiver via the autotel-terminal CLI.
Setup
Embedded mode (in-process)
import { init, trace } from 'autotel';
import {
renderTerminal,
StreamingSpanProcessor,
createTerminalSpanStream,
} from 'autotel-terminal';
const streamingProcessor = new StreamingSpanProcessor(null);
init({
service: 'my-app',
endpoint: 'http://localhost:4318',
spanProcessors: [streamingProcessor],
});
const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({ title: 'My App Traces' }, stream);
Standalone CLI (separate terminal)
npx autotel-terminal
OTEL_EXPORTER_OTLP_PROTOCOL=http/json \
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4319 \
node app.js
Configuration / Core Patterns
TerminalOptions
renderTerminal(
{
title: 'My App Traces',
showStats: true,
maxSpans: 200,
colors: true,
ai: {
provider: 'ollama',
model: 'granite4',
apiKey: 'sk-...',
baseUrl: 'http://...',
},
},
stream,
);
StreamingSpanProcessor — wrapping an existing processor
Wrap a BatchSpanProcessor so spans go to both the terminal dashboard and your OTLP backend:
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { StreamingSpanProcessor, createTerminalSpanStream } from 'autotel-terminal';
const exporter = new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' });
const batchProcessor = new BatchSpanProcessor(exporter);
const streamingProcessor = new StreamingSpanProcessor(batchProcessor);
const unsubscribe = streamingProcessor.subscribe((span) => {
console.log('Span ended:', span.name);
});
Auto-wire shortcut (no stream needed)
If you call init() before renderTerminal(), autotel-terminal auto-detects the tracer provider:
import { init } from 'autotel';
import { renderTerminal } from 'autotel-terminal';
init({ service: 'my-app' });
renderTerminal();
CLI options and environment variables
autotel-terminal \
--port 4319 \
--host 127.0.0.1 \
--title "My Dashboard" \
--ai-provider ollama \
--ai-model granite4 \
--ai-api-key sk-... \
--ai-base-url http://...
CLI OTLP endpoints (all accept OTLP JSON format):
| Endpoint | Signal |
|---|
POST /v1/traces | Spans streamed into the TUI |
POST /v1/logs | Logs shown in logs view (l) |
POST /v1/metrics | Acknowledged and counted |
GET /healthz | Health check |
AI assistant
Auto-detects Ollama (if running locally) or OpenAI (if OPENAI_API_KEY is set). Press a in the dashboard to toggle the AI panel. The assistant can answer questions about the spans currently visible in the dashboard.
Dashboard keyboard controls
| Key | Action |
|---|
↑/↓ | Navigate |
Enter | Open selected trace (span tree) |
Esc | Back / exit search |
t | Toggle trace view / span list |
l | Toggle logs view |
v | Toggle service summary |
E | Toggle errors view |
/ | Search by span name |
e | Toggle error-only filter |
p | Pause / resume live updates |
r | Record snapshot |
c | Clear all spans |
J | Export selected trace as JSON (stdout) |
? | Show help overlay |
Ctrl+C | Exit |
Common Mistakes
HIGH — Calling renderTerminal() before init()
Wrong:
renderTerminal({}, stream);
init({ service: 'my-app', spanProcessors: [streamingProcessor] });
Correct:
init({ service: 'my-app', spanProcessors: [streamingProcessor] });
const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({ title: 'My App' }, stream);
Explanation: init() must run first so the StreamingSpanProcessor is registered with the tracer provider before any spans are created.
HIGH — Not adding StreamingSpanProcessor to init()
Wrong:
const streamingProcessor = new StreamingSpanProcessor(null);
init({ service: 'my-app' });
const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({}, stream);
Correct:
const streamingProcessor = new StreamingSpanProcessor(null);
init({ service: 'my-app', spanProcessors: [streamingProcessor] });
Explanation: StreamingSpanProcessor must be in the spanProcessors list passed to init() — it is not registered automatically.
MEDIUM — Using standard OTLP port 4318 for the CLI
Wrong:
npx autotel-terminal --port 4318
Correct:
npx autotel-terminal
Explanation: The CLI defaults to port 4319 deliberately so it does not clash with an existing OTLP collector on 4318.
MEDIUM — Passing full protocol path to OTEL_EXPORTER_OTLP_ENDPOINT
Wrong:
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4319/v1/traces
Correct:
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4319
Version
Targets autotel-terminal v17.0.8. Requires autotel (peer), @opentelemetry/api ^1.9.0, @opentelemetry/sdk-trace-base ^2.6.0. Node.js 22+. Uses Ink v6 / React 19 internally.