Unify pane hold state and expiry handling
This commit is contained in:
@@ -518,15 +518,18 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}
|
||||
m.mu.Lock()
|
||||
working := m.paneFocus[user.Login].Focused || m.paneFocus[user.Login].Drafting
|
||||
humanMoved := m.humanMoved[user.Login]
|
||||
since := time.Since(humanMoved)
|
||||
move := m.moveHolds[user.Login]
|
||||
start := m.startHolds[user.Login]
|
||||
since := time.Since(move.at)
|
||||
moveHeld := since < moveHold
|
||||
startHeld := !moveHeld && time.Since(m.startedTodo[user.Login]) < startHold
|
||||
startHeld := !moveHeld && time.Since(start.at) < startHold
|
||||
if moveHeld {
|
||||
m.moveRefused[user.Login] = true
|
||||
move.refused = true
|
||||
m.moveHolds[user.Login] = move
|
||||
}
|
||||
if startHeld {
|
||||
m.startRefused[user.Login] = true
|
||||
start.refused = true
|
||||
m.startHolds[user.Login] = start
|
||||
}
|
||||
m.mu.Unlock()
|
||||
if moveHeld {
|
||||
@@ -596,13 +599,12 @@ func (m *Manager) SetFocus(ctx context.Context, login string, f api.Focus, actor
|
||||
m.mu.Lock()
|
||||
m.paneMoved[login] = at
|
||||
if actor == login {
|
||||
m.humanMoved[login] = at
|
||||
delete(m.moveRefused, login)
|
||||
m.moveHolds[login] = showHold{at: at}
|
||||
}
|
||||
m.mu.Unlock()
|
||||
if actor == login {
|
||||
time.AfterFunc(moveHold, func() {
|
||||
err := m.endMoveHold(context.Background(), login, at)
|
||||
err := m.endShowHold(context.Background(), login, at, m.moveHolds, moveHoldEnded)
|
||||
if err != nil {
|
||||
slog.Error("end move hold", "login", login, "err", err)
|
||||
}
|
||||
@@ -702,21 +704,24 @@ const moveHold = 10 * time.Second
|
||||
|
||||
const moveHoldEnded = "The move hold is over: the human moved the right pane 10 seconds ago and hasn't moved it since, and a show of yours was refused in that time, so show works again under its other rules."
|
||||
|
||||
func (m *Manager) endMoveHold(ctx context.Context, login string, at time.Time) error {
|
||||
type showHold struct {
|
||||
at time.Time
|
||||
refused bool
|
||||
}
|
||||
|
||||
func (m *Manager) endShowHold(ctx context.Context, login string, at time.Time, holds map[string]showHold, text string) error {
|
||||
m.mu.Lock()
|
||||
current, ok := m.humanMoved[login]
|
||||
if !ok || !current.Equal(at) {
|
||||
hold := holds[login]
|
||||
if !hold.at.Equal(at) {
|
||||
m.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
delete(m.humanMoved, login)
|
||||
refused := m.moveRefused[login]
|
||||
delete(m.moveRefused, login)
|
||||
delete(holds, login)
|
||||
m.mu.Unlock()
|
||||
if !refused {
|
||||
if !hold.refused {
|
||||
return nil
|
||||
}
|
||||
return m.addLeadInput(ctx, store.LeadInput{Owner: login, Kind: store.LeadSignal, Actor: "byre", Text: moveHoldEnded})
|
||||
return m.addLeadInput(ctx, store.LeadInput{Owner: login, Kind: store.LeadSignal, Actor: "byre", Text: text})
|
||||
}
|
||||
|
||||
const startHold = 10 * time.Second
|
||||
@@ -726,38 +731,20 @@ const startHoldEnded = "The start hold is over: the human started a TODO item 10
|
||||
func (m *Manager) setStartedTodo(login string, started bool) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
delete(m.startRefused, login)
|
||||
if !started {
|
||||
delete(m.startedTodo, login)
|
||||
delete(m.startHolds, login)
|
||||
return
|
||||
}
|
||||
at := time.Now()
|
||||
m.startedTodo[login] = at
|
||||
m.startHolds[login] = showHold{at: at}
|
||||
time.AfterFunc(startHold, func() {
|
||||
err := m.endStartHold(context.Background(), login, at)
|
||||
err := m.endShowHold(context.Background(), login, at, m.startHolds, startHoldEnded)
|
||||
if err != nil {
|
||||
slog.Error("end start hold", "login", login, "err", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) endStartHold(ctx context.Context, login string, at time.Time) error {
|
||||
m.mu.Lock()
|
||||
current, ok := m.startedTodo[login]
|
||||
if !ok || !current.Equal(at) {
|
||||
m.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
delete(m.startedTodo, login)
|
||||
refused := m.startRefused[login]
|
||||
delete(m.startRefused, login)
|
||||
m.mu.Unlock()
|
||||
if !refused {
|
||||
return nil
|
||||
}
|
||||
return m.addLeadInput(ctx, store.LeadInput{Owner: login, Kind: store.LeadSignal, Actor: "byre", Text: startHoldEnded})
|
||||
}
|
||||
|
||||
func (m *Manager) modelOr(model string, l *live) string {
|
||||
if model != "" {
|
||||
return model
|
||||
|
||||
@@ -58,10 +58,8 @@ type Manager struct {
|
||||
paneFocus map[string]api.PaneFocus
|
||||
paneReported map[string]time.Time
|
||||
paneMoved map[string]time.Time
|
||||
humanMoved map[string]time.Time
|
||||
moveRefused map[string]bool
|
||||
startedTodo map[string]time.Time
|
||||
startRefused map[string]bool
|
||||
moveHolds map[string]showHold
|
||||
startHolds map[string]showHold
|
||||
handoffModel map[string]string
|
||||
mergeTurns map[string]mergeTurn
|
||||
|
||||
@@ -163,10 +161,8 @@ func New(st *store.Store, worktreeRoot, leadRoot, handsRoot, codexHome, antigrav
|
||||
paneFocus: map[string]api.PaneFocus{},
|
||||
paneReported: map[string]time.Time{},
|
||||
paneMoved: map[string]time.Time{},
|
||||
humanMoved: map[string]time.Time{},
|
||||
moveRefused: map[string]bool{},
|
||||
startedTodo: map[string]time.Time{},
|
||||
startRefused: map[string]bool{},
|
||||
moveHolds: map[string]showHold{},
|
||||
startHolds: map[string]showHold{},
|
||||
handoffModel: map[string]string{},
|
||||
mergeTurns: map[string]mergeTurn{},
|
||||
signals: make(chan []api.Event, 1024),
|
||||
|
||||
Reference in New Issue
Block a user