etherplugin

package
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: GPL-3.0 Imports: 23 Imported by: 0

README

etherplugin (Go SDK)

Go authoring package (github.com/braedonsaunders/ether/sdk/go) for Ether Plugin Protocol v1 (EPP/1).

Execution modes

  1. Native HTTP or WebSocket tunnel sidecar (ether.runtime.kind: "remote"): Compile a standard Go binary and call p.Serve(ctx, etherplugin.ServeOptions{}) (or mount p as an http.Handler). Host calls go over HTTP to /ether/plugin-host/* authenticated with X-Ether-Plugin-Credential.
  2. Hosted WebAssembly guest: not yet supported. Go 1.27.3 GOOS=wasip1 GOARCH=wasm emits wasi_snapshot_preview1 imports (including proc_exit, clock_time_get, and fd_write), which the runtime forbids. TinyGo is not installed here, so a compatible TinyGo build has not been verified. Use a sidecar until a guest is built and tested against Ether's raw WASM ABI.

Usage

package main

import (
	"context"
	"os/signal"
	"syscall"

	etherplugin "github.com/braedonsaunders/ether/sdk/go"
)

func main() {
	p := etherplugin.New(etherplugin.Definition{
		Manifest: etherplugin.Manifest{
			ID:      "org.ether.examples.hello",
			Name:    "Hello plugin",
			Version: "0.1.0",
			Ether: &etherplugin.EtherManifestBlock{
				Protocol:     1,
				Kind:         etherplugin.KindExtension,
				Capabilities: []etherplugin.Capability{etherplugin.CapListSource, etherplugin.CapUI},
				Summary:      "Minimal greeting plugin for Ether.",
				Runtime:      etherplugin.RuntimeDecl{Kind: "remote"},
			},
		},
		Routes: etherplugin.Routes{
			Catalog: func(ctx *etherplugin.Context, req etherplugin.CatalogRequest) (etherplugin.CatalogResponse, error) {
				return etherplugin.CatalogResponse{
					Metas: []etherplugin.CatalogItem{{
						ID:          "tt0133093",
						Type:        req.Type,
						Name:        "Hello from " + req.ID,
						ReleaseInfo: "1999",
					}},
				}, nil
			},
		},
	})

	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()
	_ = p.Serve(ctx, etherplugin.ServeOptions{})
}

WS8b interoperability test

Once internal/plugins/remote is present, run go test -tags ws8b ./sdk/examples/hello/go -run TestWS8bSDKInterop. It starts Ether's tunnel server and exercises the Go, Python, and TypeScript hello sidecars. It requires Python 3 and a Node version with TypeScript support and WebSocket. The Go SDK reconnects automatically after a dropped tunnel.

Tunnel recovery

Start(ctx, ServeOptions{Mode: "tunnel", ...}) returns after the initial credential authentication and hello/welcome handshake; initial failures are returned to the caller. After that, dropped connections retry serially with jittered exponential backoff (50–100 ms initially, capped at 5–10 seconds). Every attempt re-authenticates and repeats the handshake, with a 10-second connection/handshake timeout. A connection stable for a minute resets backoff.

In-flight calls fail on disconnect and are not replayed. Ether runtimes resolve the current connection for subsequent calls. handle.Done stays open during recovery; cancelling ctx or calling handle.Close() stops active I/O and any retry, closes the socket, and closes Done. Close is safe to call repeatedly. Request cancellation stops that handler without closing the shared tunnel.

Documentation

Overview

Package etherplugin is the Go authoring SDK for Ether Plugin Protocol v1 (EPP/1).

It provides the same declarative router shape, settings decoder, localization helper, host service client, test harness, and capability templates as `@ether/plugin-sdk` (TypeScript) and `ether_plugin` (Python).

Execution modes

Go plugins run as native HTTP or WebSocket tunnel sidecars. Hosted Go is not supported: the standard Go wasip1 toolchain emits WASI imports, which Ether's sandbox rejects. See README.md for details.

Server packages under `internal/` and `cmd/` must not import this package.

Index

Constants

View Source
const (
	// TunnelProtocol is the WebSocket subprotocol for Ether remote plugin tunnels.
	TunnelProtocol = "ether-tunnel-v1"
	// DefaultMaxChunkBytes is the default chunk size for streamed file responses.
	DefaultMaxChunkBytes = 64 * 1024
)

Variables

View Source
var Fixtures = struct {
	PickToken     func(itemID string) string
	Movie         func() MetaItem
	CatalogItem   func() CatalogItem
	PlaybackEvent func(name string) EtherEvent
	Candidate     func() CandidateFacts
}{
	PickToken: func(itemID string) string {
		if itemID == "" {
			itemID = "ether:movie:1"
		}
		return "pick-v1:" + itemID + ":sig-test"
	},
	Movie: func() MetaItem {
		return MetaItem{
			CatalogItem: CatalogItem{
				ID:          "tt0133093",
				Type:        "movie",
				Name:        "The Matrix",
				ReleaseInfo: "1999",
				Description: "A computer hacker learns about the true nature of reality.",
				Genres:      []string{"Action", "Sci-Fi"},
				IMDBRating:  "8.7",
			},
		}
	},
	CatalogItem: func() CatalogItem {
		return CatalogItem{
			ID:          "tt0133093",
			Type:        "movie",
			Name:        "The Matrix",
			ReleaseInfo: "1999",
		}
	},
	PlaybackEvent: func(name string) EtherEvent {
		if name == "" {
			name = "playback.completed"
		}
		return EtherEvent{
			ID:       "evt_01",
			Name:     name,
			At:       "2026-11-02T12:00:00Z",
			ViewerID: 1,
			Payload: map[string]any{
				"titleId":  "tt0133093",
				"title":    "The Matrix",
				"progress": 0.95,
			},
		}
	},
	Candidate: func() CandidateFacts {
		return CandidateFacts{
			ReleaseID:  "rel_01",
			Name:       "The.Matrix.1999.2160p.UHD.BluRay.x265",
			Resolution: 2160,
			HDR:        []string{"DV", "HDR10"},
			VideoCodec: "hevc",
			Cached:     true,
			Verified:   true,
		}
	},
}

Fixtures provides sample EPP/1 records for plugin unit tests.

Functions

func AssertValidViewSpec

func AssertValidViewSpec(doc ViewSpecDocument) error

AssertValidViewSpec validates a ViewSpecDocument for structural rules and rejects any `*ClassName` fields.

func DecodeSettings

func DecodeSettings(
	schema *SettingsSchema,
	incoming map[string]any,
	defaults map[string]any,
) (map[string]any, map[string]string)

DecodeSettings applies schema defaults and validates incoming settings, returning the decoded settings map and any JSON-pointer keyed errors.

func LintCopy

func LintCopy(raw string, maxRunes int) string

LintCopy validates a user-visible string against Ether's copy rules. It returns an empty string when valid, or the plain reason when invalid.

func TRef

func TRef(key string) string

TRef formats a "$t:<key>" localization reference for manifests and ViewSpecs.

Types

type ActionProposal

type ActionProposal struct {
	Category    string         `json:"category"`
	Description string         `json:"description"`
	Input       map[string]any `json:"input,omitempty"`
}

ActionProposal describes a confirmation proposal returned by an Action handler.

type ActionRequest

type ActionRequest struct {
	Action string         `json:"action"`
	Input  map[string]any `json:"input"`
}

ActionRequest is passed to an Action route handler.

type ActionResponse

type ActionResponse struct {
	Toast    string          `json:"toast,omitempty"`
	Refresh  bool            `json:"refresh,omitempty"`
	Open     string          `json:"open,omitempty"`
	Proposal *ActionProposal `json:"proposal,omitempty"`
}

ActionResponse is returned by an Action route handler.

type BehaviorHints

type BehaviorHints struct {
	Adult                 bool `json:"adult,omitempty"`
	P2P                   bool `json:"p2p,omitempty"`
	Configurable          bool `json:"configurable,omitempty"`
	ConfigurationRequired bool `json:"configurationRequired,omitempty"`
}

BehaviorHints carries Stremio-compatible behavior hints.

type CandidateFacts

type CandidateFacts struct {
	ReleaseID     string      `json:"releaseId"`
	Name          string      `json:"name"`
	Size          int64       `json:"size,omitempty"`
	Protocol      string      `json:"protocol,omitempty"`
	SourceClass   string      `json:"sourceClass,omitempty"`
	Indexer       string      `json:"indexer,omitempty"`
	Resolution    any         `json:"resolution,omitempty"`
	HDR           []string    `json:"hdr,omitempty"`
	VideoCodec    string      `json:"videoCodec,omitempty"`
	AudioCodecs   []string    `json:"audioCodecs,omitempty"`
	AudioChannels string      `json:"audioChannels,omitempty"`
	Languages     []string    `json:"languages,omitempty"`
	Subtitles     []string    `json:"subtitles,omitempty"`
	ReleaseType   string      `json:"releaseType,omitempty"`
	Group         string      `json:"group,omitempty"`
	Cached        bool        `json:"cached,omitempty"`
	Verified      bool        `json:"verified,omitempty"`
	ClientCaps    *ClientCaps `json:"clientCaps,omitempty"`
}

CandidateFacts is the release candidate structure passed to RankKey and CondMatch.

type Capability

type Capability string

Capability names a capability declared in manifest.ether.capabilities.

const (
	CapStreamSource   Capability = "stream_source"
	CapDebridProvider Capability = "debrid_provider"
	CapListSource     Capability = "list_source"
	CapLiveTV         Capability = "livetv_channels"
	CapSubtitles      Capability = "subtitles"
	CapMarkers        Capability = "markers"
	CapNotify         Capability = "notify"
	CapEvents         Capability = "events"
	CapRankingStep    Capability = "ranking_step"
	CapRuleCondition  Capability = "rule_condition"
	CapTools          Capability = "tools"
	CapUI             Capability = "ui"
)

type CatalogItem

type CatalogItem struct {
	ID          string   `json:"id"`
	Type        string   `json:"type"`
	Name        string   `json:"name"`
	Poster      string   `json:"poster,omitempty"`
	PosterShape string   `json:"posterShape,omitempty"`
	Background  string   `json:"background,omitempty"`
	Description string   `json:"description,omitempty"`
	ReleaseInfo string   `json:"releaseInfo,omitempty"`
	IMDBRating  string   `json:"imdbRating,omitempty"`
	Genres      []string `json:"genres,omitempty"`
}

CatalogItem is one item in a catalog response.

type CatalogRequest

type CatalogRequest struct {
	Type   string            `json:"type"`
	ID     string            `json:"id"`
	Extra  map[string]string `json:"extra"`
	Skip   int               `json:"skip"`
	Search string            `json:"search,omitempty"`
	Genre  string            `json:"genre,omitempty"`
}

CatalogRequest is passed to a Catalog route handler.

type CatalogResponse

type CatalogResponse struct {
	Metas []CatalogItem `json:"metas"`
}

CatalogResponse is returned by a Catalog route handler.

type CatalogTitleSummary

type CatalogTitleSummary struct {
	ID     any    `json:"id"`
	Title  string `json:"title"`
	Type   string `json:"type"`
	Year   int    `json:"year,omitempty"`
	IMDBID string `json:"imdbId,omitempty"`
	TMDBID int    `json:"tmdbId,omitempty"`
}

CatalogTitleSummary is a catalog record returned by Host.CatalogSearch or Host.CatalogGet.

type ChannelInput

type ChannelInput struct {
	URL      string            `json:"url"`
	Name     string            `json:"name,omitempty"`
	Headers  map[string]string `json:"headers,omitempty"`
	Priority int               `json:"priority,omitempty"`
}

ChannelInput is one stream input for a Live TV channel.

type ChannelItem

type ChannelItem struct {
	ID      string         `json:"id"`
	Name    string         `json:"name"`
	Number  int            `json:"number,omitempty"`
	Group   string         `json:"group,omitempty"`
	GuideID string         `json:"guideId,omitempty"`
	Inputs  []ChannelInput `json:"inputs"`
}

ChannelItem is one Live TV channel.

type ChannelsMeta

type ChannelsMeta struct {
	Refresh string `json:"refresh,omitempty"`
	Test    bool   `json:"test"`
}

ChannelsMeta describes a Live TV channel contribution.

type ChannelsResponse

type ChannelsResponse struct {
	Channels []ChannelItem `json:"channels"`
}

ChannelsResponse is returned by a Channels route handler.

type ClientCaps

type ClientCaps struct {
	MaxHeight int      `json:"maxHeight,omitempty"`
	HDR       []string `json:"hdr,omitempty"`
	Codecs    []string `json:"codecs,omitempty"`
}

ClientCaps describes playback client capabilities passed to hot-path functions.

type CommandMeta

type CommandMeta struct {
	Key    string `json:"key"`
	Label  string `json:"label"`
	Action string `json:"action"`
}

CommandMeta describes a command contributed by a plugin.

type ConfigureResponse

type ConfigureResponse struct {
	Errors map[string]string `json:"errors"`
}

ConfigureResponse is returned by a Configure route handler.

type Context

type Context struct {
	context.Context
	Manifest  Manifest
	Settings  map[string]any
	Locale    string
	PickToken string
	RequestID string
	Headers   map[string]string
	Query     map[string]string
	Ether     Host
	I18n      *I18n
}

Context is passed to every plugin route handler.

func (*Context) T

func (c *Context) T(key string, params map[string]any) string

T resolves a localized string key with optional parameter interpolation.

type Contributes

type Contributes struct {
	Source         *SourceMeta         `json:"source,omitempty"`
	Channels       *ChannelsMeta       `json:"channels,omitempty"`
	Subtitles      *SubtitlesMeta      `json:"subtitles,omitempty"`
	Markers        *MarkersMeta        `json:"markers,omitempty"`
	Notification   *NotificationMeta   `json:"notification,omitempty"`
	Events         *EventsMeta         `json:"events,omitempty"`
	Integration    *IntegrationMeta    `json:"integration,omitempty"`
	ListSources    []ListSourceMeta    `json:"listSources,omitempty"`
	RankingSteps   []RankingStepMeta   `json:"rankingSteps,omitempty"`
	RuleConditions []RuleConditionMeta `json:"ruleConditions,omitempty"`
	Tools          []ToolMeta          `json:"tools,omitempty"`
	Pages          []PageMeta          `json:"pages,omitempty"`
	Slots          []SlotMeta          `json:"slots,omitempty"`
	Commands       []CommandMeta       `json:"commands,omitempty"`
}

Contributes declares the descriptors a plugin contributes to Ether.

type Definition

type Definition struct {
	Manifest          Manifest
	Routes            Routes
	DefaultSettings   map[string]any
	Strings           StringsCatalog
	DefaultLocale     string
	Host              Host
	RemoteHostOptions RemoteHostOptions
}

Definition configures a new Plugin instance.

type EtherEvent

type EtherEvent struct {
	ID       string         `json:"id"`
	Name     string         `json:"name"`
	At       string         `json:"at"`
	ViewerID int64          `json:"viewerId,omitempty"`
	Payload  map[string]any `json:"payload,omitempty"`
}

EtherEvent is one event delivered in a batch to POST /ether/event.

type EtherManifestBlock

type EtherManifestBlock struct {
	Protocol     int             `json:"protocol"`
	Kind         PluginKind      `json:"kind"`
	Capabilities []Capability    `json:"capabilities,omitempty"`
	Summary      string          `json:"summary"`
	Author       *PluginAuthor   `json:"author,omitempty"`
	License      string          `json:"license,omitempty"`
	Repo         string          `json:"repo,omitempty"`
	Icon         string          `json:"icon,omitempty"`
	Runtime      RuntimeDecl     `json:"runtime"`
	Cluster      string          `json:"cluster,omitempty"`
	Health       *HealthDecl     `json:"health,omitempty"`
	Permissions  *Permissions    `json:"permissions,omitempty"`
	Settings     *SettingsSchema `json:"settings,omitempty"`
	Strings      map[string]any  `json:"strings,omitempty"`
	Schedule     []ScheduleEntry `json:"schedule,omitempty"`
	Contributes  *Contributes    `json:"contributes,omitempty"`
}

EtherManifestBlock holds the EPP/1 `ether` manifest block.

type EventResponse

type EventResponse struct {
	Ack []string `json:"ack"`
}

EventResponse is returned by an Event route handler.

type EventsMeta

type EventsMeta struct {
	Subscribe []string `json:"subscribe"`
}

EventsMeta lists subscribed event names.

type FieldOption

type FieldOption struct {
	Value string `json:"value"`
	Label string `json:"label"`
	Hint  string `json:"hint,omitempty"`
}

FieldOption is one selectable option for a select or multiSelect field.

type FieldProblem

type FieldProblem struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

FieldProblem describes one schema validation or copy-rule problem.

func LintSettingsSchema

func LintSettingsSchema(schema *SettingsSchema) []FieldProblem

LintSettingsSchema checks a SettingsSchema for forbidden kinds and copy-rule violations.

type FileRangeResponse

type FileRangeResponse struct {
	Status       int               `json:"status,omitempty"`
	ContentType  string            `json:"contentType,omitempty"`
	ContentRange string            `json:"contentRange,omitempty"`
	TotalSize    *int64            `json:"totalSize,omitempty"`
	Headers      map[string]string `json:"headers,omitempty"`
	Body         []byte            `json:"-"`
}

FileRangeResponse is returned by a File route handler.

type FileRequest

type FileRequest struct {
	Path     string `json:"path"`
	Range    string `json:"range,omitempty"`
	HeadOnly bool   `json:"headOnly,omitempty"`
}

FileRequest is passed to a File route handler.

type FolderEntry

type FolderEntry struct {
	Name  string `json:"name"`
	Path  string `json:"path"`
	Dir   bool   `json:"dir"`
	Size  int64  `json:"size,omitempty"`
	Mtime int64  `json:"mtime,omitempty"`
}

FolderEntry describes one entry returned by Host.FoldersList or Host.FoldersStat.

type GuideRequest

type GuideRequest struct {
	ChannelID string `json:"channelId"`
	From      string `json:"from,omitempty"`
	To        string `json:"to,omitempty"`
}

GuideRequest is passed to a Guide route handler.

type GuideResponse

type GuideResponse struct {
	Programmes []ProgrammeItem `json:"programmes"`
}

GuideResponse is returned by a Guide route handler.

type HealthDecl

type HealthDecl struct {
	Interval string `json:"interval,omitempty"`
}

HealthDecl configures periodic health checks.

type HealthResponse

type HealthResponse struct {
	Status string `json:"status"`
	Reason string `json:"reason,omitempty"`
}

HealthResponse is returned by a Health route handler.

type Host

type Host interface {
	KVGet(ctx context.Context, key string) (string, bool, error)
	KVPut(ctx context.Context, key, value string) error
	KVDelete(ctx context.Context, key string) error
	KVList(ctx context.Context, prefix string) ([]string, error)
	SecretGet(ctx context.Context, name string) (string, error)
	Fetch(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
	CatalogSearch(ctx context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)
	CatalogGet(ctx context.Context, id string) (*CatalogTitleSummary, error)
	ViewerHistory(ctx context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)
	SetWatchState(ctx context.Context, viewerID int64, titleID string, watched bool) error
	UpsertCollection(ctx context.Context, collection map[string]any) error
	FoldersList(ctx context.Context, root, path string) ([]FolderEntry, error)
	FoldersStat(ctx context.Context, root, path string) (FolderEntry, error)
	NotifyOwner(ctx context.Context, text string) error
	Log(ctx context.Context, level, message string, attrs map[string]any) error
}

Host provides access to Ether host services (KV, secrets, HTTP, catalog, viewers, collections, folders, owner notifications, and logging).

type HostFetchRequest

type HostFetchRequest struct {
	Method  string            `json:"method,omitempty"`
	URL     string            `json:"url"`
	Headers map[string]string `json:"headers,omitempty"`
	Body    string            `json:"body,omitempty"`
}

HostFetchRequest describes an outbound HTTP call via the host service.

type HostFetchResponse

type HostFetchResponse struct {
	Status  int               `json:"status"`
	Headers map[string]string `json:"headers"`
	Body    string            `json:"body"`
}

HostFetchResponse is returned by Host.Fetch.

type I18n

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

I18n resolves localized strings with fallback to base language and "en".

func NewI18n

func NewI18n(catalog StringsCatalog, defaultLocale string) *I18n

NewI18n creates a localization helper backed by a StringsCatalog.

func (*I18n) Catalog

func (i *I18n) Catalog() StringsCatalog

Catalog returns the underlying locale catalog.

func (*I18n) T

func (i *I18n) T(rawKey string, params map[string]any, locale string) string

T resolves a key for the given locale and interpolates {param} placeholders.

type IntegrationMeta

type IntegrationMeta struct {
	Category string   `json:"category"`
	Adds     []string `json:"adds"`
	Connect  string   `json:"connect"`
	Test     bool     `json:"test,omitempty"`
}

IntegrationMeta describes an external service integration.

type JobRequest

type JobRequest struct {
	Name string `json:"name"`
}

JobRequest is passed to a Job route handler.

type JobResponse

type JobResponse map[string]any

JobResponse is returned by a Job route handler.

type ListSourceMeta

type ListSourceMeta struct {
	Key      string `json:"key"`
	Label    string `json:"label"`
	Hint     string `json:"hint,omitempty"`
	Catalog  string `json:"catalog"`
	Params   any    `json:"params,omitempty"`
	MaxItems int    `json:"maxItems,omitempty"`
	Refresh  string `json:"refresh,omitempty"`
}

ListSourceMeta describes a catalog list source.

type Manifest

type Manifest struct {
	ID            string               `json:"id"`
	Version       string               `json:"version"`
	Name          string               `json:"name"`
	Description   string               `json:"description,omitempty"`
	Background    string               `json:"background,omitempty"`
	Types         []string             `json:"types,omitempty"`
	Catalogs      []StremioCatalogDecl `json:"catalogs,omitempty"`
	Resources     []any                `json:"resources,omitempty"`
	IDPrefixes    []string             `json:"idPrefixes,omitempty"`
	BehaviorHints *BehaviorHints       `json:"behaviorHints,omitempty"`
	Ether         *EtherManifestBlock  `json:"ether,omitempty"`
}

Manifest is the EPP/1 manifest document served at GET /manifest.json.

type MarkerItem

type MarkerItem struct {
	Kind  string  `json:"kind"`
	Start float64 `json:"start"`
	End   float64 `json:"end"`
	Label string  `json:"label,omitempty"`
}

MarkerItem is one intro/credits/recap/preview marker.

type MarkersMeta

type MarkersMeta struct {
	Kinds []string `json:"kinds"`
}

MarkersMeta describes a playback markers contribution.

type MarkersRequest

type MarkersRequest struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

MarkersRequest is passed to a Markers route handler.

type MarkersResponse

type MarkersResponse struct {
	Markers []MarkerItem `json:"markers"`
}

MarkersResponse is returned by a Markers route handler.

type MetaItem

type MetaItem struct {
	CatalogItem
	Runtime  string      `json:"runtime,omitempty"`
	Cast     []string    `json:"cast,omitempty"`
	Director []string    `json:"director,omitempty"`
	Videos   []MetaVideo `json:"videos,omitempty"`
}

MetaItem is a full metadata record returned by a Meta route handler.

type MetaRequest

type MetaRequest struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

MetaRequest is passed to a Meta route handler.

type MetaResponse

type MetaResponse struct {
	Meta MetaItem `json:"meta"`
}

MetaResponse is returned by a Meta route handler.

type MetaVideo

type MetaVideo struct {
	ID        string `json:"id"`
	Title     string `json:"title"`
	Released  string `json:"released,omitempty"`
	Season    int    `json:"season,omitempty"`
	Episode   int    `json:"episode,omitempty"`
	Overview  string `json:"overview,omitempty"`
	Thumbnail string `json:"thumbnail,omitempty"`
}

MetaVideo describes one episode/video inside a MetaItem.

type MockHost

type MockHost struct {
	KV            map[string]string
	Secrets       map[string]string
	Catalog       map[string]CatalogTitleSummary
	History       map[int64][]ViewerWatchEntry
	WatchState    map[string]bool
	Collections   []map[string]any
	Folders       map[string][]FolderEntry
	Notifications []string
	Logs          []RecordedLog
	FetchHandler  func(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
	// contains filtered or unexported fields
}

MockHost is an in-memory Host implementation for unit tests.

func NewMockHost

func NewMockHost() *MockHost

NewMockHost creates an initialized MockHost.

func (*MockHost) CatalogGet

func (m *MockHost) CatalogGet(_ context.Context, id string) (*CatalogTitleSummary, error)

CatalogGet returns a title by ID from the in-memory catalog.

func (*MockHost) CatalogSearch

func (m *MockHost) CatalogSearch(_ context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)

CatalogSearch searches the in-memory catalog by case-insensitive substring.

func (*MockHost) Fetch

Fetch invokes FetchHandler if set, or returns a 200 "{}" response.

func (*MockHost) FoldersList

func (m *MockHost) FoldersList(_ context.Context, root, path string) ([]FolderEntry, error)

FoldersList returns folder entries for root/path.

func (*MockHost) FoldersStat

func (m *MockHost) FoldersStat(_ context.Context, root, path string) (FolderEntry, error)

FoldersStat returns a FolderEntry for root and path.

func (*MockHost) KVDelete

func (m *MockHost) KVDelete(_ context.Context, key string) error

KVDelete deletes a key from the in-memory KV store.

func (*MockHost) KVGet

func (m *MockHost) KVGet(_ context.Context, key string) (string, bool, error)

KVGet reads a key from the in-memory KV store.

func (*MockHost) KVList

func (m *MockHost) KVList(_ context.Context, prefix string) ([]string, error)

KVList lists keys matching prefix in sorted order.

func (*MockHost) KVPut

func (m *MockHost) KVPut(_ context.Context, key, value string) error

KVPut writes a key-value pair to the in-memory KV store.

func (*MockHost) Log

func (m *MockHost) Log(_ context.Context, level, message string, attrs map[string]any) error

Log appends a RecordedLog entry to Logs.

func (*MockHost) NotifyOwner

func (m *MockHost) NotifyOwner(_ context.Context, text string) error

NotifyOwner appends text to Notifications.

func (*MockHost) SecretGet

func (m *MockHost) SecretGet(_ context.Context, name string) (string, error)

SecretGet reads a secret from the in-memory secrets map.

func (*MockHost) SetWatchState

func (m *MockHost) SetWatchState(_ context.Context, viewerID int64, titleID string, watched bool) error

SetWatchState records watch state for viewerID:titleID.

func (*MockHost) UpsertCollection

func (m *MockHost) UpsertCollection(_ context.Context, collection map[string]any) error

UpsertCollection appends the collection to Collections.

func (*MockHost) ViewerHistory

func (m *MockHost) ViewerHistory(_ context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)

ViewerHistory returns watch history for viewerID.

type NotificationMeta

type NotificationMeta struct {
	Fields    any      `json:"fields,omitempty"`
	SendTest  bool     `json:"sendTest"`
	Formats   []string `json:"formats,omitempty"`
	MaxLength int      `json:"maxLength,omitempty"`
}

NotificationMeta describes a notification channel contribution.

type NotifyRequest

type NotifyRequest struct {
	Title    string         `json:"title,omitempty"`
	Message  string         `json:"message"`
	Event    string         `json:"event,omitempty"`
	Settings map[string]any `json:"settings,omitempty"`
}

NotifyRequest is passed to a Notify route handler.

type NotifyResponse

type NotifyResponse struct {
	OK      bool   `json:"ok"`
	Message string `json:"message,omitempty"`
}

NotifyResponse is returned by a Notify route handler.

type OpenStreamRequest

type OpenStreamRequest struct {
	StreamID string `json:"streamId"`
}

OpenStreamRequest is passed to an OpenStream route handler.

type OpenStreamResponse

type OpenStreamResponse struct {
	URL       string            `json:"url,omitempty"`
	Headers   map[string]string `json:"headers,omitempty"`
	ExpiresAt string            `json:"expiresAt,omitempty"`
	File      string            `json:"file,omitempty"`
}

OpenStreamResponse is returned by an OpenStream route handler.

type PageMeta

type PageMeta struct {
	Key   string `json:"key"`
	Label string `json:"label"`
	Route string `json:"route"`
	Group string `json:"group,omitempty"`
	Icon  string `json:"icon,omitempty"`
}

PageMeta describes a ViewSpec page contributed by a plugin.

type Permissions

type Permissions struct {
	Network     []string           `json:"network,omitempty"`
	Catalog     string             `json:"catalog,omitempty"`
	Viewers     *ViewerPermissions `json:"viewers,omitempty"`
	Collections string             `json:"collections,omitempty"`
	Folders     string             `json:"folders,omitempty"`
	Secrets     []string           `json:"secrets,omitempty"`
}

Permissions declares the host access a plugin requests.

type Plugin

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

Plugin is a runnable Ether plugin instance.

func New

func New(def Definition) *Plugin

New constructs a Plugin from a Definition.

func NewCatalogTemplate

func NewCatalogTemplate(opts TemplateOptions) *Plugin

NewCatalogTemplate builds a starter catalog and metadata plugin.

func NewConditionTemplate

func NewConditionTemplate(opts TemplateOptions) *Plugin

NewConditionTemplate builds a starter rule-condition plugin.

func NewRankerTemplate

func NewRankerTemplate(opts TemplateOptions) *Plugin

NewRankerTemplate builds a starter release-ranking step plugin.

func NewScrobblerTemplate

func NewScrobblerTemplate(opts TemplateOptions) *Plugin

NewScrobblerTemplate builds a starter playback event subscriber plugin.

func NewSubtitlesTemplate

func NewSubtitlesTemplate(opts TemplateOptions) *Plugin

NewSubtitlesTemplate builds a starter subtitles provider plugin.

func NewViewTemplate

func NewViewTemplate(opts TemplateOptions) *Plugin

NewViewTemplate builds a starter ViewSpec UI and action plugin.

func (*Plugin) CondMatch

func (p *Plugin) CondMatch(candidate CandidateFacts, operator string, value any) bool

CondMatch invokes the plugin's CondMatch hot-path function.

func (*Plugin) Dispatch

func (p *Plugin) Dispatch(ctx context.Context, req RawRequest) RawResponse

Dispatch routes a RawRequest through the plugin and returns a RawResponse.

func (*Plugin) DispatchTunnelFrame

func (p *Plugin) DispatchTunnelFrame(ctx context.Context, frame TunnelFrame, maxChunkBytes int) []TunnelFrame

DispatchTunnelFrame executes a `"request"` TunnelFrame against a Plugin and returns the outgoing response frames (either a single `"response"` frame or a `"response_start"` / `"response_chunk"` / `"response_end"` sequence for `/ether/file/*` binary responses).

func (*Plugin) GetSettings

func (p *Plugin) GetSettings() map[string]any

GetSettings returns a copy of the plugin's active settings.

func (*Plugin) Manifest

func (p *Plugin) Manifest() Manifest

Manifest returns the plugin's Manifest.

func (*Plugin) RankKey

func (p *Plugin) RankKey(candidate CandidateFacts, config map[string]any) int64

RankKey invokes the plugin's RankKey hot-path function.

func (*Plugin) Serve

func (p *Plugin) Serve(ctx context.Context, opts ServeOptions) error

Serve runs the plugin sidecar until ctx is cancelled.

func (*Plugin) ServeHTTP

func (p *Plugin) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements net/http.Handler for running a Plugin as an HTTP sidecar.

func (*Plugin) SetSettings

func (p *Plugin) SetSettings(incoming map[string]any) (map[string]any, map[string]string)

SetSettings validates and updates the plugin's settings.

func (*Plugin) Start

func (p *Plugin) Start(ctx context.Context, opts ServeOptions) (*ServeHandle, error)

Start launches the plugin sidecar in the background (either HTTP or WebSocket tunnel) and returns a ServeHandle that stops it when Close is called or ctx is cancelled.

type PluginAuthor

type PluginAuthor struct {
	Name string `json:"name,omitempty"`
	URL  string `json:"url,omitempty"`
}

PluginAuthor identifies the plugin author.

type PluginKind

type PluginKind string

PluginKind identifies the top-level plugin classification in manifest.ether.kind.

const (
	KindSource              PluginKind = "source"
	KindIntegration         PluginKind = "integration"
	KindNotificationChannel PluginKind = "notification_channel"
	KindLiveTVSource        PluginKind = "livetv_source"
	KindExtension           PluginKind = "extension"
)

type ProgrammeItem

type ProgrammeItem struct {
	ID          string   `json:"id,omitempty"`
	ChannelID   string   `json:"channelId,omitempty"`
	Title       string   `json:"title"`
	Subtitle    string   `json:"subtitle,omitempty"`
	Description string   `json:"description,omitempty"`
	Start       string   `json:"start"`
	Stop        string   `json:"stop"`
	Icon        string   `json:"icon,omitempty"`
	Categories  []string `json:"categories,omitempty"`
}

ProgrammeItem is one EPG programme entry.

type RankingStepMeta

type RankingStepMeta struct {
	Key             string `json:"key"`
	Label           string `json:"label"`
	Hint            string `json:"hint,omitempty"`
	Editor          any    `json:"editor,omitempty"`
	DefaultPosition int    `json:"defaultPosition,omitempty"`
	Budget          any    `json:"budget,omitempty"`
}

RankingStepMeta describes a custom ranking step.

type RawRequest

type RawRequest struct {
	PluginID string            `json:"pluginId,omitempty"`
	Method   string            `json:"method,omitempty"`
	Path     string            `json:"path"`
	Query    map[string]string `json:"query,omitempty"`
	Headers  map[string]string `json:"headers,omitempty"`
	Body     json.RawMessage   `json:"body,omitempty"`
	Locale   string            `json:"locale,omitempty"`
}

RawRequest is the low-level transport-agnostic request passed to Plugin.Dispatch.

type RawResponse

type RawResponse struct {
	Status     int               `json:"status"`
	Headers    map[string]string `json:"headers,omitempty"`
	Body       json.RawMessage   `json:"body,omitempty"`
	BinaryBody []byte            `json:"-"`
}

RawResponse is the low-level transport-agnostic response returned by Plugin.Dispatch.

type RecordedLog

type RecordedLog struct {
	Level   string
	Message string
	Attrs   map[string]any
}

RecordedLog is one log message recorded by MockHost.

type RemoteHostClient

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

RemoteHostClient implements Host by calling `/ether/plugin-host/*` on the Ether server authenticated with `X-Ether-Plugin-Credential`.

func NewRemoteHostClient

func NewRemoteHostClient(opts RemoteHostOptions) *RemoteHostClient

NewRemoteHostClient creates a RemoteHostClient.

func (*RemoteHostClient) CatalogGet

func (c *RemoteHostClient) CatalogGet(ctx context.Context, id string) (*CatalogTitleSummary, error)

CatalogGet fetches one title summary from the Ether catalog.

func (*RemoteHostClient) CatalogSearch

func (c *RemoteHostClient) CatalogSearch(
	ctx context.Context,
	query string,
	limit, offset int,
) ([]CatalogTitleSummary, error)

CatalogSearch searches the Ether catalog.

func (*RemoteHostClient) Fetch

Fetch performs an outbound HTTP request.

func (*RemoteHostClient) FoldersList

func (c *RemoteHostClient) FoldersList(_ context.Context, _, _ string) ([]FolderEntry, error)

FoldersList is only supported in hosted mode; sidecars access local folders directly.

func (*RemoteHostClient) FoldersStat

func (c *RemoteHostClient) FoldersStat(_ context.Context, _, _ string) (FolderEntry, error)

FoldersStat is only supported in hosted mode; sidecars access local folders directly.

func (*RemoteHostClient) KVDelete

func (c *RemoteHostClient) KVDelete(ctx context.Context, key string) error

KVDelete deletes a key from the plugin's KV namespace.

func (*RemoteHostClient) KVGet

func (c *RemoteHostClient) KVGet(ctx context.Context, key string) (string, bool, error)

KVGet reads a key from the plugin's KV namespace.

func (*RemoteHostClient) KVList

func (c *RemoteHostClient) KVList(ctx context.Context, prefix string) ([]string, error)

KVList lists keys matching the given prefix in the plugin's KV namespace.

func (*RemoteHostClient) KVPut

func (c *RemoteHostClient) KVPut(ctx context.Context, key, value string) error

KVPut writes a key-value pair to the plugin's KV namespace.

func (*RemoteHostClient) Log

func (c *RemoteHostClient) Log(ctx context.Context, level, message string, attrs map[string]any) error

Log sends a structured log entry to Ether.

func (*RemoteHostClient) NotifyOwner

func (c *RemoteHostClient) NotifyOwner(ctx context.Context, text string) error

NotifyOwner sends an owner notification through Ether.

func (*RemoteHostClient) SecretGet

func (c *RemoteHostClient) SecretGet(_ context.Context, _ string) (string, error)

SecretGet is only available in hosted mode; remote plugins receive secrets via /ether/configure.

func (*RemoteHostClient) SetWatchState

func (c *RemoteHostClient) SetWatchState(
	ctx context.Context,
	viewerID int64,
	titleID string,
	watched bool,
) error

SetWatchState updates the watch state for a granted viewer.

func (*RemoteHostClient) SettingsGet

func (c *RemoteHostClient) SettingsGet(ctx context.Context) (map[string]any, error)

SettingsGet reads the current non-secret settings from Ether.

func (*RemoteHostClient) UpsertCollection

func (c *RemoteHostClient) UpsertCollection(ctx context.Context, collection map[string]any) error

UpsertCollection creates or updates a plugin-managed collection.

func (*RemoteHostClient) ViewerHistory

func (c *RemoteHostClient) ViewerHistory(
	ctx context.Context,
	viewerID int64,
	limit, offset int,
) ([]ViewerWatchEntry, error)

ViewerHistory reads watch history for a granted viewer.

type RemoteHostOptions

type RemoteHostOptions struct {
	BaseURL    string
	Credential string
	HTTPClient *http.Client
}

RemoteHostOptions configures a RemoteHostClient for sidecar plugins.

type RouteError

type RouteError struct {
	Status  int
	Code    string
	Message string
}

RouteError represents a structured HTTP error returned by a plugin handler.

func NewRouteError

func NewRouteError(status int, code, message string) *RouteError

NewRouteError constructs a structured RouteError.

func (*RouteError) Error

func (e *RouteError) Error() string

type Routes

type Routes struct {
	Catalog          func(ctx *Context, req CatalogRequest) (CatalogResponse, error)
	Meta             func(ctx *Context, req MetaRequest) (MetaResponse, error)
	Stream           func(ctx *Context, req StreamRequest) (StreamResponse, error)
	OpenStream       func(ctx *Context, req OpenStreamRequest) (OpenStreamResponse, error)
	Subtitles        func(ctx *Context, req SubtitlesRequest) (SubtitlesResponse, error)
	SubtitleDownload func(ctx *Context, req SubtitleDownloadRequest) (SubtitleDownloadResponse, error)
	Markers          func(ctx *Context, req MarkersRequest) (MarkersResponse, error)
	Channels         func(ctx *Context) (ChannelsResponse, error)
	Guide            func(ctx *Context, req GuideRequest) (GuideResponse, error)
	Configure        func(ctx *Context, settings map[string]any) (ConfigureResponse, error)
	Test             func(ctx *Context) (TestResponse, error)
	Options          func(ctx *Context, field string) ([]FieldOption, error)
	Health           func(ctx *Context) (HealthResponse, error)
	Notify           func(ctx *Context, req NotifyRequest) (NotifyResponse, error)
	Event            func(ctx *Context, events []EtherEvent) (EventResponse, error)
	View             func(ctx *Context, req ViewRequest) (ViewResponse, error)
	Action           func(ctx *Context, req ActionRequest) (ActionResponse, error)
	Tool             func(ctx *Context, req ToolRequest) (ToolResponse, error)
	Job              func(ctx *Context, req JobRequest) (JobResponse, error)
	File             func(ctx *Context, req FileRequest) (FileRangeResponse, error)
	RankKey          func(candidate CandidateFacts, config map[string]any) int64
	CondMatch        func(candidate CandidateFacts, operator string, value any) bool
}

Routes holds the capability handlers for a Plugin.

type RuleConditionMeta

type RuleConditionMeta struct {
	Key       string   `json:"key"`
	Label     string   `json:"label"`
	Operators []string `json:"operators,omitempty"`
	Editor    any      `json:"editor,omitempty"`
}

RuleConditionMeta describes a custom rule condition.

type RuntimeDecl

type RuntimeDecl struct {
	Kind   string `json:"kind"`
	Entry  string `json:"entry,omitempty"`
	Module string `json:"module,omitempty"`
}

RuntimeDecl declares how the plugin is executed.

type ScheduleEntry

type ScheduleEntry struct {
	Every string `json:"every"`
	Call  string `json:"call"`
}

ScheduleEntry declares a scheduled background job.

type ServeHandle

type ServeHandle struct {
	// Done closes when the tunnel supervisor stops (ctx cancellation or Close).
	// Transient disconnects reconnect automatically. It is nil for HTTP servers.
	Done  <-chan struct{}
	Mode  string
	URL   string
	Port  int
	Close func() error
}

ServeHandle represents a running HTTP or tunnel sidecar session.

type ServeOptions

type ServeOptions struct {
	Mode       string
	Host       string
	Port       int
	TunnelURL  string
	Credential string
}

ServeOptions configures how Plugin.Serve runs in sidecar mode.

type SettingField

type SettingField struct {
	Key         string         `json:"key"`
	Kind        string         `json:"kind"`
	Label       string         `json:"label,omitempty"`
	Hint        string         `json:"hint,omitempty"`
	Required    bool           `json:"required,omitempty"`
	Default     any            `json:"default,omitempty"`
	Options     []FieldOption  `json:"options,omitempty"`
	Fields      []SettingField `json:"fields,omitempty"`
	Min         *float64       `json:"min,omitempty"`
	Max         *float64       `json:"max,omitempty"`
	Placeholder string         `json:"placeholder,omitempty"`
}

SettingField describes one leaf or group setting field.

func CollectSettingFields

func CollectSettingFields(schema *SettingsSchema) []SettingField

CollectSettingFields returns all leaf SettingFields from a SettingsSchema.

type SettingsGroup

type SettingsGroup struct {
	Key      string         `json:"key,omitempty"`
	Label    string         `json:"label,omitempty"`
	Hint     string         `json:"hint,omitempty"`
	Advanced bool           `json:"advanced,omitempty"`
	Fields   []SettingField `json:"fields"`
}

SettingsGroup groups related settings fields.

type SettingsSchema

type SettingsSchema struct {
	Ref    string          `json:"$ref,omitempty"`
	Fields []SettingField  `json:"fields,omitempty"`
	Groups []SettingsGroup `json:"groups,omitempty"`
}

SettingsSchema describes a plugin's configuration fields.

type SlotMeta

type SlotMeta struct {
	Slot  string `json:"slot"`
	Key   string `json:"key"`
	Label string `json:"label"`
	Route string `json:"route"`
}

SlotMeta describes a UI slot contributed by a plugin.

type SourceMeta

type SourceMeta struct {
	Class     string         `json:"class"`
	Abilities []string       `json:"abilities,omitempty"`
	Limits    map[string]any `json:"limits,omitempty"`
}

SourceMeta describes a stream source contribution.

type StreamEtherExt

type StreamEtherExt struct {
	ID          string   `json:"id,omitempty"`
	ReleaseName string   `json:"releaseName,omitempty"`
	Size        int64    `json:"size,omitempty"`
	Languages   []string `json:"languages,omitempty"`
	Lazy        bool     `json:"lazy,omitempty"`
	File        string   `json:"file,omitempty"`
}

StreamEtherExt holds Ether-specific extensions on a StreamItem.

type StreamItem

type StreamItem struct {
	Name        string          `json:"name,omitempty"`
	Title       string          `json:"title,omitempty"`
	Description string          `json:"description,omitempty"`
	URL         string          `json:"url,omitempty"`
	InfoHash    string          `json:"infoHash,omitempty"`
	FileIdx     *int            `json:"fileIdx,omitempty"`
	YtID        string          `json:"ytId,omitempty"`
	ExternalURL string          `json:"externalUrl,omitempty"`
	Ether       *StreamEtherExt `json:"ether,omitempty"`
}

StreamItem is one playable candidate returned by a Stream route handler.

type StreamRequest

type StreamRequest struct {
	Type  string            `json:"type"`
	ID    string            `json:"id"`
	Extra map[string]string `json:"extra"`
}

StreamRequest is passed to a Stream route handler.

type StreamResponse

type StreamResponse struct {
	Streams []StreamItem `json:"streams"`
}

StreamResponse is returned by a Stream route handler.

type StremioCatalogDecl

type StremioCatalogDecl struct {
	Type  string              `json:"type"`
	ID    string              `json:"id"`
	Name  string              `json:"name,omitempty"`
	Extra []StremioExtraField `json:"extra,omitempty"`
}

StremioCatalogDecl declares a Stremio catalog in the manifest.

type StremioExtraField

type StremioExtraField struct {
	Name         string   `json:"name"`
	IsRequired   bool     `json:"isRequired,omitempty"`
	Options      []string `json:"options,omitempty"`
	OptionsLimit int      `json:"optionsLimit,omitempty"`
}

StremioExtraField declares a supported extra parameter on a catalog.

type StringsCatalog

type StringsCatalog map[string]map[string]string

StringsCatalog maps locale codes (e.g. "en", "fr-CA") to key-value tables.

type SubtitleDownloadRequest

type SubtitleDownloadRequest struct {
	ID     string `json:"id"`
	Lang   string `json:"lang"`
	Format string `json:"format"`
}

SubtitleDownloadRequest identifies a viewer-picked subtitle.

type SubtitleDownloadResponse

type SubtitleDownloadResponse struct {
	Format   string `json:"format"`
	Encoding string `json:"encoding"`
	Data     string `json:"data"`
}

SubtitleDownloadResponse carries subtitle text or base64-encoded bytes.

type SubtitleItem

type SubtitleItem struct {
	ID              string `json:"id"`
	URL             string `json:"url,omitempty"`
	Name            string `json:"name,omitempty"`
	Lang            string `json:"lang"`
	Label           string `json:"label,omitempty"`
	Format          string `json:"format,omitempty"`
	HearingImpaired bool   `json:"hearingImpaired,omitempty"`
}

SubtitleItem is one subtitle track returned by a Subtitles route handler.

type SubtitlesMeta

type SubtitlesMeta struct {
	Languages any      `json:"languages,omitempty"`
	Formats   []string `json:"formats,omitempty"`
}

SubtitlesMeta describes a subtitle provider contribution.

type SubtitlesRequest

type SubtitlesRequest struct {
	Type      string            `json:"type"`
	ID        string            `json:"id"`
	Extra     map[string]string `json:"extra"`
	PickToken string            `json:"pickToken"`
	VideoHash string            `json:"videoHash,omitempty"`
	VideoSize int64             `json:"videoSize,omitempty"`
	Filename  string            `json:"filename,omitempty"`
}

SubtitlesRequest is passed to a Subtitles route handler.

type SubtitlesResponse

type SubtitlesResponse struct {
	Subtitles []SubtitleItem `json:"subtitles"`
}

SubtitlesResponse is returned by a Subtitles route handler.

type TemplateOptions

type TemplateOptions struct {
	ID          string
	Name        string
	Version     string
	Summary     string
	Description string
}

TemplateOptions configures a capability starter template.

type TestHarness

type TestHarness struct {
	Plugin *Plugin
	Host   *MockHost
}

TestHarness wraps a Plugin and MockHost for ergonomic unit tests.

func NewTestHarness

func NewTestHarness(p *Plugin, host *MockHost) *TestHarness

NewTestHarness constructs a TestHarness for p.

func (*TestHarness) Action

func (h *TestHarness) Action(action string, input map[string]any) (int, ActionResponse, error)

Action calls POST /ether/action/{action}.

func (*TestHarness) Catalog

func (h *TestHarness) Catalog(typ, id string, extra map[string]string) (int, CatalogResponse, error)

Catalog calls GET /catalog/{type}/{id}[/{extra}].json.

func (*TestHarness) Configure

func (h *TestHarness) Configure(settings map[string]any) (int, ConfigureResponse, error)

Configure calls POST /ether/configure.

func (*TestHarness) Event

func (h *TestHarness) Event(events []EtherEvent) (int, EventResponse, error)

Event calls POST /ether/event.

func (*TestHarness) File

func (h *TestHarness) File(path, rangeHeader string) RawResponse

File calls GET /ether/file/{path}.

func (*TestHarness) Health

func (h *TestHarness) Health() (int, HealthResponse, error)

Health calls GET /ether/health.

func (*TestHarness) Manifest

func (h *TestHarness) Manifest() (Manifest, error)

Manifest fetches and decodes GET /manifest.json.

func (*TestHarness) Markers

func (h *TestHarness) Markers(typ, id string) (int, MarkersResponse, error)

Markers calls GET /ether/markers/{type}/{id}.json.

func (*TestHarness) Meta

func (h *TestHarness) Meta(typ, id string) (int, MetaResponse, error)

Meta calls GET /meta/{type}/{id}.json.

func (*TestHarness) Options

func (h *TestHarness) Options(field string) (int, []FieldOption, error)

Options calls GET /ether/options/{field}.

func (*TestHarness) Request

func (h *TestHarness) Request(req RawRequest) RawResponse

Request dispatches a RawRequest against the plugin.

func (*TestHarness) Stream

func (h *TestHarness) Stream(typ, id string, extra map[string]string) (int, StreamResponse, error)

Stream calls GET /stream/{type}/{id}[/{extra}].json.

func (*TestHarness) Subtitles

func (h *TestHarness) Subtitles(typ, id, pickToken string, extra map[string]string) (int, SubtitlesResponse, RawResponse)

Subtitles calls GET /subtitles/{type}/{id}[/{extra}].json with optional pickToken.

func (*TestHarness) Test

func (h *TestHarness) Test() (int, TestResponse, error)

Test calls POST /ether/test.

func (*TestHarness) Tool

func (h *TestHarness) Tool(name string, input map[string]any) (int, ToolResponse, error)

Tool calls POST /ether/tool/{name}.

func (*TestHarness) View

func (h *TestHarness) View(page string, query map[string]string) (int, ViewResponse, error)

View calls GET /ether/view/{page} and validates the returned ViewSpecDocument.

type TestResponse

type TestResponse struct {
	OK      bool     `json:"ok"`
	Message string   `json:"message,omitempty"`
	Details []string `json:"details,omitempty"`
}

TestResponse is returned by a Test route handler.

type ToolMeta

type ToolMeta struct {
	Name        string         `json:"name"`
	Title       string         `json:"title"`
	Description string         `json:"description"`
	InputSchema map[string]any `json:"inputSchema"`
	ReadOnly    bool           `json:"readOnly,omitempty"`
	Destructive bool           `json:"destructive,omitempty"`
	OpenWorld   bool           `json:"openWorld,omitempty"`
}

ToolMeta describes an agent tool contributed by a plugin.

type ToolRequest

type ToolRequest struct {
	Name  string         `json:"name"`
	Input map[string]any `json:"input"`
}

ToolRequest is passed to a Tool route handler.

type ToolResponse

type ToolResponse map[string]any

ToolResponse is returned by a Tool route handler.

type TunnelError

type TunnelError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

TunnelError carries an error payload inside a TunnelFrame.

type TunnelFrame

type TunnelFrame struct {
	Type          string              `json:"type"`
	ID            string              `json:"id,omitempty"`
	RequestID     string              `json:"requestId,omitempty"`
	Protocol      string              `json:"protocol,omitempty"`
	Plugin        string              `json:"plugin,omitempty"`
	PluginID      string              `json:"pluginId,omitempty"`
	ConnectionID  string              `json:"connectionId,omitempty"`
	Features      []string            `json:"features,omitempty"`
	MaxChunkBytes int                 `json:"maxChunkBytes,omitempty"`
	Method        string              `json:"method,omitempty"`
	Path          string              `json:"path,omitempty"`
	Query         map[string][]string `json:"query,omitempty"`
	Headers       map[string][]string `json:"headers,omitempty"`
	Body          string              `json:"body,omitempty"`
	Data          string              `json:"data,omitempty"`
	Status        int                 `json:"status,omitempty"`
	Deadline      string              `json:"deadline,omitempty"`
	Error         *TunnelError        `json:"error,omitempty"`
}

TunnelFrame is one JSON message sent or received over the `ether-tunnel-v1` WebSocket.

type ViewRequest

type ViewRequest struct {
	Page  string            `json:"page"`
	Query map[string]string `json:"query"`
}

ViewRequest is passed to a View route handler.

type ViewResponse

type ViewResponse struct {
	Spec ViewSpecDocument `json:"spec"`
	Data map[string]any   `json:"data"`
}

ViewResponse is returned by a View route handler.

type ViewSpecDocument

type ViewSpecDocument struct {
	SpecVersion int              `json:"specVersion"`
	Layout      string           `json:"layout"`
	Route       string           `json:"route,omitempty"`
	Header      []map[string]any `json:"header"`
	Body        []map[string]any `json:"body"`
}

ViewSpecDocument is a declarative ViewSpec v1 page specification.

type ViewerPermissions

type ViewerPermissions struct {
	Identity        string `json:"identity,omitempty"`
	WatchHistory    string `json:"watch_history,omitempty"`
	WriteWatchState string `json:"write_watch_state,omitempty"`
}

ViewerPermissions scopes viewer identity and watch-history access.

type ViewerWatchEntry

type ViewerWatchEntry struct {
	TitleID   string `json:"titleId"`
	Title     string `json:"title,omitempty"`
	WatchedAt string `json:"watchedAt,omitempty"`
	Completed bool   `json:"completed,omitempty"`
}

ViewerWatchEntry is one watch-history entry returned by Host.ViewerHistory.

Jump to

Keyboard shortcuts

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