webui

package
v0.152.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package webui installs, selects and serves the compiled DataTug web app (the public archives of github.com/datatug/web-ui) from the CLI's own HTTP server.

Spec: datatug/backstage spec/features/local-frontend-distribution (decision 0006). An archive is a gzip tar of manifest.json plus the static app under browser/; it is verified file by file against the manifest before it becomes visible under the installed-versions directory, and the CLI activates it only when both sides of the compatibility contract hold (see Compatible).

Index

Constants

View Source
const (
	ManifestFile  = "manifest.json"
	SignatureFile = "manifest.json.sig"
	BrowserDir    = "browser"
	IndexFile     = BrowserDir + "/index.html"
)

ManifestFile and IndexFile are the two paths every archive must hold.

View Source
const AgentPathPrefix = "/datatug/"

AgentPathPrefix is where the agent API lives; the handler never answers under it.

View Source
const DefaultReleaseRepo = "datatug/web-ui"

DefaultReleaseRepo is the public repository of compiled frontend releases.

View Source
const DirEnv = "DATATUG_WEB_UI_DIR"

DirEnv overrides where installed web UIs live.

View Source
const LocalAPIVersion = "1.0"

LocalAPIVersion is the version of the agent's local HTTP API contract that this CLI serves (major.minor). Bump the minor for additive changes, the major when a route is removed or changes meaning: every frontend that declares "<major" is then refused cleanly instead of half-working.

View Source
const ManifestName = "datatug-web-ui"

ManifestName is the name every DataTug web UI archive declares.

View Source
const ManifestSchema = "datatug-web-ui/1"

ManifestSchema is the only manifest schema this CLI reads.

View Source
const MinFrontendVersion = "0.1.0"

MinFrontendVersion is the oldest frontend this CLI will serve. It is a security/bug floor, bumped only when an older frontend must never run against this CLI again; ordinary compatibility is the frontend's own requires.localApi range.

View Source
const SignatureFormat = "datatug-web-ui-signature/1"

SignatureFormat is the first field of manifest.json.sig:

datatug-web-ui-signature/1 ed25519 <key id> <base64 signature>

The signature is Ed25519 over the exact bytes of manifest.json. The manifest lists the size and SHA-256 of every file, so a valid signature vouches for the whole archive.

Variables

View Source
var ErrIncompatible = errors.New("web UI is not compatible with this DataTug CLI")

ErrIncompatible marks a frontend that is installed but cannot be served by this CLI.

View Source
var ErrNotInstalled = errors.New("no DataTug web UI is installed")

ErrNotInstalled is returned when no web UI is installed.

View Source
var ErrUnsigned = errors.New("the archive is not signed by a DataTug release key")

ErrUnsigned is returned for an archive with no valid signature from a trusted key, when one is required.

Functions

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions compares two valid versions like semver.Compare.

func Compatible

func Compatible(m Manifest) error

Compatible checks both sides of the compatibility contract.

func IsPrerelease

func IsPrerelease(v string) bool

IsPrerelease reports whether v carries a pre-release part.

func KeyID added in v0.147.0

func KeyID(pub []byte) string

KeyID names a public key: the first 16 hex characters of its SHA-256.

func ParseDigest

func ParseDigest(s string) (string, error)

ParseDigest reads a digest in any of the forms people paste: bare hex, "sha256:<hex>", or a sha256sum line "<hex> <file>".

func SidecarDigest

func SidecarDigest(archive string) (digest string, ok bool, err error)

SidecarDigest reads <archive>.sha256 when it exists. ok is false when there is none.

func UseTrustedKeys added in v0.147.0

func UseTrustedKeys(encoded ...string) (restore func(), err error)

UseTrustedKeys replaces the trusted release keys (raw Ed25519 public keys, base64) and returns a function that restores the previous ones. With no keys, unsigned archives install. It exists for tests of code that installs archives; it is compiled-in API only, never configuration a user or environment can set.

func ValidVersion

func ValidVersion(v string) bool

ValidVersion reports whether v is a SemVer 2.0 version without a leading "v".

Types

type BuildInfo

type BuildInfo struct {
	Commit string `json:"commit,omitempty"`
	Date   string `json:"date,omitempty"`
	Source string `json:"source,omitempty"`
}

BuildInfo says where an archive was built from. It is informational.

type Candidate

type Candidate struct {
	Manifest   Manifest
	ArchiveURL string
	DigestURL  string
}

Candidate is a release chosen for download.

type DigestSource

type DigestSource string

DigestSource says where the expected archive digest came from: the honest answer to "who vouches for this archive" until releases are signed.

const (
	DigestFromFlag    DigestSource = "--sha256 flag"
	DigestFromSidecar DigestSource = "sidecar .sha256 file"
	DigestFromRelease DigestSource = "GitHub release over HTTPS"
	DigestNone        DigestSource = "none — integrity of contents only"
)

type Entry

type Entry struct {
	Version  string
	Dir      string
	Manifest Manifest
	// Incompatible is why this CLI will not serve it; nil when it can.
	Incompatible error
}

Entry is one installed version.

type Handler

type Handler struct {

	// InlineHandlers counts inline event-handler attributes the CSP blocks.
	InlineHandlers int
	// contains filtered or unexported fields
}

Handler serves one installed web UI.

func NewHandler

func NewHandler(opts HandlerOptions) (*Handler, error)

NewHandler reads the version's index.html, injects the runtime config and builds the CSP.

func (*Handler) CSP

func (h *Handler) CSP() string

CSP is the Content-Security-Policy every response carries.

func (*Handler) Close

