Documentation
¶
Index ¶
- type Cache
- func (c *Cache) Filter(term string) []SearchResult
- func (c *Cache) FrecencyScores() map[string]float64
- func (c *Cache) GetFrecencyScore(slug string) float64
- func (c *Cache) GetQueryFrecencyScore(query, slug string) float64
- func (c *Cache) IsDirty() bool
- func (c *Cache) IsStale() bool
- func (c *Cache) QueryFrecencyScores(query string, slugs []string) (scores map[string]float64, counts map[string]int)
- func (c *Cache) RecordAccess(slug string)
- func (c *Cache) RecordQueryAccess(query, slug string)
- func (c *Cache) Search(term string) []SearchResult
- func (c *Cache) Write(provider CachePathProvider) error
- func (c *Cache) WriteIfDirty(provider CachePathProvider) error
- type CachePathProvider
- type ErrAmbiguous
- type ErrNotFound
- type EventFunc
- type EventKind
- type FrecencyData
- type Repo
- type RepoFetcher
- type SearchResult
- type UpdateConfig
- type UpdateEvent
- type UpdateOptions
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, error)
Read loads the cache from disk. A missing file is normal and yields an empty cache with no error. A file that is present but unreadable or corrupt yields an empty cache and an advisory error: callers should warn and proceed, letting auto-update rebuild. A corrupt file is moved aside to <path>.corrupt so the next write cannot silently overwrite it.
func Update ¶
func Update(ctx context.Context, 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) FrecencyScores ¶ added in v1.4.0
FrecencyScores returns all repo-level frecency scores under a single lock. Callers doing bulk lookups (e.g., Search) should use this instead of calling GetFrecencyScore per-slug to avoid repeated lock acquisition.
func (*Cache) GetFrecencyScore ¶
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
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) IsStale ¶
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 ¶
RecordAccess updates frecency data for the given slug and marks the cache as dirty.
func (*Cache) RecordQueryAccess ¶ added in v1.2.0
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 EventFunc ¶ added in v1.4.0
type EventFunc func(UpdateEvent)
EventFunc receives update events. Implementations must be safe to call from multiple goroutines concurrently, since org fetches run in parallel.
type EventKind ¶ added in v1.4.0
type EventKind int
EventKind classifies an UpdateEvent.
const ( // EventDomainStarted marks the beginning of a domain refresh. EventDomainStarted EventKind = iota // EventPersonalFetched marks personal repos fetched for a domain. EventPersonalFetched // EventOrgStarted marks an org repo fetch beginning. In the concurrent // fanout this is when the org acquires a worker slot. EventOrgStarted // EventOrgFinished marks an org repo fetch completing successfully. EventOrgFinished // EventOrgFailed marks an org repo fetch failing. Org failures are // non-fatal: the overall update continues. EventOrgFailed )
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 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 UpdateEvent ¶ added in v1.4.0
type UpdateEvent struct {
Kind EventKind
Domain string
Org string
Repos int // repo count, set on EventOrgFinished
Err error // set on EventOrgFailed
}
UpdateEvent reports a single state change during a cache update. It carries enough identity (domain, org) and lifecycle (kind) for a concurrent progress UI to track one line per in-flight org and clear it on completion. The flat string progress of old could not express which org finished; this can.
func (UpdateEvent) Message ¶ added in v1.4.0
func (e UpdateEvent) Message() string
Message renders a human-readable line for the event. It exists so a simple single-line spinner can fall back to text, and so callers have one canonical phrasing rather than scattering format strings.
type UpdateOptions ¶
type UpdateOptions struct {
// AllOrgs ignores per-domain favorite_orgs, fetching all orgs.
AllOrgs bool
// Events is called with structured progress events during update. May be
// nil. It may be invoked concurrently from multiple goroutines, since org
// fetches run in parallel.
Events EventFunc
// 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.