webterm

package module
v0.0.0-...-6ed5ca5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 11 Imported by: 0

README

WebTerm

WebTerm is a Go library that provides web-based terminal functionality using WebSockets and xterm.js. It supports both local command execution and SSH remote connections through a simple HTTP handler interface.

Features

  • 🖥️ Local Command Execution - Execute local shell commands in a web-based terminal
  • 🌐 SSH Remote Connection - Connect to remote servers via SSH in the browser
  • 📄 File Tailing - Tail one or multiple log files in real-time in the browser
  • 🎨 Multiple Themes - Built-in color schemes (Solarized, Dracula, Molokai, etc.)
  • 📦 Embedded Static Assets - All frontend assets are embedded in the binary
  • 🔌 Simple HTTP Handler - Easy integration with standard Go HTTP servers
  • 🪟 Dynamic Window Resizing - Supports terminal window size adjustments

Installation

go get github.com/OutOfBedlam/webterm

Quick Start

Local Command Execution
package main

import (
    "net/http"
    
    "github.com/OutOfBedlam/webterm"
    "github.com/OutOfBedlam/webterm/webexec"
)

func main() {
    term := webterm.New(
        &webexec.WebExec{
            Command: "/bin/bash",
            Args:    []string{"-il"},
            Dir:     "/tmp/",
        },
        webterm.WithCutPrefix("/terminal/"),
        webterm.WithTheme(webterm.ThemeDracula),
    )
    
    http.Handle("/terminal/", term)
    http.ListenAndServe(":8080", nil)
}
SSH Remote Connection
package main

import (
    "net/http"
    "os"
    "path/filepath"
    
    "github.com/OutOfBedlam/webterm"
    "github.com/OutOfBedlam/webterm/webssh"
)

func main() {
    key, _ := os.ReadFile(filepath.Join(os.Getenv("HOME"), ".ssh/id_rsa"))
    
    term := webterm.New(
        &webssh.WebSSH{
            Hops: webssh.Hops{
                {
                    Host: "example.com",
                    Port: 22,
                    User: "username",
                    Auth: []ssh.AuthMethod{
                        webssh.AuthPrivateKey(key),
                    },
                },
            },
            TermType: "xterm-256color",
        },
        webterm.WithCutPrefix("/ssh/"),
        webterm.WithTheme(webterm.ThemeMolokai),
    )
    
    http.Handle("/ssh/", term)
    http.ListenAndServe(":8080", nil)
}
File Tailing
package main

import (
    "net/http"
    
    "github.com/OutOfBedlam/webterm"
    "github.com/OutOfBedlam/webterm/webtail"
)

func main() {
    // Tail a single file
    term := webterm.New(
        &webtail.WebTail{
            Tails: []*webtail.Tail{
                webtail.NewTail("/var/log/syslog"),
            },
        },
        webterm.WithCutPrefix("/logs/"),
        webterm.WithTheme(webterm.ThemeSolarizedDark),
    )
    
    // Or tail multiple files
    multiTerm := webterm.New(
        &webtail.WebTail{
            Tails: []*webtail.Tail{
                webtail.NewTail("/var/log/syslog"),
                webtail.NewTail("/var/log/auth.log"),
                webtail.NewTail("/var/log/nginx/access.log"),
            },
        },
        webterm.WithCutPrefix("/logs/"),
        webterm.WithTheme(webterm.ThemeDracula),
    )
    
    http.Handle("/logs/", term)
    http.ListenAndServe(":8080", nil)
}

Configuration Options

WebTerm Options
// Set URL prefix to cut from requests
webterm.WithCutPrefix("/my-terminal/")

// Set terminal color theme
webterm.WithTheme(webterm.ThemeDracula)

// Set terminal font family
webterm.WithFontFamily("monospace")

// Set terminal font size
webterm.WithFontSize(14)

// Set scrollback buffer size
webterm.WithScrollback(1000)