func (h *Handler) Close() error

Close releases the directory handle.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type HandlerOptions

type HandlerOptions struct {
	// Dir is an installed version's directory (holding browser/).
	Dir     string
	Runtime RuntimeConfig
	// ConnectSrc are extra origins the page may reach (CSP connect-src), from --ui-connect-src.
	ConnectSrc []string
}

HandlerOptions configure the static web UI handler.

type InstallOptions

type InstallOptions struct {
	// ExpectedSHA256 is the archive's expected digest, lowercase hex. "" checks none.
	ExpectedSHA256 string
	Source         DigestSource
	// AllowUnsigned installs an archive with no signature from a trusted release key (a local or test build). A
	// signature that does not verify is refused regardless.
	AllowUnsigned bool
}

InstallOptions are the expectations an install verifies.

type Installed

type Installed struct {
	Manifest      Manifest
	Dir           string
	ArchiveSHA256 string
	Source        DigestSource
	// Reused is true when the same version was already installed and verified.
	Reused bool
	// Signature says which trusted release key signed the archive.
	Signature Signature
}

Installed is the outcome of an install.

type Manifest

type Manifest struct {
	Schema   string              `json:"schema"`
	Name     string              `json:"name"`
	Version  string              `json:"version"`
	Requires Requirements        `json:"requires"`
	Build    BuildInfo           `json:"build"`
	Files    []ManifestFileEntry `json:"files"`
}

Manifest is manifest.json of a web UI archive.

func ParseManifest

func ParseManifest(data []byte) (Manifest, error)

ParseManifest reads and validates manifest.json.

func VerifyDir

func VerifyDir(dir string) (Manifest, error)

VerifyDir re-checks an installed version against its manifest.

func (Manifest) Validate

func (m Manifest) Validate() error

Validate checks the manifest's own consistency (not the files it lists).

type ManifestFileEntry

type ManifestFileEntry struct {
	Path   string `json:"path"`
	Size   int64  `json:"size"`
	SHA256 string `json:"sha256"`
}

ManifestFileEntry is one file the archive holds besides manifest.json.

type ReleaseSource

type ReleaseSource struct {
	Repo         string
	APIBase      string // https://api.github.com
	DownloadBase string // https://github.com
	Client       *http.Client
}

ReleaseSource finds and downloads frontend releases on GitHub. It is used only when the person asks for a download (`web-ui install --latest`, `web-ui update`); nothing else in this package touches the network.

func (ReleaseSource) Download

func (rs ReleaseSource) Download(ctx context.Context, c Candidate, dir string) (archivePath, digest string, err error)

Download fetches the candidate's archive into dir and returns its path and expected digest.

func (ReleaseSource) Latest

func (rs ReleaseSource) Latest(ctx context.Context) (Candidate, error)

Latest returns the newest stable release that this CLI can serve.

type Requirements

type Requirements struct {
	// LocalAPI is a range over the agent's local API contract version, e.g. ">=1.0 <2".
	LocalAPI string `json:"localApi"`
}

Requirements is what a frontend needs of the agent it runs against.

type RuntimeConfig

type RuntimeConfig struct {
	Mode       string `json:"mode"`
	AgentPath  string `json:"agentPath"`
	LocalAPI   string `json:"localApi"`
	CLIVersion string `json:"cliVersion"`
	Version    string `json:"webUiVersion"`
	Telemetry  bool   `json:"telemetry"`
}

RuntimeConfig is injected into index.html as <meta name="datatug-runtime">. It tells the frontend it runs in local mode and where the agent is; it grants nothing — the agent decides every permission per request.

type Signature added in v0.147.0

type Signature struct {
	// KeyID is the trusted key that signed the manifest; "" when the archive was installed unsigned.
	KeyID string
}

Signature is what an install found out about who signed an archive.

type State

type State struct {
	Pinned   string `json:"pinned,omitempty"`
	Active   string `json:"active,omitempty"`
	Previous string `json:"previous,omitempty"`
}

State is which version is pinned, served last, and served before that.

type Store

type Store struct{ Dir string }

Store is the directory of installed web UI versions and their selection state.

func DefaultStore

func DefaultStore() Store

DefaultStore is ~/datatug/web-ui, or $DATATUG_WEB_UI_DIR.

func (Store) InstallArchive

func (s Store) InstallArchive(archivePath string, opts InstallOptions) (Installed, error)

InstallArchive verifies the archive at archivePath and installs it as versions/<version>. Nothing appears under versions/ unless every check passes.

func (Store) List

func (s Store) List() ([]Entry, error)

List returns installed versions, newest first. A directory whose manifest cannot be read is skipped: it is not a usable install.

func (Store) LoadState

func (s Store) LoadState() (State, error)

LoadState reads state.json; a missing file is the zero State.

func (Store) MarkActive

func (s Store) MarkActive(version string) error

MarkActive records that version is now being served.

func (Store) Remove

func (s Store) Remove(version string) error

Remove deletes an installed version. The pinned version cannot be removed.

func (Store) Rollback

func (s Store) Rollback() (State, error)

Rollback pins the previously used version.

func (Store) Select

func (s Store) Select(requested string) (Entry, error)

Select picks the version to serve: requested, else pinned, else the newest compatible one. A requested or pinned version that is missing or incompatible is an error: it never silently falls back. The chosen version is re-verified.

func (Store) Unpin

func (s Store) Unpin() (State, error)

Unpin returns selection to "newest compatible".

func (Store) Use

func (s Store) Use(version string) (State, error)

Use pins an installed, compatible version.

Jump to

Keyboard shortcuts

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