Documentation
¶
Index ¶
- func BufferDir() string
- func ClaudeHookDir() string
- func ConfigPath() string
- func DefaultQuilDir() string
- func EventsDir() string
- func InstancesPath() string
- func IsDefaultQuilDir(dir string) bool
- func MCPLogDir(cfg MCPConfig) string
- func Mutate(path string, fn func(*Config)) error
- func NotesDir() string
- func PasteDir() string
- func PidPath() string
- func PluginsDir() string
- func QuilDir() string
- func RecentCWDsPath(dest string) string
- func Save(path string, cfg Config) error
- func SessionsDir() string
- func SocketPath() string
- func UpdateDir() string
- func UpdateNotifiedPath() string
- func UpdateStagingDir(version string) string
- func UpdateStagingRoot() string
- func UpdateStatePath() string
- func WindowStatePath() string
- func WorkspacePath() string
- type Config
- type DaemonConfig
- type Destination
- type GhostBufferConfig
- type HookNotificationsConfig
- type KeybindingsConfig
- type LoggingConfig
- type MCPConfig
- type NotificationConfig
- type RemoteConfig
- type RemoteHost
- type SecurityConfig
- type UIConfig
- type UpdateConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClaudeHookDir ¶ added in v1.9.2
func ClaudeHookDir() string
ClaudeHookDir returns the directory where Quil writes the Claude Code SessionStart hook scripts it passes via --settings. Lives under Quil's own home so we never touch the user's ~/.claude/ config.
func ConfigPath ¶
func ConfigPath() string
func DefaultQuilDir ¶ added in v1.18.6
func DefaultQuilDir() string
DefaultQuilDir returns the production default data dir (~/.quil), ignoring QUIL_HOME. Used by dev builds to detect an inherited production-pointing QUIL_HOME.
func EventsDir ¶ added in v1.16.0
func EventsDir() string
EventsDir returns the directory where Claude / opencode hooks append per-pane JSONL event spool files (<paneID>.jsonl). The daemon's hookEventsWatcher polls these files on a 200 ms ticker, parses new lines, and feeds them through hookevents.Ingester → eventQueue → IPC fan-out. Truncated at daemon start (no replay of stale events); files for destroyed panes are unlinked.
func InstancesPath ¶
func InstancesPath() string
func IsDefaultQuilDir ¶ added in v1.18.6
IsDefaultQuilDir reports whether dir resolves to the production default data dir. Case-insensitive on Windows.
func Mutate ¶ added in v1.47.0
Save writes the config to disk atomically (write .tmp then rename). Mutate applies fn to the config ON DISK — load, change, save — and is the only correct way to write one section of a config another writer also owns.
Save serialises the WHOLE struct, so saving a Config that was loaded at launch silently reverts every key written since. That is not hypothetical here: a remote install records the absolute path it installed to under [remote.hosts.<dest>], and the very next thing the TUI does is record the new destination — which, done from the launch-time snapshot, erased the path that makes attaching work at all. The symptom was a host that installed successfully and then offered to install again on the next launch, forever.
A missing file is not an error: Load returns the defaults for one, which is exactly what a first write should be based on.
func NotesDir ¶
func NotesDir() string
NotesDir returns the directory where per-pane notes are stored.
func PasteDir ¶ added in v1.3.0
func PasteDir() string
PasteDir returns the directory where Quil writes clipboard images that are pasted into a pane. Used by the image-paste proxy that works around Claude Code's broken Windows clipboard reader (see anthropics/claude-code#32791) — Quil reads the image, saves a PNG here, and pastes the absolute path into the PTY.
func PluginsDir ¶
func PluginsDir() string
func RecentCWDsPath ¶ added in v1.41.0
RecentCWDsPath returns the file storing the last-used working directories offered as a quick pick in the pane setup dialog. TUI-owned, single writer.
dest scopes the file to one remote destination. Empty — the local case — keeps the historical name exactly, so existing installs need no migration. Without the scoping, one flat list mixed laptop and server directories: after a remote session the local picker offered paths that exist only on the server, and vice versa.
func SessionsDir ¶ added in v1.9.2
func SessionsDir() string
SessionsDir returns the directory where the Claude Code SessionStart hook writes per-pane session id files (<paneID>.id). Read on daemon restore by resumeTemplateFor so panes reattach to the latest session id after /clear, compaction, or /resume rotations.
func SocketPath ¶
func SocketPath() string
func UpdateDir ¶ added in v1.37.0
func UpdateDir() string
UpdateDir returns the root directory of the auto-update pipeline: staged binaries, the daemon-owned state.json, and the TUI-owned notified.json all live under it.
func UpdateNotifiedPath ¶ added in v1.37.0
func UpdateNotifiedPath() string
UpdateNotifiedPath is the TUI-owned once-per-version startup-dialog marker. The daemon never writes it.
func UpdateStagingDir ¶ added in v1.37.0
UpdateStagingDir returns the directory a given release version is staged into. The stager writes manifest.json into it LAST — its presence is the atomic "staging complete" marker.
func UpdateStagingRoot ¶ added in v1.37.0
func UpdateStagingRoot() string
UpdateStagingRoot returns the directory that holds one subdirectory per staged release version.
func UpdateStatePath ¶ added in v1.37.0
func UpdateStatePath() string
UpdateStatePath is the daemon-owned check/stage status file. The TUI never writes it (single-writer-per-file rule).
func WindowStatePath ¶
func WindowStatePath() string
func WorkspacePath ¶
func WorkspacePath() string
Types ¶
type Config ¶
type Config struct {
Daemon DaemonConfig `toml:"daemon"`
GhostBuffer GhostBufferConfig `toml:"ghost_buffer"`
Logging LoggingConfig `toml:"logging"`
Security SecurityConfig `toml:"security"`
UI UIConfig `toml:"ui"`
Keybindings KeybindingsConfig `toml:"keybindings"`
MCP MCPConfig `toml:"mcp"`
Notification NotificationConfig `toml:"notification"`
Update UpdateConfig `toml:"update"`
Remote RemoteConfig `toml:"remote"`
// Destinations are the ADDITIONAL daemons this client attaches to beside
// the local one, each contributing its projects to the same sidebar. A
// slice rather than a map because order is meaningful — it is the order the
// projects appear in — and TOML spells a list of tables as [[destinations]].
//
// `quil --remote <host>` ignores this list entirely: that mode is "drive
// THAT machine", and quietly attaching the configured extras to it would
// make one flag mean two different things.
Destinations []Destination `toml:"destinations"`
}
func (*Config) ClearRemoteBinary ¶ added in v1.46.1
ClearRemoteBinary forgets the recorded quil path for dest.
Called only when the host probe has ANSWERED and reported no quil at all: the record is then known-false, and keeping it means the next launch runs the same missing path and fails identically. A probe that errored is not evidence — see healRemoteRecord in cmd/quil.
Deleting from a nil map is a no-op in Go, so a config predating the [remote] section needs no special case. That matters here rather than being a curiosity: this runs on the failure path, where a panic would replace a diagnosable error with a crash.
func (*Config) RemoteBinary ¶ added in v1.44.0
RemoteBinary returns the recorded quil path for dest, or "" when none has been recorded — in which case the caller falls back to a bare `quil`, which works only if the remote's non-interactive PATH can see it.
func (*Config) SetRemoteBinary ¶ added in v1.44.0
SetRemoteBinary records where quil lives on dest, creating the map on first use so callers need not care whether the config predates this section.
type DaemonConfig ¶
type Destination ¶ added in v1.47.0
type Destination struct {
// Name labels the host in launch diagnostics. Optional; Dest is used when
// it is empty. It exists because Dest is an ssh destination — often
// `user@10.0.0.4` or an ssh_config alias — and the message a user reads
// when a host is unreachable at launch should be able to say "gpu box".
Name string `toml:"name"`
// Dest is passed to ssh VERBATIM, exactly like --remote: an ssh_config Host
// alias keeps its HostName/Port/User/ProxyJump, which is the whole reason
// the transport does not parse it. It is also the routing key — the key a
// project's Dest, its reconnect state and its link banner all carry.
Dest string `toml:"dest"`
}
Destination names one remote daemon to attach at launch.
func (Destination) Label ¶ added in v1.47.0
func (d Destination) Label() string
Label returns the name to show for a destination, falling back to the ssh destination itself.
type GhostBufferConfig ¶
type HookNotificationsConfig ¶ added in v1.16.0
type HookNotificationsConfig struct {
Claude string `toml:"claude"`
OpenCode string `toml:"opencode"`
}
HookNotificationsConfig controls which hook-driven events get spool-emitted per source. Tier values are "default" / "verbose" / "off". Daemon passes the resolved value to the hook scripts via the QUIL_HOOK_MODE env var at pane spawn so the script can branch on it (default → forward the v1 tier; verbose → also forward tool-use + pre/post events; off → no spool writes at all). Unset = "default" downstream.
type KeybindingsConfig ¶
type KeybindingsConfig struct {
Quit string `toml:"quit"`
NewTab string `toml:"new_tab"`
ClosePane string `toml:"close_pane"`
CloseTab string `toml:"close_tab"`
SplitHorizontal string `toml:"split_horizontal"`
SplitVertical string `toml:"split_vertical"`
// Linear pane cycling. Empty string = unbound (the default) — users
// now navigate spatially via PaneLeft/Right/Up/Down. Keeping the fields
// for backward compat so existing configs that set e.g. next_pane = "tab"
// continue to work (though that would re-intercept Tab from the PTY).
NextPane string `toml:"next_pane"`
PrevPane string `toml:"prev_pane"`
// Spatial pane navigation — focus the neighbor in a given direction.
// Defaults are Alt+Arrow. Tab and Shift+Tab are deliberately NOT used
// so shell completion and Claude Code mode cycling reach the PTY
// unmolested. Plain Alt+H / Alt+V are also free for the PTY (claude-code
// uses Alt+V to paste an image); splits live on Alt+Shift+H / Alt+Shift+V
// instead. Vim users can rebind to "alt+h"/"alt+l"/"alt+k"/"alt+j" in
// config.toml if they want the classic hjkl motion.
PaneLeft string `toml:"pane_left"`
PaneRight string `toml:"pane_right"`
PaneUp string `toml:"pane_up"`
PaneDown string `toml:"pane_down"`
RenameTab string `toml:"rename_tab"`
RenamePane string `toml:"rename_pane"`
CycleTabColor string `toml:"cycle_tab_color"`
ScrollPageUp string `toml:"scroll_page_up"`
ScrollPageDown string `toml:"scroll_page_down"`
Paste string `toml:"paste"`
JSONTransform string `toml:"json_transform"`
QuickActions string `toml:"quick_actions"`
FocusPane string `toml:"focus_pane"`
NotificationToggle string `toml:"notification_toggle"`
NotificationFocus string `toml:"notification_focus"`
// MutePane toggles notification mute on the active pane (idle/bell/exit
// events stop firing). Useful for `npm test --watch` and other chatty
// processes that would otherwise flood the sidebar.
MutePane string `toml:"mute_pane"`
// RestartPane kills and respawns the active pane's process in place
// (same pane, same plugin resume strategy — AI panes resume their
// session via the recorded session id). Recovery for a child that
// stopped reading stdin ("Pane not accepting input").
RestartPane string `toml:"restart_pane"`
GoBack string `toml:"go_back"`
NotesToggle string `toml:"notes_toggle"`
// Redraw forces a full screen repaint (tea.ClearScreen). Recovery key
// for rendering artifacts left behind by cell-diff drift — width
// disagreements between Quil and the host terminal (most common on
// Windows) scramble characters until something repaints everything.
Redraw string `toml:"redraw"`
// ToggleEager flips the active pane's eager-restore flag. Eager panes
// respawn immediately on daemon restart (vs the default lazy deferral) and
// show a ● marker on their tab.
ToggleEager string `toml:"toggle_eager"`
// CommandHistory opens the per-pane input-history modal (list of submitted
// prompts; Enter opens one full-text read-only). Only meaningful for panes
// whose plugin sets record_history (claude-code).
CommandHistory string `toml:"command_history"`
// ToggleLazygit opens/hides the per-tab lazygit overlay for the git
// repo resolved from the active pane's CWD.
ToggleLazygit string `toml:"toggle_lazygit"`
// ToggleWrap switches the active wide-canvas pane's preview between
// left-edge crop (default) and soft-wrap. Only meaningful for panes
// whose plugin sets [display] wide_canvas; no-op elsewhere.
ToggleWrap string `toml:"toggle_wrap"`
// CommandPalette opens the fuzzy command palette — a modal, centered
// launcher for every action plus jump-to-tab/pane. Default is alt+shift+p:
// ctrl+shift+p is intercepted by many terminals' own command palette
// (Windows Terminal, VS Code's terminal) before it reaches Quil, so it is
// deliberately NOT a default. Add it back in config.toml if your terminal
// leaves it free (e.g. `command_palette = "ctrl+shift+p,alt+shift+p"`).
CommandPalette string `toml:"command_palette"`
// SidebarToggle collapses / expands the PROJECT sidebar (the reserved
// left column, not the notification overlay on the right — that one is
// NotificationToggle). Unlike the overlay this reserves real layout
// width, so toggling it resizes every pane's PTY.
SidebarToggle string `toml:"sidebar_toggle"`
// ProjectPicker opens the fuzzy project picker, ProjectToggle bounces
// between the two most recent projects, AttentionQueue opens the
// cross-project list of panes blocked on the user, and NewProject opens
// the create-project dialog.
//
// The whole group deliberately avoids alt+w / alt+a / alt+shift+p
// (CloseTab, QuickActions, CommandPalette). alt+p and alt+o are plain
// Alt-letter keys because no AI tool binds them; the rest take the
// Alt+Shift layer for the same reason the split keys do.
ProjectPicker string `toml:"project_picker"`
ProjectToggle string `toml:"project_toggle"`
// ProjectNext/ProjectPrev cycle through the project list in order, where
// ProjectToggle bounces between the last two. Bound to alt+shift+arrows
// so they read as the project-level echo of alt+arrows' pane navigation.
// Deliberately NOT alt+[ / alt+] : those send ESC [ and ESC ], and ESC [
// is the CSI introducer, so the terminal cannot tell the keypress from
// the start of an escape sequence. Same reason alt+O (SS3) is avoided,
// and alt+b/f/d are left to readline's word operations.
ProjectNext string `toml:"project_next"`
ProjectPrev string `toml:"project_prev"`
AttentionQueue string `toml:"attention_queue"`
NewProject string `toml:"new_project"`
DestroyProject string `toml:"destroy_project"`
}
type LoggingConfig ¶
type LoggingConfig struct {
Level string `toml:"level"`
// MaxSizeMB and MaxFiles drive log rotation via logger.RotatingWriter.
// When the active quild.log / quil.log would exceed MaxSizeMB it is
// rotated to a timestamped archive (stem-YYYYMMDD-HHMMSS.log) and a
// fresh base file is opened. The newest MaxFiles archives are kept;
// older ones are pruned by modification time. Implemented natively in
// internal/logger/rotate.go — no external dependency.
MaxSizeMB int `toml:"max_size_mb"`
MaxFiles int `toml:"max_files"`
}
type NotificationConfig ¶
type NotificationConfig struct {
SidebarWidth int `toml:"sidebar_width"` // default 30
MaxEvents int `toml:"max_events"` // default 200
Hooks HookNotificationsConfig `toml:"hooks"`
}
type RemoteConfig ¶ added in v1.44.0
type RemoteConfig struct {
Hosts map[string]RemoteHost `toml:"hosts"`
}
RemoteConfig holds per-destination settings for `quil --remote`, keyed by the destination string exactly as the user types it — an ssh_config Host alias, a hostname, or user@host.
type RemoteHost ¶ added in v1.44.0
type RemoteHost struct {
// Binary is the absolute path to quil on that host, as resolved by
// `quil remote setup`. It is used verbatim as the ssh remote command,
// which is what makes attaching work when the non-interactive PATH cannot
// see the install directory — the normal case for ~/.local/bin on Debian
// and Ubuntu, where ~/.bashrc returns before reaching any PATH line.
Binary string `toml:"binary"`
}
RemoteHost pins how to reach quil on one remote destination.
type SecurityConfig ¶
type UIConfig ¶
type UIConfig struct {
TabDock string `toml:"tab_dock"`
Theme string `toml:"theme"`
MouseScrollLines int `toml:"mouse_scroll_lines"`
PageScrollLines int `toml:"page_scroll_lines"`
// LogViewerPageLines controls the cursor jump distance for Alt+Up /
// Alt+Down inside the F1 → log viewer. 0 falls back to the default 40.
LogViewerPageLines int `toml:"log_viewer_page_lines"`
ShowDisclaimer bool `toml:"show_disclaimer"`
// SidebarOpen/SidebarWidth control the project sidebar (a reserved left
// column listing projects and the active project's panes). These are
// screen properties, not session ones — client config, never
// workspace.json — so a workspace saved with the sidebar open doesn't
// fight a narrower terminal on restore.
SidebarOpen bool `toml:"sidebar_open"`
SidebarWidth int `toml:"sidebar_width"`
}
type UpdateConfig ¶ added in v1.37.0
UpdateConfig controls the auto-update pipeline. Check gates the daily GitHub release check (one unauthenticated GET to api.github.com); Auto gates background download + staging of a newer release. auto = false degrades to notify-only. Dev builds (version.IsRelease() == false) skip the pipeline regardless of these settings.