client

package
v0.70.1 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 44 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AgentStatusColor added in v0.66.12

func AgentStatusColor(agentStatus string) color.Color

AgentStatusColor returns the palette color for an agent activity status, mirroring the overlay's status-column mapping.

func BuildHandshake added in v0.18.0

func BuildHandshake(paths config.Paths, cols, rows uint16, cwd string) protocol.HandshakeMsg

BuildHandshake constructs a HandshakeMsg with the given paths and terminal dimensions. All code that needs to send a handshake should use this so the Profile field is always populated.

func CompactCount added in v0.67.6

func CompactCount(n int64) string

CompactCount renders a token count compactly: 0, 3.4k, 847k, 1.2M, 5B. It keeps one decimal below 10 of a unit (1.2M) and drops it above (12M).

func ConfigureConnection added in v0.69.1

func ConfigureConnection(t ConnectionTimeouts)

ConfigureConnection installs the configured connection deadlines into the package vars the dial/handshake paths read. It is called once from the CLI's pre-run after config is loaded. A non-positive field is ignored so a partially populated struct can't silently disable a timeout; callers pass values already defaulted by the config accessors. Attach reconnect timing lives in the cli package and is configured there.

func ConfigurePresentation added in v0.69.1

func ConfigurePresentation(p PresentationPrefs)

ConfigurePresentation installs the configured terminal presentation values into the package vars the TUI and handshake paths read. It is called once from the CLI's pre-run after config is loaded. A non-positive field is ignored so a partially populated struct can't zero a value; callers pass values already defaulted by the config accessors.

func EnsureDaemon

func EnsureDaemon(paths config.Paths, configFile string) (net.Conn, error)

EnsureDaemon returns a connection to a live graith daemon, starting one if necessary.

A successful Unix socket dial proves *something* is listening, but not that it's a live graith daemon: the socket may be stale (left behind by a stuck or crashed process) or owned by an unrelated server. Rather than trust the dial and then block forever on a handshake that never comes, EnsureDaemon probes the socket with a handshake under a deadline. If the probe fails, a fresh daemon is started — its startup removes any stale/foreign socket before binding (daemon.Listen), while its PID-file guard (daemon.AcquirePIDFile) refuses to start if a live graith daemon already owns the path. EnsureDaemon deliberately does not unlink the socket itself: doing so could orphan a live-but-slow daemon that merely lost the probe race — its socket would be gone but the PID guard would then block the replacement from rebinding.

func EnsureDaemonConfigured added in v0.70.0

func EnsureDaemonConfigured(cfg *config.Config, paths config.Paths, configFile string) (net.Conn, error)

EnsureDaemonConfigured is EnsureDaemon with the loaded config needed by the managed macOS launcher. The compatibility wrapper above preserves direct callers and tests; CLI connections use this form.

func EnsureDaemonConfiguredContext added in v0.70.0

func EnsureDaemonConfiguredContext(parent context.Context, cfg *config.Config, paths config.Paths, configFile string) (net.Conn, error)

EnsureDaemonConfiguredContext is the context-aware managed launcher used by long-lived frontends. The configured start timeout remains the upper bound; an earlier caller deadline or cancellation shortens it.

func EnsureRemoteDeviceKey added in v0.69.1

func EnsureRemoteDeviceKey(path string) (ed25519.PrivateKey, string, error)

