localbackend

package
v0.1.2 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: 24 Imported by: 0

Documentation

Overview

Package localbackend supervises the open-source Convex backend that a local-mode Project runs on loopback.

The coordination engine lives in Convex functions (ADR-072), so a Project that never leaves the member's machine still needs a backend speaking the same /v1 contract as Overgent Cloud. The bundled binary is the Convex release's own build for this platform, so the same supervision works on macOS, Linux, and Windows; only the executable's name differs.

This package starts the bundled binary, deploys the release-time function bundle to it, and keeps it alive while the service runs. Everything above the wire is unchanged.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BinaryName added in v0.1.1

func BinaryName() string

BinaryName is what the backend executable is called on this platform.

Every path Overgent builds to the backend - the desktop's Resources directory, the CLI's install hint, the release workflow's fetch output - has to agree with what the archive actually contains, and the Windows archive contains convex-local-backend.exe. Nothing else about the binary changes.

func Configured

func Configured(root string) bool

Configured reports whether this profile has a backend to manage at all. A team-mode profile has no backend.json and must never start one.

func Install

func Install(root, binaryPath, bundlePath string) error

Install records where the backend binary and the release-time deploy payload live. The desktop calls it on every launch so an app update moves the paths; a CLI-only install calls `overgent backend install`.

func IsLoopbackOrigin

func IsLoopbackOrigin(origin string) bool

IsLoopbackOrigin reports whether this origin is served by a backend running on this machine. The rule itself now lives in internal/config, because that is where a Project's backend kind is decided when the binding is written; this stays as the name every existing caller already asks it by.

func StatePath

func StatePath(root string) string

StatePath is where Install and the desktop write the bundle paths.

func Supported added in v0.1.1

func Supported() bool

Supported reports whether this machine has a pinned backend binary at all. A machine without one (Windows on ARM) can still run Overgent against a hosted backend; it just cannot run local mode.

func Verify

func Verify(ctx context.Context, binaryPath, bundlePath string) error

Verify replays a freshly built deploy payload against a fresh backend and reports whether it worked.

This is the release gate for the bundled backend. The deploy2 endpoints are internal Convex detail, so a backend or CLI bump can change the wire shape without any announcement; running the actual Go replay against the actual binary at release time is what keeps a broken pin from reaching a member as an app that starts and then coordinates nothing.

Types

type CredentialStore

type CredentialStore interface {
	Put(context.Context, string, string) error
	Get(context.Context, string) (string, error)
	Delete(context.Context, string) error
}

CredentialStore is the macOS Keychain, or a fake in tests. It mirrors onboarding.CredentialStore rather than importing it, so neither package depends on the other.

type Endpoint

type Endpoint struct {
	Origin     string `json:"origin"`
	SiteOrigin string `json:"siteOrigin"`
}

Endpoint is where a client reaches this backend. Origin serves the admin and deploy2 routes; SiteOrigin serves the Convex HTTP actions, which is where Overgent's own /v1 contract lives, so that is the API base URL a local Project is created against.

type Keychain

type Keychain struct{}

Keychain is the production credential store: the backend's instance secret and the deployment secrets key live in the macOS Keychain, never in a file under the profile root (docs/security-privacy.md, "Local").

func (Keychain) Delete

func (Keychain) Delete(ctx context.Context, account string) error

func (Keychain) Get

func (Keychain) Get(ctx context.Context, account string) (string, error)

func (Keychain) Put

func (Keychain) Put(ctx context.Context, account, secret string) error

type Manager

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

Manager owns one profile's backend process.

func New

func New(root string, creds CredentialStore, logger *slog.Logger) (*Manager, error)

New opens the manager for a profile root. It does not start anything.

func (*Manager) Ensure

func (m *Manager) Ensure(ctx context.Context) (Endpoint, error)

Ensure brings the backend up and the deployed bundle in step with the one shipped in the app, and returns where clients should reach it.

It is idempotent and adoption-based: a healthy backend already listening on the recorded ports under this profile's instance name is used as it is, whether this process started it or a previous one did. That is what lets the desktop ask the CLI to start the backend before the service exists, and the service then take over supervision without a restart.

func (*Manager) Export

func (m *Manager) Export(directory string) (string, error)

Export copies the stopped database out of the profile. It is deliberately minimal: the portable, backend-independent export is the /v1 owner export, which works against any backend; this is the "give me the file" answer.

func (*Manager) Reset

func (m *Manager) Reset(ctx context.Context) error

Reset stops the backend and deletes its database and file storage, keeping the recorded artifact paths so the next Ensure starts a fresh instance.

func (*Manager) SetArtifacts

func (m *Manager) SetArtifacts(binaryPath, bundlePath string) error

SetArtifacts validates and persists the two absolute artifact paths.

func (*Manager) Status

func (m *Manager) Status(ctx context.Context) Status

Status reports what the menu, `health`, and `overgent backend status` show.

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context) error

Stop asks the backend to exit, waits, and kills it if it does not.

func (*Manager) Touch

func (m *Manager) Touch()

Touch marks coordination activity. It feeds the idle timer only; the backend is otherwise kept running for as long as the service runs.

type State

type State struct {
	Version        string `json:"version"`
	BundleRevision string `json:"bundleRevision"`
	Port           int    `json:"port"`
	SitePort       int    `json:"sitePort"`
	InstanceName   string `json:"instanceName"`
	BinaryPath     string `json:"binaryPath"`
	BundlePath     string `json:"bundlePath"`
	PID            int    `json:"pid"`
}

State is <root>/backend/backend.json. It is deliberately a sibling of config.json, not a field inside it, so config.json can be reshaped without touching backend state.

type Status

type Status struct {
	Running        bool   `json:"running"`
	PID            int    `json:"pid,omitempty"`
	Port           int    `json:"port,omitempty"`
	SitePort       int    `json:"sitePort,omitempty"`
	Origin         string `json:"origin,omitempty"`
	SiteOrigin     string `json:"siteOrigin,omitempty"`
	Version        string `json:"version,omitempty"`
	BundleRevision string `json:"bundleRevision,omitempty"`
	DatabasePath   string `json:"databasePath,omitempty"`
	DatabaseBytes  int64  `json:"databaseBytes,omitempty"`
	LastError      string `json:"lastError,omitempty"`
	IdleSince      string `json:"idleSince,omitempty"`
}

Status is what `health` and `overgent backend status` report. InstanceName is absent: it names the Keychain item holding the instance secret, and diagnostics carries backend.json minus that field.

Jump to

Keyboard shortcuts

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