vault

package
v1.0.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrLockFileNotFound = errors.New("lock file not found")

ErrLockFileNotFound is returned when the lock file does not exist in the vault

View Source
var ErrNotImplemented = errors.New("operation not supported for this vault type")

ErrNotImplemented is returned by vaults that do not support a given management operation.

Functions

This section is empty.

Types

type AssetDetails added in v0.6.0

type AssetDetails struct {
	Name        string
	Type        asset.Type
	Description string
	CreatedAt   time.Time
	UpdatedAt   time.Time
	Versions    []AssetVersion
	Metadata    *metadata.Metadata // Metadata for latest version (or nil if not available)
}

AssetDetails contains detailed information about a specific asset

type AssetShimRegistrar added in v0.16.0

type AssetShimRegistrar struct {
	Repo assetReader
	// contains filtered or unexported fields
}

AssetShimRegistrar registers Pulse-style asset listing/loading MCP tools onto an mcp.Server. PathVault and GitVault both opt in by returning a populated registrar from GetMCPTools(); the cloud serve builder type-asserts on this type and calls Register so claude.ai / chatgpt.com see real tools when they connect via the relay.

Tool descriptions and input schemas mirror sleuth/apps/mcp_gateway/asset_shim so the local-vault MCP and the server-side shim behave identically from a client's perspective. Diverging would mean prompt-tuning has to happen twice.

func (*AssetShimRegistrar) Register added in v0.16.0

func (r *AssetShimRegistrar) Register(server *mcp.Server)

Register wires the seven shim tools onto the supplied MCP server.

type AssetSummary added in v0.6.0