// Set custom localization strings
webterm.WithLocalization(map[string]string{
    "title": "My Terminal",
})
WebExec Configuration
&webexec.WebExec{
    Command: "/usr/bin/zsh",  // Command to execute
    Args:    []string{"-il"}, // Command arguments
    Dir:     "/home/user",    // Working directory
}
WebSSH Configuration
&webssh.WebSSH{
    Hops: webssh.Hops{
        {
            Network: "tcp",              // Network type (default: "tcp")
            Host:    "example.com",      // SSH host
            Port:    22,                 // SSH port (default: 22)
            User:    "username",         // SSH user (default: $USER)
            Auth:    []ssh.AuthMethod{}, // Authentication methods
        },
    },
    TermType: "xterm-256color",   // Terminal type (default: "xterm")
    Command:  "",                 // Optional command to run (default: shell)
}
SSH Authentication
// Private key authentication
key, _ := os.ReadFile("/path/to/private/key")
auth := webssh.AuthPrivateKey(key)

// Password authentication
auth := webssh.AuthPassword("your-password")

// Multiple authentication methods
Auth: []ssh.AuthMethod{
    webssh.AuthPrivateKey(key),
    webssh.AuthPassword(password),
}
WebTail Configuration
&webtail.WebTail{
    Tails: []*webtail.Tail{
        webtail.NewTail("/path/to/file.log"),  // Single file
        webtail.NewTail("/path/to/other.log"), // Multiple files
    },
}

Available Themes

WebTerm includes several built-in color themes:

  • ThemeSolarizedDark
  • ThemeSolarizedLight
  • ThemeDracula
  • ThemeMolokai
  • ThemeNordic
  • ThemeUbuntu
  • ThemeDefault

Example:

webterm.WithTheme(webterm.ThemeDracula)

Custom Runner

You can implement your own terminal backend by implementing the Runner and Session interfaces:

type Runner interface {
    Session() (Session, error)
    Template() (*template.Template, any)
}

type Session interface {
    Open() error
    Close() error
    Read(p []byte) (n int, err error)
    Write(p []byte) (n int, err error)
    SetWinSize(cols, rows int) error
    Control(data []byte) error
}

Sub-packages

  • webexec - Local command execution runner
  • webssh - SSH remote connection runner
  • webtail - File tailing runner for monitoring log files

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Documentation

Index

Constants

View Source
const (
	ColorReset         = "\033[0m"
	ColorBlack         = "\033[30m"       // Black
	ColorRed           = "\033[31m"       // Red
	ColorGreen         = "\033[32m"       // Green
	ColorYellow        = "\033[33m"       // Yellow
	ColorBlue          = "\033[34m"       // Blue
	ColorMagenta       = "\033[35m"       // Magenta
	ColorCyan          = "\033[36m"       // Cyan for keys
	ColorLightGray     = "\033[37m"       // Light gray
	ColorNavy          = "\033[38;5;17m"  // Navy
	ColorTeal          = "\033[38;5;51m"  // Teal
	ColorMaroon        = "\033[38;5;52m"  // Maroon
	ColorIndigo        = "\033[38;5;57m"  // Indigo
	ColorLightBlue     = "\033[38;5;81m"  // Light Blue
	ColorBrown         = "\033[38;5;94m"  // Brown
	ColorOlive         = "\033[38;5;100m" // Olive
	ColorLightGreen    = "\033[38;5;120m" // Light Green
	ColorPurple        = "\033[38;5;135m" // Purple
	ColorLime          = "\033[38;5;154m" // Lime
	ColorPink          = "\033[38;5;205m" // Pink
	ColorOrange        = "\033[38;5;208m" // Orange
	ColorGray          = "\033[38;5;245m" // Gray
	ColorDarkGray      = "\033[90m"       // Dark gray
	ColorBrightRed     = "\033[91m"       // Bright Red
	ColorBrightGreen   = "\033[92m"       // Bright Green
	ColorBrightYellow  = "\033[93m"       // Bright Yellow
	ColorBrightBlue    = "\033[94m"       // Bright Blue
	ColorBrightMagenta = "\033[95m"       // Bright Magenta
	ColorBrightCyan    = "\033[96m"       // Bright Cyan
	ColorWhite         = "\033[97m"       // White
)

