plugin

package
v1.0.12 Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultRegistryURL is the primary registry endpoint (Cloudflare Worker).
	DefaultRegistryURL = "https://plugins.nself.org/registry.json"

	// FallbackRegistryURL is the GitHub raw fallback when the primary is down.
	FallbackRegistryURL = "https://raw.githubusercontent.com/nself-org/plugins/main/registry.json"

	// DefaultCacheTTL is the registry cache lifetime in seconds.
	DefaultCacheTTL = 300
)

Variables

This section is empty.

Functions

func CacheLicense

func CacheLicense(key string, valid bool, cacheDir string) error

CacheLicense writes the validation result for a license key to a cache file inside cacheDir. The cache format is: {data}|{hmac_hex} where data is {key_prefix}|{status}|{timestamp} and hmac_hex is the HMAC-SHA256 of data keyed by machineID().

Before writing, it prunes any cache entries older than 30 days.

func CheckCLICompat added in v1.0.6

func CheckCLICompat(compat *CompatBlock, cliVersion string) error

CheckCLICompat checks whether cliVersion satisfies the plugin's compat.nself range. Returns nil if no compat block is set or if the version is in range.

func CheckComplianceJSON added in v1.0.6

func CheckComplianceJSON(ctx context.Context, name string, port int) ([]byte, error)

CheckComplianceJSON returns the compliance result as JSON bytes.

func CheckEOLBlock added in v1.0.11

func CheckEOLBlock(ctx context.Context, name string, allowEOL bool) error

CheckEOLBlock fetches the registry entry for name and returns an error if the plugin's status is "eol" and allowEOL is false. (S58-T03) If the registry cannot be reached or the plugin is not found, this function returns nil (install will fail downstream with a more specific error). This is intentionally a pre-flight check: it does not install anything.

func CheckServiceCompat added in v1.0.6

func CheckServiceCompat(compat *CompatBlock, actual map[string]string) []string

CheckServiceCompat checks whether each service version in actual satisfies the corresponding constraint in compat.requires. Returns a list of services that fail the check.

func CompareVersions added in v1.0.11

func CompareVersions(a, b string) int

CompareVersions compares two semver strings a and b. Returns -1 if a < b, 0 if a == b, +1 if a > b. (S58-T06)

func DefaultCacheDir added in v1.0.11

func DefaultCacheDir() string

DefaultCacheDir is the exported alias of defaultCacheDir for use by commands that need to call FetchRegistry directly. (S58-T06)

func DisablePlugin added in v1.0.2

func DisablePlugin(name, pluginDir string) error

DisablePlugin creates a .disabled marker file in the plugin's directory, causing it to be excluded from compose files on the next build.

func EnablePlugin added in v1.0.2

func EnablePlugin(name, pluginDir string) error

EnablePlugin removes the .disabled marker file from the plugin's directory, allowing it to be included in compose files on the next build.

func GenerateEd25519Keypair added in v1.0.12

func GenerateEd25519Keypair(pluginDataDir, pluginName string) (pubKey ed25519.PublicKey, err error)

GenerateEd25519Keypair generates a new Ed25519 keypair and writes the encrypted private key to PLUGIN_DATA_DIR/<name>/identity.key. It returns the public key bytes (32 bytes) for registration with ping_api.

The encryption key is derived from PLUGIN_INTERNAL_SECRET and the plugin name using HKDF-SHA256 so each plugin has a unique encryption key.

func IdentityKeyExists added in v1.0.12

func IdentityKeyExists(pluginDataDir, pluginName string) bool

IdentityKeyExists reports whether a plugin identity key file is present on disk. It does NOT validate the key contents.

func IncompatiblePlugins added in v1.0.6

func IncompatiblePlugins(pluginDir, newCLIVersion string) []string

IncompatiblePlugins checks all installed plugins and returns a list of those whose compat.nself range will not be satisfied by newCLIVersion. This is used by `nself upgrade` to warn the user before upgrading.

func Install

func Install(ctx context.Context, cfg *config.Config, name string, pluginDir string) error

Install downloads, extracts, and configures a plugin. For paid plugins it checks the license first. Dependencies are resolved and recursively installed before the target plugin. If any step after extraction fails, the extracted directory and database schema are rolled back.

A file lock on {pluginDir}/.install.lock is held for the duration of the operation to prevent concurrent installs from corrupting plugin state.

