v0.4.4 e5506c1

new_session_test.go RawHistoryFolder

1package modes
2
3import (
4	"context"
5	"errors"
6	"testing"
7
8	"github.com/patriceckhart/zot/packages/core"
9	"github.com/patriceckhart/zot/packages/provider"
10)
11
12func TestNewSessionUnavailableWithoutPersistence(t *testing.T) {
13	i := NewInteractive(InteractiveConfig{})
14	if i.slashCancelsActiveTurn("/new") {
15		t.Fatal("unavailable /new would cancel the active turn")
16	}
17	i.runSlash(context.Background(), "/new")
18
19	if i.statusErr != "sessions are disabled by --no-session" {
20		t.Fatalf("status error = %q", i.statusErr)
21	}
22}
23
24func TestNewSessionResetsConversationView(t *testing.T) {
25	ag := core.NewAgent(nil, "model", "", nil)
26	ag.SetMessages([]provider.Message{{
27		Role:    provider.RoleUser,
28		Content: []provider.Content{provider.TextBlock{Text: "old conversation"}},
29	}})
30	calls := 0
31	var gotProvider, gotModel string
32	gate := core.NewConfirmGate(nil)
33	gate.AllowAll()
34	i := NewInteractive(InteractiveConfig{
35		Agent:       ag,
36		Provider:    "test-provider",
37		Model:       "active-model",
38		ConfirmGate: gate,
39		NewSession: func(providerName, model string) error {
40			calls++
41			gotProvider, gotModel = providerName, model
42			ag.SetMessages(nil)
43			return nil
44		},
45	})
46	i.cumUsage = provider.Usage{InputTokens: 10}
47	i.lastCtxInput = 10
48	i.extNotes = []string{"old notice"}
49
50	i.runSlash(context.Background(), "/new")
51
52	if calls != 1 {
53		t.Fatalf("NewSession calls = %d, want 1", calls)
54	}
55	if gotProvider != "test-provider" || gotModel != "active-model" {
56		t.Fatalf("NewSession model = %q/%q", gotProvider, gotModel)
57	}
58	if len(ag.Messages()) != 0 || len(i.view.Messages) != 0 {
59		t.Fatal("new session retained the previous transcript")
60	}
61	if i.cumUsage != (provider.Usage{}) || i.lastCtxInput != 0 {
62		t.Fatalf("usage was not reset: cumulative=%+v context=%d", i.cumUsage, i.lastCtxInput)
63	}
64	if len(i.extNotes) != 0 {
65		t.Fatalf("extension notices were not cleared: %v", i.extNotes)
66	}
67	if decision := gate.DecideToolCall(core.ToolCallConfirmation{Name: "bash"}); decision.Allow {
68		t.Fatal("new session retained session-scoped confirmation approval")
69	}
70	if i.statusOK != "started new session" || i.statusErr != "" {
71		t.Fatalf("status = %q, %q", i.statusOK, i.statusErr)
72	}
73}
74
75func TestNewSessionFailureKeepsConversationView(t *testing.T) {
76	ag := core.NewAgent(nil, "model", "", nil)
77	messages := []provider.Message{{
78		Role:    provider.RoleUser,
79		Content: []provider.Content{provider.TextBlock{Text: "still active"}},
80	}}
81	ag.SetMessages(messages)
82	i := NewInteractive(InteractiveConfig{
83		Agent:      ag,
84		NewSession: func(string, string) error { return errors.New("disk full") },
85	})
86
87	i.runSlash(context.Background(), "/new")
88
89	if len(ag.Messages()) != 1 || len(i.view.Messages) != 1 {
90		t.Fatal("failed session creation cleared the current transcript")
91	}
92	if i.statusErr != "start new session: disk full" {
93		t.Fatalf("status error = %q", i.statusErr)
94	}
95}

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 476

↑↓ moveenter openesc close