manifest package - github.com/FacileStudio/facile/internal/manifest - Go Packages

manifest

package
v0.12.1 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Auth

type Auth struct {
	// Kind is the flow facile runs: none, sso, oidc-device, password, device
	// or token. "token" means the credential is minted elsewhere and pasted
	// in. "device" is a tool's own headless endpoints; "oidc-device" is the
	// RFC 8628 grant at the shared identity provider, and the two are not the
	// same protocol — the prefix is there so the difference is visible here.
	Kind string `yaml:"kind"`

	// DefaultServerURL may be empty. A self-hosted appliance is right to refuse
	// to guess an address, so an empty default means facile must ask.
	DefaultServerURL string `yaml:"defaultServerUrl"`

	// APISuffix is appended when the user gives a bare origin. Some CLIs store
	// the API root rather than the site root and 404 on everything without it.
	APISuffix string `yaml:"apiSuffix"`

	// DiscoveryPath returns {sso_only, oidc_enabled} so facile can pick a flow
	// without asking the user what their instance is configured for.
	DiscoveryPath string `yaml:"discoveryPath"`

	// Flows and Env are grouped rather than listed so this struct stays under
	// filet's field cap as kinds are added. Both are inlined: the YAML is flat
	// and unchanged, and Go promotes the fields, so a.SSO and a.EnvToken still
	// read the way they always did.
	Flows `yaml:",inline"`

	// IdentityPath is fetched after login purely to name who signed in.
	IdentityPath string `yaml:"identityPath"`

	// TokenPath is the page where a human mints the credential by hand, for
	// the tools that have no login endpoint to drive. facile opens it rather
	// than telling the user to go and find it.
	TokenPath string `yaml:"tokenPath"`

	// Transport is how the credential is later presented: bearer or cookie.
	Transport  string `yaml:"transport"`
	CookieName string `yaml:"cookieName"`

	Env `yaml:",inline"`

	Store *Store `yaml:"store"`

	// Note explains a tool that cannot be logged into, so facile can say why
	// instead of pretending the command did something.
	Note string `yaml:"note"`
}

Auth describes how a tool authenticates and, crucially, where it expects to find its credential afterwards. `facile login` drives the flow and then writes the result into that exact location, so the tool itself needs no change to benefit. Every field here was read off a real CLI, not invented.

type DeviceFlow

type DeviceFlow struct {
	StartPath string `yaml:"startPath"`
	PollPath  string `yaml:"pollPath"`
}

DeviceFlow is the headless path: no browser on the machine being authorized.

type Env added in v0.10.0

type Env struct {
	EnvToken string `yaml:"envToken"`
	EnvURL   string `yaml:"envUrl"`
}

Env is the pair of environment variables that override what facile stored. EnvToken matters at logout: a variable still set keeps working, and the user would otherwise think the logout failed.

type Flows added in v0.10.0

type Flows struct {
	SSO        *SSOFlow        `yaml:"sso"`
	OIDCDevice *OIDCDeviceFlow `yaml:"oidcDevice"`
	Password   *PasswordFlow   `yaml:"password"`
	Device     *DeviceFlow     `yaml:"device"`
}

Flows are the four handshakes a tool can declare. A tool may declare several — a device sign-in keeps its loopback flow, and both keep the tool's own password endpoint — and Kind says which one facile prefers.

type Manifest

type Manifest struct {
	Version int    `yaml:"version"`
	Tools   []Tool `yaml:"tools"`
}

Manifest is the whole catalog.

func Load

func Load(cachePath string) *Manifest

Load returns the catalog, preferring a fresh remote copy and falling back to the copy embedded at build time. A network failure is never fatal: an installer that cannot install because GitHub is slow would be a poor trade.

FACILE_CATALOG points at a local file and wins over everything, which is the only way to try a catalog edit without publishing it first.

func Refresh

func Refresh(cachePath string) (*Manifest, error)

Refresh forces a fetch from the remote catalog and updates the cache.

func (*Manifest) Get

func (m *Manifest) Get(name string) (Tool, bool)

Get returns the tool with the given name.

func (*Manifest) Names

func (m *Manifest) Names() []string

Names returns every tool name in catalog order.

type OIDCDeviceFlow added in v0.10.0

type OIDCDeviceFlow struct {
	// Issuer is the OIDC issuer. Endpoints come from its discovery document,
	// never from paths assembled here: on this provider a per-application
	// discovery path answers 200 with the single-page app's HTML, which is a
	// false positive that has already misled two investigations.
	Issuer string `yaml:"issuer"`

	// ClientID names a public client. A CLI ships on the user's machine and
	// cannot keep a secret, so there is none here and none is sent.
	ClientID string `yaml:"clientId"`

	// Scopes are space separated, as OAuth spells them. profile and email are
	// what the app needs to name the account behind the token.
	Scopes string `yaml:"scopes"`

	// ExchangePath trades the provider's access token for the tool's own
	// credential, because what the tool reads is its own session and not the
	// provider's — the same reason the loopback flow exchanges a code rather
	// than storing it. The prefix mirrors this tool's SSO exchange path: an
	// app serving its API under /api serves both under /api.
	ExchangePath string `yaml:"exchangePath"`
}

