server

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 36 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WarrenColorQuery

func WarrenColorQuery(kind ghostline.ColorQueryKind) (string, bool)

WarrenColorQuery supplies Warren's Ember terminal colors to ghostline.

Types

type CursorOutputRuntime added in v0.9.0

type CursorOutputRuntime interface {
	Runtime
	Checkpoint(context.Context, string) (ghostline.Checkpoint, error)
	OpenOutput(context.Context, string, ghostline.Cursor) (*ghostline.OutputReader, error)
}

CursorOutputRuntime is implemented by Ghostline v1. The service owns one reader per session and treats Cursor as an opaque durable token; the browser-facing output protocol deliberately continues to use its own lightweight sequence anchors.

type GhostlineRuntime

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

GhostlineRuntime adapts ghostline's session-handle API to the name-based Runtime surface used by Service. Handles are cached by name and re-adopted from the server on demand, so a daemon restart keeps managing sessions owned by a detached ghostline serve process.

func NewGhostlineRuntime

func NewGhostlineRuntime(client *ghostline.Client) *GhostlineRuntime

func (*GhostlineRuntime) Capture

func (r *GhostlineRuntime) Capture(ctx context.Context, name string) ([]byte, error)

func (*GhostlineRuntime) Check

func (r *GhostlineRuntime) Check(ctx context.Context) error

func (*GhostlineRuntime) Checkpoint added in v0.9.0

func (r *GhostlineRuntime) Checkpoint(ctx context.Context, name string) (ghostline.Checkpoint, error)

Checkpoint captures a v1 replay together with an opaque output cursor. The Service owns the reader lifecycle so it never exposes or interprets v1 output storage paths.

func (*GhostlineRuntime) Create

func (r *GhostlineRuntime) Create(ctx context.Context, name, directory, command string, env []string) error

func (*GhostlineRuntime) Exists

func (r *GhostlineRuntime) Exists(ctx context.Context, name string) bool

func (*GhostlineRuntime) Input

func (r *GhostlineRuntime) Input(ctx context.Context, name string, data []byte) error

func (*GhostlineRuntime) Kill

func (r *GhostlineRuntime) Kill(ctx context.Context, name string) error

func (*GhostlineRuntime) List

func (r *GhostlineRuntime) List(ctx context.Context) (map[string]bool, error)

func (*GhostlineRuntime) ListCreated

func (r *GhostlineRuntime) ListCreated(ctx context.Context) (map[string]time.Time, error)

func (*GhostlineRuntime) Metadata

Metadata reports the foreground process snapshot from ghostline when the server was started with ProbeForeground enabled. Older servers without the capability return empty metadata without failing the roster.

func (*GhostlineRuntime) OpenOutput added in v0.9.0

func (r *GhostlineRuntime) OpenOutput(ctx context.Context, name string, cursor ghostline.Cursor) (*ghostline.OutputReader, error)

OpenOutput creates one caller-owned v1 reader from an opaque cursor.

func (*GhostlineRuntime) Resize

func (r *GhostlineRuntime) Resize(ctx context.Context, name string, columns, rows int) error

type HTTPServer

type HTTPServer struct {
	Service       *Service
	Token         string
	Logger        *slog.Logger
	Tunnels       *tunnel.Manager
	BuildVersion  string
	BuildRevision string
	BuildDirty    bool
	// GhostlineVersion is the legacy health field and aliases the RPC version.
	GhostlineVersion string
	// GhostlineRPCVersion is the protocol version reported by the running
	// Ghostline server.
	GhostlineRPCVersion string
	// GhostlineTagVersion is the Ghostline Go module version compiled into
	// Warren.
	GhostlineTagVersion string
	CACertPath          string
	// contains filtered or unexported fields
}

func NewHTTPServer

func NewHTTPServer(service *Service, token string, logger *slog.Logger) *HTTPServer

func (*HTTPServer) Handler

func (s *HTTPServer) Handler() http.Handler

type OutputRuntime

type OutputRuntime interface {
	Runtime
	EnsurePipe(context.Context, string) error
	SpoolPath(string) string
	SpoolSize(context.Context, string) (int64, error)
	TruncateSpool(context.Context, string) error
	ArchiveSpool(context.Context, string) error
	RemoveSpool(string)
}

OutputRuntime is implemented by the tmux adapter: pipe-pane installs an idempotent raw byte pipe and the service owns one SpoolWatcher per session.

type RemoveWorkspaceOptions