func IsDisabled added in v1.0.2

func IsDisabled(name, pluginDir string) bool

IsDisabled returns true if the named plugin has a .disabled marker file.

func IsFreeKey added in v1.0.12

func IsFreeKey(key string) bool

IsFreeKey returns true if the key is a nself_free_ key.

func IsPaidPlugin added in v1.0.12

func IsPaidPlugin(name string) bool

IsPaidPlugin is the exported wrapper around the package-private isPaidPlugin. Returns true if the named plugin requires a paid license key.

func LicenseCacheDir

func LicenseCacheDir() string

LicenseCacheDir returns the directory used for license validation caching. This is ~/.nself/license/ (or /tmp/.nself/license/ if the home directory cannot be determined).

func LoadPrivateKey added in v1.0.12

func LoadPrivateKey(pluginDataDir, pluginName string) (ed25519.PrivateKey, error)

LoadPrivateKey decrypts and returns the Ed25519 private key stored at PLUGIN_DATA_DIR/<name>/identity.key. Returns an error if the key does not exist, cannot be decrypted, or the file has been corrupted.

func NeedsRevalidation

func NeedsRevalidation(key string, cacheDir string) bool

NeedsRevalidation returns true if the license cache in cacheDir is missing, tampered with, or if the most recent validation timestamp is older than revalidationInterval (7 days). This is used during nself start to trigger a periodic heartbeat check against the license server. Owner keys never need revalidation.

func ProxyCommand

func ProxyCommand(cmdName string, args []string) error

ProxyCommand checks if a plugin binary exists and executes it. If not, it instructs the user to install it.

For security, the binary is looked up ONLY in the plugin bin directory, never via the full system PATH. This prevents PATH hijacking attacks.

func RegisterFreeAccount added in v1.0.12

func RegisterFreeAccount(ctx context.Context, pingURL string) (string, error)

RegisterFreeAccount calls ping_api to create a new nself_free_ key. Returns the raw key string on success.

func RegisterIdentity added in v1.0.12

func RegisterIdentity(ctx context.Context, pluginName string, pubKey ed25519.PublicKey) error

RegisterIdentity posts the plugin's public key to ping_api. pubKey is the raw 32-byte Ed25519 public key returned by GenerateEd25519Keypair.

If the plugin has previously registered (e.g., re-install without uninstall), this is treated as a "register" action; ping_api will update the record if the plugin_name already exists (idempotent).

func Remove

func Remove(ctx context.Context, cfg *config.Config, name string, pluginDir string, keepData bool, force bool) error

Remove stops a plugin (if running), optionally drops its database schema, and removes its directory from disk. When force is false and other installed plugins depend on the target, Remove returns an error listing them.

A file lock on {pluginDir}/.install.lock is held for the duration of the operation so that concurrent install and remove calls serialize correctly.

func RemoveIdentityKey added in v1.0.12

func RemoveIdentityKey(pluginDataDir, pluginName string) error

RemoveIdentityKey deletes the stored identity key for a plugin. This is called during uninstall so the revocation endpoint can be called before the key is removed from disk.

func RequestToken added in v1.0.12

func RequestToken(ctx context.Context, pluginDataDir, sourcePlugin, targetPlugin string) (string, error)

RequestToken authenticates sourcePlugin with ping_api via Ed25519 challenge-response and returns a 5-minute JWT scoped to targetPlugin. The private key for sourcePlugin must already exist on disk (generated during plugin install).

func RevokeIdentity added in v1.0.12

func RevokeIdentity(ctx context.Context, pluginName string) error

RevokeIdentity calls DELETE /plugin/identity/<name> on ping_api to mark the plugin identity as revoked. Call this before removing the private key from disk so that in-flight tokens issued to this plugin are rejected promptly.

Auth: the owner license key from NSELF_PLUGIN_LICENSE_KEY is used as the authorization credential for the delete endpoint.

func SatisfiesRange added in v1.0.6

func SatisfiesRange(version, rangeStr string) (bool, error)

SatisfiesRange checks whether version satisfies a space-separated list of semver constraints. All constraints must be satisfied (AND logic). Supported operators: >=, <=, >, <, =, != Examples: ">=1.0.0 <2.0.0", ">=14", ">=2.30"

func SendFreeInstallTelemetry added in v1.0.12

func SendFreeInstallTelemetry(pingURL string, licenseKey string, pluginName string)

