Documentation
¶
Overview ¶
Package tapper — shared OAuth2 hub helpers.
This file holds the hub-auth building blocks that are independent of any single grant type: RFC 8414 authorization-server metadata discovery, hub URL normalization/canonicalization, and opening the user's browser. The device authorization grant (auth_device_flow.go) composes these; there is no longer a loopback/PKCE flow — `tap auth login` standardizes on the device flow for browser-based login.
The metadata + browser helpers take their external dependencies (HTTP client, runtime) as arguments so the flow stays trivially testable against an httptest.Server mock hub.
Package tapper — OAuth2 refresh-token renewal for cached hub credentials.
The device-login flow now persists a refresh token (plus the client_id and token endpoint it must be presented to) alongside the short-lived access token. RefreshHubToken exchanges that refresh token for a fresh access token so a command whose cached token has expired renews silently instead of forcing the user back through `tap auth login`.
Package tapper — hub authentication store.
AuthStore is the on-disk credentials cache used by the hub-auth flow. It maps a canonical hub URL to an access token and token metadata. The store is intentionally minimal — it does not know how to refresh tokens, talk to a hub, or check expiry. Those concerns live in the caller so the store can stay time-agnostic (no clock dependency) and therefore trivially testable under a frozen clock.
File layout: YAML at <StateRoot>/auth.yaml, mode 0600, parent dir 0700 when we create it. Writes go through rt.AtomicWriteFile so a crash or concurrent reader never sees a half-written credential file.
Package tapper — hub token validation via the whoami probe.
ValidateToken confirms a bearer token resolves to a user on the hub. It backs the "paste an authentication token" login path: the token the user pastes (an API token minted on the hub's account page) is checked against GET /api/v1/whoami before it is written to the AuthStore, so a typo or a revoked token fails fast at login rather than on the first real request.
Package tapper — hub keg-administration client calls (grants + visibility).
These talk to a remote hub's per-keg admin endpoints under /api/v1/@{namespace}/kegs/{keg}: listing/creating/revoking grants and updating visibility. Like ValidateToken (auth_whoami.go) and CreateKeg (hub_kegs.go) they are slim, dependency-free functions over http.DefaultClient so tests can point hubURL at an httptest.Server.
Package tapper — hub keg-catalog client calls.
These talk to a remote hub's namespace/keg-catalog endpoints (as opposed to the per-keg operation API in pkg/keg/keg_remote.go): creating a keg and listing the kegs a user can reach. They mirror the slim, dependency-free shape of ValidateToken (auth_whoami.go) — a stand-alone function over http.DefaultClient so tests can point hubURL at an httptest.Server.
Package tapper — hub namespace-administration client calls.
These talk to a remote hub's namespace endpoints under /api/v1/namespaces and /api/v1/@{namespace}/members: listing namespaces and managing membership roles. Slim, dependency-free functions over http.DefaultClient (via doHubJSON) so tests can point hubURL at an httptest.Server.
Index ¶
- Constants
- Variables
- func AddNamespaceMember(ctx context.Context, hubURL, token, namespace, username, role string) error
- func CanonicalHubURL(s string) string
- func CreateGrant(ctx context.Context, hubURL, token, namespace, alias, username, role string) error
- func CreateKeg(ctx context.Context, hubURL, token, namespace, alias, title, visibility string) error
- func DeleteHubFlight(ctx context.Context, hubURL, token, namespace, slug string) error
- func IntegrateHosts() []string
- func IntegratePlugins(host string) ([]string, error)
- func KegBackendLabel(target *keg.Target) string
- func KegLocation(target *keg.Target) string
- func LocalGitData(ctx context.Context, rt *toolkit.Runtime, projectPath, key string) ([]byte, error)
- func NewAuthStoreTokenResolver(store *AuthStore, rt *toolkit.Runtime, storePath string) keg.TokenResolver
- func OpenBrowser(ctx context.Context, rt *toolkit.Runtime, rawURL string) error
- func RemoveNamespaceMember(ctx context.Context, hubURL, token, namespace, username string) error
- func RenameKeg(ctx context.Context, hubURL, token, namespace, oldAlias, newAlias string) error
- func ResolveLoginHubURL(cfg *Config, explicit string) (string, error)
- func RevokeGrant(ctx context.Context, hubURL, token, namespace, alias, username string) error
- func SetKegVisibility(ctx context.Context, hubURL, token, namespace, alias, visibility string) error
- func SetNamespaceMemberRole(ctx context.Context, hubURL, token, namespace, username, role string) error
- func ValidateKegAlias(alias string) error
- func ValidateNamespace(ns string) error
- func WalkConfigsUp(rt *toolkit.Runtime, start, rel string) []string
- type AuthEntry
- type AuthLoginDeviceOptions
- type AuthLogoutOptions
- type AuthLogoutResult
- type AuthStatusHub
- type AuthStatusOptions
- type AuthStatusResult
- type AuthStore
- func (s *AuthStore) Delete(hubURL string) bool
- func (s *AuthStore) Get(hubURL string) (*AuthEntry, bool)
- func (s *AuthStore) Hubs() []string
- func (s *AuthStore) IsEmpty() bool
- func (s *AuthStore) Save(ctx context.Context, rt *toolkit.Runtime, path string) error
- func (s *AuthStore) Set(hubURL string, entry AuthEntry)
- type BacklinksOptions
- type BootstrapOptions
- type BootstrapResult
- type CatOptions
- type Config
- func (cfg *Config) AddKegMap(entry KegMapEntry) error
- func (cfg *Config) Clone() *Config
- func (cfg *Config) DefaultHub() string
- func (cfg *Config) DefaultKeg() string
- func (cfg *Config) DefaultNamespace() string
- func (cfg *Config) DeleteHub(name string) (bool, error)
- func (cfg *Config) DeleteNamespace(name string) bool
- func (cfg *Config) DisableAtlasHub() bool
- func (cfg *Config) DisableLocalHub() bool
- func (cfg *Config) FallbackHub() string
- func (cfg *Config) FallbackKeg() string
- func (cfg *Config) FallbackNamespace() string
- func (cfg *Config) Flight() string
- func (cfg *Config) Hub(name string) (HubEntry, bool)
- func (cfg *Config) Hubs() map[string]HubEntry
- func (cfg *Config) KegMap() []KegMapEntry
- func (cfg *Config) LogFile() string
- func (cfg *Config) LogLevel() string
- func (cfg *Config) LookupAlias(rt *toolkit.Runtime, projectRoot string) string
- func (cfg *Config) LookupAliasForTarget(_ *toolkit.Runtime, _ string) string
- func (cfg *Config) Namespace(name string) (NamespaceRef, bool)
- func (cfg *Config) Namespaces() map[string]NamespaceRef
- func (cfg *Config) ResolveAlias(rt *toolkit.Runtime, alias string) (*keg.Target, error)
- func (cfg *Config) ResolveDefault(rt *toolkit.Runtime) (*keg.Target, error)
- func (cfg *Config) ResolveKegMap(rt *toolkit.Runtime, projectRoot string) (*keg.Target, error)
- func (cfg *Config) ResolveRef(rt *toolkit.Runtime, ref KegRef) (*keg.Target, error)
- func (cfg *Config) SetDefaultHub(_ context.Context, hub string) error
- func (cfg *Config) SetDefaultKeg(keg string) error
- func (cfg *Config) SetDefaultNamespace(ns string) error
- func (cfg *Config) SetDisableAtlasHub(disable bool) error
- func (cfg *Config) SetDisableLocalHub(disable bool) error
- func (cfg *Config) SetFallbackHub(hub string) error
- func (cfg *Config) SetFallbackKeg(keg string) error
- func (cfg *Config) SetFallbackNamespace(ns string) error
- func (cfg *Config) SetFlight(flight string) error
- func (cfg *Config) SetHub(name string, entry HubEntry) error
- func (cfg *Config) SetLogFile(_ context.Context, path string) error
- func (cfg *Config) SetLogLevel(level string) error
- func (cfg *Config) SetNamespace(name string, ref NamespaceRef) error
- func (cfg *Config) ToYAML() ([]byte, error)
- func (cfg *Config) Touch(rt *toolkit.Runtime)
- func (cfg *Config) Updated() time.Time
- func (cfg *Config) Write(rt *toolkit.Runtime, path string) error
- type ConfigEditOptions
- type ConfigExplainOptions
- type ConfigExplainResult
- type ConfigLoadWarning
- type ConfigOptions
- type ConfigService
- func (s *ConfigService) Config(cache bool) (*Config, error)
- func (s *ConfigService) ProjectConfig(cache bool) (*Config, error)
- func (s *ConfigService) ResetCache()
- func (s *ConfigService) ResolveTarget(alias, nsOverride, hubOverride string, cache bool) (*keg.Target, error)
- func (s *ConfigService) UserConfig(cache bool) (*Config, error)
- func (s *ConfigService) UserConfigExists() bool
- type ConfigTemplateOptions
- type ConfigWarning
- type CreateFlightOptions
- type CreateOptions
- type DeleteFileOptions
- type DeleteFlightOptions
- type DeleteImageOptions
- type DeviceUserPrompt
- type DoctorOptions
- type DownloadFileOptions
- type DownloadImageOptions
- type EditFlightOptions
- type EditOptions
- type EditSchemaOptions
- type ExportOptions
- type Flight
- type FlightCapability
- type FlightCover
- type FlightManifest
- type FlightRef
- type FlightRestrictionError
- type FlightRole
- type FlightService
- func (s *FlightService) GetFlight(ctx context.Context, name string) (*Flight, error)
- func (s *FlightService) GetFlightFresh(ctx context.Context, name string) (*Flight, error)
- func (s *FlightService) ListFlights(ctx context.Context, hub string, warnings *[]string) ([]string, error)
- func (s *FlightService) StoreSessionFlight(name string, f *Flight)
- type ForceUnlockOptions
- type GetFlightOptions
- type GraphOptions
- type GrepOptions
- type HubAddOptions
- type HubEntry
- type HubFlight
- func CreateHubFlight(ctx context.Context, hubURL, token, namespace string, flight HubFlight) (*HubFlight, error)
- func GetHubFlight(ctx context.Context, hubURL, token, namespace, slug string) (*HubFlight, error)
- func ListUserFlights(ctx context.Context, hubURL, token string) ([]HubFlight, error)
- func UpdateHubFlight(ctx context.Context, hubURL, token, namespace, slug string, flight HubFlight) (*HubFlight, error)
- type HubFlightCover
- type HubGrant
- type HubInfo
- type HubKeg
- type HubListOptions
- type HubMember
- type HubNamespace
- type HubRemoveOptions
- type HubSetDefaultOptions
- type ImportFromKegOptions
- type ImportOptions
- type ImportedNode
- type IndexCatOptions
- type IndexOptions
- type InfoOptions
- type InitOptions
- type IntegrateOptions
- type IntegrateResult
- type Issue
- type KegConfigEditOptions
- type KegGrantOptions
- type KegGrantsOptions
- type KegMapEntry
- type KegRef
- type KegRenameOptions
- type KegRevokeOptions
- type KegService
- type KegSettingsOptions
- type KegTargetOptions
- type KegVisibilityOptions
- type LinksOptions
- type ListFilesOptions
- type ListFlightsOptions
- type ListImagesOptions
- type ListOptions
- type ListSortType
- type LockOptions
- type LockStatusOptions
- type MetaOptions
- type MoveOptions
- type NamespaceAddMemberOptions
- type NamespaceCreateOptions
- type NamespaceCreateResult
- type NamespaceListOptions
- type NamespaceMembersOptions
- type NamespaceRef
- type NamespaceRemoveMemberOptions
- type NamespaceSetRoleOptions
- type NodeHistoryOptions
- type NodeRestoreOptions
- type NodeSnapshotOptions
- type NodeSnapshotViewOptions
- type OrientOptions
- type PathNotFoundError
- type PathService
- type ProjectKegNotFoundError
- type ReadImageOptions
- type RefContext
- type RemoveOptions
- type ResolveKegOptions
- type SchemaOptions
- type StatsOptions
- type TagsOptions
- type Tap
- func (t *Tap) ActiveFlightName(explicit string) string
- func (t *Tap) AuthLogout(ctx context.Context, opts AuthLogoutOptions) (*AuthLogoutResult, error)
- func (t *Tap) AuthRefreshAll(ctx context.Context)
- func (t *Tap) AuthStatus(ctx context.Context, opts AuthStatusOptions) (*AuthStatusResult, error)
- func (t *Tap) Backlinks(ctx context.Context, opts BacklinksOptions) ([]string, error)
- func (t *Tap) Bootstrap(ctx context.Context, opts BootstrapOptions) (*BootstrapResult, error)
- func (t *Tap) Cat(ctx context.Context, opts CatOptions) (string, error)
- func (t *Tap) Config(opts ConfigOptions) (string, error)
- func (t *Tap) ConfigEdit(ctx context.Context, opts ConfigEditOptions) error
- func (t *Tap) ConfigExplain(ctx context.Context, opts ConfigExplainOptions) ([]ConfigExplainResult, error)
- func (t *Tap) ConfigTemplate(opts ConfigTemplateOptions) (string, error)
- func (t *Tap) Create(ctx context.Context, opts CreateOptions) (keg.NodeId, error)
- func (t *Tap) CreateFlight(ctx context.Context, opts CreateFlightOptions) (*Flight, error)
- func (t *Tap) CreateSchema(ctx context.Context, opts SchemaOptions) error
- func (t *Tap) DeleteFile(ctx context.Context, opts DeleteFileOptions) error
- func (t *Tap) DeleteFlight(ctx context.Context, opts DeleteFlightOptions) error
- func (t *Tap) DeleteImage(ctx context.Context, opts DeleteImageOptions) error
- func (t *Tap) DeleteSchema(ctx context.Context, opts SchemaOptions) error
- func (t *Tap) Doctor(ctx context.Context, opts DoctorOptions) ([]Issue, error)
- func (t *Tap) DoctorConfig() []Issue
- func (t *Tap) DownloadFile(ctx context.Context, opts DownloadFileOptions) (string, error)
- func (t *Tap) DownloadImage(ctx context.Context, opts DownloadImageOptions) (string, error)
- func (t *Tap) Edit(ctx context.Context, opts EditOptions) error
- func (t *Tap) EditFlight(ctx context.Context, opts EditFlightOptions) (*Flight, error)
- func (t *Tap) EditSchema(ctx context.Context, opts EditSchemaOptions) error
- func (t *Tap) Export(ctx context.Context, opts ExportOptions) (string, error)
- func (t *Tap) ForceUnlock(ctx context.Context, opts ForceUnlockOptions) error
- func (t *Tap) GetFlight(ctx context.Context, opts GetFlightOptions) (*Flight, error)
- func (t *Tap) Graph(ctx context.Context, opts GraphOptions) (string, error)
- func (t *Tap) Grep(ctx context.Context, opts GrepOptions) ([]string, error)
- func (t *Tap) HubAdd(_ context.Context, opts HubAddOptions) error
- func (t *Tap) HubList(_ context.Context) ([]HubInfo, error)
- func (t *Tap) HubListKegs(ctx context.Context, opts HubListOptions) ([]string, error)
- func (t *Tap) HubRemove(_ context.Context, opts HubRemoveOptions) error
- func (t *Tap) HubSetDefault(ctx context.Context, opts HubSetDefaultOptions) error
- func (t *Tap) Import(ctx context.Context, opts ImportOptions) ([]keg.NodeId, error)
- func (t *Tap) ImportFromKeg(ctx context.Context, opts ImportFromKegOptions) ([]ImportedNode, error)
- func (t *Tap) Index(ctx context.Context, opts IndexOptions) (string, error)
- func (t *Tap) IndexCat(ctx context.Context, opts IndexCatOptions) (string, error)
- func (t *Tap) Info(ctx context.Context, opts InfoOptions) (string, error)
- func (t *Tap) InitKeg(ctx context.Context, options InitOptions) (*keg.Target, error)
- func (t *Tap) Integrate(ctx context.Context, opts IntegrateOptions) (*IntegrateResult, error)
- func (t *Tap) KegConfigEdit(ctx context.Context, opts KegConfigEditOptions) error
- func (t *Tap) KegGrant(ctx context.Context, opts KegGrantOptions) error
- func (t *Tap) KegGrants(ctx context.Context, opts KegGrantsOptions) ([]HubGrant, error)
- func (t *Tap) KegRename(ctx context.Context, opts KegRenameOptions) error
- func (t *Tap) KegRevoke(ctx context.Context, opts KegRevokeOptions) error
- func (t *Tap) KegSettings(ctx context.Context, opts KegSettingsOptions) (string, error)
- func (t *Tap) KegVisibility(ctx context.Context, opts KegVisibilityOptions) error
- func (t *Tap) Links(ctx context.Context, opts LinksOptions) ([]string, error)
- func (t *Tap) List(ctx context.Context, opts ListOptions) ([]string, error)
- func (t *Tap) ListFiles(ctx context.Context, opts ListFilesOptions) ([]string, error)
- func (t *Tap) ListFlights(ctx context.Context, opts ListFlightsOptions) ([]string, error)
- func (t *Tap) ListImages(ctx context.Context, opts ListImagesOptions) ([]string, error)
- func (t *Tap) ListIndexes(ctx context.Context, opts IndexCatOptions) ([]string, error)
- func (t *Tap) ListSchemas(ctx context.Context, opts SchemaOptions) ([]string, error)
- func (t *Tap) Lock(ctx context.Context, opts LockOptions) (keg.LockToken, error)
- func (t *Tap) LockStatus(ctx context.Context, opts LockStatusOptions) (keg.LockInfo, error)
- func (t *Tap) LookupKeg(ctx context.Context, kegAlias string) (keg.Keg, error)
- func (t *Tap) Meta(ctx context.Context, opts MetaOptions) (string, error)
- func (t *Tap) Move(ctx context.Context, opts MoveOptions) error
- func (t *Tap) NamespaceAddMember(ctx context.Context, opts NamespaceAddMemberOptions) error
- func (t *Tap) NamespaceCreate(ctx context.Context, opts NamespaceCreateOptions) (*NamespaceCreateResult, error)
- func (t *Tap) NamespaceList(ctx context.Context, opts NamespaceListOptions) ([]HubNamespace, error)
- func (t *Tap) NamespaceMembers(ctx context.Context, opts NamespaceMembersOptions) ([]HubMember, error)
- func (t *Tap) NamespaceRemoveMember(ctx context.Context, opts NamespaceRemoveMemberOptions) error
- func (t *Tap) NamespaceSetRole(ctx context.Context, opts NamespaceSetRoleOptions) error
- func (t *Tap) NodeHistory(ctx context.Context, opts NodeHistoryOptions) ([]keg.Snapshot, error)
- func (t *Tap) NodeRestore(ctx context.Context, opts NodeRestoreOptions) error
- func (t *Tap) NodeSnapshot(ctx context.Context, opts NodeSnapshotOptions) (keg.Snapshot, error)
- func (t *Tap) NodeSnapshotView(ctx context.Context, opts NodeSnapshotViewOptions) ([]byte, error)
- func (t *Tap) Orient(ctx context.Context, opts OrientOptions) (string, error)
- func (t *Tap) ReadImage(ctx context.Context, opts ReadImageOptions) ([]byte, string, error)
- func (t *Tap) ReadSchema(ctx context.Context, opts SchemaOptions) ([]byte, error)
- func (t *Tap) Remove(ctx context.Context, opts RemoveOptions) error
- func (t *Tap) ResolveNodeRef(ctx context.Context, ref *keg.NodeRef, rc RefContext) (keg.Keg, keg.NodeId, error)
- func (t *Tap) SetBootstrapFlight(ctx context.Context, ref string) error
- func (t *Tap) SetBootstrapNamespace(ctx context.Context, hubName, namespace string) error
- func (t *Tap) SetFallbackKeg(ctx context.Context, ref string) error
- func (t *Tap) SetHubDefaultNamespaceByURL(ctx context.Context, hubURL, namespace string) (string, error)
- func (t *Tap) Stats(ctx context.Context, opts StatsOptions) (string, error)
- func (t *Tap) Tags(ctx context.Context, opts TagsOptions) ([]string, error)
- func (t *Tap) Unlock(ctx context.Context, opts UnlockOptions) error
- func (t *Tap) UpdateFlight(ctx context.Context, opts UpdateFlightOptions) (*Flight, error)
- func (t *Tap) UploadFile(ctx context.Context, opts UploadFileOptions) (string, error)
- func (t *Tap) UploadImage(ctx context.Context, opts UploadImageOptions) (string, error)
- func (t *Tap) Use(ctx context.Context, opts UseOptions) error
- func (t *Tap) UseStatus(_ context.Context, opts KegTargetOptions) (string, error)
- func (t *Tap) Validate(ctx context.Context, opts ValidateOptions) ([]keg.SchemaValidationResult, error)
- func (t *Tap) WatchNode(ctx context.Context, opts WatchNodeOptions) (<-chan keg.NodeEvent, error)
- type TapOptions
- type UnlockOptions
- type UpdateFlightOptions
- type UploadFileOptions
- type UploadImageOptions
- type UseOptions
- type ValidateOptions
- type WatchNodeOptions
- type WhoAmI
Constants ¶
const ( TapConfigSchemaURL = "https://raw.githubusercontent.com/jlrickert/tapper/main/schemas/tap-config.json" // DefaultHubName is the compiled-in name of the default remote hub. DefaultHubName = "atlas" // DefaultHubURL is the compiled-in fallback hub used by ResolveLoginHubURL // and Config.Hub when no explicit hub, defaultHub, fallbackHub, or single // configured hub is available and the implicit default has not been // disabled. The constant exists so the fallback target is auditable: a // deployment that needs to prove no implicit network calls happen sets // disableAtlasHub: true (or TAP_DISABLE_ATLAS_HUB=1) and the chain // errors out instead of falling through here. DefaultHubURL = "https://atlas.foldwise.ai" // DefaultHubTokenEnv is the environment variable the default remote hub // reads its bearer token from when no explicit credential is configured. DefaultHubTokenEnv = "ATLAS_API_KEY" // LocalHubName is the reserved name of the built-in filesystem hub. Kegs // addressed at the "local" hub (or with namespace "local" and no hub) live // on disk under the hub's basePath rather than on a remote service. LocalHubName = "local" )
const ( // HubKindRemote is a read-write HTTP hub (the default, e.g. atlas). HubKindRemote = "remote" // HubKindLocal is a filesystem-backed hub on this machine. HubKindLocal = "local" // HubKindReadonly is a read-only HTTP hub. TODO: enforce read-only writes // in the API repository; today the kind only sets Target.Readonly. HubKindReadonly = "readonly" )
Hub kinds describe how a hub's (namespace, name) pairs are backed.
const ( // DefaultAppName is the base directory name used for Tapper user // configuration. Helpers use this value to build platform specific config // paths, for example: // $XDG_CONFIG_HOME/tapper (or ~/.config/tapper) on Unix-like systems // %APPDATA%\tapper on Windows // Example config file: // $XDG_CONFIG_HOME/tapper/aliases.yaml DefaultAppName = "tapper" // DefaultLocalConfigDir is the directory name used for repository or // project local configuration. DefaultLocalConfigDir = ".tapper" )
Config version strings identify KEG configuration schema versions. Each constant is a stable identifier for a particular config schema. When a new schema is introduced add a new constant and update the Config alias to point to the latest version. These values are used by parsing and migration code (for example ParseConfigData) to detect older formats and perform upgrades. Use a YYYY-MM format for easy sorting and human readability.
const ( FlightRoleViewer FlightRole = "viewer" FlightRoleEditor FlightRole = "editor" FlightVisibilityPrivate = "private" FlightVisibilityPublic = "public" FlightCapabilityManageFlights FlightCapability = "manage_flights" FlightCapabilityFullAccess FlightCapability = "full_access" )
const ( // BootstrapKindLocal sets up only the built-in local filesystem hub. BootstrapKindLocal = "local" // BootstrapKindCloud targets the compiled-in atlas remote hub. BootstrapKindCloud = "cloud" // BootstrapKindEnterprise registers a user-supplied remote HTTP endpoint. BootstrapKindEnterprise = "enterprise" )
Bootstrap deployment kinds. Each maps onto an existing hub kind/shape — there is no new config field, only a guided way to pick one.
const ( // FlightManifestSchemaURL is the public JSON Schema used by editor // modelines for flight manifest YAML. FlightManifestSchemaURL = "https://raw.githubusercontent.com/jlrickert/tapper/main/schemas/flight-manifest.json" )
flightsDirName is the reserved directory — a sibling of the @<namespace> dirs of a local hub — that holds flight manifests. "flights.d" is an invalid namespace (it contains a dot), so it can never collide with a keg path.
Variables ¶
var ConfigExplainFields = []string{
"defaultKeg",
"fallbackKeg",
"flight",
"logFile",
"logLevel",
"defaultHub",
"fallbackHub",
"defaultNamespace",
"fallbackNamespace",
"disableAtlasHub",
"disableLocalHub",
}
ConfigExplainFields lists the scalar config fields eligible for explain.
var ErrAtlasHubDisabled = errors.New("no hub configured; implicit atlas hub disabled")
ErrAtlasHubDisabled is returned by ResolveLoginHubURL when the chain would fall through to the compiled-in DefaultHubURL but the deployment has opted out via Config.DisableAtlasHub. Callers surface it verbatim so SOC2-conscious users see a stable string they can grep for.
var ErrNotBootstrapped = errors.New("tapper is not set up on this machine; run `tap bootstrap` to get started")
ErrNotBootstrapped is returned by hub/namespace-dependent operations on the full `tap` surface when no user config exists yet — i.e. `tap bootstrap` has not been run. Explicit filesystem destinations (--path/--project/--cwd) and the pruned `keg` binary are exempt, and callers that resolve a keg by an explicit filesystem path are too.
var ErrTokenRejected = errors.New("hub rejected the token")
ErrTokenRejected marks a token the hub actively refused (HTTP 401/403), as distinct from a transport failure (hub unreachable). Callers use errors.Is to tell "your token is bad" apart from "we couldn't reach the hub" — see Tap.AuthStatus, which renders those two cases differently.
Functions ¶
func AddNamespaceMember ¶ added in v0.23.0
AddNamespaceMember upserts a member via POST /api/v1/@{namespace}/members. role is owner|admin|member.
func CanonicalHubURL ¶ added in v0.20.0
CanonicalHubURL returns the canonical form used as the AuthStore key. It strips trailing slashes, lowercases the scheme and host, and preserves the path exactly (per RFC 3986 the path is case-sensitive). Invalid URLs fall through to TrimRight'd input so callers don't have to pre-validate — they'll hit a clearer error at the login step.
func CreateGrant ¶ added in v0.23.0
CreateGrant upserts a grant via POST .../grants. role is viewer|editor|admin.
func CreateKeg ¶ added in v0.23.0
func CreateKeg(ctx context.Context, hubURL, token, namespace, alias, title, visibility string) error
CreateKeg asks the hub to create @namespace/alias via POST /api/v1/@{namespace}/kegs. A 409 is returned as an error wrapping keg.ErrExist so callers can detect "already exists" with errors.Is; 401/403 wrap ErrTokenRejected; other non-2xx statuses surface the hub's status line.
func DeleteHubFlight ¶ added in v0.23.0
func IntegrateHosts ¶ added in v0.19.0
func IntegrateHosts() []string
func IntegratePlugins ¶ added in v0.30.0
IntegratePlugins returns the plugin names advertised by the host's embedded rendered marketplace. The marketplace, rather than installer code, is the source of truth as new optional plugins are added.
func KegBackendLabel ¶ added in v0.22.0
KegBackendLabel returns a stable, path-free identifier for a keg target suitable for user-facing output. It is used by surfaces that must describe "what kind of keg is this" without leaking the underlying filesystem path, remote URL, or other location-revealing details.
Mapping by scheme:
- file-backed: "file-backed"
- hub: "keg:@<namespace>/<kegName>"
- http(s): "http" or "https"
- in-memory: "in-memory"
- other/unknown: the scheme string, or "" when target is nil
The hub label is the canonical keg reference (Target.String): the real "keg" scheme with the hub resolved from the namespace, never encoded in the string. File-backed kegs intentionally collapse to a single token: the alias is the user-visible handle, and the path lives only behind `tap info`.
func KegLocation ¶ added in v0.23.0
KegLocation renders where a keg lives for user-facing output after `tap keg create`: "at <path>" for a file-backed keg, "on <hubURL>" for a remote keg, or "" when no concrete location is known (in-memory / nil target). Unlike KegBackendLabel it intentionally reveals the path/URL so a fresh create says exactly where the keg landed.
func LocalGitData ¶
func LocalGitData(ctx context.Context, rt *toolkit.Runtime, projectPath, key string) ([]byte, error)
LocalGitData attempts to run `git -C projectPath config --local --get key`.
If git is not present or the command fails it returns an error. The returned bytes are trimmed of surrounding whitespace. The function logs diagnostic messages using the logger from rt.
func NewAuthStoreTokenResolver ¶ added in v0.20.0
func NewAuthStoreTokenResolver(store *AuthStore, rt *toolkit.Runtime, storePath string) keg.TokenResolver
NewAuthStoreTokenResolver returns a keg.TokenResolver backed by store. rt and storePath enable in-place refresh of expired OAuth2 tokens; pass the same runtime and AuthStorePath the store was loaded from. A nil store yields a resolver that always returns "", matching AuthStore's nil-safe contract.
func OpenBrowser ¶ added in v0.23.0
OpenBrowser launches the platform-native "open URL" command and returns once the process has been started. We do NOT wait for exit because most browsers daemonize and exec.Wait would deadlock the CLI behind the user's window manager.
Quarantined stdlib exception (like pkg/tapper/editor_live.go): this spawns an external browser process whose timing is governed by the user's environment rather than any in-process clock. Routing through exec.CommandContext keeps cancellation working if the caller ctx is cancelled before the command launches.
On unrecognized platforms or launch failure, we print the URL to rt.Stream().Err so the user can copy-paste it manually — that's a successful fallback, not a hard error.
func RemoveNamespaceMember ¶ added in v0.23.0
RemoveNamespaceMember removes a member via DELETE /api/v1/@{namespace}/members/@{username}.
func RenameKeg ¶ added in v0.25.0
RenameKeg updates a keg alias in-place within the same namespace via PATCH .../settings. The hub keeps the immutable keg id and does not create redirects for the old selector.
func ResolveLoginHubURL ¶ added in v0.20.0
ResolveLoginHubURL returns the hub URL the login flow should target, applying the hub resolution chain:
- explicit non-empty → canonicalize and use
- cfg.DefaultHub names a Hubs entry → use that entry's URL
- cfg.FallbackHub names a Hubs entry → use that entry's URL
- cfg.Hubs has exactly one remote/readonly entry → use it
- cfg.DisableAtlasHub is true → ErrAtlasHubDisabled
- fall back to DefaultHubURL
A misconfigured DefaultHub or FallbackHub is a hard error rather than a silent fall-through to step 3 — typos should surface, not silently route to a different hub.
Returned URLs are canonicalized via CanonicalHubURL so callers can compare them against AuthStore keys without re-canonicalizing.
func RevokeGrant ¶ added in v0.23.0
RevokeGrant removes a grant via DELETE .../grants/@{username}.
func SetKegVisibility ¶ added in v0.23.0
func SetKegVisibility(ctx context.Context, hubURL, token, namespace, alias, visibility string) error
SetKegVisibility updates a keg's visibility via PATCH .../settings. visibility is public|private.
func SetNamespaceMemberRole ¶ added in v0.23.0
func SetNamespaceMemberRole(ctx context.Context, hubURL, token, namespace, username, role string) error
SetNamespaceMemberRole changes a member's role via PATCH /api/v1/@{namespace}/members/@{username}.
func ValidateKegAlias ¶ added in v0.22.0
ValidateKegAlias returns nil when alias matches the canonical alias shape and a wrapped keg.ErrInvalid otherwise. Empty input is rejected explicitly so callers can distinguish missing-alias errors from shape errors when reading the wrapped chain.
func ValidateNamespace ¶ added in v0.23.0
ValidateNamespace returns nil when ns is a legal namespace segment and a wrapped keg.ErrInvalid otherwise. Empty input is rejected explicitly. The "@" sigil is never part of the stored value; pass the bare namespace.
func WalkConfigsUp ¶ added in v0.23.0
WalkConfigsUp returns the absolute paths of every existing rel file found by walking from start up to the filesystem root, ordered DEEPEST-FIRST (nearest to start first). Missing candidates are skipped. The user-global config is not included; callers layer it underneath the returned project configs.
Types ¶
type AuthEntry ¶ added in v0.20.0
type AuthEntry struct {
AccessToken string `yaml:"access_token"`
TokenType string `yaml:"token_type,omitempty"`
ExpiresAt time.Time `yaml:"expires_at,omitempty"`
Scope string `yaml:"scope,omitempty"`
// RefreshToken, ClientID, and TokenEndpoint are populated by the OAuth2
// device-login flow so the CLI can silently renew an expired AccessToken
// without a re-login (see RefreshHubToken). All three are empty for a
// pasted `thub_` API token, which never expires and cannot be refreshed.
RefreshToken string `yaml:"refresh_token,omitempty"`
ClientID string `yaml:"client_id,omitempty"`
TokenEndpoint string `yaml:"token_endpoint,omitempty"`
}
AuthEntry is a single hub's cached credential. Plain value type — callers hold copies returned from Get, and pass values into Set.
Fields match the typical OAuth 2.0 shape so we can store whatever a hub returns without transformation. TokenType / ExpiresAt / Scope are all optional: a hub that only returns a bare bearer token will serialize as a single access_token field.
func AuthLoginDevice ¶ added in v0.20.0
func AuthLoginDevice(ctx context.Context, rt *toolkit.Runtime, opts AuthLoginDeviceOptions) (*AuthEntry, error)
AuthLogin runs the device authorization grant against the hub described by opts and returns a populated AuthEntry. The store is not touched — the caller persists the result via AuthStore.Set + Save, mirroring the browser-based AuthLogin contract.
func RefreshHubToken ¶ added in v0.23.0
func RefreshHubToken(ctx context.Context, rt *toolkit.Runtime, hubURL string, entry *AuthEntry) (*AuthEntry, error)
RefreshHubToken exchanges entry.RefreshToken at the hub's token endpoint and returns a new AuthEntry carrying the rotated access + refresh tokens and a recomputed expiry. The hub rotates refresh tokens single-use, so the caller must persist the returned entry (the old refresh token is now spent).
Endpoint/client resolution: the device-login flow records TokenEndpoint and ClientID on the entry, so a refresh is a single POST with no rediscovery. Entries that predate that (or omit the fields) fall back to rediscovering the token endpoint from hubURL and to the stock public client id.
type AuthLoginDeviceOptions ¶ added in v0.20.0
type AuthLoginDeviceOptions struct {
// HubURL is the hub base (e.g. "https://hub.example.com"). Required.
HubURL string
// ClientID is the OAuth2 public client identifier the hub will validate
// against its registered clients. Required.
ClientID string
// Scope is an optional space-separated scope string. Omitted from the
// device_authorization request when empty.
Scope string
// DeviceLabel is an optional human-readable label for this login session.
// Hubs may display it in account/session views.
DeviceLabel string
// Timeout bounds the whole flow including the user's browser action;
// zero uses defaultDeviceTimeout.
Timeout time.Duration
// HTTPClient executes the metadata GET, device_authorization POST, and
// token POSTs. Default: http.DefaultClient.
HTTPClient *http.Client
// PromptOut is the writer that receives the user-facing prompt
// ("Open <URL> and enter <CODE>"). Default: os.Stderr via the runtime
// stream when Out is nil; an in-memory buffer in tests.
PromptOut io.Writer
// OnUserCode, when non-nil, is invoked once the hub has issued the
// user_code + verification URI and before polling begins. It owns the
// user-facing presentation: the CLI installs a handler that prints the
// code, offers to open the browser (gh-style "press Enter to open"),
// and falls back to printing the URL for manual copy/paste. When nil,
// the flow prints a plain copy/paste prompt to PromptOut — the library
// default never opens a browser, keeping pkg/tapper free of any
// interactive/TTY dependency. A non-nil error aborts the login.
OnUserCode func(context.Context, DeviceUserPrompt) error
// Now returns the current time. Default: time.Now. Tests inject a fake
// clock to control timeout behavior deterministically.
Now func() time.Time
// Sleep blocks for d. Default: time.Sleep. Tests inject a no-op or
// channel-coordinated stub so polling loops don't actually wait.
Sleep func(d time.Duration)
}
AuthLoginDeviceOptions is the dependency envelope for AuthLoginDevice. Required: HubURL, ClientID. Everything else has a production default.
type AuthLogoutOptions ¶ added in v0.20.0
type AuthLogoutOptions struct {
// Hub is the raw or canonical hub URL. When empty and exactly one
// hub is stored, auto-resolves to that single entry; otherwise an
// empty Hub with multiple stored hubs surfaces a directed error.
Hub string
}
AuthLogoutOptions selects which hub to log out of. Flat (no KegTargetOptions) because auth state is a user-level concern that spans kegs — a login is per-hub, not per-keg.
type AuthLogoutResult ¶ added in v0.20.0
type AuthLogoutResult struct {
// Removed is true when an entry was actually deleted from the store.
// False when the store was empty or the hub was not found; both of
// those cases are soft-successes (no error returned).
Removed bool
// HubURL is the canonical hub that was targeted, or "" when the
// store was empty.
HubURL string
// Formatted is the authoritative output line terminated with \n.
// CLI routes to stdout when Removed=true, stderr otherwise.
Formatted string
}
AuthLogoutResult is the pre-formatted output plus structured fields for callers that need to route streams or surface structured output. Formatted is authoritative: the CLI emits it verbatim to stdout when Removed=true and stderr otherwise.
type AuthStatusHub ¶ added in v0.28.1
type AuthStatusHub struct {
// Present is false when no matching entry exists.
Present bool
// HubURL is the canonical key that matched.
HubURL string
// TokenPrefix is the first 12 chars of the access token followed by
// "..." — matching the non-secret prefix the hub stores and shows in
// its account UI — or "[set]" when the token is too short for a
// meaningful prefix. The raw token is never exposed here.
TokenPrefix string
// TokenType mirrors the stored entry (e.g. "Bearer"). Empty when
// the hub returned a bare token with no type.
TokenType string
// Account is the username the hub reported for this token via the
// live whoami probe. Empty when validation was skipped (--offline) or
// failed.
Account string
// DisplayName is the human name the hub reported alongside Account.
// Empty when the hub omits it or validation didn't run.
DisplayName string
// Valid is true when the live whoami probe confirmed the token. False
// when the token was rejected, the hub was unreachable, or --offline
// skipped the check.
Valid bool
// ValidationError is the error message from a failed/ skipped probe,
// empty on success. Lets structured consumers branch without parsing
// Formatted.
ValidationError string
// Scope mirrors the stored entry. Empty when no scope was granted.
Scope string
// ExpiresAt mirrors the stored entry; zero when no expiry is known.
ExpiresAt time.Time
// ExpiryStatus is a three-way tag: "unknown" | "valid" | "expired".
// Made explicit so callers (and future JSON consumers) don't have
// to re-derive from ExpiresAt vs clock.
ExpiryStatus string
// LoginMethod records how the credential was obtained: "device" for the
// OAuth2 browser/device flow (carries client + refresh + token endpoint),
// "token" for a pasted API token. Lets structured consumers branch without
// parsing Formatted.
LoginMethod string
// Renewable is true when a refresh token is stored — i.e. the access token
// renews silently on expiry rather than forcing a re-login. Always false
// for a pasted API token.
Renewable bool
// Formatted is the exact block rendered for this hub. Terminated with a
// trailing newline.
Formatted string
}
AuthStatusHub is the per-hub structured status used by AuthStatusResult.Hubs. Formatted is the exact block rendered for this hub, terminated with a trailing newline.
type AuthStatusOptions ¶ added in v0.20.0
type AuthStatusOptions struct {
// Hub is a raw or canonical hub URL. When empty, AuthStatus reports every
// stored hub login; an empty store surfaces a directed empty message (see
// AuthStatus docs).
Hub string
// Offline skips the live whoami probe and reports purely from the
// on-disk store (no network, no account name). Useful for scripts,
// air-gapped use, or when an agent must not make outbound calls.
Offline bool
}
AuthStatusOptions selects which hub to report on. Flat (no KegTargetOptions) because auth state is a user-level concern that spans kegs — a login is per-hub, not per-keg.
type AuthStatusResult ¶ added in v0.20.0
type AuthStatusResult struct {
// Present is false when no matching entry exists (empty store
// with no --hub, or --hub that isn't in the store).
Present bool
// HubURL is the canonical key that matched. Zero-value when the
// caller omitted --hub and the store is empty.
HubURL string
// TokenPrefix is the first 12 chars of the access token followed by
// "..." — matching the non-secret prefix the hub stores and shows in
// its account UI — or "[set]" when the token is too short for a
// meaningful prefix. The raw token is never exposed here.
TokenPrefix string
// TokenType mirrors the stored entry (e.g. "Bearer"). Empty when
// the hub returned a bare token with no type.
TokenType string
// Account is the username the hub reported for this token via the
// live whoami probe. Empty when validation was skipped (--offline) or
// failed.
Account string
// DisplayName is the human name the hub reported alongside Account.
// Empty when the hub omits it or validation didn't run.
DisplayName string
// Valid is true when the live whoami probe confirmed the token. False
// when the token was rejected, the hub was unreachable, or --offline
// skipped the check.
Valid bool
// ValidationError is the error message from a failed/ skipped probe,
// empty on success. Lets structured consumers branch without parsing
// Formatted.
ValidationError string
// Scope mirrors the stored entry. Empty when no scope was granted.
Scope string
// ExpiresAt mirrors the stored entry; zero when no expiry is known.
ExpiresAt time.Time
// ExpiryStatus is a three-way tag: "unknown" | "valid" | "expired".
// Made explicit so callers (and future JSON consumers) don't have
// to re-derive from ExpiresAt vs clock.
ExpiryStatus string
// LoginMethod records how the credential was obtained: "device" for the
// OAuth2 browser/device flow (carries client + refresh + token endpoint),
// "token" for a pasted API token. Lets structured consumers branch without
// parsing Formatted.
LoginMethod string
// Renewable is true when a refresh token is stored — i.e. the access token
// renews silently on expiry rather than forcing a re-login. Always false
// for a pasted API token.
Renewable bool
// Hubs contains structured per-hub status. It has one entry for single-hub
// status responses and multiple entries when Hub was omitted with multiple
// stored logins.
Hubs []AuthStatusHub
// Formatted is the exact string the CLI prints; MCP returns it
// verbatim as text content. Terminated with a trailing newline.
Formatted string
}
AuthStatusResult is the pre-formatted human-readable status output plus structured fields for the MCP surface and any future renderers. Formatted is authoritative: both CLI and MCP emit it verbatim. Scalar fields are populated for single-hub responses; Hubs carries per-hub status entries.
type AuthStore ¶ added in v0.20.0
type AuthStore struct {
// contains filtered or unexported fields
}
AuthStore is the opaque wrapper exposing getters/setters over an authStoreDTO. All methods are nil-safe on the receiver: a (*AuthStore)(nil) reads as an empty store and writes are no-ops. This lets callers skip the "did Load return something?" dance when the file didn't exist.
func LoadAuthStore ¶ added in v0.20.0
LoadAuthStore reads the auth store file at path and parses it. A missing file is NOT an error: we return an empty store and nil so first-run callers can treat "no file" and "empty file" identically. Every other read error is wrapped and returned.
func ParseAuthStore ¶ added in v0.20.0
ParseAuthStore parses raw YAML bytes into an AuthStore. Pure: no I/O, no clock. Empty input (including whitespace-only) is treated as an empty store rather than a YAML error — first-run and "user cleared the file" look the same to us.
func (*AuthStore) Delete ¶ added in v0.20.0
Delete removes the entry for hubURL. Returns whether it existed — callers can use this to decide whether to log "logged out" vs "was already logged out".
func (*AuthStore) Get ¶ added in v0.20.0
Get returns a copy of the entry for hubURL and a present flag. We return a value (not a pointer into the map) so callers can't mutate the stored entry by accident — all edits must go through Set.
func (*AuthStore) Hubs ¶ added in v0.20.0
Hubs returns the hub URL keys, sorted, for enumeration. Sorted output makes CLI listings stable without callers having to re-sort.
func (*AuthStore) IsEmpty ¶ added in v0.20.0
IsEmpty reports whether the store has no hubs. Used by Save to decide whether to delete the file rather than write an empty document.
func (*AuthStore) Save ¶ added in v0.20.0
Save writes the store to path. When the store is empty we remove the file instead of writing an empty YAML doc — keeps the filesystem tidy after a `tap auth logout` of the last hub and makes "no file" the canonical empty state (matches LoadAuthStore's contract). Parent directory is created at 0700 if it doesn't exist. If it already exists we don't touch its mode — users/admins may have intentionally widened it, and tightening on every Save would surprise them.
type BacklinksOptions ¶
type BacklinksOptions struct {
KegTargetOptions
// NodeIDs are the target nodes to inspect incoming links for.
// Results from all node IDs are merged and deduplicated.
NodeIDs []string
// Format to use. %i is node id
// %d is date
// %t is node title
// %% for literal %
Format string
IdOnly bool
Reverse bool
// Limit caps the number of results returned. 0 means no limit.
Limit int
// Offset skips the first N results before applying limit. Must be >= 0.
Offset int
}
type BootstrapOptions ¶ added in v0.23.0
type BootstrapOptions struct {
// Kind selects the deployment: local | cloud | enterprise. Empty defaults
// to cloud (atlas is the compiled-in default hub).
Kind string
// Endpoint is the hub base URL; required when Kind == enterprise, ignored
// otherwise. A bare host is upgraded to https://.
Endpoint string
// HubName overrides the hub key written for an enterprise endpoint. Empty
// derives it from the endpoint host (see deriveHubName).
HubName string
// Namespace overrides the fallback namespace. Empty auto-derives it from
// the OS user, then LocalHubName.
Namespace string
}
BootstrapOptions configures Tap.Bootstrap, the first-run onboarding that materializes or refreshes the user-level tapper config around a deployment kind.
type BootstrapResult ¶ added in v0.23.0
type BootstrapResult struct {
Path string // user config path written
Created bool // true when a fresh file was created, false on update
Kind string // normalized deployment kind
Hub string // hub name written as fallbackHub
HubURL string // login/display URL for cloud/enterprise; "" for local
Namespace string // resolved fallback namespace
Warnings []ConfigWarning // semantic warnings from ValidateConfig
}
BootstrapResult reports what Bootstrap wrote so the CLI can phrase its output, drive an optional login, and surface non-fatal config warnings.
type CatOptions ¶
type CatOptions struct {
// NodeIDs are the node identifiers to read (e.g., "0", "42").
// Multiple IDs produce concatenated output separated by blank lines.
NodeIDs []string
// Query is an optional boolean expression (same syntax as tap tags) used
// to select nodes. Mutually exclusive with NodeIDs.
Query string
KegTargetOptions
// Edit opens the node in the editor instead of printing output.
Edit bool
// ContentOnly displays content only.
ContentOnly bool
// StatsOnly displays stats only.
StatsOnly bool
// MetaOnly displays metadata only.
MetaOnly bool
// Stream carries stdin piping information when editing.
Stream *toolkit.Stream
// LockToken is an optional cross-process lock token for edit operations.
LockToken string
}
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config represents the user's tapper configuration.
Config is a data-only model. We do not preserve YAML comments or original document formatting.
func DefaultProjectConfig ¶
DefaultProjectConfig returns a project-scoped config with sensible defaults.
Project config uses DEFAULT slots (defaultHub/defaultNamespace) — the authoritative choice for the project, overriding the user-level fallbacks.
func DefaultUserConfig ¶
DefaultUserConfig returns a sensible default global/user Config.
The global user config uses the FALLBACK hub (fallbackHub) so keg references need not specify a hub. The namespace is NOT pinned by a global fallbackNamespace — it comes from the resolved hub's own namespace field, so `name` seeds the remote hub's default namespace while the local hub keeps the reserved @local. The default remote hub (atlas) and the built-in local hub are registered, the local namespace maps to the local hub, and localKegRoot seeds the local hub's basePath.
func MergeConfig ¶
MergeConfig merges multiple Config values into a single configuration.
Merge semantics:
- Later configs override earlier values for scalar keys.
- Hubs are merged by name; later entries override earlier ones.
- Namespaces are merged by name; later entries override earlier ones.
- KegMap entries are appended in order, but entries with the same alias + path pattern are replaced by later entries.
func ParseConfig ¶
ParseConfig parses raw YAML into a Config data model. Unknown keys are ignored by the decoder.
func ReadConfig ¶
ReadConfig reads the YAML file at path and returns a parsed Config.
When the file does not exist the function returns a Config value and an error that wraps keg.ErrNotExist so callers can detect no-config cases.
func (*Config) AddKegMap ¶
func (cfg *Config) AddKegMap(entry KegMapEntry) error
AddKegMap adds or updates a keg map entry in the Config. Entries are matched by alias + pathPrefix + pathRegex. An entry with the same alias but a different path pattern is treated as a separate mapping.
func (*Config) DefaultHub ¶ added in v0.20.0
DefaultHub returns the default hub name (high-precedence slot).
func (*Config) DefaultKeg ¶
DefaultKeg returns the alias to use when no explicit keg is provided.
func (*Config) DefaultNamespace ¶ added in v0.23.0
DefaultNamespace returns the default namespace (high-precedence slot).
func (*Config) DeleteHub ¶ added in v0.23.0
DeleteHub removes a hub entry by name, reporting whether it was present.
func (*Config) DeleteNamespace ¶ added in v0.23.0
DeleteNamespace removes a namespace→hub mapping by name, reporting whether it was present. `tap hub remove` uses it to prune namespace pins that route to a hub being removed.
func (*Config) DisableAtlasHub ¶ added in v0.23.0
DisableAtlasHub returns true when the synthesized built-in atlas hub is suppressed.
func (*Config) DisableLocalHub ¶ added in v0.23.0
DisableLocalHub returns true when the synthesized built-in local hub is suppressed.
func (*Config) FallbackHub ¶ added in v0.23.0
FallbackHub returns the fallback hub name (last-resort slot).
func (*Config) FallbackKeg ¶ added in v0.2.0
FallbackKeg returns the last-resort keg alias.
func (*Config) FallbackNamespace ¶ added in v0.23.0
FallbackNamespace returns the fallback namespace (last-resort slot).
func (*Config) Flight ¶ added in v0.23.0
Flight returns the persisted flight reference applied when no --flight flag is given.
func (*Config) Hub ¶ added in v0.23.0
Hub returns the named hub entry. The built-in hubs "local" (filesystem) and "atlas" (the default remote hub) are synthesized when not explicitly configured — unless disabled via disableLocalHub / disableAtlasHub, in which case the synthesized built-in is suppressed and Hub reports it as not found. An explicit configuration in hubs{} always wins over (and is unaffected by the disable flag for) the built-in.
func (*Config) KegMap ¶
func (cfg *Config) KegMap() []KegMapEntry
KegMap returns the list of path/regex to keg alias mappings.
func (*Config) LookupAlias ¶
LookupAlias returns the keg alias matching the given project root path. It first checks regex patterns in KegMap entries, then prefix matches. For multiple prefix matches, the longest matching prefix wins. Returns empty string if no match is found or config data is nil.
func (*Config) LookupAliasForTarget ¶ added in v0.6.0
LookupAliasForTarget previously reverse-mapped a resolved target back to its configured keg alias. The namespace-centric model has no alias table, so a target no longer carries a short alias; callers fall back to the canonical @namespace/name label. Retained as a no-op so those callers need no change.
func (*Config) Namespace ¶ added in v0.23.0
func (cfg *Config) Namespace(name string) (NamespaceRef, bool)
Namespace returns the namespace reference registered under name.
func (*Config) Namespaces ¶ added in v0.23.0
func (cfg *Config) Namespaces() map[string]NamespaceRef
Namespaces returns the map of namespace name to hosting hub reference.
func (*Config) ResolveAlias ¶
ResolveAlias resolves a keg selector string to a concrete Target. The selector is parsed as a keg reference (see parseKegRef) and resolved through the namespace-centric ResolveRef chain — there is no kegs alias table.
Returns (nil, error) when the selector is empty or resolution fails.
func (*Config) ResolveDefault ¶
ResolveDefault resolves the current DefaultKeg reference to a target.
func (*Config) ResolveKegMap ¶
ResolveKegMap chooses the appropriate keg (via alias) based on path.
Precedence rules:
- Regex entries in KegMap have the highest precedence.
- PathPrefix entries are considered next; when multiple prefixes match the longest prefix wins.
- If no entry matches, resolution returns an alias-not-found error.
The function expands env vars and tildes prior to comparisons, so stored prefixes and patterns may contain ~ or $VAR values.
func (*Config) ResolveRef ¶ added in v0.23.0
ResolveRef resolves a (hub, namespace, name) reference into a concrete keg.Target. It applies the namespace-centric chains via resolveNamespaceHub — namespace first (explicit → default/fallback), then the hub that hosts that namespace — and the per-kind backend mapping:
- local: <basePath>/@<namespace>/<name> as a file target
- remote: <hub.url>/api/v1/@<namespace>/kegs/<name> as a hub target
- readonly: same URL as remote, with Target.Readonly set
func (*Config) SetDefaultHub ¶ added in v0.20.0
SetDefaultHub sets the default hub name.
func (*Config) SetDefaultKeg ¶
SetDefaultKeg sets the alias used when no explicit keg is provided.
func (*Config) SetDefaultNamespace ¶ added in v0.23.0
SetDefaultNamespace sets the default namespace.
func (*Config) SetDisableAtlasHub ¶ added in v0.23.0
SetDisableAtlasHub toggles the synthesized built-in atlas hub.
func (*Config) SetDisableLocalHub ¶ added in v0.23.0
SetDisableLocalHub toggles the synthesized built-in local hub.
func (*Config) SetFallbackHub ¶ added in v0.23.0
SetFallbackHub sets the fallback hub name.
func (*Config) SetFallbackKeg ¶ added in v0.2.0
SetFallbackKeg sets the fallback keg alias.
func (*Config) SetFallbackNamespace ¶ added in v0.23.0
SetFallbackNamespace sets the fallback namespace.
func (*Config) SetFlight ¶ added in v0.23.0
SetFlight sets the persisted flight reference (or clears it when empty).
func (*Config) SetLogFile ¶
SetLogFile sets the log file path.
func (*Config) SetLogLevel ¶
SetLogLevel sets the log level.
func (*Config) SetNamespace ¶ added in v0.23.0
func (cfg *Config) SetNamespace(name string, ref NamespaceRef) error
SetNamespace adds or replaces the hub mapping for a namespace.
type ConfigEditOptions ¶
type ConfigEditOptions struct {
// Project indicates whether to edit local config instead of user config
Project bool
User bool
ConfigPath string
Stream *toolkit.Stream
}
ConfigEditOptions configures behavior for Tap.ConfigEdit.
type ConfigExplainOptions ¶ added in v0.17.0
type ConfigExplainOptions struct {
// Field limits the result to a single field. Empty means all fields.
Field string
}
ConfigExplainOptions configures behavior for Tap.ConfigExplain.
type ConfigExplainResult ¶ added in v0.17.0
type ConfigExplainResult struct {
Field string // field name (e.g. "defaultKeg")
Value string // resolved value in the merged config
Source string // which provider set this value ("user config", "project config", "env vars", "default")
}
ConfigExplainResult describes the provenance of a single config field.
type ConfigLoadWarning ¶ added in v0.17.0
type ConfigLoadWarning struct {
Source string // "user config" or "project config"
Path string // file path that caused the issue
Message string // human-readable description
Err error // underlying error
}
ConfigLoadWarning represents a non-fatal issue encountered while loading config.
type ConfigOptions ¶
type ConfigService ¶
type ConfigService struct {
Runtime *toolkit.Runtime
PathService *PathService
// ConfigPath is the path to the config file.
ConfigPath string
// LoadWarnings accumulates non-fatal issues from the last Config() call.
// Missing config files are not warnings (graceful degradation). Corrupt
// YAML, permission errors, etc. are recorded here.
LoadWarnings []ConfigLoadWarning
// ResolvedSources lists provider names that contributed to the merged config,
// most-specific first. Populated after Config() runs the cascade.
ResolvedSources []string
// contains filtered or unexported fields
}
ConfigService loads, merges, and resolves tapper configuration state.
func NewConfigService ¶
func NewConfigService(root string, rt *toolkit.Runtime) (*ConfigService, error)
NewConfigService builds a ConfigService rooted at root.
func (*ConfigService) Config ¶
func (s *ConfigService) Config(cache bool) (*Config, error)
Config returns the merged user and project configuration with optional caching. If cache is true and a merged config exists, it returns the cached version. Otherwise, it uses a cfgcascade.Cascade to resolve configuration from three providers in rank order: user config file, project config file, TAP_* env vars. When ConfigPath is set, it directly reads that file and bypasses the cascade.
func (*ConfigService) ProjectConfig ¶
func (s *ConfigService) ProjectConfig(cache bool) (*Config, error)
ProjectConfig returns the merged project-level configuration with optional caching. It walks from the workspace root up to the filesystem root, collecting every .tapper/config.yaml, and merges them so a deeper directory overrides a shallower one. Hub definitions and credentials are stripped from project layers — only the user config may define them — and each strip is recorded as a load warning surfaced by Config(). Returns keg.ErrNotExist when no project config exists.
func (*ConfigService) ResetCache ¶
func (s *ConfigService) ResetCache()
ResetCache clears cached user, project, and merged configs.
func (*ConfigService) ResolveTarget ¶
func (s *ConfigService) ResolveTarget(alias, nsOverride, hubOverride string, cache bool) (*keg.Target, error)
ResolveTarget resolves a keg selector to a keg target. When the selector is empty it uses defaultKeg, then fallbackKeg. The selector is parsed as a keg reference and turned into a concrete target by Config.ResolveAlias (the namespace-centric ResolveRef chain and per-hub-kind backend mapping).
func (*ConfigService) UserConfig ¶
func (s *ConfigService) UserConfig(cache bool) (*Config, error)
UserConfig returns the global user configuration.
func (*ConfigService) UserConfigExists ¶ added in v0.23.0
func (s *ConfigService) UserConfigExists() bool
UserConfigExists reports whether a user config file is present — the signal that `tap bootstrap` has been run. When an explicit config path is set (--config) it checks that file; otherwise the standard user config path. It inspects the filesystem only; it never parses, so a corrupt-but-present config still counts as bootstrapped.
type ConfigTemplateOptions ¶ added in v0.4.0
type ConfigTemplateOptions struct {
Project bool
}
type ConfigWarning ¶ added in v0.17.0
type ConfigWarning struct {
Field string // config field name (e.g., "kegMap[0]", "logLevel")
Message string // human-readable description
}
ConfigWarning represents a semantic issue found during config validation.
func ValidateConfig ¶ added in v0.17.0
func ValidateConfig(cfg *Config) []ConfigWarning
ValidateConfig checks a Config for semantic issues that are valid YAML but likely mistakes. It returns warnings, not errors — the config is still usable.
type CreateFlightOptions ¶ added in v0.23.0
type CreateFlightOptions struct {
Ref string
Title string
Visibility string
Capabilities []FlightCapability
Instructions string
Cover []FlightCover
}
type CreateOptions ¶
type DeleteFileOptions ¶ added in v0.2.0
type DeleteFileOptions struct {
KegTargetOptions
NodeID string
Name string
}
DeleteFileOptions configures behavior for Tap.DeleteFile.
type DeleteFlightOptions ¶ added in v0.23.0
type DeleteFlightOptions struct {
Ref string
}
type DeleteImageOptions ¶ added in v0.2.0
type DeleteImageOptions struct {
KegTargetOptions
NodeID string
Name string
}
DeleteImageOptions configures behavior for Tap.DeleteImage.
type DeviceUserPrompt ¶ added in v0.23.0
type DeviceUserPrompt struct {
UserCode string
VerificationURI string
VerificationURIComplete string
ExpiresIn int64
}
DeviceUserPrompt is the subset of the RFC 8628 device_authorization response an OnUserCode handler needs to drive the user-facing step. It is the exported projection of deviceAuthResponse so callers in other packages (the CLI) can present the code without seeing the wire type. VerificationURIComplete (a URL with the user_code embedded) is retained from the wire response but deliberately never displayed or opened — see VerificationURL.
func (DeviceUserPrompt) VerificationURL ¶ added in v0.23.0
func (p DeviceUserPrompt) VerificationURL() string
VerificationURL returns the URL the user should open: always the bare verification_uri, never a code-bearing variant. The user_code is shown separately and typed into the page (GitHub-style, RFC 8628 §3.3.1) — embedding it in the URL would leak it into browser history and any front proxy's access logs. The hub-provided verification_uri_complete is deliberately ignored for the same reason.
type DoctorOptions ¶ added in v0.5.0
type DoctorOptions struct {
KegTargetOptions
}
DoctorOptions configures behavior for Tap.Doctor.
type DownloadFileOptions ¶ added in v0.2.0
type DownloadFileOptions struct {
KegTargetOptions
NodeID string
Name string
Dest string
}
DownloadFileOptions configures behavior for Tap.DownloadFile.
type DownloadImageOptions ¶ added in v0.2.0
type DownloadImageOptions struct {
KegTargetOptions
NodeID string
Name string
Dest string
}
DownloadImageOptions configures behavior for Tap.DownloadImage.
type EditFlightOptions ¶ added in v0.24.0
type EditFlightOptions struct {
Ref string
// Stream, when piped with non-empty content, supplies the manifest YAML
// directly so scripts can apply a full manifest without an editor.
Stream *toolkit.Stream
}
EditFlightOptions configures behavior for Tap.EditFlight.
type EditOptions ¶
type EditOptions struct {
// NodeID is the node identifier to edit (e.g., "0", "42")
NodeID string
KegTargetOptions
// LockToken is an optional cross-process lock token. When provided, the
// command validates it against any held lock before proceeding.
LockToken string
// Stream carries stdin piping information.
Stream *toolkit.Stream
}
type EditSchemaOptions ¶ added in v0.25.0
type EditSchemaOptions struct {
KegTargetOptions
Type string
Stream *toolkit.Stream
}
type ExportOptions ¶ added in v0.4.0
type ExportOptions struct {
KegTargetOptions
NodeIDs []string
WithHistory bool
OutputPath string
}
type Flight ¶ added in v0.23.0
type Flight struct {
Name string `yaml:"-" json:"name,omitempty"`
Namespace string `yaml:"-" json:"namespace,omitempty"`
Slug string `yaml:"-" json:"slug,omitempty"`
Source string `yaml:"-" json:"source,omitempty"` // "local" or a hub name
ManifestHash string `yaml:"-" json:"-"`
FlightManifest
}
Flight is a discovered flight: its manifest plus provenance.
func (*Flight) HasCapability ¶ added in v0.30.0
func (f *Flight) HasCapability(capability FlightCapability) bool
HasCapability reports whether a validated manifest grants capability.
func (*Flight) RoleFor ¶ added in v0.23.0
func (f *Flight) RoleFor(alias, namespace, kegName string) (FlightRole, bool)
RoleFor reports the flight-scoped role for a keg. An empty cover denies all KEG access. Manifests normally arrive through normalizeFlightManifest, which folds legacy AllowedKegs into Cover; the fallback here only covers Flight values constructed by hand.
type FlightCapability ¶ added in v0.30.0
type FlightCapability string
type FlightCover ¶ added in v0.23.0
type FlightCover struct {
Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
Keg string `yaml:"keg" json:"keg"`
Role FlightRole `yaml:"role" json:"role"`
}
func ParseFlightCoverSpecs ¶ added in v0.23.0
func ParseFlightCoverSpecs(specs []string) ([]FlightCover, error)
ParseFlightCoverSpecs parses CLI/MCP cover specs of the form "keg", "@ns/keg", or "@ns/keg=role". Bare entries default to viewer, matching the manifest parser; editor must be requested explicitly.
type FlightManifest ¶ added in v0.23.0
type FlightManifest struct {
Title string `yaml:"title,omitempty" json:"title,omitempty"`
Visibility string `yaml:"visibility,omitempty" json:"visibility,omitempty"`
Capabilities []FlightCapability `yaml:"capabilities,omitempty" json:"capabilities,omitempty"`
Cover []FlightCover `yaml:"cover,omitempty" json:"cover,omitempty"`
AllowedKegs []string `yaml:"allowedKegs,omitempty" json:"allowedKegs,omitempty"`
Instructions string `yaml:"instructions,omitempty" json:"instructions,omitempty"`
}
FlightManifest is the on-disk/API shape of a flight: explicit covered kegs plus markdown instructions. AllowedKegs is kept for backward compatibility with local manifests and is normalized into editor-cap cover entries.
type FlightRef ¶ added in v0.23.0
func ParseFlightRef ¶ added in v0.23.0
type FlightRestrictionError ¶ added in v0.23.0
type FlightRestrictionError struct {
Flight string
Keg string
Want FlightRole
Got FlightRole
}
FlightRestrictionError is returned when a resolved keg falls outside the active flight's cover or role cap.
func (*FlightRestrictionError) Error ¶ added in v0.23.0
func (e *FlightRestrictionError) Error() string
type FlightRole ¶ added in v0.23.0
type FlightRole string
func (FlightRole) AtLeast ¶ added in v0.23.0
func (r FlightRole) AtLeast(want FlightRole) bool
AtLeast reports whether r grants at least want within a flight cover.
type FlightService ¶ added in v0.23.0
type FlightService struct {
Runtime *toolkit.Runtime
ConfigService *ConfigService
// KegService supplies the token resolver (and its cached auth store)
// for hub requests. Lazily constructed when not wired by NewTap.
KegService *KegService
// contains filtered or unexported fields
}
FlightService discovers and loads flights for configured local and remote hubs. Local-hub flights live under <basePath>/flights.d; remote-hub flights are served by the Hub API.
func (*FlightService) GetFlight ¶ added in v0.23.0
GetFlight loads a single flight by ref. Returns keg.ErrNotExist when no manifest exists. Unqualified refs first try local manifests for backward compatibility, then unique remote slug matches. Results are memoized for the life of the process (see flightCache).
func (*FlightService) GetFlightFresh ¶ added in v0.30.0
GetFlightFresh bypasses the process cache. MCP sessions use this before gated calls so a manifest change invalidates the pinned session instead of silently changing its authority.
func (*FlightService) ListFlights ¶ added in v0.23.0
func (s *FlightService) ListFlights(ctx context.Context, hub string, warnings *[]string) ([]string, error)
ListFlights returns canonical @namespace/+slug refs for flights discovered across configured hubs, sorted. When hub is non-empty, discovery is limited to that configured hub. Remote/auth/network errors are best-effort so shell completion and discovery remain responsive; when warnings is non-nil each skipped hub appends one message so user-facing listings can say what was left out.
func (*FlightService) StoreSessionFlight ¶ added in v0.30.0
func (s *FlightService) StoreSessionFlight(name string, f *Flight)
StoreSessionFlight pins a validated flight in the process cache for Tap's per-operation cover enforcement. MCP session invalidation is handled by the server-owned gate before these cached values are used.
type ForceUnlockOptions ¶ added in v0.11.0
type ForceUnlockOptions struct {
NodeID string
KegTargetOptions
}
ForceUnlockOptions configures behavior for Tap.ForceUnlock.
type GetFlightOptions ¶ added in v0.23.0
type GetFlightOptions struct {
Name string
}
GetFlightOptions selects a single flight by name.
type GraphOptions ¶ added in v0.4.0
type GraphOptions struct {
KegTargetOptions
// BundleJS is the compiled browser renderer injected into the generated page.
BundleJS []byte
}
GraphOptions configures graph HTML generation for a resolved keg.
type GrepOptions ¶
type GrepOptions struct {
KegTargetOptions
// Query is the regex pattern used to search nodes.
Query string
// Format to use. %i is node id
// %d is date
// %t is node title
// %% for literal %
Format string
IdOnly bool
Reverse bool
// IgnoreCase enables case-insensitive regex matching.
IgnoreCase bool
// MaxLines caps the number of matched lines returned per node.
// 0 means unlimited. When > 0, only the first MaxLines matching lines
// are included per node.
MaxLines int
// Limit caps the number of results returned. 0 means no limit.
Limit int
// Offset skips the first N results before applying limit. Must be >= 0.
Offset int
}
type HubAddOptions ¶ added in v0.23.0
HubAddOptions adds a remote hub connection to user config.
type HubEntry ¶ added in v0.23.0
type HubEntry struct {
Kind string `yaml:"kind,omitempty"`
// DefaultNamespace is this hub's default namespace, used when a reference
// resolved against this hub omits its namespace. A hub hosts many namespaces;
// this is only the default. The "@" sigil is implied — store the bare value.
DefaultNamespace string `yaml:"defaultNamespace,omitempty"`
URL string `yaml:"url,omitempty"`
BasePath string `yaml:"basePath,omitempty"`
Token string `yaml:"token,omitempty"`
TokenEnv string `yaml:"tokenEnv,omitempty"`
}
HubEntry describes a single configured hub, keyed by name in the hubs map.
Kind selects the backend: "remote" (read-write HTTP, the default when Kind is empty), "local" (filesystem) or "readonly" (read-only HTTP). Remote and readonly hubs use URL; local hubs use BasePath as the filesystem root that holds @<namespace>/<name> keg directories.
type HubFlight ¶ added in v0.23.0
type HubFlight struct {
Namespace string `json:"namespace"`
Slug string `json:"slug"`
Title string `json:"title"`
Instructions string `json:"instructions"`
Visibility string `json:"visibility"`
Capabilities []FlightCapability `json:"capabilities"`
Cover []HubFlightCover `json:"cover"`
}
func CreateHubFlight ¶ added in v0.23.0
func GetHubFlight ¶ added in v0.23.0
func ListUserFlights ¶ added in v0.23.0
type HubFlightCover ¶ added in v0.23.0
type HubGrant ¶ added in v0.23.0
type HubGrant struct {
Username string `json:"username"`
Role string `json:"role"` // viewer|editor|admin
}
HubGrant is one per-(user, role) grant on a keg. Mirrors the hub's handler.ListGrants JSON body — keep the two in sync. (granted_at is sent by the hub but unused here.)
type HubInfo ¶ added in v0.23.0
type HubInfo struct {
Name string
URL string
Kind string
IsDefault bool
Source string // "user" or "built-in"
}
HubInfo describes a configured hub for `tap hub list`.
type HubKeg ¶ added in v0.23.0
type HubKeg struct {
Namespace string `json:"namespace"`
Alias string `json:"alias"`
Visibility string `json:"visibility"`
Role string `json:"role"`
}
HubKeg is one keg the hub reports the authenticated user can reach. It mirrors the hub's handler.UserKegItem JSON body — keep the two in sync.
type HubListOptions ¶ added in v0.23.0
type HubListOptions struct {
Hub string
}
HubListOptions selects which hub to enumerate. An empty Hub aggregates every configured hub the user can reach.
type HubMember ¶ added in v0.23.0
type HubMember struct {
Username string `json:"username"`
Role string `json:"role"` // owner|admin|member
}
HubMember is one namespace membership row. Mirrors the hub's handler.memberWire JSON body — keep the two in sync.
type HubNamespace ¶ added in v0.23.0
type HubNamespace struct {
Name string `json:"name"`
Kind string `json:"kind,omitempty"` // user|org
Role string `json:"role,omitempty"` // caller's role
}
HubNamespace is one namespace the caller belongs to (or just created). Mirrors the hub's handler.namespaceWire JSON body — keep the two in sync.
func CreateNamespace
deprecated
added in
v0.23.0
func CreateNamespace(ctx context.Context, hubURL, token, name string) (*HubNamespace, error)
CreateNamespace is disabled for remote clients. Namespace creation is a paid hub UI flow; use Tap.NamespaceCreate to get the browser handoff URL.
Deprecated: remote namespace creation is not supported.
func ListNamespaces ¶ added in v0.23.0
func ListNamespaces(ctx context.Context, hubURL, token string) ([]HubNamespace, error)
ListNamespaces returns the namespaces the caller belongs to via GET /api/v1/namespaces.
type HubRemoveOptions ¶ added in v0.23.0
type HubRemoveOptions struct {
Name string
}
HubRemoveOptions removes a hub connection from user config.
type HubSetDefaultOptions ¶ added in v0.23.0
HubSetDefaultOptions sets the default hub. It writes project config by default and user config with User=true (mirroring `tap config edit`).
type ImportFromKegOptions ¶ added in v0.4.0
type ImportFromKegOptions struct {
// Source is the source keg to copy nodes from.
Source KegTargetOptions
// Target is the destination keg; defaults to the resolved default keg.
Target KegTargetOptions
// NodeIDs lists the source node IDs to import. Values may be bare integers
// ("5") or cross-keg references ("keg:pub/5"). All must resolve to Source.
// When empty and TagQuery is also empty, all non-zero nodes are imported.
NodeIDs []string
// TagQuery is a boolean tag expression (same syntax as tap tags EXPR) that
// selects additional source nodes; combined with NodeIDs as a union.
TagQuery string
// LeaveStubs writes a forwarding stub at each source node location after import.
LeaveStubs bool
// SkipZeroNode skips the source keg's node 0 (the index/root node).
SkipZeroNode bool
}
ImportFromKegOptions controls how ImportFromKeg copies nodes from one live keg into another.
type ImportOptions ¶ added in v0.4.0
type ImportOptions struct {
KegTargetOptions
Input string
}
type ImportedNode ¶ added in v0.4.0
ImportedNode records the source → target ID mapping for one imported node.
type IndexCatOptions ¶ added in v0.2.0
type IndexCatOptions struct {
KegTargetOptions
// Name is the index file name to dump, e.g. "changes.md" or "nodes.tsv".
// A leading "dex/" prefix is stripped automatically.
Name string
}
type IndexOptions ¶
type IndexOptions struct {
KegTargetOptions
// NoUpdate skips updating node meta information
NoUpdate bool
}
type InfoOptions ¶
type InfoOptions struct {
KegTargetOptions
// JSON renders the diagnostics as JSON instead of YAML.
JSON bool
// Debug includes working-directory and backend resolution diagnostics.
Debug bool
}
InfoOptions configures behavior for Tap.Info.
type InitOptions ¶
type InitOptions struct {
// Local (filesystem) project destination selectors. Any of these forces a
// project-local keg under the git root / cwd / explicit path; namespace and
// hub resolution do not apply.
Project bool
User bool // pin the reserved @local namespace (this machine's local hub)
Cwd bool // use cwd as the project root base instead of git root
Path string // explicit filesystem path; implies a local project destination
// Destination overrides for the namespace-centric resolution. An empty
// Namespace defers to config (kegs[name].Namespace → default/fallback); an
// empty Hub defers to namespaces[ns].Hub → default/fallback. A bare name
// thus resolves to the default namespace+hub — typically a remote create —
// while "@local/<name>" pins the filesystem hub.
Namespace string
Hub string
TokenEnv string
Creator string
Title string
Keg string
// NonInteractive suppresses interactive prompts when set, forcing the
// caller to rely on flag-driven defaults (platform user-data dir, alias
// inferred from cwd, etc.) even when the surface is attached to a TTY.
// The Tap method itself does not consult this field — TTY handling is a
// CLI/MCP concern — but the option lives on InitOptions so both the CLI
// flag and the MCP input field map to the same canonical contract.
NonInteractive bool
// RequireBootstrap makes a namespace/hub create (anything but an explicit
// local destination) fail with ErrNotBootstrapped when no user config exists
// — `tap bootstrap` has not been run. Set by the full `tap` surface and the
// MCP server; left false for direct Tap API callers (e.g. tests), which keep
// the unconfigured local fallback.
RequireBootstrap bool
}
func (InitOptions) LocalDestination ¶ added in v0.4.0
func (o InitOptions) LocalDestination() bool
LocalDestination reports whether the options force a project-local filesystem keg (as opposed to the namespace-resolved user/hub destination).
type IntegrateOptions ¶ added in v0.19.0
type IntegrateOptions struct {
KegTargetOptions
Host string
DryRun bool
Plugins []string
Scope string
}
IntegrateOptions selects the host, native install scope, dry-run behavior, and optional plugins for native plugin installation. The baseline tapper plugin is always installed.
type IntegrateResult ¶ added in v0.30.0
IntegrateResult describes the extracted marketplace and the host commands used to inspect, register, and install it.
type Issue ¶ added in v0.5.0
type Issue = keg.DoctorIssue
Issue represents a single problem found during a doctor check.
type KegConfigEditOptions ¶ added in v0.2.0
type KegConfigEditOptions struct {
KegTargetOptions
Stream *toolkit.Stream
}
KegConfigEditOptions configures behavior for Tap.KegConfigEdit.
type KegGrantOptions ¶ added in v0.23.0
type KegGrantOptions struct {
Keg string
Namespace string
Hub string
User string
Role string // viewer|editor|admin
}
KegGrantOptions upserts a grant on a keg.
type KegGrantsOptions ¶ added in v0.23.0
KegGrantsOptions selects the keg whose grants to list. Keg is the selector (a bare name or @namespace/keg); empty resolves the default keg. Namespace and Hub override the resolved reference's components.
type KegMapEntry ¶
type KegMapEntry struct {
Alias string `yaml:"alias,omitempty"`
PathPrefix string `yaml:"pathPrefix,omitempty"`
PathRegex string `yaml:"pathRegex,omitempty"`
}
KegMapEntry is an entry mapping a path prefix or regex to a keg alias.
type KegRef ¶ added in v0.23.0
type KegRef struct {
Hub string `yaml:"hub,omitempty"`
Namespace string `yaml:"namespace,omitempty"`
Name string `yaml:"name,omitempty"`
Path string `yaml:"path,omitempty"`
}
KegRef is the (hub, namespace, name) triple a keg alias resolves to. An empty Hub falls back to defaultHub/fallbackHub; an empty Namespace falls back to defaultNamespace/fallbackNamespace (see Config.ResolveRef).
Path addresses a keg by an explicit local filesystem path. When set it takes precedence over the triple and resolves to a file target at that path. The triple addresses a keg by namespace; Path addresses one directly on disk.
func (*KegRef) UnmarshalYAML ¶ added in v0.23.0
UnmarshalYAML accepts the canonical mapping form ({hub, namespace, name, path}) and a scalar shorthand parsed via keg.Parse — the canonical keg shorthand "keg:@ns/name" sets {namespace, name} (the hub is resolved from the namespace, never encoded), while a bare file/url scalar maps onto a Path. To pin a hub, use the mapping form's "hub" field. Writes always serialize the canonical mapping form.
type KegRenameOptions ¶ added in v0.25.0
KegRenameOptions renames a hub-backed keg alias within one namespace.
type KegRevokeOptions ¶ added in v0.23.0
KegRevokeOptions revokes a user's grant on a keg.
type KegService ¶
type KegService struct {
// Runtime provides filesystem and environment access used to resolve kegs.
Runtime *toolkit.Runtime
// ConfigService resolves configured keg aliases and targets.
ConfigService *ConfigService
// contains filtered or unexported fields
}
KegService resolves keg targets from config, project paths, and explicit filesystem locations.
func (*KegService) Resolve ¶
func (s *KegService) Resolve(ctx context.Context, opts ResolveKegOptions) (keg.Keg, error)
Resolve returns a keg using explicit path, project, alias, or configured fallback resolution.
type KegSettingsOptions ¶ added in v0.33.0
type KegSettingsOptions struct {
KegTargetOptions
// Minimal strips large sections (tags, entities, indexes) from the output,
// returning only core config fields. Useful for MCP tools where response
// size must stay small.
Minimal bool
}
KegSettingsOptions configures behavior for Tap.KegSettings.
type KegTargetOptions ¶
type KegTargetOptions struct {
// Keg is the keg selector: a bare name or an @namespace/keg reference.
Keg string
// Namespace overrides the namespace the keg resolves in when Keg is a bare
// name (it loses to an @namespace/ already present in Keg). Empty means use
// the configured defaultNamespace/fallbackNamespace chain.
Namespace string
// Hub pins the hub the keg resolves on, overriding namespace→hub resolution.
// Empty means resolve the hub from the namespace as usual.
Hub string
// Project resolves using project-local keg discovery. Not exposed as a tap
// flag; retained for the pruned `keg` binary (ForceProjectResolution) and
// the keg-create destination flags.
Project bool
// Cwd resolves project keg at the current working directory instead of git root.
// Works standalone or combined with Project.
Cwd bool
// Path is an explicit local project path used for project keg discovery.
Path string
// Flight is optional task context that can restrict which kegs are available
// and injects agent instructions. It composes with the single-keg selectors
// (Keg/Namespace/Hub): the selector picks a keg and the flight gates it unless
// BypassFlightRestrictions is true.
Flight string
// BypassFlightRestrictions skips flight cover and role-cap checks while
// preserving Flight for callers that still need the flight context, such as
// orient. Leave false for MCP and other agent-facing surfaces.
BypassFlightRestrictions bool
// RequireBootstrap makes config-driven resolution fail with
// ErrNotBootstrapped when no user config exists. Set by the full `tap`
// surface and the MCP server; left false by the pruned `keg` binary and by
// direct Tap API callers (e.g. tests).
RequireBootstrap bool
}
KegTargetOptions describes how a command should resolve a keg target.
type KegVisibilityOptions ¶ added in v0.23.0
type KegVisibilityOptions struct {
Keg string
Namespace string
Hub string
Visibility string // public|private
}
KegVisibilityOptions sets a keg's visibility.
type LinksOptions ¶ added in v0.5.0
type LinksOptions struct {
KegTargetOptions
// NodeIDs are the source nodes to inspect outgoing links for.
// Results from all node IDs are merged and deduplicated.
NodeIDs []string
// Format to use. %i is node id
// %d is date
// %t is node title
// %% for literal %
Format string
IdOnly bool
Reverse bool
// Limit caps the number of results returned. 0 means no limit.
Limit int
// Offset skips the first N results before applying limit. Must be >= 0.
Offset int
}
type ListFilesOptions ¶ added in v0.2.0
type ListFilesOptions struct {
KegTargetOptions
NodeID string
}
type ListFlightsOptions ¶ added in v0.23.0
type ListFlightsOptions struct {
// Hub limits discovery to one configured hub. Empty discovers flights across
// every configured hub.
Hub string
// Warnings, when non-nil, collects one message per hub that was skipped
// (missing token, network failure) instead of failing the whole listing.
// Completion paths leave it nil so discovery stays silent and best-effort.
Warnings *[]string
}
ListFlightsOptions controls Tap.ListFlights. Flights are hub-scoped, so there is no keg target.
type ListImagesOptions ¶ added in v0.2.0
type ListImagesOptions struct {
KegTargetOptions
NodeID string
}
ListImagesOptions configures behavior for Tap.ListImages.
type ListOptions ¶
type ListOptions struct {
KegTargetOptions
// Query is an optional boolean expression that filters nodes. Supports both
// plain tag names ("golang") and key=value attribute predicates
// ("entity=plan"). When empty, all nodes are listed.
Query string
// Format to use. %i is node id, %d
// %i is node id
// %d is date
// %t is node title
// %% for literal %
Format string
IdOnly bool
Reverse bool
// Sort selects the sort order. Empty string means sort by node ID (default).
Sort ListSortType
// Limit caps the number of results returned. 0 means no limit.
Limit int
// Offset skips the first N results before applying limit. Must be >= 0.
Offset int
}
type ListSortType ¶ added in v0.5.0
type ListSortType string
ListSortType controls the ordering of listed nodes.
const ( SortByDefault ListSortType = "" // default: same as SortByID SortByID ListSortType = "id" // ascending node ID SortByUpdated ListSortType = "updated" // ascending by last-updated timestamp SortByCreated ListSortType = "created" // ascending by creation timestamp SortByAccessed ListSortType = "accessed" // ascending by last-accessed timestamp )
type LockOptions ¶ added in v0.11.0
type LockOptions struct {
NodeID string
KegTargetOptions
}
LockOptions configures behavior for Tap.Lock.
type LockStatusOptions ¶ added in v0.11.0
type LockStatusOptions struct {
NodeID string
KegTargetOptions
}
LockStatusOptions configures behavior for Tap.LockStatus.
type MetaOptions ¶
type MetaOptions struct {
// NodeID is the node identifier to inspect (e.g., "0", "42")
NodeID string
KegTargetOptions
// LockToken is an optional cross-process lock token. When provided, the
// command validates it against any held lock before proceeding.
LockToken string
// Edit opens metadata in the editor.
Edit bool
// Stream carries stdin piping information.
Stream *toolkit.Stream
}
MetaOptions configures behavior for Tap.Meta.
type MoveOptions ¶
type MoveOptions struct {
KegTargetOptions
SourceID string
DestID string
}
type NamespaceAddMemberOptions ¶ added in v0.23.0
type NamespaceAddMemberOptions struct {
Namespace string
Hub string
User string
Role string // owner|admin|member
}
NamespaceAddMemberOptions upserts a member into a namespace.
type NamespaceCreateOptions ¶ added in v0.23.0
NamespaceCreateOptions creates an org namespace.
type NamespaceCreateResult ¶ added in v0.23.0
NamespaceCreateResult tells the caller where to create the namespace in the hub UI. Namespace creation is a paid hub feature, so the CLI/MCP surface hands the user to the browser instead of calling the API.
type NamespaceListOptions ¶ added in v0.23.0
type NamespaceListOptions struct {
Hub string
}
NamespaceListOptions selects which hub to query for namespaces. Empty uses the resolved default hub.
type NamespaceMembersOptions ¶ added in v0.23.0
NamespaceMembersOptions selects the namespace whose members to list. Namespace is the selector; empty resolves the default namespace. Hub pins the hub.
type NamespaceRef ¶ added in v0.23.0
type NamespaceRef struct {
Hub string `yaml:"hub,omitempty"`
}
NamespaceRef names the hub that hosts a namespace. It is the conflict resolver for namespace→hub: when a namespace could live on more than one configured hub, an entry here pins which one. An empty Hub falls back to the hub precedence chain (see Config.resolveHubForNamespace).
func (*NamespaceRef) UnmarshalYAML ¶ added in v0.23.0
func (r *NamespaceRef) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML accepts the canonical mapping form ({hub: name}) and the scalar shorthand (a bare hub name), so both `jlrickert: atlas` and `jlrickert: {hub: atlas}` load. Writes always serialize the mapping form.
type NamespaceRemoveMemberOptions ¶ added in v0.23.0
NamespaceRemoveMemberOptions removes a member from a namespace.
type NamespaceSetRoleOptions ¶ added in v0.23.0
type NamespaceSetRoleOptions struct {
Namespace string
Hub string
User string
Role string // owner|admin|member
}
NamespaceSetRoleOptions changes an existing member's role.
type NodeHistoryOptions ¶ added in v0.4.0
type NodeHistoryOptions struct {
KegTargetOptions
NodeID string
}
type NodeRestoreOptions ¶ added in v0.4.0
type NodeRestoreOptions struct {
KegTargetOptions
NodeID string
Rev string
}
type NodeSnapshotOptions ¶ added in v0.4.0
type NodeSnapshotOptions struct {
KegTargetOptions
NodeID string
Message string
}
type NodeSnapshotViewOptions ¶ added in v0.23.0
type NodeSnapshotViewOptions struct {
KegTargetOptions
NodeID string
Rev string
}
type OrientOptions ¶ added in v0.19.0
type OrientOptions struct {
KegTargetOptions
}
OrientOptions is the input to Tap.Orient. Every field is optional: a zero-valued call returns the KEG system payload with the target keg resolved from KegTargetOptions.
type PathNotFoundError ¶ added in v0.5.0
type PathNotFoundError struct {
Path string
}
PathNotFoundError indicates that the explicit --path target does not exist on disk.
func (*PathNotFoundError) Error ¶ added in v0.5.0
func (e *PathNotFoundError) Error() string
type PathService ¶
func NewPathService ¶
func NewPathService(rt *toolkit.Runtime, root string) (*PathService, error)
func (*PathService) AuthStorePath ¶ added in v0.20.0
func (s *PathService) AuthStorePath() string
AuthStorePath returns the on-disk location of the hub-auth credentials store. The file is stored under StateRoot (not ConfigRoot) because it holds mutable per-host tokens rather than user-edited configuration.
func (*PathService) Project ¶
func (s *PathService) Project() string
func (*PathService) ProjectConfig ¶
func (s *PathService) ProjectConfig() string
func (*PathService) UserConfig ¶
func (s *PathService) UserConfig() string
type ProjectKegNotFoundError ¶
type ProjectKegNotFoundError struct {
Tried []string
}
ProjectKegNotFoundError indicates project-local keg discovery failed. Tried contains the concrete keg-file locations that were checked.
func (*ProjectKegNotFoundError) Error ¶
func (e *ProjectKegNotFoundError) Error() string
func (*ProjectKegNotFoundError) UserMessage ¶ added in v0.13.0
func (e *ProjectKegNotFoundError) UserMessage(debug bool) string
UserMessage returns a CLI-context-aware message. When debug is true and search paths are available, they are included in the output.
type ReadImageOptions ¶ added in v0.24.0
type ReadImageOptions struct {
KegTargetOptions
NodeID string
Name string
}
ReadImageOptions configures behavior for Tap.ReadImage.
type RefContext ¶ added in v0.23.0
RefContext carries the "current keg" so a node reference can resolve a keg-local alias against that keg's Links table and imply the hub for a qualified reference from the current keg's hub.
type RemoveOptions ¶
type RemoveOptions struct {
KegTargetOptions
// NodeIDs lists explicit node IDs to remove.
NodeIDs []string
// Query is an optional boolean expression (tags and/or key=value attr
// predicates) that selects additional nodes to remove.
Query string
}
type ResolveKegOptions ¶
type ResolveKegOptions struct {
// Root is the base path used for project and fallback resolution.
Root string
// Keg is the explicit keg alias to resolve.
Keg string
// Namespace overrides the namespace component of the resolved reference when
// the selector is a bare name. Empty uses the configured chain.
Namespace string
// Hub pins the hub the reference resolves on, overriding namespace→hub
// resolution. Empty resolves the hub from the namespace as usual.
Hub string
// Project resolves a keg from project-local locations.
Project bool
// Cwd limits project resolution to the current working directory.
Cwd bool
// Path resolves a keg from an explicit filesystem path.
Path string
// RequireBootstrap makes config/namespace/hub-driven resolution fail with
// ErrNotBootstrapped when no user config exists (`tap bootstrap` has not been
// run). The full `tap` surface sets it; the pruned `keg` binary does not.
// Explicit filesystem destinations (Project/Cwd/Path) and selectors that are
// themselves a filesystem path are exempt.
RequireBootstrap bool
// NoCache disables in-memory keg caching for this resolution.
NoCache bool
}
ResolveKegOptions controls how KegService resolves a keg target.
type SchemaOptions ¶ added in v0.25.0
type SchemaOptions struct {
KegTargetOptions
Type string
Data []byte
}
type StatsOptions ¶
type StatsOptions struct {
// NodeID is the node identifier to inspect (e.g., "0", "42")
NodeID string
KegTargetOptions
}
type TagsOptions ¶
type TagsOptions struct {
KegTargetOptions
// Query is an optional boolean expression that filters nodes. Supports both
// plain tag names ("golang") and key=value attribute predicates
// ("entity=plan"). When empty, all tags are listed.
Query string
// Format to use. %i is node id
// %d is date
// %t is node title
// %% for literal %
Format string
IdOnly bool
Reverse bool
// Limit caps the number of results returned. 0 means no limit.
Limit int
// Offset skips the first N results before applying limit. Must be >= 0.
Offset int
}
type Tap ¶
type Tap struct {
Root string
// Runtime carries process-level dependencies.
Runtime *toolkit.Runtime
PathService *PathService
ConfigService *ConfigService
KegService *KegService
FlightService *FlightService
// AuthValidateFn is the seam AuthStatus uses for its live whoami probe.
// Defaulted to ValidateToken in NewTap; tests override it (or point the
// hub at an httptest server) to avoid real network I/O. Both the CLI and
// MCP surfaces share the same *Tap, so overriding it covers both.
AuthValidateFn func(ctx context.Context, rt *toolkit.Runtime, hubURL, token string) (*WhoAmI, error)
// KegResolver, when non-nil, overrides config-driven keg resolution. It is
// the seam tapper-hub uses to serve a per-user MCP connector: the hub injects
// a resolver that opens kegs from its own Postgres catalog and enforces the
// caller's role, bypassing the on-disk config cascade and AuthStore entirely
// (which, in the hub server's process, hold no login). role is the access
// level the calling operation needs — FlightRoleViewer for reads,
// FlightRoleEditor for writes — so the resolver can map it to a catalog role
// check. Every node read/write op funnels through resolveKegForRole, so a
// single resolver covers the whole surface. Left nil for the CLI, which keeps
// the standard config-driven resolution.
KegResolver func(ctx context.Context, opts KegTargetOptions, role FlightRole) (keg.Keg, error)
}
func NewTap ¶
func NewTap(opts TapOptions) (*Tap, error)
func (*Tap) ActiveFlightName ¶ added in v0.30.0
ActiveFlightName resolves an explicit flight or the persistent project default without mutating configuration.
func (*Tap) AuthLogout ¶ added in v0.20.0
func (t *Tap) AuthLogout(ctx context.Context, opts AuthLogoutOptions) (*AuthLogoutResult, error)
AuthLogout removes the cached credential for a hub from the on-disk auth store. Unlike AuthStatus this method is intentionally NOT exposed over MCP — an agent should never be able to yank a user's hub token out from under them. The CLI surface is the only consumer.
Resolution precedence mirrors AuthStatus:
- Hub set → canonicalize and delete that hub.
- Hub empty AND single hub stored → auto-resolve to that hub.
- Hub empty AND zero hubs stored → soft-success, "No hub logins stored.".
- Hub empty AND multiple hubs stored → error (caller must pick).
Missing entries (hub was provided but not stored) are NOT errors — they return Result{Removed: false} with a clear Formatted line. The command is idempotent by design so cleanup scripts can re-run without special-casing the already-logged-out state.
func (*Tap) AuthRefreshAll ¶ added in v0.28.1
AuthRefreshAll renews every stored hub credential whose access token is expired or within refreshSkew of expiring, persisting the rotated pairs. Entries without a refresh token (pasted API tokens) or without a known expiry are skipped. Best-effort by design: failures are logged at debug and never returned — this runs on every CLI/MCP startup and a broken hub must not block unrelated commands. Cost when all tokens are fresh: one file read, zero network calls.
func (*Tap) AuthStatus ¶ added in v0.20.0
func (t *Tap) AuthStatus(ctx context.Context, opts AuthStatusOptions) (*AuthStatusResult, error)
AuthStatus reports the login status for a stored hub.
Resolution precedence:
- Empty store AND empty Hub → not-present, directed hint message.
- Hub set → canonicalize and look up exactly that hub.
- Hub empty AND one or more hubs stored → report every stored hub.
Missing entries (hub was provided but not stored) are NOT errors — they return a Result{Present: false} with a clear Formatted line. That keeps `tap auth status --hub X` usable from scripts without requiring caller-side error-matching.
func (*Tap) Bootstrap ¶ added in v0.23.0
func (t *Tap) Bootstrap(ctx context.Context, opts BootstrapOptions) (*BootstrapResult, error)
Bootstrap creates or refreshes the user-level config for a chosen deployment kind so plain `tap` commands resolve without per-invocation flags. It writes the FALLBACK hub (the user/global convention — project config owns the high-precedence default* slots) and always ensures the built-in local hub is present and that the reserved @local namespace maps to it.
It does not write a global fallbackNamespace or a per-user namespace→hub entry: the preferred namespace comes from the resolved hub's own namespace field. For local that is @local; for cloud/enterprise it is the logged-in user's home namespace, adopted onto the hub after login by SetBootstrapNamespace. The only namespace→hub entry written is local→localHub.
It is idempotent: an existing config is loaded and only the fallback hub, the local namespace mapping, and the kind's hub entry are touched, so user-defined kegs/kegMap survive a re-run untouched.
func (*Tap) Config ¶
func (t *Tap) Config(opts ConfigOptions) (string, error)
Config displays the merged or project configuration.
func (*Tap) ConfigEdit ¶
func (t *Tap) ConfigEdit(ctx context.Context, opts ConfigEditOptions) error
ConfigEdit edits the selected tap config file.
If stdin is piped with non-empty content, the piped YAML is validated and written directly without opening an editor. Otherwise the file is opened in the configured editor.
func (*Tap) ConfigExplain ¶ added in v0.17.0
func (t *Tap) ConfigExplain(ctx context.Context, opts ConfigExplainOptions) ([]ConfigExplainResult, error)
ConfigExplain returns provenance for config fields, showing which source set each value. It loads each tier individually and walks from most-specific to least-specific to determine the effective source.
func (*Tap) ConfigTemplate ¶ added in v0.4.0
func (t *Tap) ConfigTemplate(opts ConfigTemplateOptions) (string, error)
ConfigTemplate returns starter YAML for either user or project config.
func (*Tap) CreateFlight ¶ added in v0.23.0
func (*Tap) CreateSchema ¶ added in v0.25.0
func (t *Tap) CreateSchema(ctx context.Context, opts SchemaOptions) error
func (*Tap) DeleteFile ¶ added in v0.2.0
func (t *Tap) DeleteFile(ctx context.Context, opts DeleteFileOptions) error
DeleteFile removes a file attachment from a node.
func (*Tap) DeleteFlight ¶ added in v0.23.0
func (t *Tap) DeleteFlight(ctx context.Context, opts DeleteFlightOptions) error
func (*Tap) DeleteImage ¶ added in v0.2.0
func (t *Tap) DeleteImage(ctx context.Context, opts DeleteImageOptions) error
DeleteImage removes an image from a node.
func (*Tap) DeleteSchema ¶ added in v0.25.0
func (t *Tap) DeleteSchema(ctx context.Context, opts SchemaOptions) error
func (*Tap) DoctorConfig ¶ added in v0.17.0
DoctorConfig validates the tapper configuration (not keg-level) and returns issues. This does not require a keg to be resolved.
func (*Tap) DownloadFile ¶ added in v0.2.0
DownloadFile retrieves a node file attachment and writes it to a local path. Returns the destination path.
func (*Tap) DownloadImage ¶ added in v0.2.0
DownloadImage retrieves a node image and writes it to a local path. Returns the destination path.
func (*Tap) Edit ¶
func (t *Tap) Edit(ctx context.Context, opts EditOptions) error
Edit opens a node in an editor. When the repository is an FsRepo, the real README.md is opened directly for in-place editing. Otherwise a temporary file with frontmatter is used and changes are split back on save.
The temp file format (non-FsRepo) is:
--- <meta yaml> --- <markdown body>
If stdin is piped, it seeds the content directly without opening an editor.
func (*Tap) EditFlight ¶ added in v0.24.0
EditFlight edits a Hub-backed flight's manifest as YAML.
If stdin is piped with non-empty content, the piped manifest is validated and applied directly. Otherwise the manifest opens in the configured editor; every save is validated and PUT to the hub immediately, so the editor session behaves like the rest of tapper's live-save edit flows.
The manifest carries title, visibility, capabilities, cover, and instructions. The slug and namespace are fixed by the ref: the YAML document cannot express them, and a stray "slug" key is rejected as an unknown field.
func (*Tap) EditSchema ¶ added in v0.25.0
func (t *Tap) EditSchema(ctx context.Context, opts EditSchemaOptions) error
func (*Tap) Export ¶ added in v0.4.0
Export writes a keg-archive of the selected nodes (all nodes when none are named) to opts.OutputPath and returns the resolved output path.
func (*Tap) ForceUnlock ¶ added in v0.11.0
func (t *Tap) ForceUnlock(ctx context.Context, opts ForceUnlockOptions) error
ForceUnlock unconditionally removes a cross-process lock on a node.
func (*Tap) Graph ¶ added in v0.4.0
Graph renders a self-contained HTML page for the resolved keg graph.
func (*Tap) HubAdd ¶ added in v0.23.0
func (t *Tap) HubAdd(_ context.Context, opts HubAddOptions) error
HubAdd registers a remote hub connection. Hub entries may only live in USER config (the trust boundary strips hubs from project config), so this always writes the user config regardless of the working directory.
func (*Tap) HubList ¶ added in v0.23.0
HubList returns the configured hubs (plus the synthesized built-ins when none are configured), marking the default and the config layer each came from. It inspects local config only — it does not contact any hub.
func (*Tap) HubListKegs ¶ added in v0.23.0
HubListKegs lists kegs qualified as "@namespace/keg". With no --hub it aggregates across every configured hub: local hubs are scanned on disk at <basePath>/@<namespace>/<keg>; remote/readonly hubs are queried via the hub's GET /api/v1/kegs, which returns the kegs the authenticated user can reach (namespace membership + grants). With an explicit --hub only that hub is listed and its errors surface directly; in aggregate mode an unreachable or unauthenticated hub is logged and skipped so one bad hub doesn't blank the whole listing.
func (*Tap) HubRemove ¶ added in v0.23.0
func (t *Tap) HubRemove(_ context.Context, opts HubRemoveOptions) error
HubRemove deletes a hub connection (user config only) and prunes any namespace pin that routed to it.
func (*Tap) HubSetDefault ¶ added in v0.23.0
func (t *Tap) HubSetDefault(ctx context.Context, opts HubSetDefaultOptions) error
HubSetDefault sets defaultHub. Unlike the hubs map, defaultHub is allowed in project config, so the default write target is the project config, with --user to write the user config instead.
func (*Tap) Import ¶ added in v0.4.0
Import loads a keg-archive from a file path or http(s) URL into the resolved keg and returns the imported node ids.
func (*Tap) ImportFromKeg ¶ added in v0.4.0
func (t *Tap) ImportFromKeg(ctx context.Context, opts ImportFromKegOptions) ([]ImportedNode, error)
ImportFromKeg copies nodes from a source keg into the target keg. Each node is assigned a fresh ID via targetRepo.Next() and all links in the copied content are rewritten according to the six rules described in the plan.
func (*Tap) Index ¶
Index rebuilds all indices for a keg (nodes.tsv, tags, links, backlinks) from scratch.
func (*Tap) IndexCat ¶ added in v0.2.0
IndexCat returns the raw contents of a named dex index file. opts.Name may include or omit a leading "dex/" prefix; both are accepted.
func (*Tap) InitKeg ¶
InitKeg creates a keg named options.Keg and initializes it at the resolved destination. Destination resolution is namespace-centric:
- --project/--cwd/--path → a project-local filesystem keg under the git root (or cwd / explicit path).
- otherwise the name resolves through namespace → hub (with --namespace and --hub as overrides, and --user pinning @local): a local hub yields a filesystem keg at <basePath>/@<namespace>/<name>; a remote hub creates the keg on the hub (POST /api/v1/@<namespace>/kegs), failing if it already exists. On success the keg is recorded in user config.
func (*Tap) Integrate ¶ added in v0.19.0
func (t *Tap) Integrate(ctx context.Context, opts IntegrateOptions) (*IntegrateResult, error)
Integrate atomically refreshes the embedded marketplace for one host, reuses a matching registration, and installs the requested plugins through the host CLI. Dry-run returns the complete plan without side effects.
func (*Tap) KegConfigEdit ¶ added in v0.2.0
func (t *Tap) KegConfigEdit(ctx context.Context, opts KegConfigEditOptions) error
KegConfigEdit opens the keg configuration file in the default editor.
func (*Tap) KegGrant ¶ added in v0.23.0
func (t *Tap) KegGrant(ctx context.Context, opts KegGrantOptions) error
KegGrant upserts a grant (user → role) on a keg.
func (*Tap) KegRename ¶ added in v0.25.0
func (t *Tap) KegRename(ctx context.Context, opts KegRenameOptions) error
KegRename renames a hub-backed keg alias within its namespace.
func (*Tap) KegRevoke ¶ added in v0.23.0
func (t *Tap) KegRevoke(ctx context.Context, opts KegRevokeOptions) error
KegRevoke removes a user's grant on a keg.
func (*Tap) KegSettings ¶ added in v0.33.0
KegSettings displays the keg metadata (keg file contents).
func (*Tap) KegVisibility ¶ added in v0.23.0
func (t *Tap) KegVisibility(ctx context.Context, opts KegVisibilityOptions) error
KegVisibility sets a keg's visibility to public or private.
func (*Tap) ListFlights ¶ added in v0.23.0
ListFlights returns canonical refs discovered across configured hubs, or only opts.Hub when a filter is supplied.
func (*Tap) ListImages ¶ added in v0.2.0
ListImages returns the names of images for a node.
func (*Tap) ListIndexes ¶ added in v0.2.0
ListIndexes returns the names of available index files for a keg (e.g. "changes.md", "nodes.tsv").
func (*Tap) ListSchemas ¶ added in v0.25.0
func (*Tap) Lock ¶ added in v0.11.0
Lock acquires a cross-process lock on a node and returns the token.
func (*Tap) LockStatus ¶ added in v0.11.0
LockStatus returns the lock state for a node.
func (*Tap) NamespaceAddMember ¶ added in v0.23.0
func (t *Tap) NamespaceAddMember(ctx context.Context, opts NamespaceAddMemberOptions) error
NamespaceAddMember upserts a member (user → role) into a namespace.
func (*Tap) NamespaceCreate ¶ added in v0.23.0
func (t *Tap) NamespaceCreate(ctx context.Context, opts NamespaceCreateOptions) (*NamespaceCreateResult, error)
NamespaceCreate returns the hub UI URL for creating an org namespace. It does not call the namespace creation API.
func (*Tap) NamespaceList ¶ added in v0.23.0
func (t *Tap) NamespaceList(ctx context.Context, opts NamespaceListOptions) ([]HubNamespace, error)
NamespaceList returns the namespaces the caller belongs to on a hub.
func (*Tap) NamespaceMembers ¶ added in v0.23.0
func (t *Tap) NamespaceMembers(ctx context.Context, opts NamespaceMembersOptions) ([]HubMember, error)
NamespaceMembers returns the member roster of a namespace.
func (*Tap) NamespaceRemoveMember ¶ added in v0.23.0
func (t *Tap) NamespaceRemoveMember(ctx context.Context, opts NamespaceRemoveMemberOptions) error
NamespaceRemoveMember removes a member from a namespace.
func (*Tap) NamespaceSetRole ¶ added in v0.23.0
func (t *Tap) NamespaceSetRole(ctx context.Context, opts NamespaceSetRoleOptions) error
NamespaceSetRole changes an existing member's role.
func (*Tap) NodeHistory ¶ added in v0.4.0
func (*Tap) NodeRestore ¶ added in v0.4.0
func (t *Tap) NodeRestore(ctx context.Context, opts NodeRestoreOptions) error
func (*Tap) NodeSnapshot ¶ added in v0.4.0
func (*Tap) NodeSnapshotView ¶ added in v0.23.0
func (*Tap) Orient ¶ added in v0.19.0
Orient returns one deterministic KEG system payload. It is best-effort: active-keg, flight, and hub-listing failures do not suppress the core orientation document.
func (*Tap) ReadImage ¶ added in v0.24.0
ReadImage retrieves a node image and validates that the stored bytes are still one of Tapper's supported image formats.
func (*Tap) ReadSchema ¶ added in v0.25.0
func (*Tap) ResolveNodeRef ¶ added in v0.23.0
func (t *Tap) ResolveNodeRef(ctx context.Context, ref *keg.NodeRef, rc RefContext) (keg.Keg, keg.NodeId, error)
ResolveNodeRef resolves a parsed node reference into the keg that holds it and the numeric node id within that keg:
- RefLocal: the current keg, with the bare node id.
- RefAlias: the alias is resolved against the current keg's Links table first (so authored links travel with the keg), then the tap-config kegs map.
- RefQualified: a (hub, namespace, keg) reference whose hub is implied from the current keg's hub; the reserved @local namespace pins the local hub regardless of the current keg's hub.
func (*Tap) SetBootstrapFlight ¶ added in v0.30.0
SetBootstrapFlight validates ref, canonicalizes it, and persists it as the user-level flight baseline. Project config, TAP_FLIGHT, and an explicit --flight flag remain higher-precedence overrides. A blank ref is a no-op.
func (*Tap) SetBootstrapNamespace ¶ added in v0.23.0
SetBootstrapNamespace adopts namespace as the named hub's default namespace, then persists the config. It is the post-login step of `tap bootstrap`: once a cloud/enterprise login resolves the authenticated user's home namespace (from the hub's whoami probe), the CLI calls this so plain references resolved against that hub land in the user's own namespace. The namespace lives on the hub entry so each hub carries its own default — there is no global fallbackNamespace and no per-user namespace→hub entry to maintain.
It is idempotent and a no-op when namespace is blank, or when hubName is unknown/blank (nothing to adopt onto), keeping the call safe in either case. The always-present local hub keeps its reserved @local namespace.
func (*Tap) SetFallbackKeg ¶ added in v0.23.0
SetFallbackKeg sets the user config's fallbackKeg to ref and persists it. It is the post-login step of `tap bootstrap`: once the user picks a keg (from the hub's list or by typing one), plain `tap` commands resolve it without per-invocation flags. It writes the FALLBACK slot (the global-user convention) rather than defaultKeg, so a project's defaultKeg or a kegMap path rule still overrides it. ref is a keg reference — a bare name, @namespace/name, keg:..., or a path — stored verbatim and resolved later by ResolveRef. A blank ref is a no-op.
func (*Tap) SetHubDefaultNamespaceByURL ¶ added in v0.23.0
func (t *Tap) SetHubDefaultNamespaceByURL(ctx context.Context, hubURL, namespace string) (string, error)
SetHubDefaultNamespaceByURL adopts namespace onto the configured hub whose URL matches hubURL. It returns the hub name that was updated. When no configured hub matches (for example, auth login fell through to the compiled-in atlas URL without a user config entry), it is a no-op.
func (*Tap) Unlock ¶ added in v0.11.0
func (t *Tap) Unlock(ctx context.Context, opts UnlockOptions) error
Unlock releases a cross-process lock on a node.
func (*Tap) UpdateFlight ¶ added in v0.23.0
func (*Tap) UploadFile ¶ added in v0.2.0
UploadFile reads a local file and stores it as a node file attachment. Returns the stored filename.
func (*Tap) UploadImage ¶ added in v0.2.0
UploadImage reads a local file and stores it as a node image. Returns the stored filename.
func (*Tap) Use ¶ added in v0.23.0
func (t *Tap) Use(ctx context.Context, opts UseOptions) error
Use records the project's keg + flight, or the user-wide fallback keg, in the appropriate config file. It mirrors the resolution convention: project → defaultKeg, user → fallbackKeg, with flight project-scoped.
func (*Tap) UseStatus ¶ added in v0.23.0
UseStatus returns a YAML summary of the resolved keg/flight context plus the configured keg slots and the scope that set each, for `tap use` with no args.
func (*Tap) Validate ¶ added in v0.25.0
func (t *Tap) Validate(ctx context.Context, opts ValidateOptions) ([]keg.SchemaValidationResult, error)
type UnlockOptions ¶ added in v0.11.0
type UnlockOptions struct {
NodeID string
Token string
KegTargetOptions
}
UnlockOptions configures behavior for Tap.Unlock.
type UpdateFlightOptions ¶ added in v0.23.0
type UpdateFlightOptions struct {
Ref string
Title *string
Visibility *string
Capabilities *[]FlightCapability
Instructions *string
Cover *[]FlightCover
}
UpdateFlightOptions is a partial update: nil fields keep the flight's current value. The merge against the existing flight happens inside Tap.UpdateFlight against the same resolved ref the PUT targets, so a slug that exists in several places cannot read one flight and overwrite another.
type UploadFileOptions ¶ added in v0.2.0
type UploadFileOptions struct {
KegTargetOptions
NodeID string
FilePath string
Data []byte
Name string
}
UploadFileOptions configures behavior for Tap.UploadFile.
type UploadImageOptions ¶ added in v0.2.0
type UploadImageOptions struct {
KegTargetOptions
NodeID string
FilePath string
Data []byte
Name string
}
UploadImageOptions configures behavior for Tap.UploadImage.
type UseOptions ¶ added in v0.23.0
type UseOptions struct {
// Keg is the keg reference to record (a bare name or @namespace/keg). Empty
// leaves the keg slot untouched (unless Clear is set).
Keg string
// Flight is a flight reference to record for the project (@namespace/+slug,
// +slug, or a bare slug). Empty leaves the flight untouched.
Flight string
// User writes the user config's fallbackKeg instead of the project config's
// defaultKeg.
User bool
// ConfigPath, when set, writes that explicit config file instead of the
// user/project file. The slot still follows User.
ConfigPath string
// Clear unsets the slot(s) for the chosen scope (defaultKeg + flight for the
// project scope; fallbackKeg for the user scope).
Clear bool
}
UseOptions configures Tap.Use, the `tap use` setter that records which keg (and flight) a project resolves, or a user-wide fallback keg.
Scope picks the keg slot: the default (project) scope writes defaultKeg; the user scope (User=true) writes fallbackKeg. Flight is project-scoped only.
type ValidateOptions ¶ added in v0.25.0
type ValidateOptions struct {
KegTargetOptions
NodeIDs []string
}
type WatchNodeOptions ¶ added in v0.23.0
type WatchNodeOptions struct {
NodeID string
KegTargetOptions
}
type WhoAmI ¶ added in v0.23.0
type WhoAmI struct {
UserID int64 `json:"user_id"`
Username string `json:"username"`
DisplayName string `json:"display_name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
DefaultNamespace string `json:"default_namespace"`
Namespaces []string `json:"namespaces,omitempty"`
}
WhoAmI is the authenticated user the hub reports for a token. It mirrors the hub's GET /api/v1/whoami JSON body (handler.WhoamiResponse) — keep the two structs in sync. DisplayName is the human name and is empty when the hub omits it (older hub, or no display name set), in which case callers fall back to the username alone.
DefaultNamespace is the user's home namespace as the hub sees it (its name equals the username by construction). `tap bootstrap` adopts it as the fallback namespace so the hub, not the client, decides which namespace a fresh login lands in. Namespaces lists every namespace the user belongs to (personal + orgs) and is empty when the hub omits it (older hub).
func ValidateToken ¶ added in v0.23.0
ValidateToken calls GET {hubURL}/api/v1/whoami with the bearer token and returns the resolved user. A 401/403 is reported as a rejected token; any other non-200 surfaces the hub's status so misconfigurations are visible. The default HTTP client is used; callers that need to inject one for tests can hit an httptest.Server, whose URL works with http.DefaultClient.
Source Files
¶
- alias.go
- auth_device_flow.go
- auth_flow.go
- auth_refresh.go
- auth_resolver.go
- auth_store.go
- auth_whoami.go
- config.go
- config_env.go
- config_service.go
- config_validate.go
- constants.go
- editor_live.go
- error_types.go
- flight.go
- hub_flights.go
- hub_grants.go
- hub_kegs.go
- hub_namespaces.go
- keg_backend.go
- keg_service.go
- node_exists.go
- node_ref_resolve.go
- path_service.go
- tap.go
- tap_archive.go
- tap_auth.go
- tap_bootstrap.go
- tap_cat.go
- tap_config.go
- tap_create.go
- tap_doctor.go
- tap_edit.go
- tap_files.go
- tap_flight.go
- tap_flight_edit.go
- tap_graph.go
- tap_hub.go
- tap_import.go
- tap_index.go
- tap_info.go
- tap_init.go
- tap_integrate.go
- tap_keg.go
- tap_list.go
- tap_lock.go
- tap_move.go
- tap_namespace.go
- tap_orient.go
- tap_remove.go
- tap_schema.go
- tap_snapshots.go
- tap_stats.go
- tap_use.go
- tap_watch.go