EnsureRemoteDeviceKey establishes or reloads the one canonical device key while holding the cross-process store lock, then durably republishes the latest store before returning it. The lock is released before the caller begins the potentially long human/network pairing wait (issue #1330).

func FallbackGeometry added in v0.69.1

func FallbackGeometry() (cols, rows uint16)

FallbackGeometry returns the configured fallback terminal geometry used when a real terminal size cannot be probed. Exposed so the cli package's remote attach path shares the same defaults as the local client.

func FetchConversation added in v0.59.0

func FetchConversation(cfg *config.Config, paths config.Paths, configFile string, sessionID string) ([]protocol.ConversationMessage, error)

FetchConversation retrieves the full direct-message conversation (both directions) for sessionID via a one-shot passive connection. It is safe for the human CLI: msg_conversation authorises with the self-or-descendant rule, which permits unauthenticated callers.

func FetchScreenSnapshot added in v0.2.0

func FetchScreenSnapshot(cfg *config.Config, paths config.Paths, configFile string, sessionID string) *protocol.ScreenSnapshotResponseMsg

func FetchScrollback added in v0.66.15

func FetchScrollback(cfg *config.Config, paths config.Paths, configFile string, sessionID string, lines int) string

FetchScrollback retrieves up to `lines` lines of a session's raw scrollback via a one-shot connection using the same "logs" message `gr logs` uses. It collects the data frames until the daemon signals logs_done (or an error) and returns the accumulated output cleaned to plain, scroll-friendly text. It returns "" when the daemon is unreachable or the session has no output.

func FetchScrollbackPreview

func FetchScrollbackPreview(cfg *config.Config, paths config.Paths, configFile string, sessionID string) string

func OlderServerProtocolFromHandshakeError added in v0.70.0

func OlderServerProtocolFromHandshakeError(reason string) (string, bool)

OlderServerProtocolFromHandshakeError recognizes the exact rejection emitted by older graith daemons. Protocol 1 rejects a protocol-2 client before it can report handshake_ok, so this is the only safe point at which the new client can choose a clean, non-preserving transition. Only an older numeric major is accepted; arbitrary handshake failures never trigger process lifecycle work. Exported so the `gr daemon restart` path (internal/cli) can recognize the same boundary and fall through to a clean stop/start instead of aborting.

func PersistRemoteHost added in v0.69.1

func PersistRemoteHost(path string, host *RemoteHost) error

PersistRemoteHost reloads and durably updates one paired host while holding the cross-process store lock. On any save error it restores the exact prior entry before releasing the lock; this includes post-rename errors where the new, not-yet-acknowledged credential may already be visible on disk. Because the transaction starts from the latest store, unrelated hosts and the canonical device key survive both the update and the rollback (issue #1330).

func PrepareDaemonCleanRestart added in v0.70.0

func PrepareDaemonCleanRestart(ctx context.Context, paths config.Paths) error

PrepareDaemonCleanRestart reserves the managed service identity before a destructive stop. Fallback installations have nothing to reserve.

func RemoteHostsPath added in v0.66.3

func RemoteHostsPath(dataDir string) string

RemoteHostsPath returns the store path within a data dir.

func RunCreateInput added in v0.52.0

func RunCreateInput(defaultRepo string, repos []RepoSuggestion, agents []string, defaultAgent string) (string, string, string, []string)

RunCreateInput launches a bubbletea prompt for creating a session. Returns (name, repoPath, agent, labels) or empty values on cancel.

func RunMessageOverlay added in v0.59.0

func RunMessageOverlay(sessionID string, keys MessageKeys, fetch func() ([]protocol.ConversationMessage, bool), names map[string]string)

RunMessageOverlay displays the chatroom-style message viewer for sessionID, showing direct messages to and from that session grouped by peer. It is read-only in v1 and re-polls the daemon at the configured shared refresh interval (terminal.refresh_interval), matching the picker and status bar. fetch returns the conversation and ok=false on a transient error (so the last good snapshot is kept). Returns when the user closes the overlay; the caller then reattaches.

func RunNameInput added in v0.9.0

func RunNameInput(title string) string

RunNameInput launches a bubbletea prompt asking for a session name. Returns the entered name, or "" if the user cancelled.

func RunScrollView added in v0.66.15

func RunScrollView(title, content string, keys ScrollKeys)

RunScrollView launches a full-screen pager over the given scrollback content and blocks until the user quits. An empty content shows a placeholder so the pager still opens cleanly rather than flashing an empty screen.

func RunShellInWorktree

func RunShellInWorktree(worktreePath string) error

RunShellInWorktree spawns an interactive shell with its working directory set to the given worktree path, and GRAITH_WORKTREE exported in the env. A non-zero exit status from the shell is not treated as an error since interactive shells commonly inherit the status of their last command.

func ShortDuration added in v0.3.0

func ShortDuration(d time.Duration) string

func SortSessions added in v0.5.1

func SortSessions(sessions []protocol.SessionInfo)

func SplitKeys added in v0.69.1

func SplitKeys(s string) []string

SplitKeys parses a space-separated key list (e.g. "j down ctrl+n") into its individual key names, dropping empty fields. It is exported so the cli layer can translate config strings into the key slices these overlays consume.

func StatusColor added in v0.66.12

func StatusColor(status string) color.Color

StatusColor returns the palette color for a session lifecycle status, matching the colors used by the overlay's status column: running is green, errored is red, and everything else (stopped, unknown) is dimmed.

It is exported so other renderers (e.g. `gr list`) can share the overlay's palette instead of duplicating the hex values.

func StopDaemonIdentity added in v0.70.0

func StopDaemonIdentity(identity DaemonIdentity) error

StopDaemonIdentity signals a previously authenticated daemon process while guarding against PID reuse.

func TruncateSummary added in v0.70.0

func TruncateSummary(text string, width int) string

TruncateSummary limits text to a display-cell budget, preserving ANSI styling and UTF-8/grapheme boundaries. A non-positive width means unlimited. The ellipsis counts toward the budget.

func WaitForDaemonSocketGone added in v0.70.0

func WaitForDaemonSocketGone(sockPath string) bool

WaitForDaemonSocketGone proves that a stopped daemon no longer owns its filesystem rendezvous point before lifecycle state is committed.

func WriteScreenRestore added in v0.2.0

func WriteScreenRestore(snap *protocol.ScreenSnapshotResponseMsg)

Types

type Client

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

func Connect

func Connect(cfg *config.Config, paths config.Paths, configFile string) (*Client, error)

Connect creates a new client, performs the handshake, and reads the handshake response. If the daemon is running a different version, it automatically triggers a restart and reconnects. On failure the connection is closed automatically.

func ConnectExisting added in v0.70.0

func ConnectExisting(cfg *config.Config, paths config.Paths) (*Client, error)

ConnectExisting connects and authenticates to an already-running daemon but never starts or upgrades one. Lifecycle controls such as `daemon stop` use it so a down service is not demand-started merely in order to stop it.

func ConnectFast added in v0.11.0

func ConnectFast(paths config.Paths) (*Client, error)

ConnectFast is a fast-path connect for hooks. It dials the daemon socket directly with the configured local dial timeout ([connection].dial_timeout, installed via ConfigureConnection) and does NOT auto-start the daemon. The short handshake deadline set below stays independent of the dial timeout.

func ConnectForPolicy added in v0.70.0

func ConnectForPolicy(paths config.Paths, timeout time.Duration) (*Client, error)

ConnectForPolicy establishes a hook connection with a bounded end-to-end deadline. The deadline remains installed for the synchronous policy reply.

func ConnectPassive added in v0.40.0

func ConnectPassive(cfg *config.Config, paths config.Paths, configFile string) (*Client, error)

ConnectPassive creates a new client and performs the handshake, but never triggers daemon auto-upgrade on version mismatch. Use this for long-lived helper processes that may outlive a binary upgrade and should not race with the user's explicit daemon restart.

func ConnectPassiveContext added in v0.70.0

func ConnectPassiveContext(ctx context.Context, cfg *config.Config, paths config.Paths, configFile string) (*Client, error)

ConnectPassiveContext is ConnectPassive with caller cancellation applied to daemon startup. It intentionally retains passive version-mismatch behavior.

func ConnectRemote added in v0.66.3

func ConnectRemote(paths config.Paths, rh *RemoteHost, signer ed25519.PrivateKey, cols, rows uint16) (*Client, error)

ConnectRemote dials a paired remote daemon over TLS (SPKI-pinned), performs the handshake, completes proof-of-possession (signing the daemon's challenge with the device key), and returns a ready Client authenticated as this device. Unlike New/Connect it never touches the local daemon (no EnsureDaemon, no auto-upgrade).

func New

func New(cfg *config.Config, paths config.Paths, configFile string) (*Client, error)

func NewContext added in v0.70.0

func NewContext(ctx context.Context, cfg *config.Config, paths config.Paths, configFile string) (*Client, error)

NewContext constructs a client while allowing daemon startup to be bounded by the caller as well as the configured connection policy.

func (*Client) Close

func (c *Client) Close()

func (*Client) DaemonIdentity added in v0.70.0

func (c *Client) DaemonIdentity() (DaemonIdentity, error)

DaemonIdentity captures the exact process currently owning the authenticated daemon connection. Callers must capture it before closing the socket.

func (*Client) DaemonPID added in v0.69.5

func (c *Client) DaemonPID() (int, error)

DaemonPID returns the operating-system peer PID for this client's local Unix socket. Unlike the daemon PID file, this identity is bound to the process that owns the connection and can therefore be used to guard restart races.

func (*Client) Handshake

func (c *Client) Handshake() error

func (*Client) ReadControlResponse

func (c *Client) ReadControlResponse() (protocol.Envelope, error)

func (*Client) ReadFrame

func (c *Client) ReadFrame() (protocol.Frame, error)

func (*Client) RunPassthrough

func (c *Client) RunPassthrough(ctx context.Context, opts PassthroughOpts) PassthroughResult

func (*Client) SendControl

func (c *Client) SendControl(msgType string, payload any) error

func (*Client) SendData

func (c *Client) SendData(data []byte) error

func (*Client) SendFrame added in v0.23.0

func (c *Client) SendFrame(channel byte, data []byte) error

func (*Client) SetDeadline added in v0.69.1

func (c *Client) SetDeadline(t time.Time) error

SetDeadline sets the read/write deadline on the underlying connection. A zero time clears it. The CLI exec-upgrade path uses this to bound its raw handshake + upgrade exchange (issue #1319).

func (*Client) SetReadDeadline added in v0.66.15

func (c *Client) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline on the underlying connection. A zero time clears the deadline. Callers reading a bounded stream of frames (e.g. the check-inbox hook) use this so a slow or hung daemon can't block them indefinitely.

type ConnectionTimeouts added in v0.69.1

type ConnectionTimeouts struct {
	Dial            time.Duration
	Handshake       time.Duration
	Start           time.Duration
	StartPoll       time.Duration
	RemoteDial      time.Duration
	RemoteHandshake time.Duration
	RemotePairing   time.Duration
}

ConnectionTimeouts carries the client-side connection deadlines resolved from the [connection] config block. It is defined here (not in internal/config) so config need not import client; the CLI maps config accessors into this struct and hands it to ConfigureConnection.

type DaemonIdentity added in v0.70.0

type DaemonIdentity struct {
	PID       int
	StartTime int64
}

DaemonIdentity is the authenticated Unix-socket peer PID together with the operating-system process start time that makes the identity safe against PID reuse between authentication and signalling.

type ExistingDaemonHandshakeError added in v0.70.0

type ExistingDaemonHandshakeError struct {
	ResponseType string
}

ExistingDaemonHandshakeError means a well-formed control response rejected lifecycle authentication. Unlike a stale/foreign socket transport failure, callers must not treat this as an absent daemon and continue destructively.

func (*ExistingDaemonHandshakeError) Error added in v0.70.0

func (err *ExistingDaemonHandshakeError) Error() string

type MessageKeys added in v0.69.1

type MessageKeys struct {
	Up          []string
	Down        []string
	PageUp      []string
	PageDown    []string
	Top         []string
	Bottom      []string
	Pin         []string
	ExpandAll   []string
	CollapseAll []string
	NextConv    []string
	PrevConv    []string
	Cancel      []string
}

MessageKeys are the keys the message-viewer overlay listens for.

func DefaultMessageKeys added in v0.69.1

func DefaultMessageKeys() MessageKeys

DefaultMessageKeys returns the built-in message-viewer bindings.

type OverlayKeys added in v0.66.15

type OverlayKeys struct {
	DeleteSession string
	ResumeSession string
	Search        string
}

OverlayKeys carries the configurable picker keybindings from [keybindings]. Empty fields fall back to the built-in defaults (see newOverlayModel).

type OverlayResult

type OverlayResult struct {
	Action         string
	SessionID      string
	CreateName     string
	CreateRepoPath string
	CreateAgent    string
	CreateLabels   []string
	Collapsed      map[string]bool
	PickerState    PickerState
}

OverlayResult holds the outcome of the overlay interaction.

func RunOverlay

func RunOverlay(opts RunOverlayOpts) *OverlayResult

RunOverlay launches the bubbletea session picker.

type PassthroughKeys

type PassthroughKeys struct {
	Prefix              byte
	Detach              byte
	SessionList         byte
	Shell               byte
	NextSession         byte
	PrevSession         byte
	LastSession         byte
	NewSession          byte
	ForkSession         byte
	OrchestratorSession byte
	RenameSession       byte
	ScrollMode          byte
	Messages            byte
	RestartSession      byte
}

type PassthroughOpts added in v0.3.0

type PassthroughOpts struct {
	Keys      PassthroughKeys
	SessionID string
	Info      *protocol.SessionInfo
	StatusBar *StatusBarCfg
	// DragArrowKeys enables the touch/hold-and-drag gesture that translates
	// left-button mouse drags into arrow-key presses. Off by default.
	DragArrowKeys bool
	// DragArrowThreshold is the cells-per-arrow drag distance; <1 uses the default.
	DragArrowThreshold int
	// ReadOnly gates all keystroke input: the client streams PTY output but never
	// forwards typed bytes to the daemon, so an observer can watch a session
	// without risk of injecting input (issue #31). Prefix-key actions (detach,
	// session switching, overlays) still work; only data sent to the agent is
	// suppressed. A persistent indicator shows the mode.
	ReadOnly bool
}

type PassthroughResult

type PassthroughResult int
const (
	ResultDetached PassthroughResult = iota
	ResultOverlay
	ResultShell
	ResultQuit
	ResultDisconnected
	ResultRestart
	ResultNextSession
	ResultPrevSession
	ResultNewSession
	ResultForkSession
	ResultLastSession
	ResultOrchestratorSession
	ResultMessageOverlay
	ResultRenameSession
	ResultScrollMode
)

type PickerState added in v0.70.0

type PickerState struct {
	View       PickerView
	SessionID  string
	LabelGroup string
}

PickerState is the minimal navigation state carried between overlay opens. Search and other transient overlay modes are intentionally excluded.

type PickerView added in v0.70.0

type PickerView int

PickerView identifies the session-picker view to restore within one attach client. It is deliberately a client-local value; it is never persisted.

const (
	PickerViewAll PickerView = iota
	PickerViewRepo
	PickerViewStarred
	PickerViewLabels
	PickerViewScenario
	PickerViewDeleted
)

type PresentationPrefs added in v0.69.1

type PresentationPrefs struct {
	RefreshInterval time.Duration
	DefaultCols     int
	DefaultRows     int
	SummaryWidth    int
}

PresentationPrefs carries the [terminal] presentation values resolved from config. It is defined here (not in internal/config) so config need not import client; the CLI maps config accessors into this struct and hands it to ConfigurePresentation, mirroring ConnectionTimeouts / ConfigureConnection.

type RemoteHost added in v0.66.3

type RemoteHost struct {
	Host    string `json:"host"`           // MagicDNS name / tailnet address
	Port    int    `json:"port"`           // remote listener port
	Token   string `json:"client_token"`   // bearer token (this device's)
	TLSPin  string `json:"tls_pin_spki"`   // pinned SPKI (TOFU)
	Profile string `json:"daemon_profile"` // remote daemon profile (handshake must match)
}

RemoteHost is a paired remote graith daemon reachable over the tailnet (design §A/§B, #615). Credentials are minted by the remote daemon's `gr remote pairings approve` and delivered in pair_response.

func PairRemote added in v0.66.3

func PairRemote(paths config.Paths, host string, port int, profile, deviceLabel, devicePubKey string) (*RemoteHost, error)

PairRemote performs the CLI side of device pairing with a remote daemon: it dials (capturing the server's SPKI pin via TOFU), handshakes, sends pair_request with the device public key, and blocks until the remote human runs `gr remote pairings approve`, then returns the minted RemoteHost credentials. No token or proof-of-possession is used — this is the roleNone pairing lane.

type RemoteHostStore added in v0.66.3

type RemoteHostStore struct {
	// DeviceKey is this device's ed25519 private key (base64), used for
	// proof-of-possession against every paired remote daemon.
	DeviceKey string                 `json:"device_key"`
	Hosts     map[string]*RemoteHost `json:"hosts"`
	// contains filtered or unexported fields
}

RemoteHostStore persists this CLI's device identity and its paired remote hosts. It lives in the data dir (0600) — the local filesystem is the trust boundary, mirroring the daemon's 0700 socket.

func LoadRemoteHostStore added in v0.66.3

func LoadRemoteHostStore(path string) (*RemoteHostStore, error)

LoadRemoteHostStore loads the store, returning an empty one if the file does not exist.

func (*RemoteHostStore) EnsureDeviceKey added in v0.66.3

func (s *RemoteHostStore) EnsureDeviceKey() (ed25519.PrivateKey, string, error)

EnsureDeviceKey returns this device's ed25519 private key and base64 public key, generating and storing the key on first use. The caller should Save after a fresh key is generated.

func (*RemoteHostStore) Get added in v0.66.3

func (s *RemoteHostStore) Get(host string) (*RemoteHost, bool)

Get returns a paired host by name.

func (*RemoteHostStore) Names added in v0.66.4

func (s *RemoteHostStore) Names() []string

Names returns the paired host keys, sorted — for stable listings and error messages.

func (*RemoteHostStore) Put added in v0.66.3

func (s *RemoteHostStore) Put(h *RemoteHost)

Put stores/updates a paired host (keyed by Host).

func (*RemoteHostStore) Resolve added in v0.66.4

func (s *RemoteHostStore) Resolve(host string) (*RemoteHost, []string)

Resolve finds a paired host by exact key or by short-name/prefix match, so a user can type "myhost" for a host stored as "myhost.tailnet.ts.net". On a unique match it returns the host; otherwise it returns nil plus the sorted list of paired names (empty, or the candidates) for a helpful error.

func (*RemoteHostStore) Save added in v0.66.3

func (s *RemoteHostStore) Save() error

Save writes the store atomically (temp file + rename) with 0600 perms, so a crash mid-write can't corrupt the credential store or lose the device key, and an existing file with looser perms is replaced by a 0600 one.

type RepoSuggestion added in v0.52.0

type RepoSuggestion struct {
	Name string
	Path string
}

func DiscoverRepos added in v0.52.0

func DiscoverRepos(allowedPaths []string, sessions []protocol.SessionInfo) []RepoSuggestion

type RunOverlayOpts added in v0.67.2

type RunOverlayOpts struct {
	// Sessions is the initial list rendered in the overlay.
	Sessions []protocol.SessionInfo
	// CurrentSessionID highlights the session the user was just attached to.
	CurrentSessionID string
	// FetchPreview is called asynchronously to load scrollback for the
	// selected session.
	FetchPreview func(sessionID string) string
	// RefreshSessions re-fetches the live session list.
	RefreshSessions func() []protocol.SessionInfo
	// RefreshDeleted re-fetches the soft-deleted session list.
	RefreshDeleted func() []protocol.SessionInfo
	// DeleteSession soft-deletes a session by ID.
	DeleteSession func(sessionID string) error
	// RestartSession restarts a stopped session by ID.
	RestartSession func(sessionID string) error
	// StopSession stops a running session by ID.
	StopSession func(sessionID string) error
	// ToggleStar stars or unstars a session by ID.
	ToggleStar func(sessionID string, star bool) error
	// RestoreSession restores a soft-deleted session by ID.
	RestoreSession func(sessionID string) error
	// Profile is the active configuration profile name.
	Profile string
	// Collapsed is the initial fold state, keyed by session ID.
	Collapsed map[string]bool
	// PickerState restores navigation from an earlier overlay opening in the
	// same attach client. Zero value starts in the All view.
	PickerState PickerState
	// RepoSuggestions seeds the create-session repo picker.
	RepoSuggestions []RepoSuggestion
	// ShortcutKeys is the set of quick-jump shortcut runes.
	ShortcutKeys string
	// Agents is the list of available agent types for create-session.
	Agents []string
	// DefaultAgent is the pre-selected agent for create-session.
	DefaultAgent string
	// Keys is the resolved overlay keybinding set.
	Keys OverlayKeys
}

RunOverlayOpts configures the session-picker overlay. It replaces the long positional parameter list of RunOverlay — several of its fields are structurally identical callbacks (five `func(sessionID string) error`) that were trivially transposable when passed positionally.

type ScrollKeys added in v0.69.1

type ScrollKeys struct {
	Top    []string
	Bottom []string
	Cancel []string
}

ScrollKeys are the keys the scrollback pager listens for on top of the bubbles viewport's own scrolling (up/down/page keys are handled by the viewport and are not remapped here).

func DefaultScrollKeys added in v0.69.1

func DefaultScrollKeys() ScrollKeys

DefaultScrollKeys returns the built-in scroll-pager bindings.

type SessionColumn added in v0.66.15

type SessionColumn struct {
	// Key is a stable identifier used for TUI width lookups.
	Key string
	// Header is the title-case header text. The CLI upper-cases it ("STATUS");
	// the TUI uses it verbatim ("Status").
	Header string

	// ShowCLI includes the column in `gr ls` snapshot mode.
	ShowCLI bool
	// ShowTUI includes the column in the TUI session picker.
	ShowTUI bool
	// Wide restricts a CLI column to `gr ls --wide`.
	Wide bool

	// MinWidth is the minimum TUI column width; MaxWidth caps it (0 = no cap).
	MinWidth int
	MaxWidth int

	// CLIValue returns the plain-text cell for `gr ls`. now is the reference
	// time for age/attached columns; other columns ignore it.
	CLIValue func(s protocol.SessionInfo, now time.Time) string
	// CLIColor returns the foreground colour for the CLI cell, or nil for none.
	// The list command applies it via colorize; the renderer measures cells with
	// ansi.StringWidth so the colour escapes don't disturb column alignment.
	CLIColor func(s protocol.SessionInfo) color.Color

	// TUIValue returns the cell text for the TUI picker. It may include "—"
	// placeholders and unicode status glyphs.
	TUIValue func(s protocol.SessionInfo) string
	// TUIStyle returns the lipgloss style (foreground/bold) for the TUI cell.
	// The zero style renders text unchanged.
	TUIStyle func(s protocol.SessionInfo) lipgloss.Style
}

SessionColumn is the single source of truth for one column shown in the session picker (the TUI overlay) and/or the `gr ls` snapshot. A column is defined exactly once here, so adding a new column makes it appear in every enabled surface — flip ShowCLI/ShowTUI to control where it shows up and the views stay in sync automatically.

The list snapshot table and picker render differently: the list aligns plain-text cells (optionally colourised) by visible width, while the picker uses fixed-width cells with unicode glyphs and per-cell styling. So each column carries a value formatter (and styling) for each kind of surface rather than a single shared string.

The NAME/Session column is deliberately NOT part of this registry: both surfaces render it specially (star prefix and tree indentation in list, collapse indicators and tree prefixes in the picker), so it is handled inline by each renderer. This registry covers only the trailing columns.

func SessionColumns added in v0.66.15

func SessionColumns() []SessionColumn

SessionColumns returns every trailing column in a single display order. Each surface filters by ShowCLI/ShowTUI (list snapshot/watch additionally hide Wide columns unless --wide is set) and renders the survivors in this order. The order is chosen so that the two filtered subsets each match their historical layout:

CLI: Repo Agent Status Activity Summary [Model Branch] Git PR Review Age [Attached]
TUI: Status Summary Git PR Review Output

type StatusBarCfg added in v0.3.0

type StatusBarCfg struct {
	Position string
}

Jump to

Keyboard shortcuts

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