SendFreeInstallTelemetry fires a non-blocking install event to ping_api. Errors are silently discarded — telemetry must never block installs.

func Start

func Start(ctx context.Context, pluginDir string, name string) error

Start launches a plugin process in the background. It locates the plugin's entry point inside pluginDir, starts it, writes the PID to ~/.nself/runtime/pids/{name}.pid, and records the state in ~/.nself/runtime/states/{name}.state.

func Stop

func Stop(ctx context.Context, name string) error

Stop gracefully shuts down a running plugin. It sends SIGTERM first, waits up to gracePeriod() for the process to exit, then sends SIGKILL if it is still alive. The grace window respects DOCKER_STOP_GRACE_PERIOD env var to match the compose layer's stop_grace_period (default 30s). PID and state files are cleaned up.

func Update

func Update(ctx context.Context, cfg *config.Config, name string, pluginDir string) error

Update backs up the current installation, then reinstalls from the registry. If the new install fails, the previous version is restored automatically.

func ValidateIncomingJWT added in v1.0.12

func ValidateIncomingJWT(ctx context.Context, tokenStr, expectedAudience string, store ReplayStore) error

ValidateIncomingJWT validates a JWT presented in an inter-plugin HTTP call. expectedAudience is the short plugin name (e.g., "mux"), NOT the full aud claim (which has the "plugin:" prefix).

Returns nil on success, a descriptive error on any validation failure.

func ValidateLicenseRemote

func ValidateLicenseRemote(ctx context.Context, key string, pingURL string) (bool, error)

ValidateLicenseRemote performs a remote license check by POSTing to the given pingURL. It returns (true, nil) on HTTP 200, (false, nil) on 401/403/404, and (false, error) on network or unexpected failures.

func ValidateNetworkAccess

func ValidateNetworkAccess(ctx context.Context, registryURL string) error

ValidateNetworkAccess does a HEAD request to the registry URL. Returns an error with a clear message if the registry is unreachable. Call before any operation that requires network access to the plugin registry.

Types

type CLICommand

type CLICommand struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

CLICommand describes a CLI command provided by a plugin.

type CompatBlock added in v1.0.6

type CompatBlock struct {
	Nself    string            `json:"nself,omitempty" yaml:"nself,omitempty"`
	Requires map[string]string `json:"requires,omitempty" yaml:"requires,omitempty"`
}

CompatBlock describes the compatibility requirements declared by a plugin manifest. The Nself field is a semver range constraint for the CLI version (e.g. ">=1.0.0 <2.0.0"). Requires maps service names to their own semver range constraints (e.g. "postgres": ">=14", "hasura": ">=2.30").

type ComplianceResult added in v1.0.6

type ComplianceResult struct {
	PluginName string
	Compliant  bool
	Endpoints  []EndpointCheck
}

ComplianceResult holds the outcome of a plugin compliance check.

func CheckCompliance added in v1.0.6

func CheckCompliance(ctx context.Context, name string, port int) *ComplianceResult

CheckCompliance verifies that a running plugin implements the standard interface endpoints (/health, /version, /capabilities). Non-compliant plugins log a warning but are not stopped.

type DeprecationBlock added in v1.0.11

type DeprecationBlock struct {
	AnnouncedDate   string `json:"announcedDate"`
	EOLDate         string `json:"eolDate"`
	ReplacedBy      string `json:"replacedBy,omitempty"`
	MigrationGuide  string `json:"migrationGuide"`
	MigrationScript string `json:"migrationScript,omitempty"`
}

DeprecationBlock carries the required deprecation metadata when a plugin's status is "deprecated". All five fields must be present (S58-T02). announcedDate and eolDate are ISO 8601 date strings (YYYY-MM-DD). replacedBy is the name of the replacement plugin (optional but recommended). migrationGuide is a URL that must resolve with HTTP 200 at CI time. migrationScript is a repo-relative path to an automated migration script (optional).

type EndpointCheck added in v1.0.6

type EndpointCheck struct {
	Path      string
	Available bool
	Status    int
}

EndpointCheck records whether a specific endpoint responded.

type EnvVar

type EnvVar struct {
	Name        string `json:"name"`
	Required    bool   `json:"required"`
	Description string `json:"description"`
	Default     string `json:"default,omitempty"`
}

EnvVar describes an environment variable required or used by a plugin.

type ExitCodeError added in v1.0.2