ANSI color codes

Variables

View Source
var ThemeDefault = TerminalTheme{
	Background:          "#1e1e1e",
	Foreground:          "#ffffff",
	Cursor:              "#ffffff",
	CursorAccent:        "#1e1e1e",
	SelectionBackground: "#264f78",
	Black:               "#000000",
	Red:                 "#cd3131",
	Green:               "#0dbc79",
	Yellow:              "#e5e510",
	Blue:                "#2472c8",
	Magenta:             "#bc3fbc",
	Cyan:                "#11a8cd",
	White:               "#e5e5e5",
	BrightBlack:         "#666666",
	BrightRed:           "#f14c4c",
	BrightGreen:         "#23d18b",
	BrightYellow:        "#f5f543",
	BrightBlue:          "#3b8eea",
	BrightMagenta:       "#d670d6",
	BrightCyan:          "#29b8db",
	BrightWhite:         "#ffffff",
}

ThemeDefault provides a standard dark terminal color scheme

View Source
var ThemeDracula = TerminalTheme{
	Background:          "#282a36",
	Foreground:          "#f8f8f2",
	Cursor:              "#f8f8f2",
	CursorAccent:        "#282a36",
	SelectionBackground: "#44475a",
	Black:               "#21222c",
	Red:                 "#ff5555",
	Green:               "#50fa7b",
	Yellow:              "#f1fa8c",
	Blue:                "#bd93f9",
	Magenta:             "#ff79c6",
	Cyan:                "#8be9fd",
	White:               "#f8f8f2",
	BrightBlack:         "#6272a4",
	BrightRed:           "#ff6e6e",
	BrightGreen:         "#69ff94",
	BrightYellow:        "#ffffa5",
	BrightBlue:          "#d6acff",
	BrightMagenta:       "#ff92df",
	BrightCyan:          "#a4ffff",
	BrightWhite:         "#ffffff",
}

ThemeDracula provides the Dracula color scheme

View Source
var ThemeLight = TerminalTheme{
	Background:          "#ffffff",
	Foreground:          "#000000",
	Cursor:              "#000000",
	CursorAccent:        "#ffffff",
	SelectionBackground: "#d3d3d3",
	SelectionForeground: "#000000",
	Black:               "#000000",
	Red:                 "#cd0000",
	Green:               "#00cd00",
	Yellow:              "#cdcd00",
	Blue:                "#0000ee",
	Magenta:             "#cd00cd",
	Cyan:                "#00cdcd",
	White:               "#e5e5e5",
	BrightBlack:         "#7f7f7f",
	BrightRed:           "#ff0000",
	BrightGreen:         "#00ff00",
	BrightYellow:        "#ffff00",
	BrightBlue:          "#5c5cff",
	BrightMagenta:       "#ff00ff",
	BrightCyan:          "#00ffff",
	BrightWhite:         "#ffffff",
}

ThemeLight provides a light color scheme with white background and black text

View Source
var ThemeMolokai = TerminalTheme{
	Background:          "#1b1d1e",
	Foreground:          "#f8f8f2",
	Cursor:              "#f8f8f0",
	CursorAccent:        "#1b1d1e",
	SelectionBackground: "#49483e",
	Black:               "#1b1d1e",
	Red:                 "#f92672",
	Green:               "#a6e22e",
	Yellow:              "#e6db74",
	Blue:                "#66d9ef",
	Magenta:             "#ae81ff",
	Cyan:                "#a1efe4",
	White:               "#f8f8f2",
	BrightBlack:         "#75715e",
	BrightRed:           "#f92672",
	BrightGreen:         "#a6e22e",
	BrightYellow:        "#e6db74",
	BrightBlue:          "#66d9ef",
	BrightMagenta:       "#ae81ff",
	BrightCyan:          "#a1efe4",
	BrightWhite:         "#f9f8f5",
}

