server

package
v1.38.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: AGPL-3.0 Imports: 61 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConnectOptions

func ConnectOptions(registry interceptors.ErrorRecorder) []connect.HandlerOption

ConnectOptions returns standard ConnectRPC options with OpenTelemetry instrumentation and optional SQLite error recording. Pass a non-nil registry to persist RPC errors.

func LoadTLSConfig

func LoadTLSConfig(certFile, keyFile string) (*tls.Config, error)

LoadTLSConfig returns a *tls.Config from the given certificate files.

Types

type BuildOptions added in v1.35.0

type BuildOptions struct {
	// EntClient supplies a pre-opened *ent.Client, bypassing config-based DB path
	// discovery and schema migration. nil = open from config as usual.
	EntClient *ent.Client
}

BuildOptions carries optional overrides for BuildCoreDepsWithOptions. The zero value uses all defaults (equivalent to calling BuildCoreDeps).

type CoreDeps

type CoreDeps struct {
	SessionService *services.SessionService
	Storage        *session.Storage
	EventBus       *events.EventBus
	ReviewQueue    *session.ReviewQueue
	ApprovalStore  *services.ApprovalStore
	ErrorRegistry  *services.ErrorRegistry
}

CoreDeps holds the foundational dependencies created during Phase 1. These have no external prerequisites and form the base for all other components.

func BuildCoreDeps

func BuildCoreDeps() (*CoreDeps, error)

BuildCoreDeps constructs Phase 1 dependencies using config defaults. It is a thin wrapper around BuildCoreDepsWithOptions(BuildOptions{}).

func BuildCoreDepsWithOptions added in v1.35.0

func BuildCoreDepsWithOptions(opts BuildOptions) (*CoreDeps, error)

BuildCoreDepsWithOptions constructs Phase 1 dependencies with optional overrides. Use BuildOptions to inject a pre-built EntClient (for tests).

type FilterProvider

type FilterProvider interface {
	GetPriorityFilter() []session.Priority
	GetReasonFilter() []session.AttentionReason
	GetSessionIDs() []string
	GetIncludeStatistics() bool
	GetInitialSnapshot() bool
}

FilterProvider is an interface that provides filter values for type-safe conversion

type ReactiveQueueManager

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

ReactiveQueueManager manages the review queue with immediate reactivity to user interactions. It listens to interaction events and immediately re-evaluates the queue instead of waiting for the next poll cycle, providing <100ms feedback to users.

func NewReactiveQueueManager

func NewReactiveQueueManager(
	queue *session.ReviewQueue,
	poller *session.ReviewQueuePoller,
	eventBus *events.EventBus,
	statusManager *session.InstanceStatusManager,
	storage *session.Storage,
) *ReactiveQueueManager

NewReactiveQueueManager creates a new reactive queue manager.

func (*ReactiveQueueManager) AddStreamClient

func (rqm *ReactiveQueueManager) AddStreamClient(ctx context.Context, filtersInterface interface{}) (<-chan *sessionv1.ReviewQueueEvent, string)

AddStreamClient adds a new streaming client for WatchReviewQueue.

func (*ReactiveQueueManager) OnControllerStatusChange added in v1.35.0

func (rqm *ReactiveQueueManager) OnControllerStatusChange(inst *session.Instance, _ detection.DetectedStatus)

OnControllerStatusChange is called by a ClaudeController's status-change goroutine when it detects a terminal status transition. Safe to call from any goroutine.

func (*ReactiveQueueManager) OnItemAdded

func (rqm *ReactiveQueueManager) OnItemAdded(item *session.ReviewItem)

OnItemAdded is called when an item is added to the queue.

func (*ReactiveQueueManager) OnItemRemoved

func (rqm *ReactiveQueueManager) OnItemRemoved(sessionID string)

OnItemRemoved is called when an item is removed from the queue.

func (*ReactiveQueueManager) OnQueueUpdated

func (rqm *ReactiveQueueManager) OnQueueUpdated(items []*session.ReviewItem)

OnQueueUpdated is called when the queue is updated.

func (*ReactiveQueueManager) RemoveStreamClient

func (rqm *ReactiveQueueManager) RemoveStreamClient(clientID string)

RemoveStreamClient removes a streaming client.

func (*ReactiveQueueManager) Start

func (rqm *ReactiveQueueManager) Start(ctx context.Context)

Start initializes the reactive queue manager and subscribes to events.