type RemoveWorkspaceOptions struct {
	Force bool
	// RemoveWorktree controls whether a Git worktree directory is removed
	// together with its Warren workspace. It only applies to worktree-backed
	// workspaces; main checkouts are never deleted from disk.
	RemoveWorktree bool
}

type Runtime

type Runtime interface {
	Create(context.Context, string, string, string, []string) error
	Exists(context.Context, string) bool
	Capture(context.Context, string) ([]byte, error)
	Input(context.Context, string, []byte) error
	Resize(context.Context, string, int, int) error
	Kill(context.Context, string) error
}

type RuntimeCreatedLister

type RuntimeCreatedLister interface {
	ListCreated(context.Context) (map[string]time.Time, error)
}

RuntimeCreatedLister is implemented by the tmux adapter and lets the lifecycle loop reclaim sessions that are no longer tracked in state.

type RuntimeLister

type RuntimeLister interface {
	List(context.Context) (map[string]bool, error)
}

type Service

type Service struct {
	Store *store.Store
	// HostName is the Warren Host/system name used for the default gnar
	// account. It is injected by the daemon from --name/WARREN_HOST_NAME;
	// embedded callers may leave it empty and use os.Hostname as a fallback.
	HostName string
	// Runtime is the adapter for DefaultRuntime, kept for compatibility with
	// existing construction sites and tests.
	Runtime Runtime
	// Runtimes maps runtime kind ("ghostline", "tmux") to its adapter.
	Runtimes map[string]Runtime
	// DefaultRuntime is the engine used for sessions created without an
	// explicit kind.
	DefaultRuntime string
	// Settings holds the persisted headless settings (default runtime and
	// runtime environment overrides) and is returned by the settings API.
	Settings settings.Settings
	// SettingsPath persists settings changes made over the API.
	SettingsPath string

	// Logger receives lifecycle warnings and performance diagnostics. A nil
	// logger falls back to slog's process-wide default for warnings; optional
	// informational diagnostics stay disabled for tests and embedders.
	Logger *slog.Logger
	// ColorQuery supplies terminal foreground and background colors for
	// capability queries answered while no client is attached.
	ColorQuery   ghostline.ColorQueryCallback
	WorktreeRoot string
	// AgentFinder locates Codex/Claude transcript files. When nil, agent
	// projection is disabled and sessions behave exactly as before.
	AgentFinder agent.Finder
	// AgentHooks installs the Warren-managed Codex hook that reports the
	// CLI session ID and transcript path. Nil disables installation; the
	// finder then remains the best-effort fallback.
	AgentHooks    func() error
	MaxSpoolBytes int64
	// MaxSpoolReplayBytes bounds raw spool replay during attach. Gaps larger
	// than this fall back to a screen-resetting snapshot reanchor instead of
	// feeding tens of megabytes of raw bytes to the client's terminal. Zero
	// uses the in-memory ring byte limit.
	MaxSpoolReplayBytes int64
	RingCapacity        int
	RingMaxBytes        int
	// CommandTimeout bounds tmux commands run during attach and adoption. A
	// stuck tmux client must fail the attach and release the session broadcast
	// lock and paused output watcher instead of wedging the session until the
	// daemon restarts.
	CommandTimeout time.Duration
	// ProbeForeground enables live foreground process metadata from runtime
	// adapters that support it. Disabled by default so roster snapshots stay
	// cheap; clients fall back to launch command and workspace path.
	ProbeForeground bool
	// ClientsActive reports whether any client can observe roster snapshots.
	// The merge projection only refreshes while clients are connected; nil
	// means "always active" for tests and embedders.
	ClientsActive func() bool
	// contains filtered or unexported fields
}

func (*Service) AddProject

func (s *Service) AddProject(path, name string) (api.Project, error)

func (*Service) AddProjectWithOptions

func (s *Service) AddProjectWithOptions(path, name string, autoImportGitWorktrees bool) (api.Project, error)

AddProjectWithOptions adds a project and optionally imports every existing Git worktree for that project. The option is persisted on the Project, not in host-wide settings, so repositories can opt in independently.

func (*Service) ConfiguredGnarAccount

func (s *Service) ConfiguredGnarAccount() string

ConfiguredGnarAccount returns only a user-provided account override.

func (*Service) CreateDefaultGroupSession

func (s *Service) CreateDefaultGroupSession(ctx context.Context, command, kind, title, runtimeKind string) (api.Session, error)

CreateDefaultGroupSession creates a standalone shell in the first ordered Group, recreating Inbox when a Host has no Groups left.

func (*Service) CreateGroupSession

func (s *Service) CreateGroupSession(ctx context.Context, groupID, command, kind, title, runtimeKind string) (api.Session, error)

