VS Code extension session sidebar should match Codex CLI resume picker semantics

Resolved 💬 4 comments Opened Apr 25, 2026 by iqdoctor Closed May 31, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

The VS Code extension session sidebar/task history currently behaves like a small recent-task teaser instead of an operational local session picker. In heavy local Codex usage this makes existing sessions hard to resume even when the same sessions are available through Codex CLI.

I think the sidebar should match the semantics of the Codex CLI resume picker, not necessarily its table layout.

Current behavior observed locally

On extension build:

openai.chatgpt-26.5422.30944-linux-x64

I observed the sidebar opening with a tiny visible subset such as a few rows plus a large View all (...) count. Earlier local hotpatches that increased page sizes made more sessions visible, but they either preserved a hidden cap or made first render slow when routed through full traversal.

Current relevant compiled locations in this build:

  • Manager bundle:

/root/.vscode-server/extensions/openai.chatgpt-26.5422.30944-linux-x64/webview/assets/app-server-manager-signals-DaIWbgQQ.js

  • refetchThreadList(...)
  • loadNextThreadListPage(...)
  • refreshRecentConversations(...)
  • loadMoreRecentConversations(...)
  • UI bundle:

/root/.vscode-server/extensions/openai.chatgpt-26.5422.30944-linux-x64/webview/assets/index-CrsC77dA.js

  • inline cap: slice(0,Math.max(3,e.length))
  • count label: View all ({total}) with values:{total:n.length}
  • task-history search filters loaded client-side arrays

CLI reference semantics

The current Codex CLI resume picker appears to use a better model:

  • /home/tools/codex/codex-rs/tui/src/resume_picker.rs
  • PAGE_SIZE = 25
  • LOAD_NEAR_THRESHOLD = 5
  • background page loader
  • progressive search
  • default sort by UpdatedAt
  • /home/tools/codex/codex-rs/app-server/src/codex_message_processor.rs
  • default thread-list limit is 25
  • individual server pages are bounded
  • /home/tools/codex/codex-rs/app-server-protocol/src/protocol/v2.rs
  • ThreadListResponse currently has data, nextCursor, and backwardsCursor
  • it does not expose an exact same-filter total count

Desired behavior

On opening the VS Code extension/sidebar:

  1. Show about 25 local/recent session rows immediately, not just a tiny teaser.
  2. Sort by last updated time descending by default.
  3. Expose both session creation time and last updated time in a compact sidebar-appropriate form.
  4. Notify/render after the first page, then continue cursor pagination in bounded background/on-demand pages.
  5. Keep UI responsive; do not block first local render on full traversal of all historical sessions.
  6. Make the count label semantically honest:
  • distinguish visible rows vs loaded rows vs exact total;
  • if exact total is unavailable, say loaded/loaded+ rather than implying all rows are loaded.
  1. Search should work beyond only the currently rendered rows, via backend searchTerm or progressive search/loading similar to CLI.

Local validation / experiment

I tested a local runtime hotpatch with the following semantics:

Manager bundle:

refetchThreadList: first page -> limit:25
loadNextThreadListPage: follow-up pages -> limit:100
refreshRecentConversations: notify after first page, then start bounded background cursor loading
loadMoreRecentConversations: serialize concurrent load-more calls to avoid cursor races

UI bundle:

slice(0,Math.max(3,e.length))
-> slice(0,Math.max(25,e.length))

View all ({total})
-> View all ({visible} / {loaded} loaded)

Local inline session rows were also patched to expose both timings compactly:

C <created relative time> · U <updated relative time>

Verification performed:

node --check app-server-manager-signals-DaIWbgQQ.js
node --check index-CrsC77dA.js

Both syntax checks passed, and static patch needles for first-page 25, next-page 100, background loader, serialized load-more guard, inline cap 25, loaded counter, and created/updated timing were present.

Why this matters

For users with hundreds or thousands of local Codex sessions, the VS Code extension needs to be a real resume/search surface. A tiny visible subset plus a misleading count makes session recovery unreliable, while synchronous full traversal can make the UI appear empty or cloud-only for too long.