type ExitCodeError struct {
	Code int
}

ExitCodeError is returned when a plugin process exits with a non-zero code. The caller (main) should call os.Exit with Code.

func (*ExitCodeError) Error added in v1.0.2

func (e *ExitCodeError) Error() string

type InstalledPluginInfo

type InstalledPluginInfo struct {
	Name        string
	Version     string
	Tier        string
	Status      string
	Description string
}

InstalledPluginInfo is a richer view of an installed plugin used by the inventory subcommand. It includes Description and Tier from the manifest.

func ListInstalled

func ListInstalled(pluginDir string) ([]InstalledPluginInfo, error)

ListInstalled scans pluginDir and returns detailed information for every installed plugin. Each entry's Status is "running", "installed", or "unknown" depending on the plugin's current runtime state.

type LicenseClient

type LicenseClient interface {
	Validate(ctx context.Context, key string) (bool, error)
}

LicenseClient abstracts license validation for testability.

type LicenseValidateResponse added in v1.0.4

type LicenseValidateResponse struct {
	Valid   bool     `json:"valid"`
	Reason  string   `json:"reason,omitempty"`
	Tier    string   `json:"tier"`
	Plugins []string `json:"plugins"`
	Expires string   `json:"expires,omitempty"`
}

LicenseValidateResponse is the JSON body returned by the license validation endpoint on HTTP 200. The Tier and Plugins fields are used to populate the local entitlement cache.

func ValidateLicenseRemoteWithDetails added in v1.0.4

func ValidateLicenseRemoteWithDetails(ctx context.Context, key string, pingURL string) (bool, *LicenseValidateResponse, error)

ValidateLicenseRemoteWithDetails performs a remote license check and returns the full response including tier, plugins, and expiry information.

type MultiApp

type MultiApp struct {
	Supported       bool   `json:"supported"`
	IsolationColumn string `json:"isolationColumn,omitempty"`
	PKStrategy      string `json:"pkStrategy,omitempty"`
	DefaultValue    string `json:"defaultValue,omitempty"`
}

MultiApp describes multi-tenancy configuration for a plugin.

type PluginGraphQLBlock added in v1.0.12

type PluginGraphQLBlock struct {
	// Enabled must be true for this plugin to register as a subgraph.
	Enabled bool `json:"enabled" yaml:"enabled"`
	// SubgraphName is the unique lowercase subgraph identifier.
	// Must not be "hasura" (reserved). Format: [a-z][a-z0-9_]*.
	SubgraphName string `json:"subgraph_name" yaml:"subgraph_name"`
	// SubgraphURL is the HTTP endpoint serving the subgraph SDL.
	// ${PORT} is substituted with the plugin's declared Port field.
	SubgraphURL string `json:"subgraph_url" yaml:"subgraph_url"`
	// SchemaPath is a repo-relative path to the static SDL file.
	// Used by rover supergraph compose. Optional when SubgraphURL is live.
	SchemaPath string `json:"schema_path,omitempty" yaml:"schema_path,omitempty"`
	// Entities lists Apollo Federation entity types this subgraph owns.
	Entities []PluginGraphQLEntityKey `json:"entities,omitempty" yaml:"entities,omitempty"`
}

PluginGraphQLBlock is the graphql: block in a plugin manifest. When Enabled is true and NSELF_FEDERATION=true, nself build registers this plugin as a subgraph in the Apollo Router supergraph (G05).

type PluginGraphQLEntityKey added in v1.0.12

type PluginGraphQLEntityKey struct {
	// Type is the GraphQL type name (e.g. "User").
	Type string `json:"type" yaml:"type"`
	// Key is the @key field used for entity resolution (e.g. "id").
	Key string `json:"key" yaml:"key"`
}

PluginGraphQLEntityKey describes a single Apollo Federation entity type that a plugin subgraph owns. Used for cross-subgraph entity resolution.

type PluginInfo

type PluginInfo struct {
	Name          string
	Version       string
	Category      string
	Installed     bool
	Running       bool
	PublishStatus string // S58-T01: "experimental"|"planned"|"beta"|"stable"|"deprecated"|"eol" — from registry
}

PluginInfo describes a plugin's identity and current state.

func List

func List(pluginDir string, installed bool) ([]PluginInfo, error)

List returns plugin information. When installed is true it scans pluginDir for locally installed plugins. When false it returns all plugins known to the registry.