func (*Service) CreateSession

func (s *Service) CreateSession(ctx context.Context, workspaceID, command, kind, title, runtimeKind string) (api.Session, error)

func (*Service) CreateTerminalGroup

func (s *Service) CreateTerminalGroup(name, home string) (api.TerminalGroup, error)

func (*Service) CreateWorkspace

func (s *Service) CreateWorkspace(projectID, branch, name, path string) (api.WorkspaceCreateResult, error)

func (*Service) DeleteSession

func (s *Service) DeleteSession(ctx context.Context, id string) error

func (*Service) EffectiveGnarAccount

func (s *Service) EffectiveGnarAccount() string

EffectiveGnarAccount returns the account label Warren will pass to gnar for a bootstrap login. The value is never a credential.

func (*Service) GitCheckout

func (s *Service) GitCheckout(ctx context.Context, workspaceID, branch string, create bool) (api.GitCommandResult, error)

func (*Service) GitCommit

func (s *Service) GitCommit(ctx context.Context, workspaceID, message string) (api.GitCommandResult, error)

func (*Service) GitCreatePullRequest

func (s *Service) GitCreatePullRequest(ctx context.Context, workspaceID, title, body string) (api.GitPullRequest, error)

GitCreatePullRequest pushes the workspace branch if needed and opens a pull request against the repository's main branch.

func (*Service) GitDiff

func (s *Service) GitDiff(ctx context.Context, workspaceID, path string, staged bool, commit string) (api.GitDiff, error)

GitDiff returns the full content and unified diff of one path in a workspace, either in the working tree (staged selects the index) or for a specific commit.

func (*Service) GitPanel

func (s *Service) GitPanel(ctx context.Context, workspaceID string, fetch, force bool) (api.GitPanel, error)

func (*Service) GitPull

func (s *Service) GitPull(ctx context.Context, workspaceID string) (api.GitCommandResult, error)

func (*Service) GitPush

func (s *Service) GitPush(ctx context.Context, workspaceID string) (api.GitCommandResult, error)

func (*Service) ImportProjectWorktrees

func (s *Service) ImportProjectWorktrees(projectID string, paths []string) ([]api.Workspace, error)

ImportProjectWorktrees registers selected existing Git worktrees as workspaces. It never creates, moves, or removes a checkout on disk.

func (*Service) ListProjectWorktrees

func (s *Service) ListProjectWorktrees(projectID string) ([]api.WorktreeCandidate, error)

ListProjectWorktrees returns existing external Git worktrees for a project. Already registered worktrees stay in the result so clients can render them disabled and explain that import is a one-time operation.

func (*Service) MoveProject

func (s *Service) MoveProject(id, before string) error

MoveProject moves one project before another project (or to the end when before is empty) and renumbers the stored sidebar order.

func (*Service) MoveSession

func (s *Service) MoveSession(ctx context.Context, id, workspaceID, groupID string) (api.Session, error)

MoveSession changes the Host scope of a Session between a Workspace and a Terminal Group. The compatibility wrapper keeps existing API callers working; new callers should use MoveSessionWithExpectations.

func (*Service) MoveSessionWithExpectations

func (s *Service) MoveSessionWithExpectations(_ context.Context, id, workspaceID, groupID string, expectations SessionMoveExpectations) (api.Session, error)

MoveSessionWithExpectations performs an atomic move with optional source context guards and records a reversible operation audit entry. The runtime, working directory, output history, and Session ID are all preserved.

func (*Service) MoveTerminalGroup

func (s *Service) MoveTerminalGroup(id, before string) error

func (*Service) MoveWorkspace

func (s *Service) MoveWorkspace(id, before string) error

MoveWorkspace moves one workspace before another workspace inside the same project (or to the end when before is empty) and renumbers the stored per-project sidebar order.

func (*Service) PingOutput

func (s *Service) PingOutput(sessionID string)

func (*Service) PreflightSessionMove

func (s *Service) PreflightSessionMove(id, workspaceID, groupID string, expectations SessionMoveExpectations) (api.SessionMovePreflight, error)

PreflightSessionMove validates a move without changing durable state. It uses the same context checks as the atomic mutation path so dry-run output is actionable rather than a best-effort local guess.

func (*Service) PublicAccessEnabled

func (s *Service) PublicAccessEnabled() bool

PublicAccessEnabled reports the persisted user intent independently of the current gnar process. This distinction lets recovery retry after a daemon restart without claiming that an endpoint is already live.

func (*Service) RemoveProject

func (s *Service) RemoveProject(id string, force bool) error