type AssetSummary struct {
	Name          string
	Type          asset.Type
	LatestVersion string
	VersionsCount int
	Description   string
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

AssetSummary contains summary information about a vault asset

type AssetVersion added in v0.6.0

type AssetVersion struct {
	Version    string
	CreatedAt  time.Time
	FilesCount int
}

AssetVersion contains version information for an asset

type BotApiKeyManager added in v1.0.0

type BotApiKeyManager interface {
	CreateBotApiKey(ctx context.Context, botName, label string) (rawToken string, key mgmt.BotApiKey, err error)
	ListBotApiKeys(ctx context.Context, botName string) ([]mgmt.BotApiKey, error)
	DeleteBotApiKey(ctx context.Context, botName, keyID string) error
}

BotApiKeyManager is implemented by vaults that issue API tokens for bot identities. File-based vaults (path/git) do not implement this — their trust model is "vault read access ⇒ asset access" so bots are identity-only there. Sleuth vaults issue real OAuth tokens via the existing skills.new createBotApiKey mutation.

type Config

type Config interface {
	GetType() string
	GetServerURL() string
	GetAuthToken() string
	GetRepositoryURL() string
}

Config represents the minimal configuration needed to create a vault This avoids circular dependency with the config package

type ErrVersionExists added in v0.9.1

type ErrVersionExists struct {
	Name    string
	Version string
	Message string
}

ErrVersionExists is returned when attempting to add an asset version that already exists

func (*ErrVersionExists) Error added in v0.9.1

func (e *ErrVersionExists) Error() string

type GitSourceHandler

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

GitSourceHandler handles assets with source-git

func NewGitSourceHandler

func NewGitSourceHandler(gitClient *git.Client) *GitSourceHandler

NewGitSourceHandler creates a new Git source handler

func (*GitSourceHandler) Fetch

func (g *GitSourceHandler) Fetch(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

Fetch clones/fetches a git repository and retrieves the asset

func (*GitSourceHandler) ResolveRef

func (g *GitSourceHandler) ResolveRef(ctx context.Context, repoURL, ref string) (string, error)

ResolveRef resolves a branch or tag name to a commit SHA This is used during lock file generation to convert friendly names to commit SHAs

type GitVault

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

GitVault implements Vault for Git vaults

func NewGitVault

func NewGitVault(repoURL string) (*GitVault, error)

NewGitVault creates a new Git repository

func (*GitVault) AddAsset

func (g *GitVault) AddAsset(ctx context.Context, asset *lockfile.Asset, zipData []byte) error

AddAsset uploads an asset to the Git repository

func (*GitVault) AddBotTeam added in v1.0.0

func (g *GitVault) AddBotTeam(ctx context.Context, bot, team string) error

func (*GitVault) AddTeamMember added in v0.15.0

func (g *GitVault) AddTeamMember(ctx context.Context, team, email string, admin bool) error

func (*GitVault) AddTeamRepository added in v0.15.0

func (g *GitVault) AddTeamRepository(ctx context.Context, team, repoURL string) error

func (*GitVault) Authenticate

func (g *GitVault) Authenticate(ctx context.Context) (string, error)

Authenticate performs authentication with the Git repository For Git repos, this is a no-op as authentication is handled by git itself

func (*GitVault) ClearAssetInstallations added in v0.15.0

func (g *GitVault) ClearAssetInstallations(ctx context.Context, assetName string) error

func (*GitVault) CommitAndPush

func (g *GitVault) CommitAndPush(ctx context.Context, asset *lockfile.Asset) error

CommitAndPush commits all changes and pushes to remote

func (*GitVault) CreateBot added in v1.0.0

func (g *GitVault) CreateBot(ctx context.Context, bot mgmt.Bot) (string, error)

CreateBot on a git vault returns ("", err) — file-based vaults are identity-only for bots and never issue API keys.

func (*GitVault) CreateTeam added in v0.15.0

func (g *GitVault) CreateTeam(ctx context.Context, team mgmt.Team) error

func (*GitVault) CurrentActor added in v0.15.0

func (g *GitVault) CurrentActor(ctx context.Context) (mgmt.Actor, error)

CurrentActor resolves the caller's identity via git config.

func (*GitVault) DeleteBot added in v1.0.0

func (g *GitVault) DeleteBot(ctx context.Context, name string) error

func (*GitVault) DeleteTeam added in v0.15.0

func (g *GitVault) DeleteTeam(ctx context.Context, name string) error

func (*GitVault) ExistingAssetScopes added in v0.15.0

func (g *GitVault) ExistingAssetScopes(name string) []lockfile.Scope

ExistingAssetScopes is the GitVault version; see PathVault's doc.

func (*GitVault) GetAsset

func (g *GitVault) GetAsset(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

GetAsset downloads an asset using its source configuration

func (*GitVault) GetAssetByVersion

func (g *GitVault) GetAssetByVersion(ctx context.Context, name, version string) ([]byte, error)

GetAssetByVersion retrieves an asset by name and version from the git repository This creates a zip from the exploded directory

func (*GitVault) GetAssetDetails added in v0.6.0

func (g *GitVault) GetAssetDetails(ctx context.Context, name string) (*AssetDetails, error)

GetAssetDetails returns detailed information about a specific asset

func (*GitVault) GetBootstrapOptions added in v0.9.2

func (g *GitVault) GetBootstrapOptions(ctx context.Context) []bootstrap.Option

GetBootstrapOptions returns no bootstrap options for GitVault

func (*GitVault) GetBot added in v1.0.0

func (g *GitVault) GetBot(ctx context.Context, name string) (*mgmt.Bot, error)

func (*GitVault) GetLockFile

func (g *GitVault) GetLockFile(ctx context.Context, cachedETag string) (content []byte, etag string, notModified bool, err error)

GetLockFile clones or syncs the Git vault, then returns a lock file resolved from the vault's manifest for the caller's identity. Team and user scopes are flattened to repo-scoped entries based on team membership and the caller's git config email.

func (*GitVault) GetMCPTools added in v0.6.0

func (g *GitVault) GetMCPTools() any

GetMCPTools returns the asset-shim registrar so callers (notably the cloud serve MCP builder) can publish list_my_assets / load_my_asset / … on top of the git-backed vault. Without this, claude.ai connects to the relay and reports "no tools available" because GitVault has no native MCP surface.

func (*GitVault) GetMetadata

func (g *GitVault) GetMetadata(ctx context.Context, name, version string) (*metadata.Metadata, error)

GetMetadata retrieves metadata for a specific asset version Not applicable for Git repositories (metadata is inside the zip)

func (*GitVault) GetTeam added in v0.15.0

func (g *GitVault) GetTeam(ctx context.Context, name string) (*mgmt.Team, error)

func (*GitVault) GetUsageStats added in v0.15.0

func (g *GitVault) GetUsageStats(ctx context.Context, filter mgmt.UsageFilter) (*mgmt.UsageSummary, error)

func (*GitVault) GetVersionList

func (g *GitVault) GetVersionList(ctx context.Context, name string) ([]string, error)

GetVersionList retrieves available versions for an asset from list.txt

func (*GitVault) InheritInstallations added in v0.12.8

func (g *GitVault) InheritInstallations(ctx context.Context, asset *lockfile.Asset) error

InheritInstallations copies scopes from any existing entry of this asset in the manifest, upserts the asset with those scopes, and commits/pushes.

func (*GitVault) ListAssets added in v0.6.0

func (g *GitVault) ListAssets(ctx context.Context, opts ListAssetsOptions) (*ListAssetsResult, error)

ListAssets returns a list of all assets in the vault by reading the assets/ directory

func (*GitVault) ListBots added in v1.0.0

func (g *GitVault) ListBots(ctx context.Context) ([]mgmt.Bot, error)

func (*GitVault) ListTeams added in v0.15.0

func (g *GitVault) ListTeams(ctx context.Context) ([]mgmt.Team, error)

func (*GitVault) ManifestPath added in v0.15.0

func (g *GitVault) ManifestPath() string

ManifestPath returns the absolute path to the vault's manifest file.

func (*GitVault) PostUsageStats

func (g *GitVault) PostUsageStats(ctx context.Context, jsonlData string) error

PostUsageStats parses the JSONL payload produced by stats.FlushQueue and persists it to .sx/usage/YYYY-MM.jsonl via RecordUsageEvents. This keeps wire compatibility with the existing queue flush pipeline while moving the real storage into the git vault.

func (*GitVault) QueryAuditEvents added in v0.15.0

func (g *GitVault) QueryAuditEvents(ctx context.Context, filter mgmt.AuditFilter) ([]mgmt.AuditEvent, error)

func (*GitVault) RecordUsageEvents added in v0.15.0

func (g *GitVault) RecordUsageEvents(ctx context.Context, events []mgmt.UsageEvent) error

RecordUsageEvents appends usage events to the local JSONL log without committing or pushing. Under active use this can run hundreds of times per hour, and a commit-per-call would spam the git history and turn a background observation channel into a noisy multi-writer workload. The next management mutation (team, install, etc.) runs runInVaultTx, which sweeps .sx/ into its commit and picks up any queued usage files on the way through. Queries on the same machine see the events immediately because GetUsageStats reads the local working tree.

func (*GitVault) RemoveAsset

func (g *GitVault) RemoveAsset(ctx context.Context, assetName, version string, delete bool) error

RemoveAsset removes an asset from the lock file and pushes to remote. If delete is true, also permanently removes the asset files from the vault.

func (*GitVault) RemoveBotTeam added in v1.0.0

func (g *GitVault) RemoveBotTeam(ctx context.Context, bot, team string) error

func (*GitVault) RemoveTeamMember added in v0.15.0

func (g *GitVault) RemoveTeamMember(ctx context.Context, team, email string) error

func (*GitVault) RemoveTeamRepository added in v0.15.0

func (g *GitVault) RemoveTeamRepository(ctx context.Context, team, repoURL string) error

func (*GitVault) RenameAsset added in v0.14.0

func (g *GitVault) RenameAsset(ctx context.Context, oldName, newName string) error

RenameAsset renames an asset in the vault. All versions and installations are preserved under the new name.

func (*GitVault) SetAssetInstallation added in v0.15.0

func (g *GitVault) SetAssetInstallation(ctx context.Context, assetName string, target InstallTarget) error

func (*GitVault) SetInstallations added in v0.6.0

func (g *GitVault) SetInstallations(ctx context.Context, asset *lockfile.Asset, scopeEntity string) error

SetInstallations upserts the asset into the vault's manifest and pushes.

func (*GitVault) SetTeamAdmin added in v0.15.0

func (g *GitVault) SetTeamAdmin(ctx context.Context, team, email string, admin bool) error

func (*GitVault) UpdateBot added in v1.0.0

func (g *GitVault) UpdateBot(ctx context.Context, bot mgmt.Bot) error

func (*GitVault) UpdateTeam added in v0.15.0

func (g *GitVault) UpdateTeam(ctx context.Context, team mgmt.Team) error

func (*GitVault) UpdateTemplates

func (g *GitVault) UpdateTemplates(ctx context.Context, commit bool) ([]string, error)

UpdateTemplates updates templates in the repository if needed and returns the list of updated files The commit parameter controls whether to commit and push changes (git-specific behavior)

func (*GitVault) VerifyIntegrity

func (g *GitVault) VerifyIntegrity(data []byte, hashes map[string]string, size int64) error

VerifyIntegrity checks hashes and sizes for downloaded assets

type HTTPSourceHandler

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

HTTPSourceHandler handles assets with source-http

func NewHTTPSourceHandler

func NewHTTPSourceHandler(authToken string) *HTTPSourceHandler

NewHTTPSourceHandler creates a new HTTP source handler

func (*HTTPSourceHandler) DownloadWithProgress

func (h *HTTPSourceHandler) DownloadWithProgress(ctx context.Context, url string, progressCallback func(current, total int64)) ([]byte, error)

DownloadWithProgress downloads a file with progress reporting This is used for user-facing downloads with progress bars

func (*HTTPSourceHandler) Fetch

func (h *HTTPSourceHandler) Fetch(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

Fetch downloads an asset from an HTTP URL

type InstallKind added in v0.15.0

type InstallKind string

InstallKind identifies which kind of installation a CLI command is asking the vault to record.

const (
	InstallKindOrg  InstallKind = "org"
	InstallKindRepo InstallKind = "repo"
	InstallKindPath InstallKind = "path"
	InstallKindTeam InstallKind = "team"
	InstallKindUser InstallKind = "user"
	InstallKindBot  InstallKind = "bot"
)

type InstallTarget added in v0.15.0

type InstallTarget struct {
	Kind  InstallKind
	Repo  string   // Repo and Path
	Paths []string // Path
	Team  string   // Team
	User  string   // User (email)
	Bot   string   // Bot (name)
}

InstallTarget describes a single installation target for an asset. Only fields relevant to the chosen Kind need to be set.

func (InstallTarget) AuditData added in v0.15.0

func (t InstallTarget) AuditData() map[string]any

AuditData returns the payload attached to an install.set audit event for this target. Single source of truth for what each kind records.

func (InstallTarget) Describe added in v0.15.0

func (t InstallTarget) Describe() string

Describe returns a short human-readable summary of the target, suitable for commit messages and CLI output.

type ListAssetsArgs added in v0.16.0

type ListAssetsArgs struct {
	Type   string `` /* 207-byte string literal not displayed */
	Search string `json:"search,omitempty" jsonschema:"Case-insensitive substring filter over name + description."`
}

ListAssetsArgs is the input for list_my_assets.

type ListAssetsOptions added in v0.6.0

type ListAssetsOptions struct {
	Type   string // Filter by asset type (skill, mcp, etc.)
	Search string // Search query for filtering assets
	Limit  int    // Maximum number of assets to return (default 100)
}

ListAssetsOptions contains options for listing vault assets

type ListAssetsResult added in v0.6.0

type ListAssetsResult struct {
	Assets []AssetSummary
}

ListAssetsResult contains the results of a ListAssets call

type ListByTypeArgs added in v0.16.0

type ListByTypeArgs struct {
	Search string `json:"search,omitempty" jsonschema:"Case-insensitive substring filter over name + description."`
}

ListByTypeArgs is the input for the per-type list aliases (list_my_skills, …). They pin the type filter server-side so callers can omit it.

type LoadAssetArgs added in v0.16.0

type LoadAssetArgs struct {
	Slug string `json:"slug" jsonschema:"Asset slug from list_my_assets."`
}

LoadAssetArgs is the input for load_my_asset.

type LoadAssetFileArgs added in v0.16.0

type LoadAssetFileArgs struct {
	Slug string `json:"slug" jsonschema:"Asset slug."`
	Path string `json:"path" jsonschema:"File path as returned by load_my_asset's bundled_files."`
}

LoadAssetFileArgs is the input for load_my_asset_file.

type PathSourceHandler

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

PathSourceHandler handles assets with source-path

func NewPathSourceHandler

func NewPathSourceHandler(lockFileDir string) *PathSourceHandler

NewPathSourceHandler creates a new path source handler

func (*PathSourceHandler) Fetch

func (p *PathSourceHandler) Fetch(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

Fetch reads an asset from a local file path

func (*PathSourceHandler) ResolvePath

func (p *PathSourceHandler) ResolvePath(path string) (string, error)

ResolvePath resolves a path (absolute, relative, or tilde) to an absolute path

type PathVault

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

PathVault implements Vault for local filesystem directories It follows the same pattern as GitRepository and SleuthRepository

func NewPathVault

func NewPathVault(repoURL string) (*PathVault, error)

NewPathVault creates a new path repository from a file:// URL

func (*PathVault) AddAsset

func (p *PathVault) AddAsset(ctx context.Context, asset *lockfile.Asset, zipData []byte) error

AddAsset adds an asset to the local repository Follows the same pattern as GitRepository: exploded storage + list.txt

func (*PathVault) AddBotTeam added in v1.0.0

func (p *PathVault) AddBotTeam(ctx context.Context, bot, team string) error

func (*PathVault) AddTeamMember added in v0.15.0

func (p *PathVault) AddTeamMember(ctx context.Context, team, email string, admin bool) error

func (*PathVault) AddTeamRepository added in v0.15.0

func (p *PathVault) AddTeamRepository(ctx context.Context, team, repoURL string) error

func (*PathVault) Authenticate

func (p *PathVault) Authenticate(ctx context.Context) (string, error)

Authenticate performs authentication - no-op for path repositories

func (*PathVault) ClearAssetInstallations added in v0.15.0

func (p *PathVault) ClearAssetInstallations(ctx context.Context, assetName string) error

func (*PathVault) CreateBot added in v1.0.0

func (p *PathVault) CreateBot(ctx context.Context, bot mgmt.Bot) (string, error)

CreateBot on a path vault returns ("", err) — file-based vaults are identity-only for bots and never issue API keys.

func (*PathVault) CreateTeam added in v0.15.0

func (p *PathVault) CreateTeam(ctx context.Context, team mgmt.Team) error

func (*PathVault) CurrentActor added in v0.15.0

func (p *PathVault) CurrentActor(ctx context.Context) (mgmt.Actor, error)

currentActor reads the caller's git identity, falling back to $USER@host. Cached by mgmt.CurrentGitActor for the CLI's lifetime.

func (*PathVault) DeleteBot added in v1.0.0

func (p *PathVault) DeleteBot(ctx context.Context, name string) error

func (*PathVault) DeleteTeam added in v0.15.0

func (p *PathVault) DeleteTeam(ctx context.Context, name string) error

func (*PathVault) ExistingAssetScopes added in v0.15.0

func (p *PathVault) ExistingAssetScopes(name string) []lockfile.Scope

ExistingAssetScopes returns the manifest's current repo/path scopes for the named asset. Team and user scopes are excluded — the method exists to support UX prompts in `sx add` that show the publisher what repo- shaped scopes an asset already has. Returns nil if the asset is not in the manifest or the vault doesn't support manifest-backed lookup.

func (*PathVault) GetAsset

func (p *PathVault) GetAsset(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

GetAsset downloads an asset using its source configuration Reuses the same dispatch pattern as GitRepository and SleuthRepository

func (*PathVault) GetAssetByVersion added in v0.9.1

func (p *PathVault) GetAssetByVersion(ctx context.Context, name, version string) ([]byte, error)

GetAssetByVersion retrieves an asset by name and version Creates a zip from the exploded directory

func (*PathVault) GetAssetDetails added in v0.6.0

func (p *PathVault) GetAssetDetails(ctx context.Context, name string) (*AssetDetails, error)

GetAssetDetails returns detailed information about a specific asset

func (*PathVault) GetBootstrapOptions added in v0.9.2

func (p *PathVault) GetBootstrapOptions(ctx context.Context) []bootstrap.Option

GetBootstrapOptions returns no bootstrap options for PathVault

func (*PathVault) GetBot added in v1.0.0

func (p *PathVault) GetBot(ctx context.Context, name string) (*mgmt.Bot, error)

func (*PathVault) GetLockFile

func (p *PathVault) GetLockFile(ctx context.Context, cachedETag string) (content []byte, etag string, notModified bool, err error)

GetLockFile loads the vault's manifest and returns a lock file resolved for the caller's identity. Team/user scopes in the manifest are flattened to repo-scoped entries based on team membership and the caller's email so the install pipeline sees a concrete, identity- specific view. A shared read lock is held for the duration of the read so concurrent mgmt writes can't commit a manifest without its audit trail between the two IO operations.

func (*PathVault) GetMCPTools added in v0.6.0

func (p *PathVault) GetMCPTools() any

GetMCPTools returns the asset-shim registrar so callers (notably the cloud serve MCP builder) can publish list_my_assets / load_my_asset / … on top of the path-backed vault. Without this, claude.ai connects to the relay and reports "no tools available" because PathVault has no native MCP surface.

func (*PathVault) GetMetadata

func (p *PathVault) GetMetadata(ctx context.Context, name, version string) (*metadata.Metadata, error)

GetMetadata retrieves metadata for a specific asset version

func (*PathVault) GetTeam added in v0.15.0

func (p *PathVault) GetTeam(ctx context.Context, name string) (*mgmt.Team, error)

func (*PathVault) GetUsageStats added in v0.15.0

func (p *PathVault) GetUsageStats(ctx context.Context, filter mgmt.UsageFilter) (*mgmt.UsageSummary, error)

func (*PathVault) GetVersionList

func (p *PathVault) GetVersionList(ctx context.Context, name string) ([]string, error)

GetVersionList retrieves available versions for an asset from list.txt Reuses the same pattern as GitRepository

func (*PathVault) InheritInstallations added in v0.12.8

func (p *PathVault) InheritInstallations(ctx context.Context, asset *lockfile.Asset) error

InheritInstallations copies scopes from any existing entry of this asset in the manifest, then upserts. Used when adding a new version of an asset so its install scopes are preserved.

func (*PathVault) ListAssets added in v0.6.0

func (p *PathVault) ListAssets(ctx context.Context, opts ListAssetsOptions) (*ListAssetsResult, error)

ListAssets returns a list of all assets in the vault by reading the assets/ directory

func (*PathVault) ListBots added in v1.0.0

func (p *PathVault) ListBots(ctx context.Context) ([]mgmt.Bot, error)

func (*PathVault) ListTeams added in v0.15.0

func (p *PathVault) ListTeams(ctx context.Context) ([]mgmt.Team, error)

func (*PathVault) ManifestPath added in v0.15.0

func (p *PathVault) ManifestPath() string

ManifestPath returns the absolute path to the vault's manifest file.

func (*PathVault) PostUsageStats

func (p *PathVault) PostUsageStats(ctx context.Context, jsonlData string) error

PostUsageStats parses the JSONL payload and persists events to .sx/usage/YYYY-MM.jsonl via RecordUsageEvents.

func (*PathVault) QueryAuditEvents added in v0.15.0

func (p *PathVault) QueryAuditEvents(ctx context.Context, filter mgmt.AuditFilter) ([]mgmt.AuditEvent, error)

func (*PathVault) RecordUsageEvents added in v0.15.0

func (p *PathVault) RecordUsageEvents(ctx context.Context, events []mgmt.UsageEvent) error

func (*PathVault) RemoveAsset

func (p *PathVault) RemoveAsset(ctx context.Context, assetName, version string, delete bool) error

RemoveAsset removes an asset from the manifest. If delete is true, the asset's files are also removed from the vault's storage directory.

func (*PathVault) RemoveBotTeam added in v1.0.0

func (p *PathVault) RemoveBotTeam(ctx context.Context, bot, team string) error

func (*PathVault) RemoveTeamMember added in v0.15.0

func (p *PathVault) RemoveTeamMember(ctx context.Context, team, email string) error

func (*PathVault) RemoveTeamRepository added in v0.15.0

func (p *PathVault) RemoveTeamRepository(ctx context.Context, team, repoURL string) error

func (*PathVault) RenameAsset added in v0.14.0

func (p *PathVault) RenameAsset(ctx context.Context, oldName, newName string) error

RenameAsset renames an asset in the vault.

func (*PathVault) SetAssetInstallation added in v0.15.0

func (p *PathVault) SetAssetInstallation(ctx context.Context, assetName string, target InstallTarget) error

func (*PathVault) SetInstallations added in v0.6.0

func (p *PathVault) SetInstallations(ctx context.Context, asset *lockfile.Asset, scopeEntity string) error

SetInstallations upserts an asset into the vault's manifest. Scopes on the incoming asset are preserved verbatim.

func (*PathVault) SetTeamAdmin added in v0.15.0

func (p *PathVault) SetTeamAdmin(ctx context.Context, team, email string, admin bool) error

func (*PathVault) UpdateBot added in v1.0.0

func (p *PathVault) UpdateBot(ctx context.Context, bot mgmt.Bot) error

func (*PathVault) UpdateTeam added in v0.15.0

func (p *PathVault) UpdateTeam(ctx context.Context, team mgmt.Team) error

func (*PathVault) VerifyIntegrity

func (p *PathVault) VerifyIntegrity(data []byte, hashes map[string]string, size int64) error

VerifyIntegrity checks hashes and sizes for downloaded assets Same as GitRepository: no verification needed for local files

type QueryInput added in v0.6.0

type QueryInput struct {
	Query       string `` /* 235-byte string literal not displayed */
	Integration string `json:"integration" jsonschema:"which integration to query (github, circleci, linear, or datadog)"`
}

QueryInput is the input type for query tool

type Role added in v0.11.1

type Role struct {
	Title       string `json:"title"`
	Slug        string `json:"slug"`
	Description string `json:"description"`
}

Role represents a skill profile (role) from the server

type RoleListResponse added in v0.11.1

type RoleListResponse struct {
	Roles  []Role  `json:"profiles"`
	Active *string `json:"active"`
}

RoleListResponse represents the response from the roles list endpoint

type ScopeOption added in v0.12.8

type ScopeOption struct {
	Label       string // Display text (e.g., "Just for me")
	Value       string // Machine value passed to SetInstallations
	Description string // Help text
}

ScopeOption represents a vault-specific scope option (e.g., "personal", "team") displayed in the interactive UI alongside the built-in global/repo options.

type ScopeOptionProvider added in v0.12.8

type ScopeOptionProvider interface {
	GetScopeOptions() []ScopeOption
}

ScopeOptionProvider is implemented by vaults that provide additional scope options beyond global and per-repository scoping.

type SleuthVault

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

SleuthVault implements Vault for Sleuth HTTP servers

func NewSleuthVault

func NewSleuthVault(serverURL, authToken string) *SleuthVault

NewSleuthVault creates a new Sleuth repository. If SX_BOT_KEY is set in the environment, it overrides authToken — the bot's API key becomes the bearer for every request, so the same Sleuth vault wired to a CI runner authenticates as the bot rather than the user who ran `sx cloud connect` on a different machine. The user-token path stays untouched when SX_BOT_KEY is empty so interactive use is unchanged.

func (*SleuthVault) AddAsset

func (s *SleuthVault) AddAsset(ctx context.Context, asset *lockfile.Asset, zipData []byte) error

AddAsset uploads an asset to the Sleuth server

func (*SleuthVault) AddBotTeam added in v1.0.0

func (s *SleuthVault) AddBotTeam(ctx context.Context, botName, teamName string) error

AddBotTeam appends a team to a bot's team set via UpdateBot. Sleuth's updateBot expects the full team list, so we read-modify-write — same limitation as AddTeamMember.

func (*SleuthVault) AddTeamMember added in v0.15.0

func (s *SleuthVault) AddTeamMember(ctx context.Context, team, email string, admin bool) error

AddTeamMember adds a user to a team via the UpdateTeam mutation. Known limitation: this is a read-modify-write against the server's member list, so two concurrent AddTeamMember calls against the same team can interleave their reads and lose one of the additions. The GraphQL schema does not currently expose an additive "append member" mutation; when that becomes available we should switch to it. Sequential usage (the typical interactive CLI case) is safe.

func (*SleuthVault) AddTeamRepository added in v0.15.0

func (s *SleuthVault) AddTeamRepository(ctx context.Context, team, repoURL string) error

func (*SleuthVault) Authenticate

func (s *SleuthVault) Authenticate(ctx context.Context) (string, error)

Authenticate performs authentication with the Sleuth server

func (*SleuthVault) ClearAssetInstallations added in v0.15.0

func (s *SleuthVault) ClearAssetInstallations(ctx context.Context, assetName string) error

func (*SleuthVault) CreateBot added in v1.0.0

func (s *SleuthVault) CreateBot(ctx context.Context, bot mgmt.Bot) (string, error)

func (*SleuthVault) CreateBotApiKey added in v1.0.0

func (s *SleuthVault) CreateBotApiKey(ctx context.Context, botName, label string) (string, mgmt.BotApiKey, error)

func (*SleuthVault) CreateTeam added in v0.15.0

func (s *SleuthVault) CreateTeam(ctx context.Context, team mgmt.Team) error

func (*SleuthVault) CurrentActor added in v0.15.0

func (s *SleuthVault) CurrentActor(ctx context.Context) (mgmt.Actor, error)

func (*SleuthVault) DeleteBot added in v1.0.0

func (s *SleuthVault) DeleteBot(ctx context.Context, name string) error

func (*SleuthVault) DeleteBotApiKey added in v1.0.0

func (s *SleuthVault) DeleteBotApiKey(ctx context.Context, botName, keyID string) error

func (*SleuthVault) DeleteTeam added in v0.15.0

func (s *SleuthVault) DeleteTeam(ctx context.Context, name string) error

func (*SleuthVault) GetAsset

func (s *SleuthVault) GetAsset(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

GetAsset downloads an asset using its source configuration

func (*SleuthVault) GetAssetByVersion added in v0.9.1

func (s *SleuthVault) GetAssetByVersion(ctx context.Context, name, ver string) ([]byte, error)

GetAssetByVersion downloads an asset by name and version

func (*SleuthVault) GetAssetDetails added in v0.6.0

func (s *SleuthVault) GetAssetDetails(ctx context.Context, name string) (*AssetDetails, error)

GetAssetDetails retrieves detailed information about a specific asset using GraphQL

func (*SleuthVault) GetBootstrapOptions added in v0.9.2

func (s *SleuthVault) GetBootstrapOptions(ctx context.Context) []bootstrap.Option

GetBootstrapOptions returns bootstrap options for the Sleuth vault. This includes the Sleuth AI Query MCP server.

func (*SleuthVault) GetBot added in v1.0.0

func (s *SleuthVault) GetBot(ctx context.Context, name string) (*mgmt.Bot, error)

func (*SleuthVault) GetLockFile

func (s *SleuthVault) GetLockFile(ctx context.Context, cachedETag string) (content []byte, etag string, notModified bool, err error)

GetLockFile retrieves the lock file from the Sleuth server

func (*SleuthVault) GetMCPTools added in v0.6.0

func (s *SleuthVault) GetMCPTools() any

GetMCPTools returns the query tool for Sleuth vault

func (*SleuthVault) GetMetadata

func (s *SleuthVault) GetMetadata(ctx context.Context, name, version string) (*metadata.Metadata, error)

GetMetadata retrieves metadata for a specific asset version

func (*SleuthVault) GetScopeOptions added in v0.12.8

func (s *SleuthVault) GetScopeOptions() []ScopeOption

GetScopeOptions returns additional scope options for the Sleuth vault

func (*SleuthVault) GetTeam added in v0.15.0

func (s *SleuthVault) GetTeam(ctx context.Context, name string) (*mgmt.Team, error)

func (*SleuthVault) GetUsageStats added in v0.15.0

func (s *SleuthVault) GetUsageStats(ctx context.Context, filter mgmt.UsageFilter) (*mgmt.UsageSummary, error)

func (*SleuthVault) GetVersionList

func (s *SleuthVault) GetVersionList(ctx context.Context, name string) ([]string, error)

GetVersionList retrieves available versions for an asset

func (*SleuthVault) InheritInstallations added in v0.12.8

func (s *SleuthVault) InheritInstallations(ctx context.Context, asset *lockfile.Asset) error

InheritInstallations is a no-op for Sleuth vaults. The server auto-inherits installations when AddAsset uploads a new version.

func (*SleuthVault) ListAssets added in v0.6.0

func (s *SleuthVault) ListAssets(ctx context.Context, opts ListAssetsOptions) (*ListAssetsResult, error)

ListAssets retrieves a list of all assets in the vault using GraphQL

func (*SleuthVault) ListBotApiKeys added in v1.0.0

func (s *SleuthVault) ListBotApiKeys(ctx context.Context, botName string) ([]mgmt.BotApiKey, error)

func (*SleuthVault) ListBots added in v1.0.0

func (s *SleuthVault) ListBots(ctx context.Context) ([]mgmt.Bot, error)

func (*SleuthVault) ListRoles added in v0.11.1

func (s *SleuthVault) ListRoles(ctx context.Context) (*RoleListResponse, error)

ListRoles retrieves the list of available roles from the server

func (*SleuthVault) ListTeams added in v0.15.0

func (s *SleuthVault) ListTeams(ctx context.Context) ([]mgmt.Team, error)

func (*SleuthVault) PostUsageStats

func (s *SleuthVault) PostUsageStats(ctx context.Context, jsonlData string) error

PostUsageStats sends asset usage statistics to the Sleuth server

func (*SleuthVault) QueryAuditEvents added in v0.15.0

func (s *SleuthVault) QueryAuditEvents(ctx context.Context, filter mgmt.AuditFilter) ([]mgmt.AuditEvent, error)

func (*SleuthVault) QueryIntegration added in v0.6.0

func (s *SleuthVault) QueryIntegration(ctx context.Context, query, integration string, gitContext any) (string, error)

QueryIntegration queries integrated services (GitHub, CircleCI, Linear) using natural language

func (*SleuthVault) QueryIntegrationStream added in v0.6.1

func (s *SleuthVault) QueryIntegrationStream(
	ctx context.Context,
	query, integration string,
	gitContext any,
	onEvent func(eventType, content string),
) (string, error)

QueryIntegrationStream queries integrated services using SSE streaming. The onEvent callback is called for each event received, which can be used to send MCP log notifications to keep the connection alive.

func (*SleuthVault) RecordUsageEvents added in v0.15.0

func (s *SleuthVault) RecordUsageEvents(ctx context.Context, events []mgmt.UsageEvent) error

func (*SleuthVault) RemoveAsset

func (s *SleuthVault) RemoveAsset(ctx context.Context, assetName, version string, delete bool) error

RemoveAsset removes an asset from the Sleuth server's lock file. The delete flag is passed to the server mutation for permanent deletion.

func (*SleuthVault) RemoveBotTeam added in v1.0.0

func (s *SleuthVault) RemoveBotTeam(ctx context.Context, botName, teamName string) error

func (*SleuthVault) RemoveTeamMember added in v0.15.0

func (s *SleuthVault) RemoveTeamMember(ctx context.Context, team, email string) error

func (*SleuthVault) RemoveTeamRepository added in v0.15.0

func (s *SleuthVault) RemoveTeamRepository(ctx context.Context, team, repoURL string) error

func (*SleuthVault) RenameAsset added in v0.14.0

func (s *SleuthVault) RenameAsset(ctx context.Context, oldName, newName string) error

RenameAsset renames an asset on the Sleuth server using a GraphQL mutation.

func (*SleuthVault) SetActiveRole added in v0.11.1

func (s *SleuthVault) SetActiveRole(ctx context.Context, slug *string) (*Role, error)

SetActiveRole sets or clears the active role on the server. Pass nil to clear the active role.

func (*SleuthVault) SetAssetInstallation added in v0.15.0

func (s *SleuthVault) SetAssetInstallation(ctx context.Context, assetName string, target InstallTarget) error

func (*SleuthVault) SetInstallations added in v0.6.0

func (s *SleuthVault) SetInstallations(ctx context.Context, asset *lockfile.Asset, scopeEntity string) error

SetInstallations sets the installation scopes for an asset using GraphQL mutation

func (*SleuthVault) SetTeamAdmin added in v0.15.0

func (s *SleuthVault) SetTeamAdmin(ctx context.Context, team, email string, admin bool) error

func (*SleuthVault) UpdateBot added in v1.0.0

func (s *SleuthVault) UpdateBot(ctx context.Context, bot mgmt.Bot) error

func (*SleuthVault) UpdateTeam added in v0.15.0

func (s *SleuthVault) UpdateTeam(ctx context.Context, team mgmt.Team) error

func (*SleuthVault) VerifyIntegrity

func (s *SleuthVault) VerifyIntegrity(data []byte, hashes map[string]string, size int64) error

VerifyIntegrity checks hashes and sizes for downloaded assets

type SourceHandler

type SourceHandler interface {
	// Fetch retrieves asset data from the source
	Fetch(ctx context.Context, asset *lockfile.Asset) ([]byte, error)
}

SourceHandler handles fetching assets from specific source types This is used internally by Vault implementations to handle different source types

type ToolDef added in v0.6.0

type ToolDef struct {
	Tool    *mcp.Tool
	Handler func(context.Context, *mcp.CallToolRequest, QueryInput) (*mcp.CallToolResult, any, error)
}

ToolDef represents an MCP tool with its handler

type Vault

type Vault interface {
	// Authenticate performs authentication with the repository
	// Returns an auth token or empty string if no auth needed
	Authenticate(ctx context.Context) (string, error)

	// GetLockFile retrieves the lock file from the repository
	// Returns lock file content and ETag for caching
	// If cachedETag matches, returns notModified=true with empty content
	GetLockFile(ctx context.Context, cachedETag string) (content []byte, etag string, notModified bool, err error)

	// GetAsset downloads an asset using its source configuration from the lock file
	// The asset parameter contains the source configuration (source-http, source-git, source-path)
	GetAsset(ctx context.Context, asset *lockfile.Asset) ([]byte, error)

	// AddAsset uploads an asset to the repository
	AddAsset(ctx context.Context, asset *lockfile.Asset, zipData []byte) error

	// SetInstallations configures where an asset should be installed
	// Updates the lock file with the installation scopes
	// scopeEntity is a vault-specific value from ScopeOptionProvider (e.g., "personal").
	// Empty string means standard global/repo scoping via asset.Scopes.
	SetInstallations(ctx context.Context, asset *lockfile.Asset, scopeEntity string) error

	// InheritInstallations preserves existing installation scopes for an asset.
	// Called when no scope flags are provided (e.g., `sx add ./skill --yes`).
	// For server-managed vaults (Sleuth), this is a no-op since the server
	// auto-inherits installations when a new version is uploaded.
	// For file-based vaults (Path, Git), this copies scopes from any existing
	// version of the asset in the lock file.
	InheritInstallations(ctx context.Context, asset *lockfile.Asset) error

	// GetVersionList retrieves available versions for an asset (for resolution)
	// Only applicable to repositories with version management (Sleuth, not Git)
	GetVersionList(ctx context.Context, name string) ([]string, error)

	// GetMetadata retrieves metadata for a specific asset version
	GetMetadata(ctx context.Context, name, version string) (*metadata.Metadata, error)

	// GetAssetByVersion downloads an asset by name and version
	// Used for comparing content when adding assets
	GetAssetByVersion(ctx context.Context, name, version string) ([]byte, error)

	// VerifyIntegrity checks hashes and sizes for downloaded assets
	VerifyIntegrity(data []byte, hashes map[string]string, size int64) error

	// PostUsageStats sends asset usage statistics to the repository
	// jsonlData is newline-separated JSON (JSONL format)
	PostUsageStats(ctx context.Context, jsonlData string) error

	// RemoveAsset removes an asset from the lock file.
	// If delete is true, also permanently removes the asset files from the vault.
	// If version is empty, removes all versions of the asset.
	RemoveAsset(ctx context.Context, assetName, version string, delete bool) error

	// RenameAsset renames an asset in the vault.
	// All versions and installations are preserved under the new name.
	RenameAsset(ctx context.Context, oldName, newName string) error

	// ListAssets returns a list of all assets in the vault
	// This enables asset discovery via `sx vault list`
	ListAssets(ctx context.Context, opts ListAssetsOptions) (*ListAssetsResult, error)

	// GetAssetDetails returns detailed information about a specific asset
	// This enables asset inspection via `sx vault show <name>`
	GetAssetDetails(ctx context.Context, name string) (*AssetDetails, error)

	// GetMCPTools returns additional MCP tools provided by this vault
	// Returns nil if the vault doesn't provide any MCP tools
	GetMCPTools() any

	// GetBootstrapOptions returns bootstrap options provided by this vault
	// These are options for MCP servers or other infrastructure the vault provides
	GetBootstrapOptions(ctx context.Context) []bootstrap.Option

	// CurrentActor returns the identity of the caller as resolved by this
	// vault. For git/path vaults this comes from `git config user.email`;
	// for sleuth vaults it comes from the authenticated user token.
	CurrentActor(ctx context.Context) (mgmt.Actor, error)

	// Team management
	ListTeams(ctx context.Context) ([]mgmt.Team, error)
	GetTeam(ctx context.Context, name string) (*mgmt.Team, error)
	CreateTeam(ctx context.Context, team mgmt.Team) error
	UpdateTeam(ctx context.Context, team mgmt.Team) error
	DeleteTeam(ctx context.Context, name string) error
	AddTeamMember(ctx context.Context, team, email string, admin bool) error
	RemoveTeamMember(ctx context.Context, team, email string) error
	SetTeamAdmin(ctx context.Context, team, email string, admin bool) error
	AddTeamRepository(ctx context.Context, team, repoURL string) error
	RemoveTeamRepository(ctx context.Context, team, repoURL string) error

	// Bot management. Bots are non-human service identities. They gain
	// repo context through teams (the same way human team members do)
	// and can also be a direct install target via InstallKindBot.
	ListBots(ctx context.Context) ([]mgmt.Bot, error)
	GetBot(ctx context.Context, name string) (*mgmt.Bot, error)
	// CreateBot creates a new bot. The returned rawToken is non-empty
	// only on Sleuth vaults, which auto-issue a default API key as part
	// of bot creation; file-based vaults treat bots as identity-only and
	// always return "". Callers print the token (shown once) when
	// non-empty so the auto-issued key is not silently wasted.
	CreateBot(ctx context.Context, bot mgmt.Bot) (rawToken string, err error)
	UpdateBot(ctx context.Context, bot mgmt.Bot) error
	DeleteBot(ctx context.Context, name string) error
	AddBotTeam(ctx context.Context, bot, team string) error
	RemoveBotTeam(ctx context.Context, bot, team string) error

	// SetAssetInstallation records a new installation target for an
	// asset. File-backed vaults append the target to the asset's scope
	// list in sx.toml; Sleuth vaults delegate to the server.
	SetAssetInstallation(ctx context.Context, assetName string, target InstallTarget) error

	// ClearAssetInstallations removes every installation target from an
	// asset. Soft no-op if the asset is absent from the vault.
	ClearAssetInstallations(ctx context.Context, assetName string) error

	// RecordUsageEvents appends usage events to the vault's persistent
	// usage log. Replaces the string-based PostUsageStats for new code.
	RecordUsageEvents(ctx context.Context, events []mgmt.UsageEvent) error

	// GetUsageStats returns an aggregated usage summary across the vault.
	GetUsageStats(ctx context.Context, filter mgmt.UsageFilter) (*mgmt.UsageSummary, error)

	// QueryAuditEvents returns audit events matching the filter.
	QueryAuditEvents(ctx context.Context, filter mgmt.AuditFilter) ([]mgmt.AuditEvent, error)
}

Vault represents a source of assets with read and write capabilities This interface unifies the concepts of "vault" and "source fetcher"

func NewFromConfig

func NewFromConfig(cfg Config) (Vault, error)

NewFromConfig creates a vault instance from configuration This factory function eliminates repetitive switch statements across commands

Jump to

Keyboard shortcuts

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