type PluginManifest

type PluginManifest struct {
	// Required fields
	Name        string `json:"name"`
	Version     string `json:"version"`
	Description string `json:"description"`
	Category    string `json:"category"`
	License     string `json:"license"`

	// Optional metadata
	Author               string   `json:"author,omitempty"`
	Homepage             string   `json:"homepage,omitempty"`
	Repository           string   `json:"repository,omitempty"`
	Tags                 []string `json:"tags,omitempty"`
	IsCommercial         bool     `json:"isCommercial,omitempty"`
	LicenseType          string   `json:"licenseType,omitempty"`
	RequiredEntitlements []string `json:"requiredEntitlements,omitempty"`
	RequiresLicense      bool     `json:"requires_license,omitempty"`
	MinNselfVersion      string   `json:"minNselfVersion,omitempty"`
	MinNodeVersion       string   `json:"minNodeVersion,omitempty"`
	ArchSupport          []string `json:"arch_support,omitempty"`

	// Implementation
	Language       string `json:"language,omitempty"`
	Runtime        string `json:"runtime,omitempty"`
	Port           int    `json:"port,omitempty"`
	EntryPoint     string `json:"entryPoint,omitempty"`
	CLI            string `json:"cli,omitempty"`
	HealthEndpoint string `json:"health_endpoint,omitempty"`
	PackageManager string `json:"packageManager,omitempty"`
	Framework      string `json:"framework,omitempty"`

	// Database
	Tables []string `json:"tables,omitempty"`
	Views  []string `json:"views,omitempty"`

	// API
	APIEndpoints []string     `json:"apiEndpoints,omitempty"`
	Webhooks     []string     `json:"webhooks,omitempty"`
	CLICommands  []CLICommand `json:"cliCommands,omitempty"`

	// Environment
	EnvVars []EnvVar `json:"envVars,omitempty"`

	// Dependencies
	Dependencies         []string           `json:"dependencies,omitempty"`
	OptionalDependencies []string           `json:"optionalDependencies,omitempty"`
	SystemDependencies   SystemDependencies `json:"systemDependencies,omitempty"`

	// Inter-plugin communication contract (S43-T17).
	// Consumes lists the plugin names whose HTTP APIs this plugin may call via
	// X-Source-Plugin. Every entry must be installed for this plugin to work
	// correctly; install-time validation enforces this.
	// Provides lists the API services this plugin exposes for other plugins to
	// consume. Both fields use plugin name format (lowercase-with-hyphens).
	Consumes []string `json:"consumes,omitempty"`
	Provides []string `json:"provides,omitempty"`

	// Multi-tenancy
	MultiApp MultiApp `json:"multiApp,omitempty"`

	// Permissions
	Permissions []string `json:"permissions,omitempty"`

	// Compatibility
	Compat *CompatBlock `json:"compat,omitempty"`

	// Registry-specific fields (not in plugin.json, populated by registry)
	Tier     string `json:"tier,omitempty"`
	Checksum string `json:"checksum,omitempty"`

	// PublishStatus is the plugin's lifecycle status from the registry (S58-T01).
	// Valid values: "experimental" | "planned" | "beta" | "stable" | "deprecated" | "eol"
	// Missing status defaults to "stable" for backwards compatibility (CR-A).
	// "planned"     — not yet installable; rejected at install time.
	// "experimental"— early-access; installs with a prominent warning.
	// "beta"        — pre-stable; installs with a warning.
	// "stable"      — default production-ready state; no warning.
	// "deprecated"  — install warns and offers replacedBy alternative if set.
	//                 Requires a Deprecation block in the manifest.
	// "eol"         — install blocked by default; --allow-eol override required.
	PublishStatus string `json:"status,omitempty"`

	// Deprecation carries the required metadata when status == "deprecated". (S58-T02)
	// All five fields are required when the block is present.
	Deprecation *DeprecationBlock `json:"deprecation,omitempty"`

	// GraphQL carries the Apollo Federation subgraph registration for this
	// plugin. When graphql.enabled is true and NSELF_FEDERATION=true, the
	// build pipeline includes this plugin as a subgraph in the Apollo Router
	// supergraph. The field is ignored in non-federation deployments (G05).
	GraphQL *PluginGraphQLBlock `json:"graphql,omitempty"`

	// MaxNselfVersion is the last CLI version this plugin is compatible with. (S58-T06)
	// Empty means "no upper bound". compat-check reads this field.
	MaxNselfVersion string `json:"maxNselfVersion,omitempty"`

	// AuthorPublicKey is the hex-encoded Ed25519 public key of the plugin
	// publisher, pinned in the registry. Used to verify Signature.
	AuthorPublicKey string `json:"author_public_key,omitempty"`

	// Signature is the hex-encoded Ed25519 signature of the tarball checksum.
	// Format: Ed25519Sign(privateKey, sha256(tarball)).
	// Pinned in registry alongside AuthorPublicKey.
	Signature string `json:"signature,omitempty"`
}

