Skip to content
telnety

Plugin development

v1.1 preview. The plugin SDK ships in the Telnety v1.1 release. Telnety v1.0 ships SSH, RDP, VNC, SFTP, Telnet, and Serial only. The manifest format and the API surface below are locked, but the SDK package and the signed registry are still being wired up.

Telnety plugins are small JavaScript bundles that run inside an isolated-vm sandbox. They can add commands to the palette, register new tabs, react to connection events, and call a curated subset of the Telnety API surface. Plugins are signed at publish time and distributed through the official registry.

What plugins can do

  • Add commands to the Ctrl+K palette.
  • Register new tools that appear in the Tools tab.
  • Listen for connection events (connected, disconnected, command-run).
  • Read and (with permission) write host metadata.
  • Open new tabs with custom HTML content rendered inside a sandbox iframe.
  • Persist plugin-local state in a sandboxed KV store.

Project layout

A minimal plugin
my-plugin/
  manifest.json
  index.js
  README.md
  icon.svg          # optional, shown in the plugin manager

Manifest format

Every plugin ships a manifest.json. Telnety validates the manifest on install and refuses to load anything with an unrecognised field or an invalid version constraint.

manifest.json
{
  "manifest_version": 1,
  "name":          "uptime-watcher",
  "version":       "0.1.0",
  "description":   "Annotates the sidebar with each host's last successful connect.",
  "author":        "Telnety Plugin Team",
  "entry":         "index.js",
  "min_app_version": "1.1.0",
  "permissions": [
    "host:read",
    "session:read"
  ],
  "commands": [
    {
      "id":    "uptime-watcher.show-recent",
      "title": "Show recently online hosts",
      "shortcut": "Ctrl+Alt+U"
    }
  ],
  "sandbox": true
}

The isolated-vm sandbox

Plugins run inside an isolated-vm V8 isolate spawned by the Telnety host. Each plugin gets:

  • A fresh V8 heap with a 128 MiB cap.
  • A 10 ms CPU-time budget per host-IPC call. Slow plugins are auto-suspended.
  • No access to require, fetch, the filesystem, or the network — only the Telnety API surface and an opt-in HTTPS allowlist declared in the manifest.
  • A JSON-RPC bridge to the Telnety host process; all calls cross the isolate boundary as serialised JSON.
The sandbox enforces a strict CSP for plugin-rendered HTML: no inline scripts, no remote scripts, no eval. Plugins that want richer UI ship pre-compiled bundles (any framework that ends up as a single JS file is fine).

Plugin API surface

Plugins import a telnety module. Anything not on the API surface below is unavailable; the isolate will throw a ReferenceError.

index.js
import { hosts, sessions, ui, events, kv } from "telnety";

export async function activate() {
  // Register a command in the palette
  ui.commands.register("uptime-watcher.show-recent", async () => {
    const all = await hosts.list();
    const last = await kv.get("last-seen") ?? {};
    const recent = all
      .filter(h => last[h.id] && (Date.now() - last[h.id]) < 24 * 3600 * 1000)
      .sort((a, b) => last[b.id] - last[a.id]);
    ui.notify(`Active in last 24h: ${recent.length} host(s)`);
  });

  // Track when sessions connect successfully
  events.on("session:connected", async ({ host_id }) => {
    const last = await kv.get("last-seen") ?? {};
    last[host_id] = Date.now();
    await kv.set("last-seen", last);
  });
}

export function deactivate() {
  // Telnety unregisters commands and event listeners automatically;
  // this hook is for cleaning up your own resources.
}

Available modules

  • hosts — list, get, create, update, delete (subject to permissions).
  • sessions — list, get, open, close, send-input (Tier 2+ permissions).
  • ui — commands, notifications, custom tab rendering.
  • events — subscribe to session and host lifecycle events.
  • kv — per-plugin key-value store, capped at 4 MiB.
  • http — HTTPS fetch limited to the allowlist declared in the manifest.

Permissions

Permissions are declared in the manifest. The user sees them on install and can revoke them at any time from the plugin settings.

  • host:read — list and read host metadata.
  • host:write — create, update, delete hosts.
  • session:read — observe sessions and read scrollback.
  • session:write — open and close sessions, send input.
  • vault:read — access vault entries (per-call approval, like MCP Tier 4).
  • network:<origin> — allow HTTPS fetch to a specific origin.

Hot reload during development

  1. Run telnety dev install ./my-plugin to install your plugin in development mode.
  2. Telnety watches the plugin directory and reloads the isolate on save. Reload time is consistently under 200 ms on a modern laptop.
  3. Open the Plugin console from the developer menu to see console.log output and unhandled errors from your isolate.

Publishing

Plugins ship through the Telnety registry. Each release is signed with an Ed25519 key you create at publish time; the registry rejects uploads whose signature doesn't match the manifest's declared author key.

Publish a release
# One-time: generate a publisher key
telnety plugin keygen

# For each release
telnety plugin bundle ./my-plugin -o uptime-watcher-0.1.0.tpkg
telnety plugin sign  uptime-watcher-0.1.0.tpkg
telnety plugin push  uptime-watcher-0.1.0.tpkg

Example plugins

  • uptime-watcher — the plugin shown above. Tracks last-seen times per host.
  • prom-overview — renders a tab with Prometheus query results, fetched through the manifest-declared network allowlist.
  • k8s-context — surfaces the current kubectl context and namespace in the status bar; switches contexts via command palette.