Skip to content

Commit 5cb9a47

Browse files
feat(tui): add configurable session_list_limit for session picker
Adds session_list_limit config option to limit sessions displayed in the session list dialog (default: 150). Limit only applies when not searching; search uses server-side limit of 30. Remove message_limit as it conflicts with cursor-based pagination (anomalyco#8535) and is now redundant. Closes anomalyco#6137
1 parent d9b9485 commit 5cb9a47

File tree

5 files changed

+57
-23
lines changed

5 files changed

+57
-23
lines changed

packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,36 +33,52 @@ export function DialogSessionList() {
3333
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
3434

3535
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
36+
const fallback = 150
3637

3738
const sessions = createMemo(() => searchResults() ?? sync.data.session)
39+
const isSearching = createMemo(() => search().length > 0)
3840

3941
const options = createMemo(() => {
4042
const today = new Date().toDateString()
41-
return sessions()
43+
const limit = sync.data.config.tui?.session_list_limit ?? fallback
44+
const list = sessions()
4245
.filter((x) => x.parentID === undefined)
4346
.toSorted((a, b) => b.time.updated - a.time.updated)
44-
.map((x) => {
45-
const date = new Date(x.time.updated)
46-
let category = date.toDateString()
47-
if (category === today) {
48-
category = "Today"
49-
}
50-
const isDeleting = toDelete() === x.id
51-
const status = sync.data.session_status?.[x.id]
52-
const isWorking = status?.type === "busy"
53-
return {
54-
title: isDeleting ? `Press ${keybind.print("session_delete")} again to confirm` : x.title,
55-
bg: isDeleting ? theme.error : undefined,
56-
value: x.id,
57-
category,
58-
footer: Locale.time(x.time.updated),
59-
gutter: isWorking ? (
60-
<Show when={kv.get("animations_enabled", true)} fallback={<text fg={theme.textMuted}>[⋯]</text>}>
61-
<spinner frames={spinnerFrames} interval={80} color={theme.primary} />
62-
</Show>
63-
) : undefined,
64-
}
65-
})
47+
const limited = (() => {
48+
if (isSearching()) return list
49+
const slice = list.slice(0, limit)
50+
const current = currentSessionID()
51+
if (!current) return slice
52+
if (slice.some((x) => x.id === current)) return slice
53+
const item = list.find((x) => x.id === current)
54+
if (!item) return slice
55+
const trimmed = list.filter((x) => x.id !== current).slice(0, limit - 1)
56+
const index = trimmed.findIndex((x) => x.time.updated < item.time.updated)
57+
if (index === -1) return [...trimmed, item]
58+
return [...trimmed.slice(0, index), item, ...trimmed.slice(index)]
59+
})()
60+
return limited.map((x) => {
61+
const date = new Date(x.time.updated)
62+
let category = date.toDateString()
63+
if (category === today) {
64+
category = "Today"
65+
}
66+
const isDeleting = toDelete() === x.id
67+
const status = sync.data.session_status?.[x.id]
68+
const isWorking = status?.type === "busy"
69+
return {
70+
title: isDeleting ? `Press ${keybind.print("session_delete")} again to confirm` : x.title,
71+
bg: isDeleting ? theme.error : undefined,
72+
value: x.id,
73+
category,
74+
footer: Locale.time(x.time.updated),
75+
gutter: isWorking ? (
76+
<Show when={kv.get("animations_enabled", true)} fallback={<text fg={theme.textMuted}>[⋯]</text>}>
77+
<spinner frames={spinnerFrames} interval={80} color={theme.primary} />
78+
</Show>
79+
) : undefined,
80+
}
81+
})
6682
})
6783

6884
onMount(() => {

packages/opencode/src/cli/cmd/tui/component/tips.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ const TIPS = [
8585
"Add {highlight}$schema{/highlight} to your config for autocomplete in your editor",
8686
"Configure {highlight}model{/highlight} in config to set your default model",
8787
"Override any keybind in config via the {highlight}keybinds{/highlight} section",
88+
"Set {highlight}tui.session_list_limit{/highlight} to cap sessions shown in the picker",
8889
"Set any keybind to {highlight}none{/highlight} to disable it completely",
8990
"Configure local or remote MCP servers in the {highlight}mcp{/highlight} config section",
9091
"OpenCode auto-handles OAuth for remote MCP servers requiring auth",

packages/opencode/src/config/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,13 @@ export namespace Config {
810810
.enum(["auto", "stacked"])
811811
.optional()
812812
.describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"),
813+
session_list_limit: z
814+
.number()
815+
.int()
816+
.min(1)
817+
.max(10000)
818+
.optional()
819+
.describe("Maximum number of sessions to display in session list when not searching (default: 150)"),
813820
})
814821

815822
export const Server = z

packages/sdk/js/src/v2/gen/types.gen.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,10 @@ export type Config = {
16091609
* Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column
16101610
*/
16111611
diff_style?: "auto" | "stacked"
1612+
/**
1613+
* Maximum number of sessions to display in session list (default: 150)
1614+
*/
1615+
session_list_limit?: number
16121616
}
16131617
server?: ServerConfig
16141618
/**

packages/sdk/openapi.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9343,6 +9343,12 @@
93439343
"description": "Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column",
93449344
"type": "string",
93459345
"enum": ["auto", "stacked"]
9346+
},
9347+
"session_list_limit": {
9348+
"description": "Maximum number of sessions to display in session list (default: 150)",
9349+
"type": "integer",
9350+
"minimum": 1,
9351+
"maximum": 10000
93469352
}
93479353
}
93489354
},

0 commit comments

Comments
 (0)