func (*ReactiveQueueManager) Stop

func (rqm *ReactiveQueueManager) Stop()

Stop stops the reactive queue manager.

type RuntimeDeps

type RuntimeDeps struct {
	*ServiceDeps
	Instances               []*session.Instance
	ReactiveQueueMgr        *ReactiveQueueManager
	ScrollbackManager       *scrollback.ScrollbackManager
	TmuxStreamerManager     *session.ExternalTmuxStreamerManager
	ExternalDiscovery       *session.ExternalSessionDiscovery
	ExternalApprovalMonitor *session.ExternalApprovalMonitor
	PRStatusPoller          *session.PRStatusPoller
	HistoryLinker           *session.HistoryLinker
	ErrorRegistry           *services.ErrorRegistry

	// Unfinished work scanning.
	UnfinishedScanner     *unfinished.Scanner
	UnfinishedStateStore  *unfinished.StateStore
	UnfinishedWorkService *services.UnfinishedWorkService
	WorktreePRPoller      *session.WorktreePRPoller

	// GitHub user PR cache and service.
	UserPRCache       *githubpkg.UserPRCache
	GitHubUserService *services.GitHubUserService

	// Token usage analytics.
	InsightsService *services.InsightsService

	BacklogService *services.BacklogService
	SyncLoop       *session.SyncLoop
	Config         *config.Config // Used for encryption of sensitive data

	// Analytics storage.
	AnalyticsEntClient *ent.Client

	// VNCDeps holds the result of the startup VNC dependency check.
	VNCDeps vnc.DepsResult

	// CDPDeps holds the result of the startup CDP (Chrome) dependency check.
	CDPDeps cdp.DepsResult

	// HeadlessPool manages headless LLM calling. Nil when claude binary is not found.
	HeadlessPool *headless.Pool

	// WorkflowRepo persists workflow definitions.
	WorkflowRepo session.WorkflowRepository

	// WorkflowScheduler manages cron-based workflow execution.
	WorkflowScheduler *workflows.Scheduler

	// Registry is the live-handle map for all running sessions.
	Registry *session.Registry
}

RuntimeDeps holds Phase 3 dependencies: runtime components that involve process creation, filesystem I/O, and callback wiring.

func BuildRuntimeDeps

func BuildRuntimeDeps(_ tmux.TmuxServerReady, svc *ServiceDeps, cfg *config.Config) (*RuntimeDeps, error)

BuildRuntimeDeps constructs Phase 3 dependencies using Phase 2 outputs. This implements steps 5-12 from the original BuildDependencies:

  • Step 5: LoadInstances + wire ReviewQueue/StatusManager on each instance
  • Step 6: Start tmux sessions for loaded instances (non-fatal failures)
  • Step 6.5: Persist auto-detected worktree info
  • Step 7: Start controllers for running instances
  • Step 7.5: Startup scan + orphaned approval sync
  • Step 8: ReactiveQueueManager + wire into SessionService
  • Step 9: ScrollbackManager (independent)
  • Step 10: TmuxStreamerManager (independent)
  • Step 11: ExternalDiscovery with session-added/removed callbacks
  • Step 12: ExternalApprovalMonitor with approval-to-review-queue bridge
  • SetExternalDiscovery on SessionService (moved from server.go)

BuildRuntimeDeps requires a TmuxServerReady token to enforce that tmux.EnsureServerRunning was called before sessions are loaded. Without this ordering, DoesSessionExist() may trigger recoverFromServerFailure, which starts a fresh server that considers all sessions non-existent and cold-restores them. cfg may be nil; when non-nil, is used for token encryption in backlog sources.

func (*RuntimeDeps) ToServerDeps added in v1.35.0

func (rt *RuntimeDeps) ToServerDeps() *ServerDependencies

ToServerDeps converts RuntimeDeps to the flat ServerDependencies struct consumed by NewServerWithDeps. This mirrors the projection done inside BuildDependencies.

type Server

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

Server manages the HTTP server with ConnectRPC handlers.

func NewServer

func NewServer(addr string) *Server

NewServer creates a new HTTP server instance with SessionService registered.