OIDCDeviceFlow is RFC 8628 run against the suite's identity provider rather than against the tool. It exists because the loopback flow assumes the browser is on the machine that started the login: when it is not, the provider redirects the wrong machine's browser to 127.0.0.1 and the login hangs until the code expires. Here nothing is redirected anywhere — the user carries a short code to whatever device has the browser.

A tool declaring this keeps its SSO block. The loopback flow stays the same-machine path and is what runs when the provider does not advertise the grant, so a catalog entry can name the device flow before the provider serves it.

type PasswordFlow

type PasswordFlow struct {
	Path string `yaml:"path"`

	// WithEmail distinguishes a multi-user login from a single instance password.
	WithEmail bool `yaml:"withEmail"`

	// TokenField is empty when the credential comes back as a Set-Cookie header.
	TokenField string `yaml:"tokenField"`
}

PasswordFlow posts credentials to the tool's own API.

type SSOFlow

type SSOFlow struct {
	StartPath    string `yaml:"startPath"`
	PortParam    string `yaml:"portParam"`
	StateParam   string `yaml:"stateParam"`
	ExtraParams  string `yaml:"extraParams"`
	CallbackWith string `yaml:"callbackWith"`
	ExchangePath string `yaml:"exchangePath"`

	// CallbackPath is the loopback path the server redirects to, and it is not
	// the same everywhere: casier redirects to /callback, porte — and so
	// sablier — redirects to /. Empty means /callback.
	CallbackPath string `yaml:"callbackPath"`

	// RequireState is false only where the server does not echo the nonce back
	// yet. It is a defect to be fixed server-side, never a setting to prefer.
	RequireState bool `yaml:"requireState"`
}

SSOFlow is the browser round trip. The callback carries either the token directly or a one-time code to exchange; the code form is preferred, since a token in a query string lands in browser history.

type Store

type Store struct {
	Kind string `yaml:"kind"`

	KeychainService string `yaml:"keychainService"`
	KeychainAccount string `yaml:"keychainAccount"`

	Path       string   `yaml:"path"`
	Format     string   `yaml:"format"`
	TokenField string   `yaml:"tokenField"`
	URLField   string   `yaml:"urlField"`
	Mode       uint32   `yaml:"mode"`
	DirMode    uint32   `yaml:"dirMode"`
	Preserve   bool     `yaml:"preserve"`
	Extra      []string `yaml:"extra"`
}

Store is where the credential lands. Getting a single character wrong here means facile writes a token the tool will never read, so these values are transcribed from each CLI's own read path rather than chosen.

type Tool

type Tool struct {
	Name         string   `yaml:"name"`
	Summary      string   `yaml:"summary"`
	Repo         string   `yaml:"repo"`
	Branch       string   `yaml:"branch"`
	Bin          string   `yaml:"bin"`
	Build        string   `yaml:"build"`
	SrcSubdir    string   `yaml:"srcSubdir"`
	Asset        string   `yaml:"asset"`
	Skill        string   `yaml:"skill"`
	GoVersionVar string   `yaml:"goVersionVar"`
	Requires     []string `yaml:"requires"`
	Auth         *Auth    `yaml:"auth"`
}

Tool is one installable Facile CLI. The field names mirror the config block of the per-repo install.sh so a divergence between the two is easy to spot.

func (Tool) AuthKind added in v0.3.0

func (t Tool) AuthKind() string

AuthKind is the flow this tool needs, or "none".

func (Tool) EnvToken added in v0.2.0

func (t Tool) EnvToken() string

EnvToken is the environment variable that overrides the stored credential.

func (Tool) Federates added in v0.10.0

func (t Tool) Federates() bool

Federates reports whether this tool signs in through the shared identity provider. Those flows run first: the first of them authenticates and the rest complete without the user touching anything, which is only worth anything if they are not queued behind a prompt.

func (Tool) NeedsLogin

func (t Tool) NeedsLogin() bool

NeedsLogin reports whether `facile login` can do anything for this tool.

func (Tool) Note added in v0.2.0

func (t Tool) Note() string

Note is why a tool cannot be logged into, or what is unusual about how it stores its credential. Empty when there is nothing to say.

func (Tool) TokenPage added in v0.3.0

func (t Tool) TokenPage(serverURL string) string

TokenPage is where a human goes to mint the credential themselves. Only the tools with no login endpoint have one, and opening it beats printing a sentence that sends the user hunting through a dashboard for the right page.

Jump to

Keyboard shortcuts

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