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()
|
m.mu.Lock()
|
||||||
working := m.paneFocus[user.Login].Focused || m.paneFocus[user.Login].Drafting
|
working := m.paneFocus[user.Login].Focused || m.paneFocus[user.Login].Drafting
|
||||||
humanMoved := m.humanMoved[user.Login]
|
move := m.moveHolds[user.Login]
|
||||||
since := time.Since(humanMoved)
|
start := m.startHolds[user.Login]
|
||||||
|
since := time.Since(move.at)
|
||||||
moveHeld := since < moveHold
|
moveHeld := since < moveHold
|
||||||
startHeld := !moveHeld && time.Since(m.startedTodo[user.Login]) < startHold
|
startHeld := !moveHeld && time.Since(start.at) < startHold
|
||||||
if moveHeld {
|
if moveHeld {
|
||||||
m.moveRefused[user.Login] = true
|
move.refused = true
|
||||||
|
m.moveHolds[user.Login] = move
|
||||||
}
|
}
|
||||||
if startHeld {
|
if startHeld {
|
||||||
m.startRefused[user.Login] = true
|
start.refused = true
|
||||||
|
m.startHolds[user.Login] = start
|
||||||
}
|
}
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
if moveHeld {
|
if moveHeld {
|
||||||
@@ -596,13 +599,12 @@ func (m *Manager) SetFocus(ctx context.Context, login string, f api.Focus, actor
|
|||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
m.paneMoved[login] = at
|
m.paneMoved[login] = at
|
||||||
if actor == login {
|
if actor == login {
|
||||||
m.humanMoved[login] = at
|
m.moveHolds[login] = showHold{at: at}
|
||||||
delete(m.moveRefused, login)
|
|
||||||
}
|
}
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
if actor == login {
|
if actor == login {
|
||||||
time.AfterFunc(moveHold, func() {
|
time.AfterFunc(moveHold, func() {
|
||||||
err := m.endMoveHold(context.Background(), login, at)
|
err := m.endShowHold(context.Background(), login, at, m.moveHolds, moveHoldEnded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("end move hold", "login", login, "err", err)
|
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."
|
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()
|
m.mu.Lock()
|
||||||
current, ok := m.humanMoved[login]
|
hold := holds[login]
|
||||||
if !ok || !current.Equal(at) {
|
if !hold.at.Equal(at) {
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
delete(m.humanMoved, login)
|
delete(holds, login)
|
||||||
refused := m.moveRefused[login]
|
|
||||||
delete(m.moveRefused, login)
|
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
if !refused {
|
if !hold.refused {
|
||||||
return nil
|
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
|
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) {
|
func (m *Manager) setStartedTodo(login string, started bool) {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
delete(m.startRefused, login)
|
|
||||||
if !started {
|
if !started {
|
||||||
delete(m.startedTodo, login)
|
delete(m.startHolds, login)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
at := time.Now()
|
at := time.Now()
|
||||||
m.startedTodo[login] = at
|
m.startHolds[login] = showHold{at: at}
|
||||||
time.AfterFunc(startHold, func() {
|
time.AfterFunc(startHold, func() {
|
||||||
err := m.endStartHold(context.Background(), login, at)
|
err := m.endShowHold(context.Background(), login, at, m.startHolds, startHoldEnded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("end start hold", "login", login, "err", err)
|
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 {
|
func (m *Manager) modelOr(model string, l *live) string {
|
||||||
if model != "" {
|
if model != "" {
|
||||||
return model
|
return model
|
||||||
|
|||||||
@@ -58,10 +58,8 @@ type Manager struct {
|
|||||||
paneFocus map[string]api.PaneFocus
|
paneFocus map[string]api.PaneFocus
|
||||||
paneReported map[string]time.Time
|
paneReported map[string]time.Time
|
||||||
paneMoved map[string]time.Time
|
paneMoved map[string]time.Time
|
||||||
humanMoved map[string]time.Time
|
moveHolds map[string]showHold
|
||||||
moveRefused map[string]bool
|
startHolds map[string]showHold
|
||||||
startedTodo map[string]time.Time
|
|
||||||
startRefused map[string]bool
|
|
||||||
handoffModel map[string]string
|
handoffModel map[string]string
|
||||||
mergeTurns map[string]mergeTurn
|
mergeTurns map[string]mergeTurn
|
||||||
|
|
||||||
@@ -163,10 +161,8 @@ func New(st *store.Store, worktreeRoot, leadRoot, handsRoot, codexHome, antigrav
|
|||||||
paneFocus: map[string]api.PaneFocus{},
|
paneFocus: map[string]api.PaneFocus{},
|
||||||
paneReported: map[string]time.Time{},
|
paneReported: map[string]time.Time{},
|
||||||
paneMoved: map[string]time.Time{},
|
paneMoved: map[string]time.Time{},
|
||||||
humanMoved: map[string]time.Time{},
|
moveHolds: map[string]showHold{},
|
||||||
moveRefused: map[string]bool{},
|
startHolds: map[string]showHold{},
|
||||||
startedTodo: map[string]time.Time{},
|
|
||||||
startRefused: map[string]bool{},
|
|
||||||
handoffModel: map[string]string{},
|
handoffModel: map[string]string{},
|
||||||
mergeTurns: map[string]mergeTurn{},
|
mergeTurns: map[string]mergeTurn{},
|
||||||
signals: make(chan []api.Event, 1024),
|
signals: make(chan []api.Event, 1024),
|
||||||
|
|||||||
Reference in New Issue
Block a user