plugin

package
v1.47.1 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CategoryOrder

func CategoryOrder() []struct{ Key, Label string }

CategoryOrder returns the display order for categories.

func ExpandMessage

func ExpandMessage(msg string, instanceArgs []string) string

ExpandMessage replaces {key} placeholders in error messages with values from instance args. Supports {host}, {user}, {port} extracted from common argument patterns.

func ExpandResumeArgs

func ExpandResumeArgs(template []string, state map[string]string) []string

ExpandResumeArgs replaces {key} placeholders in resume args with scraped values from plugin state. Returns nil if any placeholder remains unresolved (missing state value).

func ParseSchemaVersion added in v1.4.0

func ParseSchemaVersion(data []byte) int

ParseSchemaVersion extracts plugin.schema_version from raw TOML bytes.

func ScrapeOutput

func ScrapeOutput(p *PanePlugin, data []byte) map[string]string

ScrapeOutput checks PTY output data against a plugin's scrape patterns and returns any matched key-value pairs.

Types

type CommandConfig

type CommandConfig struct {
	Cmd              string
	Path             string // optional: full path to binary (overrides PATH lookup)
	Args             []string
	Env              []string
	DetectCmd        string
	ShellIntegration bool
	ArgTemplate      []string    // template args with {field} placeholders, e.g., ["-p", "{port}", "{user}@{host}"]
	FormFields       []FormField // fields for instance creation form (if empty, no instance management)
	PromptsCWD       bool        // if true, create-pane setup dialog prompts for the working directory
	Toggles          []Toggle    // runtime on/off switches rendered as checkboxes in the setup dialog
	// RawKeys lists key strings (in Bubble Tea form, e.g. "shift+tab") that
	// should bypass Quil's global shortcut layer for panes of this plugin and
	// be forwarded directly to the PTY. This lets TUI apps like Claude Code
	// receive shift+tab (mode toggle) which Quil otherwise binds to PrevPane.
	RawKeys []string
	// Discover selects a discovery mode for the pane setup dialog.
	// "" = none (plain directory browser). "git" = the CWD step lists git
	// repo candidates (enclosing repo + 1-level sub-repos of the active
	// pane's CWD) with a "Browse…" escape hatch; only meaningful when
	// PromptsCWD is true. "kube" = a context pick-list lists kube contexts
	// from the kubeconfig and injects --context <name> (CWD-independent).
	Discover string
	// RecordHistory enables per-pane user-input history capture for this
	// plugin. When true, the daemon sets QUIL_RECORD_HISTORY=1 in the pane's
	// PTY env, and the plugin's hook producer appends submitted prompts to
	// <quilDir>/history/<paneID>.jsonl. Meaningful only for plugins with a
	// hook producer (claude-code; opencode is a follow-up).
	RecordHistory bool
	// Sessions enables the pane setup dialog's "resume an existing session"
	// field for this plugin. "" = off (a new pane always starts a fresh
	// session). "claude" = list the Claude Code transcripts recorded for the
	// selected working directory and, when one is chosen, spawn
	// `--resume <id>` instead of the preassign_id strategy's start args.
	//
	// Only meaningful together with PromptsCWD: the list is scoped to the
	// directory chosen in the dialog.
	Sessions string
}

CommandConfig describes how to launch the plugin's process.

type DisplayConfig

type DisplayConfig struct {
	BorderColor string
	DialogWidth int // width for plugin dialogs (0 = default 50)
	// WideCanvas keeps the pane's PTY/emulator sized to the full window
	// regardless of its layout rect; small rects render a soft-wrapped
	// preview TUI-side. For AI tools (claude-code, opencode) whose
	// transcript is immutable hard-wrapped text: rendering wide once and
	// wrapping down beats resizing, which garbles history. Default false.
	WideCanvas bool
	// MinNativeCols is the inner-width threshold (columns) at or above which
	// a wide_canvas pane renders natively (real pane-width PTY) instead of
	// the window canvas + preview. 0 means "use the built-in default" (80).
	MinNativeCols int
}

DisplayConfig controls visual appearance of the pane.

type ErrorHandler

type ErrorHandler struct {
	Pattern string
	Title   string
	Message string
	Action  string // "dialog" | "log"
	// contains filtered or unexported fields
}

ErrorHandler matches PTY output patterns and triggers help dialogs.

func MatchError

func MatchError(p *PanePlugin, data []byte) *ErrorHandler

MatchError checks PTY output against a plugin's error handlers. Returns the first matching handler, or nil if none match.

func (*ErrorHandler) Compile

func (eh *ErrorHandler) Compile() error