Initialization Order (dependencies flow downward):

  1. SessionService — creates Storage (Ent-backed), EventBus, ReviewQueue
  2. StatusManager — depends on nothing; created before instances load
  3. ReviewQueuePoller — depends on ReviewQueue, StatusManager, Storage
  4. Instance wiring — LoadInstances, SetReviewQueue + SetStatusManager on each
  5. Instance.Start() — starts tmux sessions; requires wired dependencies
  6. Controller startup — requires started instances and StatusManager
  7. ReactiveQueueMgr — depends on ReviewQueue, Poller, EventBus, StatusManager, Storage
  8. ScrollbackManager — independent; depends only on filesystem paths
  9. TmuxStreamerManager — independent

11. ExternalDiscovery — depends on Storage, ReviewQueue, StatusManager, Poller (via callbacks) 12. ExternalApprovalMonitor — depends on ExternalDiscovery

Violating this order causes nil pointer panics or silent failures. Dependency construction is encapsulated in BuildDependencies (server/dependencies.go). See docs/tasks/architecture-refactor.md for the ongoing simplification plan.

func NewServerWithDeps added in v1.35.0

func NewServerWithDeps(addr string, deps *ServerDependencies) *Server

NewServerWithDeps creates a Server using pre-built dependencies. Use this when deps are constructed externally (e.g. via Warren lifecycle phases) so the build phases can be observed and timed independently.

func (*Server) GetAddr

func (s *Server) GetAddr() string

GetAddr returns the server address.

func (*Server) GetHostnames

func (s *Server) GetHostnames() []string

GetHostnames returns the detected LAN hostnames.

func (*Server) GetOrigins

func (s *Server) GetOrigins() []string

GetOrigins returns the allowed CORS origins.

func (*Server) Mux

func (s *Server) Mux() *http.ServeMux

Mux returns the HTTP request multiplexer so callers can register additional routes before calling Start().

func (*Server) RegisterConnectHandler

func (s *Server) RegisterConnectHandler(path string, handler http.Handler)

RegisterConnectHandler registers a ConnectRPC service handler. This should be called before Start().

func (*Server) RegisterHTTPHandler

func (s *Server) RegisterHTTPHandler(pattern string, handler http.Handler)

RegisterHTTPHandler registers a standard HTTP handler. Useful for health checks, static files, etc.

func (*Server) SetHTTPSURL

func (s *Server) SetHTTPSURL(url string)

SetHTTPSURL records the public HTTPS URL for this server (used by /api/server-info). Call this after remote access is configured in main.go.

func (*Server) SetHostnames

func (s *Server) SetHostnames(hostnames []string)

SetHostnames records the detected LAN hostnames for this server.

func (*Server) SetOrigins

func (s *Server) SetOrigins(origins []string)

SetOrigins records the allowed CORS origins.

func (*Server) SetupAuth

func (s *Server) SetupAuth(authMiddleware func(http.Handler) http.Handler)

SetupAuth installs authentication middleware. Must be called before Start(). authMiddleware is a function that wraps an http.Handler; pass nil to disable.

func (*Server) SetupTLS

func (s *Server) SetupTLS(cfg *tls.Config)

SetupTLS configures the server to use TLS with the provided tls.Config. Must be called before Start().

func (*Server) Shutdown

func (s *Server) Shutdown() error

Shutdown gracefully shuts down the HTTP server.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start starts the HTTP server with middleware chain. This is a blocking call. Use Start() in a goroutine for concurrent operation.

func (*Server) StartRemote

func (s *Server) StartRemote(ctx context.Context, remoteAddr string, tlsCfg *tls.Config, authMW func(http.Handler) http.Handler) error

StartRemote starts a second HTTPS server on remoteAddr, sharing the same route mux as the local server but protected by TLS and auth middleware. It binds eagerly (returns a bind error immediately if the port is in use), then runs the server in a background goroutine until ctx is cancelled.

type ServerDependencies

