Documentation
¶
Index ¶
- Variables
- func AppearanceFromBackground(payload string) string
- func AttachLogProgram(program *tea.Program)
- func ConfigPath() string
- func KeybindingsPath() string
- func ReadPluginTrust(path string) map[string]string
- func RemovePlugin(path, nameOrExecutable string) (entry, canonical string, changed bool, err error)
- func SaveAppearance(path, appearance string) error
- func SaveAutoTheme(path string, enabled bool) error
- func SavePlugin(path, canonical, digest string) (changed bool, err error)
- func SaveTableOpenTarget(path, target string) error
- func SaveTheme(path string, name appTheme) error
- func SaveVimMode(path string, enabled bool) error
- func SetAppConfig(config Config)
- func SetSystemAppearance(value string)
- type CommandID
- type CompletionItem
- type CompletionKind
- type Config
- type Keybindings
- type Model
- func (m Model) Init() tea.Cmd
- func (m *Model) Service() sharedsql.Service
- func (m *Model) SetAI(client chat.Client, history chat.History)
- func (m *Model) SetKeybindings(b Keybindings)
- func (m *Model) SetNoQuit(noQuit bool)
- func (m *Model) SetPluginControl(control PluginControl)
- func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd)
- func (m Model) View() tea.View
- type OpenDatabase
- type PluginControl
Constants ¶
This section is empty.
Variables ¶
var BuiltinFunctions = map[string][]string{
"SQLite": {
"ABS", "AVG", "CAST", "CHAR", "COALESCE", "COUNT", "CURRENT_DATE",
"CURRENT_TIME", "CURRENT_TIMESTAMP", "DATE", "DATETIME", "GROUP_CONCAT",
"IFNULL", "INSTR", "JSON_EXTRACT", "JSON_OBJECT", "JSON_ARRAY",
"JULIANDAY", "LENGTH", "LIKE", "LOWER", "LTRIM", "MAX", "MIN", "NULLIF",
"PRINTF", "RANDOM", "REPLACE", "ROUND", "RTRIM", "STRFTIME", "SUBSTR",
"SUM", "TIME", "TRIM", "TYPEOF", "UNICODE", "UPPER", "ZEROBLOB",
},
"MySQL": {
"AVG", "CAST", "CHAR_LENGTH", "COALESCE", "CONCAT", "COUNT", "CURDATE",
"CURRENT_DATE", "CURRENT_TIMESTAMP", "CURTIME", "DATE", "DATE_FORMAT",
"DATEDIFF", "DAY", "FIND_IN_SET", "FORMAT", "FROM_UNIXTIME", "GROUP_CONCAT",
"IFNULL", "INSTR", "JSON_EXTRACT", "JSON_OBJECT", "JSON_ARRAY",
"LENGTH", "LOCATE", "LOWER", "LPAD", "LTRIM", "MAX", "MD5", "MIN",
"MONTH", "NOW", "NULLIF", "RAND", "REGEXP", "REPLACE", "REVERSE",
"ROUND", "RPAD", "RTRIM", "SHA1", "SHA2", "SUBSTRING", "SUM",
"TIMESTAMP", "TRIM", "TRUNCATE", "UNIX_TIMESTAMP", "UPPER", "UUID",
"VERSION", "WEEK", "YEAR",
},
"PostgreSQL": {
"ABS", "AGE", "ARRAY_AGG", "AVG", "CAST", "CEIL", "CHAR_LENGTH",
"COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME",
"CURRENT_TIMESTAMP", "DATE", "DATE_PART", "DATE_TRUNC", "DATEDIFF",
"EXTRACT", "FLOOR", "GREATEST", "JSON_AGG", "JSON_BUILD_OBJECT",
"JSON_EXTRACT_PATH", "LATERAL", "LEAST", "LENGTH", "LOWER", "LPAD",
"LTRIM", "MAX", "MIN", "NOW", "NULLIF", "POSITION", "POW",
"RANDOM", "REGEXP_MATCHES", "REGEXP_REPLACE", "REPLACE", "REVERSE",
"ROUND", "RPAD", "RTRIM", "SPLIT_PART", "STRING_AGG", "SUBSTRING",
"SUM", "TO_CHAR", "TO_DATE", "TO_NUMBER", "TO_TIMESTAMP", "TRIM",
"TRUNC", "UPPER", "UUID_GENERATE_V4", "WIDTH_BUCKET",
},
}
BuiltinFunctions returns SQL built-in function names keyed by product name.
Functions ¶
func AppearanceFromBackground ¶
AppearanceFromBackground converts a terminal-reported background color to a light/dark appearance using the WCAG-relative luminance of the linearized sRGB channels. Payload is the rune payload of an OSC 11 response, e.g. "rgb:1c1c/1c1c/1c1c". An unparseable or empty payload yields "".
func AttachLogProgram ¶
AttachLogProgram wires the running program into the log notification pipeline so entries logged by async commands surface as popups even when the UI is idle. Call once with the program returned by tea.NewProgram, before program.Run. Attaching nil detaches.
func ConfigPath ¶
func ConfigPath() string
ConfigPath returns the default config file path in the user's XDG config directory.
func KeybindingsPath ¶
func KeybindingsPath() string
KeybindingsPath returns the default config file path in the user's XDG config directory.
func ReadPluginTrust ¶
ReadPluginTrust reads only the plugin_trust mapping from the config file without writing, validating, or materializing anything: a missing, empty, or malformed file yields nil. Read-only commands use it to report fingerprint state without ever mutating config.
func RemovePlugin ¶
RemovePlugin removes the configured plugin matching nameOrExecutable and its trust record. The operand matches the config entry exactly, or — when no entry string matches — resolves like a startup entry (bare names through PATH, relative paths against the config file's directory) and must equal exactly one configured entry's canonical path; ambiguous matches fail instead of removing multiple entries. The trust record is dropped only when no remaining entry resolves to the removed canonical path. The rewrite is atomic and preserves every unrelated key; the original file is left intact on failure. The resolved in-memory config follows the persisted state.
func SaveAppearance ¶
SaveAppearance persists the explicit appearance into config.json, preserving every other key.
func SaveAutoTheme ¶
SaveAutoTheme persists the follow-system toggle into config.json, preserving every other key.
func SavePlugin ¶
SavePlugin pins one plugin executable: canonical is the canonical absolute path and digest its lowercase SHA-256. The entry is appended to the plugins list when no entry resolves to it, or replaced by the canonical path when an existing entry resolves to it (so a re-pin never duplicates the executable), and plugin_trust[canonical] is set to digest. Every other config key is preserved byte-for-byte and the file is rewritten atomically (same-directory temp + rename, mode 0600); the original is left intact on any failure. When the resulting plugins/trust state already matches, nothing is written and changed is false. The resolved in-memory config follows the persisted state.
func SaveTableOpenTarget ¶
SaveTableOpenTarget persists the table-open target into config.json, replacing only the table_open_target key and preserving every other key byte-for-byte.
func SaveTheme ¶
SaveTheme persists a theme choice into config.json under the slot key for its scheme (dark_theme or light_theme), preserving every other key.
func SaveVimMode ¶
SaveVimMode persists the vim-mode toggle into config.json, replacing only the vim_mode key and preserving every other key byte-for-byte.
func SetAppConfig ¶
func SetAppConfig(config Config)
SetAppConfig applies user configuration. Call it before New so startup defaults (browse page size, query-log page size, read-only, theme) pick it up. Env-var overrides (PERK_WORKBENCH_QUERY_LOG_*) still win over config values at their read sites.
func SetSystemAppearance ¶
func SetSystemAppearance(value string)
SetSystemAppearance records the system light/dark appearance captured at startup so auto-following can resolve it. Call it before SetAppConfig when auto_theme is enabled. An empty value is ignored so that unavailable detection leaves the fallback (persisted appearance, then dark) untouched.
Types ¶
type CompletionItem ¶
type CompletionItem struct {
Label string // display text
InsertText string // text inserted on accept (defaults to Label)
Kind CompletionKind // for display/label
Detail string // extra info shown alongside the label
Summary string // tertiary muted line shown after Detail
}
CompletionItem is a single suggestion candidate.
type CompletionKind ¶
type CompletionKind int
CompletionKind classifies the type of suggestion.
const ( KindKeyword CompletionKind = iota KindTable KindView KindColumn KindSchema KindFunction KindBufferWord KindCommand )
func (CompletionKind) String ¶
func (k CompletionKind) String() string
type Config ¶
type Config struct {
// BrowsePageSize is the default row limit for table browsing.
// Must be within [1, sharedsql.MaxRows] when set.
BrowsePageSize int `json:"browse_page_size"`
// QueryLogPageSize is the default page size of the query-log pane.
// Must be within [1, queryLogLimit] when set.
QueryLogPageSize int `json:"query_log_page_size"`
// QueryLogRetentionDays keeps query-log entries for this many days.
// Omitted or 0 keeps the built-in default (30); to keep no history at
// all, set PERK_WORKBENCH_QUERY_LOG_RETENTION_DAYS=0 (config cannot
// express it, since 0 means unset).
QueryLogRetentionDays int `json:"query_log_retention_days"`
// NotificationRetentionDays keeps notification entries for this many
// days. Omitted or 0 keeps the built-in default (30).
NotificationRetentionDays int `json:"notification_retention_days"`
// NotificationTimeoutSeconds is how long a notification popup stays
// visible. Omitted or 0 keeps the built-in default (10); values above
// one day are rejected.
NotificationTimeoutSeconds int `json:"notification_timeout_seconds"`
// ReadOnly opens every connection read-only by default. The
// per-connection form toggle still opts a connection back to read-write.
ReadOnly bool `json:"read_only"`
// Appearance is the effective light/dark theme: "light" or "dark".
// Omitted or empty keeps the built-in default (dark). While auto_theme
// is enabled it is the fallback used when system detection is
// unavailable and the value resolved into when auto is turned off.
Appearance string `json:"appearance"`
// AutoTheme follows the system light/dark appearance at startup.
// Omitted means enabled (the built-in default).
AutoTheme *bool `json:"auto_theme"`
// DarkTheme is the theme used while appearance is dark: one of the
// dark-scheme themes (ocean, nord, monokai, dracula, catppuccin,
// solarized).
DarkTheme string `json:"dark_theme"`
// LightTheme is the theme used while appearance is light: one of the
// light-scheme themes (light-ocean, light-nord, ...).
LightTheme string `json:"light_theme"`
// VimMode enables modal vim-style editing: normal mode navigates with
// j/k-style keys and insert mode (i/Enter) types. Disabled, the focused
// input is always editable — click to type, no mode switch. Omitted
// means enabled (the built-in default).
VimMode *bool `json:"vim_mode"`
// NerdFont renders the schema tree's node markers as Nerd Font icons
// (database, folder, table). Omitted means enabled (the built-in
// default); terminals without a Nerd Font can set false to fall back to
// geometric symbols.
NerdFont *bool `json:"nerd_font"`
// LogLevel is the minimum severity written to the event log and
// surfaced as notifications: debug, info, warn, or error. Omitted
// keeps the built-in default (info).
LogLevel string `json:"log_level"`
// TableOpenTarget is the workspace tab focused after selecting a table
// in the schema tree: structure (columns), browse, sql, indexes, or
// foreign_keys. Omitted keeps the built-in default (structure).
TableOpenTarget string `json:"table_open_target"`
// Plugins lists external database driver plugin executables to load at
// startup. Each entry is a bare executable name resolved through PATH
// or a path relative to the config file's directory. Nil or empty
// disables plugins.
Plugins []string `json:"plugins"`
// PluginTrust pins configured plugin executables to the lowercase
// SHA-256 digest of the exact bytes approved with `plugin add
// --approve`, keyed by the canonical absolute executable path. An
// entry without a record loads unpinned for compatibility; a record
// whose digest does not match the current bytes is refused at startup
// before anything spawns. Nil or empty keeps every entry unpinned.
PluginTrust map[string]string `json:"plugin_trust,omitempty"`
}
Config holds user-configurable default behavior. Zero values mean the built-in default, so fields can be omitted from config.json.
func LoadConfig ¶
LoadConfig reads config.json and returns the Config. If the file does not exist, it writes the default config file and returns the defaults.
type Keybindings ¶
type Keybindings struct {
// contains filtered or unexported fields
}
Keybindings is an immutable registry of application keyboard bindings.
func DefaultKeybindings ¶
func DefaultKeybindings() Keybindings
DefaultKeybindings returns the built-in default bindings.
func LoadKeybindings ¶
func LoadKeybindings(path string) (Keybindings, error)
LoadKeybindings reads a JSON config file and returns Keybindings. If the file does not exist, it writes the default config file and returns the defaults.
func MustLoadKeybindings ¶
func MustLoadKeybindings(path string) Keybindings
MustLoadKeybindings is like LoadKeybindings but panics on error. Suitable for cmd/perk-workbench startup.
func NewKeybindings ¶
func NewKeybindings(overrides map[string][]string) (Keybindings, error)
NewKeybindings creates a registry by merging overrides over defaults. An empty slice disables a command. Unknown command IDs, invalid keystrokes, and same-scope duplicates return an error.
func (Keybindings) DisplayKey ¶
func (b Keybindings) DisplayKey(id CommandID) string
DisplayKey returns the first configured key label for a command.
func (Keybindings) DisplayKeys ¶
func (b Keybindings) DisplayKeys(id CommandID) string
DisplayKeys returns all configured key labels for a command, comma-separated.
func (Keybindings) Match ¶
func (b Keybindings) Match(msg tea.KeyPressMsg, id CommandID, scopes []scope) bool
Match checks whether a key press triggers the given command in the given scope priority order.
func (Keybindings) ResolveAny ¶
func (b Keybindings) ResolveAny(msg tea.KeyPressMsg, scopes []scope) (string, bool)
ResolveAny finds any command matching a key press in the given scopes. Returns ("", false) if unmatched. Prefer Match for specific commands.
type Model ¶
func (*Model) SetAI ¶
SetAI wires the assistant provider and history store into the chat component and enables the pane.
func (*Model) SetKeybindings ¶
func (m *Model) SetKeybindings(b Keybindings)
func (*Model) SetNoQuit ¶
SetNoQuit locks the session: every in-app quit affordance (Ctrl+C, Ctrl+Q, the header quit button, the command-palette quit entry, and the footer hints) is removed. The program still exits when its context is cancelled, so the embedding host owns the session lifecycle.
func (*Model) SetPluginControl ¶
func (m *Model) SetPluginControl(control PluginControl)
SetPluginControl injects the live plugin lifecycle controller (the real plugin.Loader from cmd main, or a fake in tests). Without it the plugin manager shows add/remove only: no live status or restart.
type PluginControl ¶
type PluginControl interface {
// Statuses returns one status per configured entry, in config order.
Statuses() []plugin.Status
// Restart recovers the configured entry identified by its entry
// text or canonical path.
Restart(ctx context.Context, identifier string) error
// EntryForService returns the configured entry text of the plugin
// child backing service, or "" when service is not a live session of
// the controller's current generation.
EntryForService(service sharedsql.Service) (string, bool)
}
PluginControl is the injected live plugin lifecycle controller: the real plugin.Loader in production, a fake in tests. The workbench never owns plugin child processes — cmd main builds the loader and hands it over through Model.SetPluginControl. Statuses never spawn, mutate, or exchange protocol traffic; Restart recovers exactly one configured entry; EntryForService reports which configured entry backs a live service (never an old generation).
Source Files
¶
- action_log.go
- appearance_picker.go
- browse.go
- capabilities.go
- cell_viewer.go
- chat.go
- command_palette.go
- completion.go
- completion_query.go
- config.go
- confirmation.go
- connection.go
- editable_input.go
- editor.go
- explain_picker.go
- external_editor.go
- foreign_keys_query.go
- form_buttons.go
- form_click.go
- form_mode.go
- indexes_query.go
- keybindings.go
- keybindings_config.go
- keybindings_defaults.go
- keybindings_display.go
- layout.go
- model.go
- model_click.go
- model_context_menu.go
- model_navigation.go
- model_palette.go
- model_update.go
- model_update_active.go
- model_update_open.go
- notification.go
- pane.go
- plugin_config.go
- plugin_control.go
- plugin_manager.go
- query.go
- query_confirmation.go
- query_execution.go
- query_history.go
- query_log.go
- query_textarea.go
- redact.go
- schema_graph.go
- styles.go
- table_target_picker.go
- theme.go
- theme_picker.go
- view.go
- workspace_tabs.go
- workspace_view.go