cache

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

type Cache struct {
	Repositories  []Repo                             `json:"repositories"`
	LastUpdated   time.Time                          `json:"last_updated"`
	Frecency      map[string]FrecencyData            `json:"frecency"`
	QueryFrecency map[string]map[string]FrecencyData `json:"query_frecency"`
	// contains filtered or unexported fields
}

Cache holds the full repository cache with frecency data.

func BuildUpdatedCache

func BuildUpdatedCache(repos []Repo, existingFrecency map[string]FrecencyData, existingQueryFrecency map[string]map[string]FrecencyData) *Cache

BuildUpdatedCache creates a new cache from a fresh list of repos, preserving frecency data from the existing cache for repos that still exist. Frecency entries for repos no longer present are garbage collected.

func Read

func Read(provider CachePathProvider) *Cache

Read loads the cache from disk. If the file is missing, corrupted, or unreadable, it returns an empty cache so auto-update can recreate it.

func Update

func Update(cfg UpdateConfig, existing *Cache, opts UpdateOptions) (*Cache, error)

Update performs a full cache refresh across all configured domains. For each domain it fetches personal repos and org repos (applying filters and favorites), then rebuilds the cache preserving frecency data from existing. The new cache is written to disk.

func (*Cache) Filter

func (c *Cache) Filter(term string) []SearchResult

Filter finds repositories using substring matching only — no fuzzy, no frecency ranking. Used by `work list --filter`.

func (*Cache) GetFrecencyScore

func (c *Cache) GetFrecencyScore(slug string) float64

GetFrecencyScore computes the frecency score for a repository slug. Score = access_count * recency_multiplier. Returns 0 if the slug has never been accessed.

func (*Cache) GetQueryFrecencyScore added in v1.2.0

func (c *Cache) GetQueryFrecencyScore(query, slug string) float64

GetQueryFrecencyScore computes the query-level frecency score for a (query, slug) pair. Returns 0 if the pair has never been recorded. The query is normalized before lookup.

func (*Cache) IsDirty

func (c *Cache) IsDirty() bool

IsDirty returns whether the cache has been modified since last write.

func (*Cache) IsStale

func (c *Cache) IsStale() bool

IsStale returns true if the cache was last updated more than 24 hours ago or has never been updated (zero time).

func (*Cache) QueryFrecencyScores added in v1.2.0

func (c *Cache) QueryFrecencyScores(query string, slugs []string) (scores map[string]float64, counts map[string]int)

QueryFrecencyScores returns frecency scores and raw access counts for all given slugs under a query, acquired under a single lock. Slugs with no history are returned with zero score and zero count.

func (*Cache) RecordAccess

func (c *Cache) RecordAccess(slug string)

RecordAccess updates frecency data for the given slug and marks the cache as dirty.

func (*Cache) RecordQueryAccess added in v1.2.0

func (c *Cache) RecordQueryAccess(query, slug string)

RecordQueryAccess updates query-level frecency data for the given (query, slug) pair and marks the cache as dirty. The query is normalized to lowercase with whitespace trimmed.

func (*Cache) Search

func (c *Cache) Search(term string) []SearchResult

Search finds repositories matching the given term using tiered scoring: exact match (100), substring (50), fuzzy (normalized). Results are ranked by matchScore + frecencyScore, limited to 20.

func (*Cache) Write

func (c *Cache) Write(provider CachePathProvider) error

Write serializes the cache to disk, creating parent directories as needed.

func (*Cache) WriteIfDirty

func (c *Cache) WriteIfDirty(provider CachePathProvider) error

WriteIfDirty writes the cache to disk only if it has been modified since the last read or write.

type CachePathProvider

type CachePathProvider interface {
	CacheFile() string
}

CachePathProvider is the interface needed from config to locate the cache file.

type ErrAmbiguous

type ErrAmbiguous struct {
	Query       string
	Suggestions []SearchResult
}

ErrAmbiguous is returned when multiple repositories match and there is no single exact match to disambiguate.

func (*ErrAmbiguous) Error

func (e *ErrAmbiguous) Error() string

type ErrNotFound

type ErrNotFound struct {
	Query string
}

ErrNotFound is returned when no repositories match the query.

func (*ErrNotFound) Error

func (e *ErrNotFound) Error() string

type FrecencyData

type FrecencyData struct {
	AccessCount int       `json:"access_count"`
	LastAccess  time.Time `json:"last_access"`
}

FrecencyData tracks access frequency and recency for a repository.

type ProgressFunc

type ProgressFunc func(msg string)

ProgressFunc is called to report status during cache update.

type Repo

type Repo struct {
	Slug     string `json:"slug"`
	CloneURL string `json:"clone_url"`
	Domain   string `json:"domain"`
}

Repo represents a single cached repository.

func Resolve

func Resolve(results []SearchResult, query string) (*Repo, error)

Resolve takes search results and returns the single best match.

Resolution rules:

  • 0 results → ErrNotFound
  • 1 result → use it
  • 1 exact match among many → use the exact match
  • multiple with no single exact → ErrAmbiguous with suggestions

func ResolveQueryFrecency added in v1.2.0

func ResolveQueryFrecency(c *Cache, ambig *ErrAmbiguous) *Repo

ResolveQueryFrecency checks whether the user has a strong established association between the query and one of the ambiguous candidates. If so, it returns that candidate. Otherwise it returns nil.

This should be called only after Resolve returns ErrAmbiguous. The caller passes the ambiguous error's suggestions directly.

type RepoFetcher

type RepoFetcher interface {
	ListUserOrgs(ctx context.Context) ([]ghclient.Org, error)
	ListOrgRepos(ctx context.Context, org string) ([]ghclient.Repo, error)
	ListPersonalRepos(ctx context.Context) ([]ghclient.Repo, error)
}

RepoFetcher abstracts GitHub API calls needed for cache updates.

type SearchResult

type SearchResult struct {
	Repo         Repo
	MatchScore   float64
	FrecencyAdd  float64
	TotalScore   float64
	IsExactMatch bool
}

SearchResult holds a matched repo with its combined score.

type UpdateConfig

type UpdateConfig interface {
	CachePathProvider
	// DomainNames returns the configured domain hostnames.
	DomainNames() []string
	// DomainFavorites returns the favorite org names for the given domain.
	DomainFavorites(domain string) []string
	// DomainExtraOrgs returns extra org names for the given domain.
	// These are orgs the user has access to but may not be a member of.
	DomainExtraOrgs(domain string) []string
	// ShouldIncludeOrg determines whether an org passes the global include/exclude filters.
	ShouldIncludeOrg(org string) bool
}

UpdateConfig provides configuration needed for cache updates. This is a narrow interface consistent with CachePathProvider and RepoFetcher — callers pass only what Update needs rather than the full *config.Config.

type UpdateOptions

type UpdateOptions struct {
	// AllOrgs ignores per-domain favorite_orgs, fetching all orgs.
	AllOrgs bool

	// Progress is called with status messages during update. May be nil.
	Progress ProgressFunc

	// ClientFactory creates a RepoFetcher for a domain. If nil, uses github.NewClient.
	ClientFactory func(domain, token string) RepoFetcher

	// TokenFunc resolves auth tokens for a domain. Required.
	TokenFunc func(domain string) (string, error)
}

UpdateOptions controls cache update behavior.

Jump to

Keyboard shortcuts

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