Compile pre-compiles the regex pattern. Must be called before concurrent use. Returns an error if the pattern is invalid (instead of panicking).

func (*ErrorHandler) Compiled

func (eh *ErrorHandler) Compiled() *regexp.Regexp

Compiled returns the compiled regex, or nil if compilation failed.

type FormField

type FormField struct {
	Name     string // field key (used in ArgTemplate placeholders)
	Label    string // display label in form
	Required bool   // must be filled before submit
	Default  string // pre-filled value (empty = blank)
}

FormField defines a user-fillable field for creating plugin instances.

type IdleHandler

type IdleHandler struct {
	Pattern  string
	Title    string
	Severity string // "info", "warning", "error"
	// contains filtered or unexported fields
}

IdleHandler matches patterns against pane content when the pane goes idle. Unlike NotificationHandler (checked on every output chunk), IdleHandler runs only at idle time against the last few lines — much less noisy.

func MatchIdle

func MatchIdle(p *PanePlugin, text string) *IdleHandler

MatchIdle checks ANSI-stripped pane text against a plugin's idle handlers. Called at idle time with the last few lines of output, not on every chunk.

func (*IdleHandler) Compile

func (ih *IdleHandler) Compile() error

Compile pre-compiles the regex pattern.

func (*IdleHandler) Compiled

func (ih *IdleHandler) Compiled() *regexp.Regexp

Compiled returns the compiled regex, or nil if compilation failed.

type InstanceConfig

type InstanceConfig struct {
	Name        string
	DisplayName string
	Args        []string
	Env         []string
}

InstanceConfig is a pre-configured variant of a plugin (e.g., a specific SSH host).

type NotificationHandler

type NotificationHandler struct {
	Pattern  string
	Title    string
	Severity string // "info", "warning", "error"
	// contains filtered or unexported fields
}

NotificationHandler matches PTY output patterns and triggers notification events.

func MatchNotification deprecated

func MatchNotification(p *PanePlugin, data []byte) *NotificationHandler

Deprecated: MatchNotification is no longer called from the daemon. Notification matching was replaced by idle-time analysis via MatchIdle. Kept for backward compatibility with TOML files that define [[notification_handlers]].

func (*NotificationHandler) Compile

func (nh *NotificationHandler) Compile() error

Compile pre-compiles the regex pattern.

func (*NotificationHandler) Compiled

func (nh *NotificationHandler) Compiled() *regexp.Regexp

Compiled returns the compiled regex, or nil if compilation failed.

type PanePlugin

type PanePlugin struct {
	Name                 string
	DisplayName          string
	Category             string
	Description          string
	Homepage             string // optional project/tool URL, shown when the binary is missing
	Command              CommandConfig
	Persistence          PersistenceConfig
	Display              DisplayConfig
	Instances            []InstanceConfig
	ErrorHandlers        []ErrorHandler
	NotificationHandlers []NotificationHandler
	IdleHandlers         []IdleHandler
	Available            bool // set at startup by running detect cmd
}

PanePlugin defines a pane type with its command, persistence strategy, and optional error handlers.

type PersistenceConfig

type PersistenceConfig struct {
	Strategy    string   // "none", "cwd_only", "rerun", "session_scrape", "preassign_id"
	StartArgs   []string // template args for fresh start (e.g., ["--session-id", "{session_id}"])
	ResumeArgs  []string
	Scrapers    []ScrapePattern
	GhostBuffer bool // save PTY output to disk for replay on reconnect (default true)

	// RedrawKey is written to the pane's stdin when a client attaches and the
	// pane had no ghost replay to send.
	//
	// Only meaningful with GhostBuffer = false, which is what leaves a
	// reconnecting client with a blank rectangle in front of a live process.
	//
	// Empty (the default) does NOT mean "do nothing": such a pane is given a
	// resize instead, so its program repaints via SIGWINCH. Declaring a key
	// therefore means "my program IGNORES SIGWINCH, send this instead", and
	// suppresses the resize. Declare one only if that is true — adding a key to
	// a program that does repaint on SIGWINCH replaces a working mechanism with
	// a broken one, which is exactly how opencode came to be blank on every
	// reattach.
	//
	// It is opt-IN because a key is INPUT, not a signal: the plugin author is
	// asserting that their program treats the byte as "repaint" and that nothing
	// else is reading its stdin. A pane running `cat > file` or a password
	// prompt would receive it as data. SIGWINCH carries no such risk, which is
	// why it needs no opt-in and is the default.
	//
	// Neither trigger is universal, and the measurements are counter-intuitive
	// in both directions: vim repaints with ~5 KB on a resize; claude-code emits
	// 0 bytes there (it re-lays-out but only paints on its own render tick,
	// which input drives) and ~3.8 KB on Ctrl+L; opencode is the exact inverse
	// of claude-code, ~8 KB on a resize and nothing on Ctrl+L. Measure before
	// declaring.
	RedrawKey string
}

