# nterm

**A network-aware SSH terminal that understands what it sees.**

nterm combines a multi-tab SSH terminal, real-time output parsing, and live device telemetry in a single desktop application. Run a show command, click a gutter mark, and get structured, exportable data — without ever leaving the terminal.

![nterm desktop — two-pane layout with SSH terminal and live telemetry](https://raw.githubusercontent.com/scottpeterman/nterm-ng/refs/heads/main/screenshots/slides2.gif)

---

## Why nterm

Every network engineer lives in a terminal. You run commands, read output, copy-paste into spreadsheets, and repeat. nterm sits in that workflow and makes the output useful:

- **You type a command.** The terminal works exactly like any SSH session.
- **nterm detects the response.** A sniffer pipeline identifies command boundaries in real time — no agents, no API calls, no device-side config.
- **A gutter mark appears.** Subtle amber indicators line up next to each detected command block.
- **You click when you want insight.** Right-click a mark → Visualize, and the output is parsed into a structured table you can copy into a Word doc, export as JSON/CSV, or just read without squinting at fixed-width columns.

The terminal is never interrupted. You opt in to the intelligence. That's the difference between a tool engineers adopt and one they ignore.

![Visualizer overlay — parsed LLDP neighbors with confidence scoring and export](https://raw.githubusercontent.com/scottpeterman/nterm-ng/refs/heads/main/screenshots/arista1.png)

---

## Features

**Multi-Tab SSH Terminal** — xterm.js rendering with full color support, resize, and the nterm dark palette. Password, key file, key paste, and vault-backed authentication. Legacy device mode for older equipment with deprecated ciphers.

**Session Tree with Context Menu** — Saved sessions in a searchable tree with folder hierarchy and vendor-colored indicators. Right-click any device to Connect SSH, Open Telemetry, or Copy Hostname. Single-click populates the connect form, double-click auto-connects if credentials are available.

**Session Sniffer** — A client-side pipeline that processes every byte of the SSH stream through four stages: line accumulation → interruption detection → prompt detection → block extraction. No server load, no round-trip latency. Works across vendors without device-side configuration.

**Gutter Bar** — CRT-phosphor amber marks rendered alongside the terminal viewport, one per detected command block. Dynamic offset algorithm keeps marks aligned even through scrollback and line wrapping.

**Visualizer + Parse Engine** — On-demand structured parsing via a provider chain: 1,000+ TextFSM templates → 800+ TTP templates → LLM fallback. High-confidence results short-circuit in milliseconds. Results cached per block.

**Credential Vault** — Fernet-encrypted SQLite storage with PBKDF2 key derivation (480K iterations). Pattern-based credential matching by hostname. Secrets never cross the WebSocket — the server resolves credentials and injects them into SSH connections. Unlock the vault once at startup and every session tree action resolves credentials automatically. Optional keychain integration for auto-unlock (requires `keyring` — see Optional Dependencies below).

**Live Telemetry (Wirlwind)** — Right-pane dashboard with per-device polling: interface throughput (ECharts), LLDP/CDP topology (SVG), interface status table, CPU/memory gauges, device log, and BGP summary. Independent SSH connections per telemetry tab. Four launch paths: session tree right-click, LLDP neighbor modal, File menu dialog, or implicit vault auto-resolve. Supports network devices and generic Linux hosts — any SSH-reachable system can be monitored.

**Neighbor Hop** — Click any node in the live LLDP/CDP neighbor map to open an SSH terminal or telemetry tab on that device. Credentials carry forward automatically — enter your password once, then click through the entire topology. No inventory required. No IP copying. No re-authentication. At 2 AM during an outage, the network is one click deep from wherever you are. See [NEIGHBOR_HOP.md](NEIGHBOR_HOP.md) for the full guide.

**Session Management** — Import from CSV, JSON, TerminalTelemetry YAML, or Secure Cartography topology maps. Drag-and-drop organization via native session editor.

**Diagnostics Panel** — Six views: Stream log, session stats, sniffer output, prompt detector state, block history, and performance instrumentation with P50/P95/P99 timing across all hot paths.

---

## Neighbor Hop

**Walk the network from any starting point. One click per device.**

SSH into a device and open a telemetry tab. Wirlwind polls the device and renders a live LLDP/CDP neighbor map. Every neighbor node is clickable:

- **Connect SSH** — opens a terminal tab connected to the neighbor, reusing your existing credentials
- **Telemetry** — opens a Wirlwind tab monitoring the neighbor, with its own clickable LLDP map

Enter your password once. Click through the entire fabric. Each hop auto-detects the vendor (Arista → Juniper → Cisco → Linux) and adjusts the parse chain and collection templates. The vault provides per-device credential matching when the environment requires it.

This is the workflow for outage triage: land on one device at the edge of the problem, and trace the blast radius by clicking neighbors. No context switching, no IP lookup, no re-authentication.

<!-- ![Neighbor Hop — LLDP neighbor detail modal with Connect SSH and Telemetry](screenshots/neighbor_hop.png) -->

See [NEIGHBOR_HOP.md](NEIGHBOR_HOP.md) for the full feature guide, architecture, and credential reuse details.

---

## Quick Start

### Requirements

- Python 3.10+
- PyQt6 with QtWebEngine

### Install from PyPI

```bash
pip install nterm-ng
```

### Install from Source

```bash
git clone https://github.com/scottpeterman/nterm-ng.git
cd nterm-ng
pip install .
```

### Run

```bash
nterm
```

This starts a local FastAPI server on an auto-discovered port and opens the two-pane desktop window. Multiple instances are supported — each finds its own port automatically.

Connect to a device via Quick Connect, the session tree (single-click to populate, double-click to connect), or right-click a session and choose Connect SSH or Open Telemetry.

### Command-Line Options

```bash
nterm                                    # standard launch
nterm --debug                            # debug logging + DevTools menu
nterm --port 8800                        # prefer specific server port
nterm --remote-debug 9222                # Chrome DevTools remote debugger
```

Qt/Chromium flags pass through automatically:

```bash
nterm --webEngineArgs --remote-debugging-port=9222
```

### Optional Dependencies

| Package | Purpose | Install |
|---------|---------|---------|
| `keyring` | OS keychain integration for vault auto-unlock | `pip install nterm-ng[keychain]` |

---

## Multi-Vendor Support


| Vendor | Terminal + Sniffer | Telemetry | Parse Templates |
|--------|-------------------|-----------|-----------------|
| Arista EOS | ✅ First-class | ✅ | ✅ |
| Cisco IOS / IOS-XE | ✅ Tested | ✅ | ✅ |
| Cisco NX-OS | ✅ Tested | ✅ | ✅ |
| Juniper JunOS | ✅ Tested | ✅ | ✅ |
| Cisco IOS-XR | ✅ | — | ✅ |
| Linux | ✅ | ✅ | ✅ |


> Arista EOS is the optimized experience — the cleanest CLI output in the industry means the sniffer, gutter, and visualizer work at their best.
>
> **Wirlwind Telemetry** supports Arista, Cisco, Juniper, and generic Linux platforms. The Linux driver works on any SSH-reachable host — bare-metal servers, VMs, containers, and Linux-based network devices (Cumulus, SONiC, VyOS). It uses standard Linux tools (`top`, `free`, `ip`, `journalctl`, `lldpctl`) with custom TextFSM templates and requires no agent installation.
>
> The parse engine includes the full NTC TextFSM template library (1,000+ templates across 30+ vendors), so structured parsing may work out of the box for vendors not listed above. Templates are added regularly.

---

## Architecture

PyQt6 desktop shell with two `QWebEngineView` panes sharing a unified theme:

```
┌────────────────────────────────┬─────────────────────────┐
│         nterm Terminal          │   Wirlwind Telemetry    │
│                                │                         │
│  xterm.js + Sniffer Pipeline   │  ECharts + SVG Topology │
│  Gutter Bar + Visualizer       │  Per-device SSH polling  │
│  Session Tree + Context Menu   │  QWebChannel bridge     │
├────────────────────────────────┴─────────────────────────┤
│  FastAPI Backend (uvicorn daemon thread, in-process)      │
│  SSH sessions · Parse API · Session tree · Vault API      │
│  Telemetry request queue (thread-safe, in-process)        │
├──────────────────────────────────────────────────────────┤
│  Paramiko SSH · ParseBroker (TextFSM → TTP → Ollama)     │
│  CredentialStore (Fernet) · SessionStore (SQLite)         │
└──────────────────────────────────────────────────────────┘
```

The frontend is vanilla JavaScript — 8 purpose-built modules, no framework, no build step, directly debuggable. The desktop wrapper is ~700 lines of Python managing two web surfaces, credential resolution, and the telemetry request lifecycle.

See [README_Arch.md](README_Arch.md) for the full architecture document.

---

## Context Menu Actions

Right-click any gutter mark:

| Action | What It Does |
|--------|-------------|
| **Visualize** | Parse output via provider chain, display as structured table |
| **Copy Block** | Clean output text to clipboard (no ANSI, no prompts) |
| **Copy Command** | Extracted command string to clipboard |
| **Copy Table** | Parsed table to clipboard — rich HTML for Word/Docs, plain text fallback |
| **Export JSON** | Download block with metadata as `.json` |
| **Export CSV** | Download line-numbered output as `.csv` |
| **Export Markdown** | Download with metadata table + fenced code block |
| **Re-run Command** | Send command over the active SSH session |

Right-click any session in the session tree:

| Action | What It Does |
|--------|-------------|
| **Connect SSH** | Open terminal tab, auto-connect if credentials available |
| **Open Telemetry** | Open Wirlwind monitoring tab with vault credential resolution |
| **Copy Hostname** | Copy device hostname to clipboard |

---

## Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+T` | Add telemetry tab |
| `Ctrl+\` | Toggle telemetry panel |
| `Ctrl+U` | Toggle vault lock/unlock |
| `Ctrl+Shift+K` | Credential manager |
| `Ctrl+Shift+S` | Session editor |
| `Ctrl+Shift+T` | Template tester |
| `Ctrl+Shift+R` | Reload nterm |
| `Ctrl+=` / `Ctrl+-` / `Ctrl+0` | Zoom in / out / reset |
| `Ctrl+Shift+=` / `Ctrl+Shift+-` | Font scale up / down |
| `Ctrl+Shift+C` | Cycle contrast mode |
| `F1` | Help topics |
| `F12` | DevTools (debug mode) |
| `Ctrl+Q` | Quit |

---

## Ecosystem

nterm is the operational interface for a network management workflow:

| Phase | Tool | Function |
|-------|------|----------|
| **Day 0** | [Secure Cartography](https://github.com/scottpeterman/secure_cartography) | Network discovery, topology mapping |
| **Day 1** | [VelocityCMDB](https://github.com/scottpeterman/velocitycmdb) | Device inventory, configuration management |
| **Day 1** | nterm Secure Cartography Import | Import topology map into session tree |
| **Day 2** | **nterm** | Operational terminal, real-time interaction |
| **Day 2** | Neighbor Hop | Walk the live topology from any device |
| **Day 2** | Day 2 validation tools | fibtrace, trafikwatch, BGP validation |

Secure Cartography discovers your network and exports a `map.json`. Import it into nterm's session tree (Sessions → Import from Secure Cartography) to get an organized inventory by site. Connect to any device, then use Neighbor Hop to walk the rest of the fabric live. The full pipeline works end-to-end — but each tool also operates independently.

---

## Documentation

| Document | Purpose |
|----------|---------|
| [README_Arch.md](README_Arch.md) | System architecture, data flows, module contracts |
| [README_Sniffer.md](README_Sniffer.md) | Sniffer pipeline spec, test strategies, class interfaces |
| [README_vault.md](README_vault.md) | Vault encryption, resolution, API, integration guide |
| [README_SSH.md](README_SSH.md) | SSH transport architecture, auth methods, legacy mode |
| [README_Parsing_providers.md](README_Parsing_providers.md) | Parse provider chain documentation |
| [NEIGHBOR_HOP.md](NEIGHBOR_HOP.md) | Neighbor Hop feature guide, credential reuse, architecture |
| [README_Current_State.md](README_Current_State.md) | Living reference for implementation state |

---

## Known Issues

See [README_Arch.md — Known Issues](README_Arch.md#known-issues) for the current list.

---

## Author

**Scott Peterman** — Principal Infrastructure Engineer
[github.com/scottpeterman](https://github.com/scottpeterman)

---

## License

GPLv3 — See [LICENSE](LICENSE) for details.