server

package
v0.38.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 49 Imported by: 0

Documentation

Overview

syscall.Flock is absent on solaris and aix, so `unix` alone claims two platforms this file cannot compile on. Excluding them says what is true; making them work would mean x/sys/unix.Flock, which neither shipped image needs.

Package server implements the aeman HTTP server: the embedded single-page application, the /api/v1 resource API and watch stream, the MCP transport, and the board store over the board's git repositories. The browser never holds a credential: identity is resolved server-side (the owner of the credential a local run resolved, or per-user OAuth sessions) and the push credential is the server's.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DataDirHold added in v0.33.0

func DataDirHold(dir string) (io.Closer, error)

DataDirHold takes the claim on a data directory and keeps it until the returned value is closed. A caller about to configure a long-running process holds it just long enough to learn the directory is free, then closes it; the answer is advisory, since it goes stale the moment it is given and the daemon takes the claim for real at its own start.

Types

type GitBackend added in v0.26.0

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

GitBackend is a git-mode store without an HTTP server — what `aeman mcp --repo` runs on: its own clone, cache, queue and push.

func OpenGitBackend added in v0.26.0

func OpenGitBackend(cfg *GitConfig, log *slog.Logger) (*GitBackend, error)

OpenGitBackend clones or reopens the configured repository and returns a backend over it. log may be nil.

func (*GitBackend) AttachPersonal added in v0.26.0

func (g *GitBackend) AttachPersonal(ctx context.Context, login, token string) error

AttachPersonal attaches the login's personal repository, if the primary links one, using token to clone and push — what `aeman mcp` does for the local user at start, the way the HTTP server does for each visitor.

func (*GitBackend) Backend added in v0.26.0

func (g *GitBackend) Backend() boardservice.Backend

Backend is the boardservice.Backend to build a service on.

func (*GitBackend) Close added in v0.33.0

func (g *GitBackend) Close() error

Close releases this process's claim on the data directory, so the next `aeman serve` or `aeman mcp` may open the clones. It does not stop the background sync, so it belongs on a process's way out rather than mid-life.

func (*GitBackend) Drain added in v0.26.0

func (g *GitBackend) Drain(ctx context.Context) error

Drain waits for the write queue and pushes — what a stdio MCP process does before it exits, so a client that closes the pipe right after a mutation loses nothing. It reports a queue that did not empty as an ERROR rather than pushing on in silence: what is left never became a commit and does not survive this process, so a caller that logs the error is the only thing standing between a lost change and nobody knowing.

func (*GitBackend) UnpushedAge added in v0.33.0

func (g *GitBackend) UnpushedAge() time.Duration

UnpushedAge is how long the oldest commit this process has failed to push has been waiting; zero when everything has landed. A stdio process lived one editor session and reported a failed push on the client's stderr; a daemon runs unattended for weeks, so this is what tells one that is working apart from one whose credential died a week ago.

type GitConfig added in v0.26.0

type GitConfig struct {
	// Repos are the board's domains, primary first. Only the primary is
	// served for now.
	Repos []RepoSpec
	// Token is the push/fetch credential (HTTPS basic auth) for the
	// repositories that name none of their own; empty means an
	// unauthenticated transport (local file remotes, tests).
	Token string
	// App mints the server credential per repository from a GitHub App
	// installation instead of a static token: nothing to issue by hand,
	// nothing that quietly expires in a .env file. A repository that names
	// its own Token keeps it; the App covers the rest. GitHub only.
	App *forge.GitHubApp
	// Forge is the code host the repositories live on: it says how the
	// token travels over HTTPS (the basic-auth username differs per forge).
	// GitHub when nil.
	Forge forge.Forge
	// DataDir holds the clones (<DataDir>/repos/<name>).
	DataDir string
	// History is the background deepening horizon; zero disables it.
	History time.Duration
	// HistoryMax caps on-demand deepening — a card's log cut by the horizon
	// fetches back to the card's creation, but never further than this.
	// Zero means no on-demand deepening.
	HistoryMax time.Duration
	// SyncInterval is the fetch cadence; zero disables the ticker.
	SyncInterval time.Duration
	// UnpushedWarn is the age of the oldest unpushed commit that turns
	// health red; zero means 5 minutes.
	UnpushedWarn time.Duration
	Committer    gitstore.Identity
	// AuthorEmail is the author email template ("{login}" substituted);
	// empty means <login>@aeman.
	AuthorEmail string
}

GitConfig enables git mode.

type OAuthConfig

type OAuthConfig struct {
	ClientID     string
	ClientSecret string
	// BaseURL is the public origin (e.g. https://aeman.example.com) used to
	// build the OAuth redirect URI.
	BaseURL string
	// Scopes is a space-separated OAuth scope list (defaults to the forge's).
	Scopes string
	// SessionFile, when set, persists the dynamic MCP client registry to this
	// path so registered clients survive restarts. GitHub tokens (sessions) are
	// written here only when SessionKey is set — encrypted — so without a key a
	// restart signs users out but leaks no credentials to disk.
	SessionFile string
	// SessionKey, when set, is a secret that encrypts the persisted sessions at
	// rest (AES-256-GCM, key = SHA-256 of this value). With it, sessions and
	// MCP tokens survive a restart; the on-disk file holds only ciphertext, so
	// a leak of the file alone (backup, stray volume) exposes no token. Empty =
	// sessions stay in memory only (signed out on restart).
	SessionKey string
}

OAuthConfig enables multi-user mode: each visitor signs in with GitHub and the proxy forwards requests with that user's own token.

type Options

type Options struct {
	// Addr is the listen address, e.g. "127.0.0.1:8765".
	Addr string
	// Version is reported to the frontend via /api/config.
	Version string
	// Logger receives structured logs; slog.Default() is used when nil.
	Logger *slog.Logger
	// Auth, when non-nil, enables OAuth multi-user mode: each visitor signs
	// in with the forge, and their own token decides which of the board's
	// repositories they may read and write.
	Auth *OAuthConfig
	// Git is the board's storage — its repositories (see gitmode.go). A
	// server without it serves no board; tests inject a service instead.
	Git *GitConfig
	// Forge is the code host behind the board — the identity provider,
	// the authority on repository access, the directory of names and
	// avatars, the git credential's dialect. GitHub when nil.
	Forge forge.Forge
	// CLI is where a single-user server reads its credential and the
	// person it belongs to — the environment, the OS keychain, or the
	// forge's own tool; the gh CLI when nil. Unused in OAuth mode.
	CLI forge.CLI
}

Options configures a Server.

type RepoSpec added in v0.26.0

type RepoSpec struct {
	Name string
	URL  string
	// Token is this repository's own credential — a board may span two
	// organisations, and one token narrow enough for either cannot reach
	// both. Empty falls back to GitConfig.Token.
	Token string
}

RepoSpec names one domain: a repository and its label.

type Server

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

Server is the aeman local HTTP server.

func New

func New(opts Options) (*Server, error)

New builds a Server from the given options.

func (*Server) Close added in v0.33.0

func (s *Server) Close() error

Close releases the server's claim on its data directory, so the next `aeman serve` or `aeman mcp` may open the board's clones. It does not stop the background sync, so it belongs on a process's way out rather than mid-life. A server built without git mode holds no directory and Close does nothing.

func (*Server) Run

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

Run starts the server and blocks until ctx is cancelled or it fails.

func (*Server) URL

func (s *Server) URL() string

URL returns the address the server can be reached on in a browser.

Jump to

Keyboard shortcuts

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