The CLI already has a good model: small first page, updated-time sort, cursor loading, and progressive search. The extension should share those semantics.

Related

This is related to, but broader than, the hidden-cap/history issue:

  • #15368

That issue is about sessions being hidden/truncated. This issue frames the desired fix as CLI-aligned session picker semantics for the VS Code extension/sidebar.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #19572
  • #18640
  • #18364

Powered by Codex Action

iqdoctor · 4 months ago

Additional local runtime observation and correction after the first CLI-like hotpatch:

Observed behavior:

  • the loaded count could move from 25 / 326 to 25 / 426;
  • then it could regress to 25 / 53 or 25 / 26;
  • this points to a page-1 refresh rebuilding the local list and moving the cursor boundary backwards, instead of merging into a stable loaded map/list.

Local hotpatch correction in openai.chatgpt-26.5422.30944-linux-x64:

  • refetchThreadList(...) still fetches page 1 with limit:25, but now preserves the previously loaded conversationIds tail;
  • when the current loaded list is already beyond page 1, it preserves the furthest known nextCursor rather than resetting to page 2;
  • loadMoreRecentConversations(...) remains serialized through a promise guard;
  • inline sidebar search is now visible before clicking View all;
  • local inline rows no longer use C / U prefixes; title, created time, and updated time are rendered on one compact row;
  • View all now has a phase hint (loading local index... -> loaded+).

Current static verification passed:

no-reset keeps previous cursor: True
no-reset appends loaded tail: True
first page 25: True
next page 100: True
background loader: True
serialized load more: True
inline search state/input: True
one-line title timings: True
no noisy C/U prefixes: True
loading phase visible: True

Upstream implication: the extension should maintain a stable internal loaded map/list and merge page refreshes into it. A first-page refresh should update/prepend the head, not discard already loaded rows. If a source/filter change truly resets the list, the UI should indicate that transition explicitly.

iqdoctor · 4 months ago

Follow-up from the same local hotpatch against the current VS Code extension build openai.chatgpt-26.5422.30944-linux-x64.

The first CLI-like patch fixed the 50-row cap and no-reset list issue, but the sidebar could still take >40s before local sessions became useful. The slow path appears to be deeper than just thread/list page size: refreshRecentConversations() was still awaiting loadProjectlessConversationIds(true) before the first visible local page, and background loading then ran dense follow-up pages.

Additional implementation points validated locally:

  • Keep first visible page at CLI-like 25 rows.
  • Do not block first paint on projectless/filesystem indexing; start loadProjectlessConversationIds() asynchronously and notify again when it completes.
  • Keep cursor page loading serialized, but defer background pages with a small gap (750ms) so the webview stays responsive.
  • Add lightweight phase telemetry: refresh:start, refresh:first-page, page:start, page:done, and projectless-index errors.
  • Treat the old View all row as an inline paging/loading sentinel, not as a menu opener, now that search is always visible in the sidebar.
  • Reveal loaded rows in 25-row portions (visibleLimit += 25) so the sidebar behaves more like an infinite feed.
  • Align created/updated timestamps to the right side of the row instead of immediately after the title.
  • For transient resume failures containing Server overloaded; retry later, avoid showing an immediate Failed to resume chat danger toast; log a deferred-resume event and retry with a longer backoff (~5s).

Current hotpatch needles in this build:

  • manager bundle: webview/assets/app-server-manager-signals-DaIWbgQQ.js
  • UI bundle: webview/assets/index-CrsC77dA.js
  • loader points: refreshRecentConversations, loadMoreRecentConversations, refetchThreadList, loadNextThreadListPage
  • UI point: inline recent-task component t2(...)

Static validation performed locally:

  • node --check passes for both patched bundles.
  • First page remains limit:25; next page remains cursor-based limit:100.
  • The first render path no longer awaits projectless indexing before refetchThreadList.
  • The old bottom-row open-recent-tasks-menu dispatch is removed from that row.

This keeps the proposed upstream direction the same: match Codex CLI resume-picker semantics, but explicitly separate first-paint state DB loading from slower secondary filesystem/projectless hydration.

etraut-openai contributor · 2 months ago

This feature request hasn't received enough upvotes, so I'm closing.