Plugin development
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
my-plugin/
manifest.json
index.js
README.md
icon.svg # optional, shown in the plugin managerManifest 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_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.
Plugin API surface
Plugins import a telnety module. Anything not on the API surface below is unavailable; the isolate will throw a ReferenceError.
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
- Run
telnety dev install ./my-pluginto install your plugin in development mode. - Telnety watches the plugin directory and reloads the isolate on save. Reload time is consistently under 200 ms on a modern laptop.
- Open the Plugin console from the developer menu to see
console.logoutput 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.
# 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.tpkgExample 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.