ThemeMolokai provides the Molokai color scheme

View Source
var ThemeNordic = TerminalTheme{
	Background:          "#2e3440",
	Foreground:          "#d8dee9",
	Cursor:              "#d8dee9",
	CursorAccent:        "#2e3440",
	SelectionBackground: "#434c5e",
	Black:               "#3b4252",
	Red:                 "#bf616a",
	Green:               "#a3be8c",
	Yellow:              "#ebcb8b",
	Blue:                "#81a1c1",
	Magenta:             "#b48ead",
	Cyan:                "#88c0d0",
	White:               "#e5e9f0",
	BrightBlack:         "#4c566a",
	BrightRed:           "#bf616a",
	BrightGreen:         "#a3be8c",
	BrightYellow:        "#ebcb8b",
	BrightBlue:          "#81a1c1",
	BrightMagenta:       "#b48ead",
	BrightCyan:          "#8fbcbb",
	BrightWhite:         "#eceff4",
}

ThemeNordic provides the Nordic color scheme

View Source
var ThemeSolarizedDark = TerminalTheme{
	Background:          "#002b36",
	Foreground:          "#839496",
	Cursor:              "#839496",
	CursorAccent:        "#002b36",
	SelectionBackground: "#073642",
	Black:               "#073642",
	Red:                 "#dc322f",
	Green:               "#859900",
	Yellow:              "#b58900",
	Blue:                "#268bd2",
	Magenta:             "#d33682",
	Cyan:                "#2aa198",
	White:               "#eee8d5",
	BrightBlack:         "#002b36",
	BrightRed:           "#cb4b16",
	BrightGreen:         "#586e75",
	BrightYellow:        "#657b83",
	BrightBlue:          "#839496",
	BrightMagenta:       "#6c71c4",
	BrightCyan:          "#93a1a1",
	BrightWhite:         "#fdf6e3",
}

ThemeSolarizedDark provides the Solarized Dark color scheme

View Source
var ThemeSolarizedLight = TerminalTheme{
	Background:          "#fdf6e3",
	Foreground:          "#1f4755",
	Cursor:              "#657b83",
	CursorAccent:        "#fdf6e3",
	SelectionBackground: "#eee8d5",
	Black:               "#073642",
	Red:                 "#dc322f",
	Green:               "#859900",
	Yellow:              "#b58900",
	Blue:                "#268bd2",
	Magenta:             "#d33682",
	Cyan:                "#2aa198",
	White:               "#eee8d5",
	BrightBlack:         "#002b36",
	BrightRed:           "#cb4b16",
	BrightGreen:         "#586e75",
	BrightYellow:        "#657b83",
	BrightBlue:          "#839496",
	BrightMagenta:       "#6c71c4",
	BrightCyan:          "#93a1a1",
	BrightWhite:         "#fdf6e3",
}

ThemeSolarizedLight provides the Solarized Light color scheme

View Source
var ThemeUbuntu = TerminalTheme{
	Background:          "#300a24",
	Foreground:          "#ffffff",
	Cursor:              "#ffffff",
	CursorAccent:        "#300a24",
	SelectionBackground: "#b3d4fc",
	Black:               "#2e3436",
	Red:                 "#cc0000",
	Green:               "#4e9a06",
	Yellow:              "#c4a000",
	Blue:                "#3465a4",
	Magenta:             "#75507b",
	Cyan:                "#06989a",
	White:               "#d3d7cf",
	BrightBlack:         "#555753",
	BrightRed:           "#ef2929",
	BrightGreen:         "#8ae234",
	BrightYellow:        "#fce94f",
	BrightBlue:          "#729fcf",
	BrightMagenta:       "#ad7fa8",
	BrightCyan:          "#34e2e2",
	BrightWhite:         "#eeeeec",
}

ThemeUbuntu provides the Ubuntu terminal color scheme

Functions

func Colorize

func Colorize(s string, color string) string

