v0.46.0 ea0e112

interactive_plan.go RawHistoryFolder

1package modes
2
3import "github.com/bnema/zut/packages/core"
4
5// RefreshPlan reseeds the plan counters and the per-call checklist snapshot map
6// after a session switch. The CLI seeds the agent's core plan state before it
7// commits a loaded session; this reads it back and installs the snapshots the
8// CLI reconstructed from the session's full transcript.
9//
10// It mirrors RefreshGoal: the CLI owns agent/session swapping and calls this
11// once the swap is committed. snapshots must come from the untrimmed transcript:
12// a resumed agent only holds the trim window, and replaying a delta against an
13// empty base rebuilds the wrong checklist.
14func (i *Interactive) RefreshPlan(snapshots map[string]core.PlanUpdate) {
15	var steps []core.PlanStep
16	if i.cfg.CurrentPlan != nil {
17		// CurrentPlan reaches back into the live agent, so read it before
18		// taking i.mu to keep the lock order one-directional.
19		steps = i.cfg.CurrentPlan()
20	}
21	i.applyPlanState(steps, snapshots)
22}
23
24// applyPlanState installs the plan counters and snapshot map. The revision bump
25// is part of msgVisualKey, so every cached checklist row is invalidated.
26func (i *Interactive) applyPlanState(steps []core.PlanStep, snapshots map[string]core.PlanUpdate) {
27	i.mu.Lock()
28	i.planSnapshots = snapshots
29	i.planRevision++
30	i.planCurrent, i.planTotal = planProgress(steps)
31	i.mu.Unlock()
32	i.invalidate()
33}
34
35// PlanStatus reports the session-scoped plan counters along with the number of
36// reconstructed per-call checklist snapshots. Hosts and tests read the plan
37// view through it instead of reaching into the private render state.
38func (i *Interactive) PlanStatus() (current, total, snapshots int) {
39	i.mu.Lock()
40	defer i.mu.Unlock()
41	return i.planCurrent, i.planTotal, len(i.planSnapshots)
42}
43
44// seedPlanState populates the initial plan counters and snapshot map during
45// construction, before the first render. cfg.CurrentPlan reads the live agent
46// (not i), so this may run while the Interactive is still private.
47//
48// InitialPlanSnapshots, when supplied by the CLI, was reconstructed from the
49// session's full transcript; it is the only correct source after a resume whose
50// trim window starts mid-plan. Without it (embedders, tests) the agent's own
51// messages are the best available transcript.
52func (i *Interactive) seedPlanState() {
53	if i.agent != nil {
54		snapshots := i.cfg.InitialPlanSnapshots
55		if snapshots == nil {
56			snapshots = core.PlanUpdateSnapshots(i.agent.Messages())
57		}
58		i.planSnapshots = snapshots
59		// Advance rather than assign so a re-seed on a live instance cannot
60		// move the revision backwards past a render that already observed it.
61		i.planRevision++
62	}
63	if i.cfg.CurrentPlan != nil {
64		i.planCurrent, i.planTotal = planProgress(i.cfg.CurrentPlan())
65	}
66}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 477

↑↓ moveenter openesc close