type ServerDependencies struct {
	SessionService          *services.SessionService
	Storage                 *session.Storage
	Instances               []*session.Instance
	EventBus                *events.EventBus
	StatusManager           *session.InstanceStatusManager
	ReviewQueue             *session.ReviewQueue
	ReviewQueuePoller       *session.ReviewQueuePoller
	PRStatusPoller          *session.PRStatusPoller
	ReactiveQueueMgr        *ReactiveQueueManager
	ScrollbackManager       *scrollback.ScrollbackManager
	TmuxStreamerManager     *session.ExternalTmuxStreamerManager
	ExternalDiscovery       *session.ExternalSessionDiscovery
	ExternalApprovalMonitor *session.ExternalApprovalMonitor
	HistoryLinker           *session.HistoryLinker
	ErrorRegistry           *services.ErrorRegistry

	// Unfinished work scanning.
	UnfinishedScanner     *unfinished.Scanner
	UnfinishedStateStore  *unfinished.StateStore
	UnfinishedWorkService *services.UnfinishedWorkService
	WorktreePRPoller      *session.WorktreePRPoller

	// GitHub user PR cache and service. Nil when no GitHub token is available.
	UserPRCache       *githubpkg.UserPRCache
	GitHubUserService *services.GitHubUserService

	// Token usage analytics.
	InsightsService *services.InsightsService

	BacklogService *services.BacklogService
	SyncLoop       *session.SyncLoop

	// Analytics storage. Nil when the analytics DB failed to open (LogAnalyticsProvider
	// is used as a fallback in that case).
	AnalyticsEntClient *ent.Client

	// VNCDeps holds the result of the startup VNC dependency check.
	// Available=false means the Browser tab will be hidden on all sessions.
	VNCDeps vnc.DepsResult

	// CDPDeps holds the result of the startup CDP (Chrome) dependency check.
	// Available=false means CDP browser streaming is unavailable on this host.
	CDPDeps cdp.DepsResult

	// HeadlessPool manages headless LLM calls. Nil when the claude binary is not found.
	HeadlessPool *headless.Pool

	// WorkflowRepo persists workflow definitions.
	WorkflowRepo session.WorkflowRepository

	// WorkflowScheduler manages cron-based workflow execution.
	WorkflowScheduler *workflows.Scheduler

	// Registry is the live-handle map for all running sessions.
	Registry *session.Registry
}

ServerDependencies holds all wired service components for the HTTP server. Use BuildDependencies to construct and wire them in the correct order. See the initialization order comment on NewServer for dependency constraints.

func BuildDependencies

func BuildDependencies() (*ServerDependencies, error)

BuildDependencies constructs and wires all server dependencies in the correct order. Returns an error only for unrecoverable failures (SessionService init, Storage start). Non-fatal failures (individual instance start) are logged and skipped.

Delegates to the three-phase constructors: BuildCoreDeps -> BuildServiceDeps -> BuildRuntimeDeps.

type ServiceDeps

type ServiceDeps struct {
	*CoreDeps
	StatusManager     *session.InstanceStatusManager
	ReviewQueuePoller *session.ReviewQueuePoller
	PRStatusPoller    *session.PRStatusPoller
	Registry          *session.Registry
}

ServiceDeps holds Phase 2 dependencies: management components that depend on CoreDeps.

func BuildServiceDeps

func BuildServiceDeps(core *CoreDeps) (*ServiceDeps, error)

BuildServiceDeps constructs Phase 2 dependencies using Phase 1 outputs. Compile-time guarantee: cannot be called without a *CoreDeps.

type TLSPaths

type TLSPaths struct {
	CertFile string
	KeyFile  string
	CAFile   string
}

TLSPaths holds the file paths for the generated TLS certificate set.

func EnsureTLSCerts

func EnsureTLSCerts(hostnames []string) (*TLSPaths, error)

EnsureTLSCerts ensures a stable CA exists and issues/reissues a server certificate when the SAN list changes or the server cert nears expiry.

The CA is intentionally kept stable across SAN changes so that phones only need to import it once. Only the server cert (signed by the stable CA) is replaced when hostnames change — the CA file on disk is never overwritten unless it is missing or within 30 days of expiry.

type WatchReviewQueueFilters

type WatchReviewQueueFilters struct {
	PriorityFilter    []session.Priority
	ReasonFilter      []session.AttentionReason
	SessionIDs        []string
	IncludeStatistics bool
	InitialSnapshot   bool
}

WatchReviewQueueFilters contains filters for review queue event streaming

Directories

Path Synopsis
Package analytics provides the provider interface and implementations for recording analytics events from the stapler-squad web UI and backend.
Package analytics provides the provider interface and implementations for recording analytics events from the stapler-squad web UI and backend.
Package featureregistry is the Go counterpart of the TypeScript feature catalog.
Package featureregistry is the Go counterpart of the TypeScript feature catalog.
Package mcp: thin-client stdio proxy.
Package mcp: thin-client stdio proxy.
Package services provides the server-side service implementations.
Package services provides the server-side service implementations.
Package workflows provides the WorkflowScheduler for cron-based session automation.
Package workflows provides the WorkflowScheduler for cron-based session automation.

Jump to

Keyboard shortcuts

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