func StripAnsiCodes

func StripAnsiCodes(s string) string

Types

type Option

type Option func(*WebTerm)

func WithCutPrefix

func WithCutPrefix(cutPrefix string) Option

func WithFontFamily

func WithFontFamily(fontFamily string) Option

func WithFontSize

func WithFontSize(fontSize int) Option

func WithLocalization

func WithLocalization(localization map[string]string) Option

func WithScrollback

func WithScrollback(scrollback int) Option

func WithTheme

func WithTheme(theme TerminalTheme) Option

type Runner

type Runner interface {
	Session() (Session, error)
	// provide custom template, and template-data if nil default will be used
	Template() (*template.Template, any)
}

type Session

type Session interface {
	Open() error
	Close() error
	Read(p []byte) (n int, err error)
	Write(p []byte) (n int, err error)
	SetWinSize(cols, rows int) error
	Control(data []byte) error // handle messages from client
}

type TemplateData

type TemplateData struct {
	Terminal     TerminalOptions
	Localization map[string]string
	Ext          any
}

func (TemplateData) Localize

func (td TemplateData) Localize(s string) string

type TerminalOptions

type TerminalOptions struct {
	CursorBlink         bool          `json:"cursorBlink"`
	CursorInactiveStyle string        `json:"cursorInactiveStyle,omitempty"`
	CursorStyle         string        `json:"cursorStyle,omitempty"`
	FontSize            int           `json:"fontSize,omitempty"`
	FontFamily          string        `json:"fontFamily,omitempty"`
	LineHeight          float64       `json:"lineHeight,omitempty"`
	Theme               TerminalTheme `json:"theme"`
	Scrollback          int           `json:"scrollback,omitempty"`
	DisableStdin        bool          `json:"disableStdin"`
	ConvertEol          bool          `json:"convertEol,omitempty"`
}

func DefaultTerminalOptions

func DefaultTerminalOptions() TerminalOptions

func (TerminalOptions) String

func (tt TerminalOptions) String() string

func (TerminalOptions) ToJSON

func (tt TerminalOptions) ToJSON() template.JS

type TerminalTheme

type TerminalTheme struct {
	Background                  string `json:"background,omitempty"`
	Foreground                  string `json:"foreground.omitempty"`
	SelectionBackground         string `json:"selectionBackground,omitempty"`
	SelectionForeground         string `json:"selectionForeground,omitempty"`
	SelectionInactiveBackground string `json:"selectionInactiveBackground,omitempty"`
	Cursor                      string `json:"cursor,omitempty"`
	CursorAccent                string `json:"cursorAccent,omitempty"`
	ExtendedAnsi                string `json:"extendedAnsi,omitempty"`
	Black                       string `json:"black,omitempty"`
	Blue                        string `json:"blue,omitempty"`
	BrightBlack                 string `json:"brightBlack,omitempty"`
	BrightBlue                  string `json:"brightBlue,omitempty"`
	BrightCyan                  string `json:"brightCyan,omitempty"`
	BrightGreen                 string `json:"brightGreen,omitempty"`
	BrightMagenta               string `json:"brightMagenta,omitempty"`
	BrightRed                   string `json:"brightRed,omitempty"`
	BrightWhite                 string `json:"brightWhite,omitempty"`
	BrightYellow                string `json:"brightYellow,omitempty"`
	Cyan                        string `json:"cyan,omitempty"`
	Green                       string `json:"green,omitempty"`
	Magenta                     string `json:"magenta,omitempty"`
	Red                         string `json:"red,omitempty"`
	White                       string `json:"white,omitempty"`
	Yellow                      string `json:"yellow,omitempty"`
}

type WebTerm

type WebTerm struct {
	// contains filtered or unexported fields
}

func New

func New(runner Runner, opts ...Option) *WebTerm

func (*WebTerm) ServeHTTP

func (wt *WebTerm) ServeHTTP(w http.ResponseWriter, r *http.Request)

Directories

Path Synopsis
cmd
webport command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL