Documentation
¶
Index ¶
- Variables
- func CloseAllRepoManagers()
- func GetMemoryManager() *memory.Manager
- func GetOrCreateRepoManager(slug string) (*memory.Manager, error)
- func GetRepoManagersForPaths(repoPath, worktreePath string) (repoMgr *memory.Manager, legacyRepoMgr *memory.Manager, repoSlug string, ...)
- func InjectMemoryContext(worktreePath string, globalMgr *memory.Manager, repoMgr *memory.Manager, ...) error
- func InjectMemoryContextForRepo(worktreePath, repoName string, globalMgr *memory.Manager, ...) error
- func KillInstanceAsync(inst *Instance)
- func SendMemoryAutoWritePrompt(inst *Instance) (sent bool, err error)
- func SendNotification(title, body string)
- func SetMemoryFactory(fn func(dir string) (*memory.Manager, error))
- func SetMemoryManager(mgr *memory.Manager, count, systemBudget int)
- func WaitForAllClosing(timeout time.Duration)
- type Activity
- type DiffStatsData
- type EmbeddedTerminal
- type GitWorktreeData
- type Instance
- func (i *Instance) Attach() (chan struct{}, error)
- func (i *Instance) GetDiffStats() *git.DiffStats
- func (i *Instance) GetGitWorktree() (*git.GitWorktree, error)
- func (i *Instance) GetPaneContent() (string, error)
- func (i *Instance) GetRepoPath() string
- func (i *Instance) GetWorkingPath() string
- func (i *Instance) HasUpdated() (updated bool, hasPrompt bool)
- func (i *Instance) Kill() error
- func (i *Instance) NewEmbeddedTerminalForInstance(cols, rows int) (*EmbeddedTerminal, error)
- func (i *Instance) Pause() error
- func (i *Instance) Paused() bool
- func (i *Instance) Preview() (string, error)
- func (i *Instance) PreviewFullHistory() (string, error)
- func (i *Instance) RepoName() (string, error)
- func (i *Instance) Resume() error
- func (i *Instance) SendKeys(keys string) error
- func (i *Instance) SendPrompt(prompt string) error
- func (i *Instance) SetPreviewSize(width, height int) error
- func (i *Instance) SetStatus(status Status)
- func (i *Instance) SetTitle(title string) error
- func (i *Instance) SetTmuxSession(session *tmux.TmuxSession)
- func (i *Instance) Start(firstTimeSetup bool) error
- func (i *Instance) StartInMainRepo() error
- func (i *Instance) StartInSharedWorktree(worktree *git.GitWorktree, branch string) error
- func (i *Instance) Started() bool
- func (i *Instance) TapEnter()
- func (i *Instance) TmuxAlive() bool
- func (i *Instance) ToInstanceData() InstanceData
- func (i *Instance) UpdateDiffStats() error
- func (i *Instance) UpdateResourceUsage()
- func (i *Instance) WaitForReady(timeout time.Duration)
- type InstanceData
- type InstanceOptions
- type Status
- type Storage
- func (s *Storage) DeleteAllInstances() error
- func (s *Storage) DeleteInstance(title string) error
- func (s *Storage) LoadInstances() ([]*Instance, error)
- func (s *Storage) LoadTopics() ([]*Topic, error)
- func (s *Storage) SaveInstances(instances []*Instance) error
- func (s *Storage) SaveTopics(topics []*Topic) error
- func (s *Storage) UpdateInstance(instance *Instance) error
- type SubAgentInfo
- type Topic
- type TopicData
- type TopicOptions
- type TopicTask
- type TopicWorktreeMode
Constants ¶
This section is empty.
Variables ¶
var ( ErrInstanceNotStarted = errors.New("instance not started") ErrInstanceAlreadyPaused = errors.New("instance is already paused") ErrBranchCheckedOut = errors.New("branch is currently checked out") ErrTitleEmpty = errors.New("instance title cannot be empty") ErrTitleImmutable = errors.New("cannot change title of a started instance") )
var NotificationsEnabled = true
NotificationsEnabled controls whether desktop notifications are sent. Set from config at startup.
Functions ¶
func CloseAllRepoManagers ¶ added in v0.2.2
func CloseAllRepoManagers()
CloseAllRepoManagers closes and removes all per-repo memory managers. Should be called on TUI shutdown.
func GetMemoryManager ¶ added in v0.2.2
GetMemoryManager returns the application-wide memory manager, or nil if memory is disabled. It is safe for concurrent use.
func GetOrCreateRepoManager ¶ added in v0.2.2
GetOrCreateRepoManager returns (creating if necessary) a Manager for the given repo slug. The repo memory dir is ~/.hivemind/memory/repos/{slug}/. Returns nil if memory is globally disabled (no global manager set).
func GetRepoManagersForPaths ¶ added in v0.2.2
func GetRepoManagersForPaths(repoPath, worktreePath string) (repoMgr *memory.Manager, legacyRepoMgr *memory.Manager, repoSlug string, err error)
GetRepoManagersForPaths returns the canonical repo manager and, when in transition mode, a legacy repo manager for read-merge. Canonical slug is derived from repoPath; legacy slug is derived from worktreePath (historic behavior).
func InjectMemoryContext ¶ added in v0.2.2
func InjectMemoryContext(worktreePath string, globalMgr *memory.Manager, repoMgr *memory.Manager, count int) error
InjectMemoryContext is the compatibility wrapper used by older call sites.
func InjectMemoryContextForRepo ¶ added in v0.2.2
func InjectMemoryContextForRepo(worktreePath, repoName string, globalMgr *memory.Manager, repoMgr *memory.Manager, legacyRepoMgr *memory.Manager, count int) error
InjectMemoryContextForRepo is the primary injection function called on agent start/resume. globalMgr must be non-nil; repo managers may be nil.
func KillInstanceAsync ¶ added in v0.2.2
func KillInstanceAsync(inst *Instance)
KillInstanceAsync runs Kill() in a background goroutine. The operation is tracked via closeWg so shutdown can wait for completion.
func SendMemoryAutoWritePrompt ¶ added in v0.2.2
SendMemoryAutoWritePrompt sends a final prompt to the agent asking it to persist session learnings to memory. It is fire-and-forget: we do not wait for the agent to respond. Only called when memory is configured.
Callers are responsible for ensuring the instance is in a valid state before calling this function. Kill() uses CompareAndSwap to guarantee single-caller semantics before invoking this.
Returns sent=true only when the prompt was successfully delivered.
func SendNotification ¶
func SendNotification(title, body string)
SendNotification sends a desktop notification. It is fire-and-forget: the command is started but we do not wait for it to finish.
func SetMemoryFactory ¶ added in v0.2.2
SetMemoryFactory stores a function used to create new Managers for per-repo dirs. If not set, GetOrCreateRepoManager falls back to creating a keyword-only (FTS) manager.
func SetMemoryManager ¶ added in v0.2.2
SetMemoryManager configures the memory manager used for startup injection. Called once from app.go when the TUI starts.
func WaitForAllClosing ¶ added in v0.2.2
WaitForAllClosing blocks until all in-flight Kill() calls finish or the timeout elapses. Called from the TUI quit handler to avoid exiting while instances are still shutting down.
Types ¶
type Activity ¶
type Activity struct {
// Action is the type of activity (e.g. "editing", "running", "reading", "searching", "working").
Action string
// Detail provides additional context (e.g. filename or command).
Detail string
// Timestamp is when this activity was detected.
Timestamp time.Time
}
Activity represents what an agent is currently doing.
func ParseActivity ¶
ParseActivity parses the pane content to extract the current activity. It scans the last ~30 lines for known patterns. program is the agent name (e.g. "claude", "aider"). Returns nil if no activity is detected.
type DiffStatsData ¶
type DiffStatsData struct {
Added int `json:"added"`
Removed int `json:"removed"`
Content string `json:"content"`
}
DiffStatsData represents the serializable data of a DiffStats
type EmbeddedTerminal ¶
type EmbeddedTerminal struct {
// contains filtered or unexported fields
}
EmbeddedTerminal provides a zero-latency embedded terminal view.
Architecture: creates a dedicated `tmux attach-session` PTY, reads its output stream directly through a VT emulator (charmbracelet/x/vt), and renders from the emulator's in-memory screen buffer. No subprocess calls per frame.
Data flow:
PTY stdout → readLoop → emu.Write() (updates screen state) PTY stdin ← responseLoop ← emu.Read() (terminal query responses) User keys → SendKey → PTY stdin (zero latency, bypasses emulator) Display ← Render() ← renderLoop cache (decoupled from emulator lock)
Signal-driven rendering: readLoop signals dataReady after each Write(), renderLoop wakes immediately and snapshots the screen into the cache, then signals renderReady so the display tick fires without fixed sleeps.
func NewEmbeddedTerminal ¶
func NewEmbeddedTerminal(sessionName string, cols, rows int) (*EmbeddedTerminal, error)
NewEmbeddedTerminal creates an embedded terminal connected to a tmux session. It spawns a dedicated `tmux attach-session` process with its own PTY, reads the output stream through a VT emulator, and renders from memory.
func (*EmbeddedTerminal) Close ¶
func (t *EmbeddedTerminal) Close()
Close shuts down the terminal: stops all goroutines, closes the PTY, and kills the tmux attach process.
func (*EmbeddedTerminal) Render ¶
func (t *EmbeddedTerminal) Render() (string, bool)
Render returns the latest cached screen content. This never blocks on the emulator lock — it only touches the lightweight cacheMu for microseconds. Returns ("", false) if nothing changed since the last call.
func (*EmbeddedTerminal) Resize ¶
func (t *EmbeddedTerminal) Resize(cols, rows int)
Resize updates the terminal dimensions.
func (*EmbeddedTerminal) SendKey ¶
func (t *EmbeddedTerminal) SendKey(data []byte) error
SendKey writes raw bytes directly to the PTY.
func (*EmbeddedTerminal) WaitForRender ¶
func (t *EmbeddedTerminal) WaitForRender(timeout time.Duration)
WaitForRender blocks until new rendered content is available in the cache, or until the timeout expires. Used by the Bubble Tea display tick to wake immediately when content changes instead of polling on a fixed interval.
type GitWorktreeData ¶
type GitWorktreeData struct {
RepoPath string `json:"repo_path"`
WorktreePath string `json:"worktree_path"`
SessionName string `json:"session_name"`
BranchName string `json:"branch_name"`
BaseCommitSHA string `json:"base_commit_sha"`
}
GitWorktreeData represents the serializable data of a GitWorktree
type Instance ¶
type Instance struct {
// Title is the title of the instance.
Title string
// Path is the path to the workspace.
Path string
// Branch is the branch of the instance.
Branch string
// Status is the status of the instance.
Status Status
// Program is the program to run in the instance.
Program string
// Height is the height of the instance.
Height int
// Width is the width of the instance.
Width int
// CreatedAt is the time the instance was created.
CreatedAt time.Time
// UpdatedAt is the time the instance was last updated.
UpdatedAt time.Time
// AutoYes is true if the instance should automatically press enter when prompted.
AutoYes bool
// SkipPermissions is true if the instance should run Claude with --dangerously-skip-permissions.
SkipPermissions bool
// TopicName is the name of the topic this instance belongs to (empty = ungrouped).
TopicName string
// Role is the agent's role (coder, reviewer, architect, tester, etc.).
// Set when created via brain action. Empty for manually created instances.
Role string
// ParentTitle is the title of the agent that spawned this instance via brain create_instance.
// Empty for manually created (top-level) instances.
ParentTitle string
// SetupScript is an optional shell command to run once after the worktree is ready.
SetupScript string
// InitialPrompt is passed to Claude Code via `-p` flag at startup (ephemeral, not persisted).
InitialPrompt string
// AutomationID is set when this instance was spawned by an automation.
// Empty for manually-created instances.
AutomationID string
// BrainChildCount is the number of brain-spawned child instances (set by TUI, not persisted).
BrainChildCount int
// LoadingStage tracks the current startup progress. Exported so the UI can read it.
LoadingStage int
// LoadingTotal is the total number of startup stages.
LoadingTotal int
// LoadingMessage describes the current loading step.
LoadingMessage string
// Notified is true when the instance finished (Running→Ready) and the user
// hasn't selected it yet. Cleared when the user selects this instance.
Notified bool
// LastActiveAt is set whenever the instance is marked as Running.
LastActiveAt time.Time
// PromptDetected is true when the instance's program is waiting for user input.
// Reset to false when the instance resumes running. Used by the sidebar to
// persistently show a running indicator without flickering.
PromptDetected bool
// CPUPercent is the current CPU usage of the instance's process tree.
CPUPercent float64
// MemMB is the current memory usage in megabytes (aggregated across process tree).
MemMB float64
// SubAgentCount is the number of detected sub-agent processes (e.g. spawned Claude Code tasks).
SubAgentCount int
// SubAgents holds details of each detected sub-agent process.
SubAgents []SubAgentInfo
// LastActivity is the most recently detected agent activity (ephemeral, not persisted).
LastActivity *Activity
// contains filtered or unexported fields
}
Instance is a running instance of claude code.
func FromInstanceData ¶
func FromInstanceData(data InstanceData) (*Instance, error)
FromInstanceData creates a new Instance from serialized data
func NewInstance ¶
func NewInstance(opts InstanceOptions) (*Instance, error)
func (*Instance) GetDiffStats ¶
GetDiffStats returns the current git diff statistics
func (*Instance) GetGitWorktree ¶
func (i *Instance) GetGitWorktree() (*git.GitWorktree, error)
GetGitWorktree returns the git worktree for the instance
func (*Instance) GetPaneContent ¶
GetPaneContent returns the current tmux pane content for activity parsing.
func (*Instance) GetRepoPath ¶
GetRepoPath returns the repo path for this instance, or empty string if not started.
func (*Instance) GetWorkingPath ¶ added in v0.2.2
GetWorkingPath returns the working directory for this instance. For instances with a git worktree, this is the worktree path. For main-repo instances, this is the repo path (i.Path).
func (*Instance) HasUpdated ¶
func (*Instance) NewEmbeddedTerminalForInstance ¶
func (i *Instance) NewEmbeddedTerminalForInstance(cols, rows int) (*EmbeddedTerminal, error)
NewEmbeddedTerminalForInstance creates an embedded terminal emulator connected to this instance's tmux PTY for zero-latency interactive focus mode.
func (*Instance) Pause ¶
Pause stops the tmux session and removes the worktree, preserving the branch
func (*Instance) PreviewFullHistory ¶
PreviewFullHistory captures the entire tmux pane output including full scrollback history
func (*Instance) SendPrompt ¶
SendPrompt sends a prompt to the tmux session using `tmux send-keys`, which delivers text reliably through tmux's server rather than raw PTY writes.
func (*Instance) SetPreviewSize ¶
func (*Instance) SetTitle ¶
SetTitle sets the title of the instance. Returns an error if the instance has started. We cant change the title once it's been used for a tmux session etc.
func (*Instance) SetTmuxSession ¶
func (i *Instance) SetTmuxSession(session *tmux.TmuxSession)
SetTmuxSession sets the tmux session for testing purposes
func (*Instance) Start ¶
firstTimeSetup is true if this is a new instance. Otherwise, it's one loaded from storage.
func (*Instance) StartInMainRepo ¶ added in v0.2.2
StartInMainRepo starts the instance directly in the repository directory. Unlike Start(), this does NOT create a git worktree or a new branch.
func (*Instance) StartInSharedWorktree ¶
func (i *Instance) StartInSharedWorktree(worktree *git.GitWorktree, branch string) error
StartInSharedWorktree starts the instance using a topic's shared worktree. Unlike Start(), this does NOT create a new git worktree — it uses the one provided.
func (*Instance) TapEnter ¶
func (i *Instance) TapEnter()
TapEnter sends an enter key press to the tmux session if AutoYes is enabled.
func (*Instance) TmuxAlive ¶
TmuxAlive returns true if the tmux session is alive. This is a sanity check before attaching.
func (*Instance) ToInstanceData ¶
func (i *Instance) ToInstanceData() InstanceData
ToInstanceData converts an Instance to its serializable form
func (*Instance) UpdateDiffStats ¶
UpdateDiffStats updates the git diff statistics for this instance
func (*Instance) UpdateResourceUsage ¶
func (i *Instance) UpdateResourceUsage()
UpdateResourceUsage queries the process tree for CPU and memory usage, and detects sub-agent processes via tmux windows.
Claude Code's tmux spawn backend creates sub-agents as additional windows (index > 0) in the same tmux session. We use tmux list-windows for detection and the process tree for resource metrics per window.
Values are kept from the previous tick if the query fails, so the UI doesn't flicker.
func (*Instance) WaitForReady ¶ added in v0.2.2
WaitForReady polls the tmux output until it stabilizes, indicating the program has finished initializing and is ready for input. Returns after the output hasn't changed for 2 consecutive checks (~1s of stability), or after the timeout elapses (best-effort, never errors on timeout).
type InstanceData ¶
type InstanceData struct {
Title string `json:"title"`
Path string `json:"path"`
Branch string `json:"branch"`
Status Status `json:"status"`
Height int `json:"height"`
Width int `json:"width"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
AutoYes bool `json:"auto_yes"`
SkipPermissions bool `json:"skip_permissions"`
TopicName string `json:"topic_name,omitempty"`
Role string `json:"role,omitempty"`
ParentTitle string `json:"parent_title,omitempty"`
AutomationID string `json:"automation_id,omitempty"`
Program string `json:"program"`
Worktree GitWorktreeData `json:"worktree"`
DiffStats DiffStatsData `json:"diff_stats"`
}
InstanceData represents the serializable data of an Instance
type InstanceOptions ¶
type InstanceOptions struct {
// Title is the title of the instance.
Title string
// Path is the path to the workspace.
Path string
// Program is the program to run in the instance (e.g. "claude", "aider --model ollama_chat/gemma3:1b")
Program string
// If AutoYes is true, then
AutoYes bool
// SkipPermissions enables --dangerously-skip-permissions for Claude instances.
SkipPermissions bool
// TopicName assigns this instance to a topic.
TopicName string
// Role is the agent's role (coder, reviewer, architect, tester, etc.).
Role string
// ParentTitle is the title of the parent agent that spawned this instance.
ParentTitle string
// AutomationID links this instance to the automation that spawned it.
AutomationID string
// SetupScript is an optional shell command to run before the agent starts.
// It runs in the instance's worktree directory.
SetupScript string
// InitialPrompt is passed to Claude Code via `-p` flag at startup.
// This is more reliable than injecting text after the agent starts.
InitialPrompt string
}
Options for creating a new instance
type Status ¶
type Status int
const ( // Running is the status when the instance is running and claude is working. Running Status = iota // Ready is if the claude instance is ready to be interacted with (waiting for user input). Ready // Loading is if the instance is loading (if we are starting it up or something). Loading // Paused is if the instance is paused (worktree removed but branch preserved). Paused )
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage handles saving and loading instances using the state interface
func NewStorage ¶
func NewStorage(state config.StateManager) (*Storage, error)
NewStorage creates a new storage instance
func (*Storage) DeleteAllInstances ¶
DeleteAllInstances removes all stored instances
func (*Storage) DeleteInstance ¶
DeleteInstance removes an instance from storage
func (*Storage) LoadInstances ¶
LoadInstances loads the list of instances from disk
func (*Storage) LoadTopics ¶
LoadTopics loads the list of topics from disk
func (*Storage) SaveInstances ¶
SaveInstances saves the list of instances to disk
func (*Storage) SaveTopics ¶
SaveTopics saves the list of topics to disk
func (*Storage) UpdateInstance ¶
UpdateInstance updates an existing instance in storage
type SubAgentInfo ¶ added in v0.2.1
type SubAgentInfo struct {
PID int
Name string // process name (e.g. "node")
Activity string // what the sub-agent is doing (e.g. "running git diff", "thinking")
CPU float64 // CPU% for this sub-agent's process tree
MemMB float64 // memory in MB for this sub-agent's process tree
}
SubAgentInfo holds metadata about a detected sub-agent process.
type Topic ¶
type Topic struct {
Name string
WorktreeMode TopicWorktreeMode
AutoYes bool
Branch string
Path string
CreatedAt time.Time
Notes string
Tasks []TopicTask
// contains filtered or unexported fields
}
Topic groups related instances, optionally sharing a single git worktree.
func FromTopicData ¶
FromTopicData creates a Topic from serialized data.
func NewTopic ¶
func NewTopic(opts TopicOptions) *Topic
func (*Topic) GetGitWorktree ¶
func (t *Topic) GetGitWorktree() *git.GitWorktree
func (*Topic) GetWorktreePath ¶
func (*Topic) IsMainRepo ¶ added in v0.2.2
IsMainRepo reports whether instances in this topic run directly in the repo directory.
func (*Topic) IsSharedWorktree ¶ added in v0.2.2
IsSharedWorktree reports whether all instances in this topic share one worktree.
func (*Topic) ToTopicData ¶
ToTopicData converts a Topic to its serializable form.
type TopicData ¶
type TopicData struct {
Name string `json:"name"`
WorktreeMode TopicWorktreeMode `json:"worktree_mode,omitempty"`
// SharedWorktree is kept for backwards-compatible JSON deserialization.
// New writes use WorktreeMode instead.
AutoYes bool `json:"auto_yes"`
Branch string `json:"branch,omitempty"`
Path string `json:"path"`
CreatedAt time.Time `json:"created_at"`
Worktree GitWorktreeData `json:"worktree,omitempty"`
Notes string `json:"notes,omitempty"`
Tasks []TopicTask `json:"tasks,omitempty"`
}
TopicData represents the serializable data of a Topic.
type TopicOptions ¶
type TopicOptions struct {
Name string
WorktreeMode TopicWorktreeMode
Path string
}
type TopicTask ¶ added in v0.2.2
TopicTask is a single item in the topic's todo list.
func NewTopicTask ¶ added in v0.2.2
NewTopicTask creates a TopicTask with a unique ID generated from the current time.
type TopicWorktreeMode ¶ added in v0.2.2
type TopicWorktreeMode string
TopicWorktreeMode controls how instances in a topic interact with git.
const ( // TopicWorktreeModePerInstance gives each instance its own branch + worktree directory. TopicWorktreeModePerInstance TopicWorktreeMode = "per_instance" TopicWorktreeModeShared TopicWorktreeMode = "shared" // TopicWorktreeModeMainRepo runs instances directly in the repo directory with no worktree. TopicWorktreeModeMainRepo TopicWorktreeMode = "main_repo" )