Documentation
¶
Overview ¶
Package coord implements the coordination layer of dibs: leases on file patterns, agent presence, broadcast notes, and the event journal.
All state is plain JSON files under the store's State dir. Nothing here runs in the background: expiry is evaluated lazily whenever state is read or mutated, so dibs needs no daemon.
Index ¶
- Constants
- func AutoName(worktree string) string
- func Intersect(a, b string) bool
- func Normalize(p, repoRoot string) (string, error)
- func NormalizePath(p, repoRoot string) (string, error)
- func PathCoveredBy(path, pattern string) bool
- func SanitizeName(s string) string
- type AgentInfo
- type Conflict
- type Event
- type Lease
- type Manager
- func (m *Manager) ActiveLeases() ([]Lease, error)
- func (m *Manager) Agents() ([]AgentInfo, error)
- func (m *Manager) Check(paths []string) ([]Conflict, error)
- func (m *Manager) Claim(patterns []string, reason string, ttl time.Duration) (*Lease, []Conflict, error)
- func (m *Manager) Journal(n int) ([]Event, error)
- func (m *Manager) MarkNotesRead(seen []Note) error
- func (m *Manager) Notes() ([]Note, error)
- func (m *Manager) PostNote(msg string) (*Note, error)
- func (m *Manager) Release(ids, patterns []string, all bool) ([]Lease, error)
- func (m *Manager) Renew(ttl time.Duration) ([]Lease, error)
- func (m *Manager) Touch()
- func (m *Manager) UnreadNotes() ([]Note, error)
- type Note
Constants ¶
const ( DefaultTTL = 30 * time.Minute MaxTTL = 24 * time.Hour )
Variables ¶
This section is empty.
Functions ¶
func AutoName ¶
AutoName derives a stable, human-friendly agent name from a worktree path. The same worktree always maps to the same name, so an agent working in ./wt-auth is "the same agent" across sessions without any configuration.
func Normalize ¶
Normalize canonicalizes a claim pattern: slashes, absolute paths mapped into the repo, no escaping the repo, and directory-like literals expanded to "dir/**". A meta-free pattern stays literal only when it names an existing regular file; a directory — or a path that does not exist (yet, or in this worktree) — is claimed as its whole subtree, which errs on the conservative side. Note that "dir/**" also matches "dir" itself in doublestar semantics. repoRoot may be "" in contexts (like tests) with no filesystem to consult.
func NormalizePath ¶ added in v0.1.1
NormalizePath canonicalizes a concrete filesystem path for conflict checking. Unlike Normalize it never reinterprets the path as a glob and never expands it — a path is data, not a pattern.
func PathCoveredBy ¶ added in v0.1.1
PathCoveredBy reports whether a concrete path is covered by a claim pattern. The path is matched literally: glob metacharacters in file names ("docs/[draft].md") have no special meaning.
func SanitizeName ¶ added in v0.1.1
SanitizeName restricts an agent name to filesystem- and display-safe characters. Presence records are stored under the agent's name, so this is a safety boundary, not cosmetics.
Types ¶
type AgentInfo ¶
type AgentInfo struct {
Name string `json:"name"`
Worktree string `json:"worktree,omitempty"`
Branch string `json:"branch,omitempty"`
LastReason string `json:"last_reason,omitempty"`
FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `json:"last_seen"`
LastNoteRead time.Time `json:"last_note_read,omitempty"`
}
AgentInfo is what dibs knows about one agent, updated as a side effect of every command that agent runs. There are no heartbeats: freshness is simply "when did it last do something".
type Conflict ¶
Conflict pairs a requested pattern (or checked path) with the foreign lease that covers it.
type Event ¶
type Event struct {
At string `json:"at"`
Event string `json:"event"`
Agent string `json:"agent"`
Details map[string]any `json:"details,omitempty"`
}
Event is one line of the append-only journal: who did what, when. The journal is the answer to "what have the agents been doing?".
type Lease ¶
type Lease struct {
ID string `json:"id"`
Agent string `json:"agent"`
Patterns []string `json:"patterns"`
Reason string `json:"reason,omitempty"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Renewals int `json:"renewals,omitempty"`
Worktree string `json:"worktree,omitempty"`
Branch string `json:"branch,omitempty"`
}
Lease is one agent's claim on a set of file patterns for a limited time.
type Manager ¶
type Manager struct {
St *store.Store
Agent string
// AutoIdentity is true when Agent was derived from the worktree path
// rather than chosen explicitly. An auto identity means "I am this
// worktree", which widens what counts as our own lease — see isSelf.
AutoIdentity bool
Now func() time.Time
}
Manager performs coordination operations as one named agent.
func NewManager ¶
NewManager resolves the acting agent's identity and returns a manager. Identity precedence: explicit name (--agent) > DIBS_AGENT env > a stable name derived from the worktree path.
func (*Manager) ActiveLeases ¶
ActiveLeases returns unexpired leases without mutating state.
func (*Manager) Check ¶
Check reports which of the given paths (repo-relative or absolute) are covered by another agent's active lease. Paths are matched literally — never parsed as globs — so file names containing glob metacharacters are handled correctly. Check never mutates state, so it is safe and fast to call from hooks on every file edit.
func (*Manager) Claim ¶
func (m *Manager) Claim(patterns []string, reason string, ttl time.Duration) (*Lease, []Conflict, error)
Claim asks for a lease on patterns. It returns either the granted (or renewed) lease, or the list of conflicts that denied it.
func (*Manager) MarkNotesRead ¶
MarkNotesRead advances this agent's read cursor to the newest note it actually saw — never to "now", which would silently swallow any note that lands between reading and acknowledging.
func (*Manager) PostNote ¶
PostNote broadcasts a message to every agent on this repository. The timestamp is assigned inside the lock, so a note can never be created in another agent's past (which would let a read cursor skip it).
func (*Manager) Release ¶
Release drops leases held by this agent: all of them, by lease ID, or by exact pattern. It returns the leases that were released.
func (*Manager) Touch ¶
func (m *Manager) Touch()
Touch records activity for this agent; exported for commands that don't otherwise mutate state (status, mcp startup).
func (*Manager) UnreadNotes ¶
UnreadNotes returns notes from other agents newer than this agent's read cursor.
type Note ¶
type Note struct {
ID string `json:"id"`
From string `json:"from"`
Message string `json:"message"`
CreatedAt time.Time `json:"created_at"`
}
Note is a small broadcast message between agents: "I changed the User schema — regenerate types before touching api/". Notes are the handoff mechanism; anything bigger belongs in a lesson or a commit message.