Documentation
¶
Overview ¶
Package repos holds the connected-repos machinery for cross-repo references: the user-global configuration naming which repositories this user is connected to, and the managed read-only clone caches those connections resolve against. The package reads no ambient state — the config path and cache root arrive as an explicit Locations value, resolved once at the composition root (repos.DefaultLocations for the XDG convention). Pure reads live on Registry; the side-effectful cache lifecycle (clone, pull, config save) lives on Manager, orchestrated by handlers that invalidate the read side's GraphSource on completion.
Index ¶
- Constants
- func DeclaredRepoID(dir string) (string, error)
- func GraphDir(dir string) (string, error)
- func IsCloned(dir string) bool
- func LegacyIndexDir(dir string) string
- func SaveConfigTo(path string, cfg *GlobalConfig) error
- type ConnectedRepo
- type Git
- type GlobalConfig
- func (c *GlobalConfig) AddRepo(repo ConnectedRepo) error
- func (c *GlobalConfig) Connected(repoID string) (ConnectedRepo, bool)
- func (c *GlobalConfig) ConnectedByURL(cloneURL string) (ConnectedRepo, bool)
- func (c *GlobalConfig) RemoveRepo(repoID string) bool
- func (c *GlobalConfig) SelectRepoIDs(named []string, all bool) ([]string, error)
- func (c *GlobalConfig) UnconnectedDependencies(deps []string) []string
- type Locations
- type Manager
- func (m *Manager) CooldownPull(ctx context.Context, dir string, cooldown time.Duration) (bool, error)
- func (m *Manager) EnsureCloned(ctx context.Context, repo ConnectedRepo, dir string) (bool, error)
- func (m *Manager) ForcePull(ctx context.Context, dir string) error
- func (m *Manager) Registry() *Registry
- func (m *Manager) Save(cfg *GlobalConfig) error
- type Registry
Constants ¶
const DefaultPullCooldown = 15 * time.Minute
DefaultPullCooldown gates how often a read triggers a cache pull.
Variables ¶
This section is empty.
Functions ¶
func DeclaredRepoID ¶
DeclaredRepoID reads the repo_id the cached repo declares in its committed .sdd/config.yaml. Verification for `sdd repo add`: the connection is only valid when the target declares the identity the caller registers it under.
func GraphDir ¶
GraphDir resolves the cached repo's graph directory from its committed config, defaulting to the conventional location.
func LegacyIndexDir ¶
LegacyIndexDir is the pre-store per-repo index location inside a clone cache (<cache>/.index) — kept only so `sdd init` can migrate an existing build into the machine-global store. Nothing writes here anymore.
func SaveConfigTo ¶
func SaveConfigTo(path string, cfg *GlobalConfig) error
SaveConfigTo writes a user-global config to an explicit path, creating parent directories as needed. 0600 — the embedding block may carry API keys.
Types ¶
type ConnectedRepo ¶
ConnectedRepo names one connection: the canonical repo identity and the URL its cache clones from. CloneURL is per-user (ssh vs https), RepoID is identical for everyone (declared in the target repo's committed config).
type Git ¶
type Git interface {
// Clone clones url into dir.
Clone(ctx context.Context, url, dir string) error
// PullFFOnly pulls the checkout at dir, fast-forward only — the cache is
// read-only, so a non-ff state means the remote rewrote history; surface
// that rather than merging.
PullFFOnly(ctx context.Context, dir string) error
}
Git is the narrow git surface the cache lifecycle needs. The production implementation is internal/git's exec adapter; tests inject fakes.
type GlobalConfig ¶
type GlobalConfig struct {
model.BaseConfig `yaml:",inline"`
// Repos is the per-user resolution of connected repositories: for each
// repo_id, how this machine reaches it (clone URL, homedir cache). The
// committed per-repo `dependencies` list declares what a graph needs;
// this list resolves how — which is why it is global-only.
Repos []ConnectedRepo `yaml:"repos,omitempty"`
}
GlobalConfig is the user-global SDD configuration. It embeds the shared user/machine settings (model.BaseConfig — participant, llm, embedding, sync) that seed the config overlay for every repo on this machine; its embedding config doubles as the global embedder every connected repo's index is built with — one vector space so cosine scores are comparable across repos (a repo indexed under a different fingerprint is excluded from cross-graph search and flagged by lint). Hand-editable YAML underneath; per-repo-only fields (repo_id above all) do not exist on this schema, so a misplaced one is a parse error.
func LoadConfigFrom ¶
func LoadConfigFrom(path string) (*GlobalConfig, error)
LoadConfigFrom reads a user-global config from an explicit path. A missing file is not an error — it yields an empty config (no connections). Unknown keys are an error: a setting placed in the wrong file must surface at load time, never be silently dropped (d-cpt-6cq's fail-loud rule).
func (*GlobalConfig) AddRepo ¶
func (c *GlobalConfig) AddRepo(repo ConnectedRepo) error
AddRepo registers a connection. A connection with the same repo_id must not already exist — re-registering is a remove + add, never a silent overwrite.
func (*GlobalConfig) Connected ¶
func (c *GlobalConfig) Connected(repoID string) (ConnectedRepo, bool)
Connected returns the connection for repoID, if present.
func (*GlobalConfig) ConnectedByURL ¶
func (c *GlobalConfig) ConnectedByURL(cloneURL string) (ConnectedRepo, bool)
ConnectedByURL returns the connection whose clone URL matches cloneURL, if any — the `repo add` fast-path check (already connected under this URL), shared by the handler and the CLI's view-gate so both read one definition of "already connected".
func (*GlobalConfig) RemoveRepo ¶
func (c *GlobalConfig) RemoveRepo(repoID string) bool
RemoveRepo drops the connection for repoID, reporting whether it existed.
func (*GlobalConfig) SelectRepoIDs ¶
func (c *GlobalConfig) SelectRepoIDs(named []string, all bool) ([]string, error)
SelectRepoIDs resolves a caller's repo selection against the connected set: all=true means every connected repo; an explicitly named repo that is not connected is an error — silent narrowing would misreport coverage. An empty selection resolves to nil.
func (*GlobalConfig) UnconnectedDependencies ¶
func (c *GlobalConfig) UnconnectedDependencies(deps []string) []string
UnconnectedDependencies returns the declared dependencies (committed repo_ids) that have no connection in this user-global config — the gap `sdd init` reports after a fresh clone, since the clone_url half of a connection is per-user and cannot ride in the committed declaration.
type Locations ¶
type Locations struct {
// ConfigPath is the user-global config file
// (default $XDG_CONFIG_HOME/sdd/config.yaml).
ConfigPath string
// CacheRoot is the base directory for connected-repo clone caches
// (default $XDG_CACHE_HOME/sdd).
CacheRoot string
}
Locations names the user-global places the connected-repos machinery works against: the config file and the cache root. Resolved once at the composition root and passed down explicitly — tests point both at temp dirs, no environment involved.
func DefaultLocations ¶
DefaultLocations resolves the conventional locations: the XDG base directories, defaulting to ~/.config and ~/.cache. Implemented against the XDG convention directly (not os.UserConfigDir) so the paths are uniform across platforms and match the documented locations. This is the only place the package touches the environment — called by composition roots, never by library code.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the side-effectful half of the connected-repos machinery: cache clone and pull, and config writes. It wraps the pure Registry and is the dependency handlers get injected — the write-side counterpart to the finder-injected Registry.
func NewManager ¶
NewManager builds a Manager over the registry and the git dependency.
func (*Manager) CooldownPull ¶
func (m *Manager) CooldownPull(ctx context.Context, dir string, cooldown time.Duration) (bool, error)
CooldownPull pulls the cache when the last attempt is older than cooldown. Reports whether a pull ran. The marker is touched on every attempt — cooldown bounds attempts, not successes — but a failed pull still returns its error (fail loud; the caller decides whether stale reads may proceed).
func (*Manager) EnsureCloned ¶
EnsureCloned clones repo.CloneURL into dir when no clone is present yet. Reports whether a clone ran (false: the cache already existed).
func (*Manager) Registry ¶
Registry exposes the pure read surface, so a Manager-holding handler reads through the same paths the finders do.
func (*Manager) Save ¶
func (m *Manager) Save(cfg *GlobalConfig) error
Save writes the user-global config to the registry's config path.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the pure read surface over the connected-repos state: which repos are connected and where their caches live. It is the dependency the read side (finders) gets injected — it carries no way to clone, pull, or save, so finder purity is enforced by the type, not by discipline. The side-effectful lifecycle lives on Manager.
func NewRegistry ¶
NewRegistry builds a Registry over explicit locations. Composition roots pass DefaultLocations(); tests pass temp dirs.
func (*Registry) CacheDir ¶
CacheDir resolves a connected repo's clone location under the cache root. The repo-id's host/path shape nests naturally under the root.
func (*Registry) ConfigPath ¶
ConfigPath returns the user-global config file path. Exposed for the comment-preserving `sdd config set` upsert, which patches the file bytes in place rather than round-tripping through Save (which would drop comments).
func (*Registry) Load ¶
func (r *Registry) Load() (*GlobalConfig, error)
Load reads the user-global config. Deliberately lazy — read per call, not snapshotted at construction — so a long-lived process (the MCP server) sees a repo connected from another terminal without a restart. A missing file yields an empty config.