func (*Service) RemoveTerminalGroup

func (s *Service) RemoveTerminalGroup(ctx context.Context, id string, force bool) error

func (*Service) RemoveWorkspace

func (s *Service) RemoveWorkspace(ctx context.Context, id string, options RemoveWorkspaceOptions) error

func (*Service) RenameProject

func (s *Service) RenameProject(id, name string) error

func (*Service) RenameSession

func (s *Service) RenameSession(id, title string) error

func (*Service) RenameTerminalGroup

func (s *Service) RenameTerminalGroup(id, name string) error

func (*Service) RenameWorkspace

func (s *Service) RenameWorkspace(id, name string) error

func (*Service) Roster

func (s *Service) Roster(ctx context.Context) api.State

func (*Service) RosterVersion

func (s *Service) RosterVersion(_ context.Context) (api.State, uint64)

func (*Service) Session

func (s *Service) Session(id string) (api.Session, bool)

func (*Service) SetAutoOpenShell

func (s *Service) SetAutoOpenShell(enabled bool) error

SetAutoOpenShell records whether opening an empty workspace creates a Shell session by default. Explicit session actions are unaffected.

func (*Service) SetAutoStartAI

func (s *Service) SetAutoStartAI(enabled bool) error

SetAutoStartAI records whether entering an empty workspace starts the first AI preset. Explicit session actions are unaffected.

func (*Service) SetDefaultRuntime

func (s *Service) SetDefaultRuntime(kind string) error

SetDefaultRuntime changes the engine used for newly created sessions while preserving the configured runtime environment overrides.

func (*Service) SetProjectAutoImportGitWorktrees

func (s *Service) SetProjectAutoImportGitWorktrees(projectID string, enabled bool) (api.Project, error)

SetProjectAutoImportGitWorktrees changes one project's automatic import policy. Enabling it also imports currently visible external worktrees once; this is deliberately non-interactive and leaves imported checkouts on disk.

func (*Service) SetProjectPinned

func (s *Service) SetProjectPinned(id string, pinned bool) error

func (*Service) SetSessionPinned

func (s *Service) SetSessionPinned(id string, pinned bool) error

func (*Service) SetTerminalGroupHome

func (s *Service) SetTerminalGroupHome(id, home string) error

func (*Service) SetWorkspacePinned

func (s *Service) SetWorkspacePinned(id string, pinned bool) error

func (*Service) Shutdown

func (s *Service) Shutdown()

func (*Service) Start

func (s *Service) Start(parent context.Context)

Start runs the single lifecycle watcher. One goroutine probes tmux for all managed sessions; it never creates a polling task per Session.

func (*Service) UndoSessionMove

func (s *Service) UndoSessionMove(operationID string) (api.Session, error)

UndoSessionMove reverts a recorded move only while the session still has the exact post-move ownership recorded by the operation. Any intervening change fails closed and leaves both state and audit history untouched.

func (*Service) UpdatePublicAccessConfig

func (s *Service) UpdatePublicAccessConfig(edge, account string) error

UpdatePublicAccessConfig persists the non-secret gnar Edge configuration. Invite and approval keys are intentionally not accepted here; they belong only to the in-memory enable request and are forwarded to gnar over stdin.

func (*Service) UpdateSettings

func (s *Service) UpdateSettings(kind string, runtimeEnv map[string]string, gnarEdge string) error

UpdateSettings changes the engine used for newly created sessions and the runtime environment overrides and the gnar edge, persisting them when a settings file is configured. Existing sessions keep their own runtimeKind.

func (*Service) UpdateTunnelEnabled

func (s *Service) UpdateTunnelEnabled(kind string, enabled bool) error

UpdateTunnelEnabled records whether a reachability adapter should be restored after a daemon restart, persisting the intent when a settings file is configured. A tunnel that fails to start still keeps its intent so the next daemon retries; only an explicit stop clears it.

type SessionMoveExpectations

type SessionMoveExpectations struct {
	WorkspaceID    *string
	AgentSessionID *string
}

SessionMoveExpectations are optional compare-and-swap guards. A nil pointer means the caller did not observe that piece of source context and therefore does not ask the Host to guard it. A non-nil pointer, including an empty string, is an explicit expectation.

type SpoolRecoverer

type SpoolRecoverer interface {
	Recover(context.Context, string, int64, int64) ([]byte, error)
}

SpoolRecoverer serves raw spool bytes when the in-memory ring no longer retains a client's anchor. The ghostline adapter implements it through the session handle; the tmux adapter does not.

Jump to

Keyboard shortcuts

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