PluginManifest describes a single plugin, parsed from plugin.json.

func FindPluginByName added in v1.0.11

func FindPluginByName(reg *Registry, name string) (*PluginManifest, bool)

FindPluginByName is the exported wrapper around findPlugin for use by commands outside the plugin package. (S58-T06)

func LoadManifestsFromDir added in v1.0.12

func LoadManifestsFromDir(pluginDir string) ([]*PluginManifest, error)

LoadManifestsFromDir scans pluginDir and returns the full PluginManifest for every installed plugin. It is the full-manifest counterpart to ListInstalled, used by features that need manifest fields beyond name/version/tier/status (e.g., federation's GraphQL block). Directories without a valid plugin.json are silently skipped. If pluginDir does not exist, nil is returned.

type PluginStatus

type PluginStatus struct {
	Name  string
	State string // starting, running, stopping, stopped, failed
	PID   int
}

PluginStatus describes the current state of a plugin process.

func Status

func Status(name string) (*PluginStatus, error)

Status returns the current status of a plugin by reading its PID and state files. If the PID file indicates a process that is no longer running, the state is corrected to "stopped".

type Registry

type Registry struct {
	Plugins []PluginManifest
}

Registry represents the full plugin registry response.

func FetchRegistry

func FetchRegistry(ctx context.Context, registryURL string, cacheDir string) (*Registry, error)

FetchRegistry is the standalone entry point for fetching a registry. It creates an ephemeral client and delegates to Fetch.

Fallback chain:

  1. registryURL (default: https://plugins.nself.org/registry.json)
  2. GitHub raw fallback
  3. Stale cache at cacheDir/registry.json

func (Registry) MarshalJSON

func (r Registry) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for Registry so the cache round-trips through the array format consistently.

type RegistryClient

type RegistryClient interface {
	Fetch(ctx context.Context) (*Registry, error)
	GetPlugin(ctx context.Context, name string) (*PluginManifest, error)
}

RegistryClient abstracts plugin registry HTTP operations for testability.

type ReplayStore added in v1.0.12

type ReplayStore interface {
	// Seen returns true and records the jti if it has not been seen before.
	// The entry expires after ttl. Returns (false, nil) if jti is new.
	Seen(ctx context.Context, jti string, ttl time.Duration) (bool, error)
}

ReplayStore is the interface for jti replay caching. A Redis-backed implementation is provided by the shared auth package. A no-op shim is used when Redis is unavailable (degrades replay protection, logs a warning).

type StandardEndpoint added in v1.0.6

type StandardEndpoint struct {
	Path     string
	Required bool // if false, missing endpoint is a warning not an error
}

StandardEndpoint describes one of the standard plugin interface endpoints.

type SystemDependencies

type SystemDependencies struct {
	Required    []SystemDependency `json:"required,omitempty"`
	Recommended []SystemDependency `json:"recommended,omitempty"`
}

SystemDependencies groups required and recommended system deps.

type SystemDependency

type SystemDependency struct {
	Name          string `json:"name"`
	Verify        string `json:"verify"`
	MinVersion    string `json:"minVersion,omitempty"`
	Apt           string `json:"apt,omitempty"`
	Brew          string `json:"brew,omitempty"`
	CustomInstall string `json:"custom_install,omitempty"`
}

SystemDependency describes a system-level dependency for a plugin.

Directories

Path Synopsis
Package scaffold provides the canonical plugin scaffolding logic shared between the nself CLI (plugin new command) and the standalone new-plugin binary in plugin-sdk-go/devkit.
Package scaffold provides the canonical plugin scaffolding logic shared between the nself CLI (plugin new command) and the standalone new-plugin binary in plugin-sdk-go/devkit.

Jump to

Keyboard shortcuts

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