PersistenceConfig describes how to restore the pane after daemon restart.

type Registry

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

Registry holds all known plugins (built-in + user TOML).

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a registry pre-loaded with built-in plugins.

func (*Registry) All

func (r *Registry) All() []*PanePlugin

All returns all registered plugins.

func (*Registry) Availability added in v1.46.0

func (r *Registry) Availability() map[string]bool

Availability snapshots each plugin's availability under the read lock.

All() hands out LIVE pointers and then releases the lock, so reading p.Available off them races DetectAvailability's writes — reachable with two attached clients, since ipc dispatches one read loop per connection and a plugin reload on one conn can run while another asks for the list.

func (*Registry) AvailableByCategory

func (r *Registry) AvailableByCategory() map[string][]*PanePlugin

AvailableByCategory returns only available plugins grouped by category.

func (*Registry) ByCategory

func (r *Registry) ByCategory() map[string][]*PanePlugin

ByCategory returns plugins grouped by category.

func (*Registry) DetectAvailability

func (r *Registry) DetectAvailability()

DetectAvailability checks whether each plugin's tool is installed. Search order: 1) explicit Path field, 2) PATH lookup, 3) common install locations.

func (*Registry) Get

func (r *Registry) Get(name string) *PanePlugin

Get returns a plugin by name, or nil if not found.

func (*Registry) LoadFromDir

func (r *Registry) LoadFromDir(dir string) error

LoadFromDir loads all *.toml plugin files from dir. TOML plugins override built-ins with the same name.

LoadFromDir is also the reload entry point: any plugin currently in the registry that no longer has a corresponding TOML file on disk is dropped, EXCEPT the Go-built-in "terminal" plugin which always survives. This makes "delete a TOML, hit reload" behave the way users expect.

func (*Registry) SetAvailability added in v1.46.0

func (r *Registry) SetAvailability(avail map[string]bool)

SetAvailability replaces locally-detected availability with an authoritative answer from elsewhere — in practice the daemon, which may be on another host.

A plugin absent from avail becomes unavailable rather than keeping its local value: if the answering side has no definition for it, spawning that type there falls back to "terminal", so the pane would open as a shell wearing the wrong name. Greying it is the honest answer.

type ScrapePattern

type ScrapePattern struct {
	Name    string
	Pattern string
	// contains filtered or unexported fields
}

ScrapePattern extracts named values from PTY output via regex.

func (*ScrapePattern) Compile

func (sp *ScrapePattern) Compile() error

Compile pre-compiles the regex pattern. Must be called before concurrent use. Returns an error if the pattern is invalid (instead of panicking).

func (*ScrapePattern) Compiled

func (sp *ScrapePattern) Compiled() *regexp.Regexp

Compiled returns the compiled regex, or nil if compilation failed.

type StalePlugin added in v1.4.0

type StalePlugin struct {
	Name        string // plugin name (e.g., "claude-code")
	FilePath    string // absolute path to the user's TOML file
	UserData    []byte // current content of the user's file
	DefaultData []byte // embedded default content (newer schema)
}

StalePlugin holds data for a plugin whose on-disk schema_version is lower than the embedded default. The TUI uses this to show a migration dialog.

func EnsureDefaultPlugins

func EnsureDefaultPlugins(dir string) ([]StalePlugin, error)

EnsureDefaultPlugins writes embedded default plugin TOML files to dir if they don't already exist. Existing files whose schema_version is lower than the embedded default are NOT overwritten — instead they are returned as StalePlugin entries so the TUI can show a migration dialog.

type Toggle added in v1.3.0

type Toggle struct {
	Name       string   // identifier (stable across renames for future addressability)
	Label      string   // text shown next to the checkbox in the setup dialog
	ArgsWhenOn []string // args appended to the command when this toggle is checked
	Default    bool     // initial checked state
	Group      string   // optional mutual-exclusion group; empty = independent checkbox
}

Toggle is a boolean runtime flag the user can enable when creating a pane. When enabled, ArgsWhenOn is appended to the spawn args (and persisted via the pane's InstanceArgs so it survives daemon restarts).

Group gives mutual-exclusion semantics: toggles that share a non-empty Group value are rendered as radio buttons and only one member may be ON at a time. Enabling one automatically disables the others in the group. A toggle with an empty Group behaves as an independent checkbox.

Jump to

Keyboard shortcuts

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