You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,26 @@
1
1
# Changelog
2
2
3
+
## 1.4.10 — 2026-06-18
4
+
5
+
> Session history that stays fast with thousands of sessions.
6
+
7
+
### Features
8
+
9
+
-**Session history loads in pages and stays fast at scale.** The history dropdown used to read and parse *every* saved session on each open, which got slow once a project had hundreds or thousands of them. It now loads the **most recent 100** (newest first by last activity) and pulls in older ones as you **scroll to the bottom**. The **search box** filters by name across your **entire** history — not just the loaded page — so you can still find an old session instantly. Behind the scenes it orders sessions with one cheap directory `stat` each (no file reads), reads only the page you're looking at, and caches by file modification time so re-opening the dropdown costs effectively no disk reads. ([src/sessions.ts](src/sessions.ts), [src/sidebar.ts](src/sidebar.ts), [media/chat.js](media/chat.js), [media/chat.css](media/chat.css))
10
+
-**Switching model or reasoning effort on a fresh session no longer clutters history.** Some model and effort changes need the session to restart. If you flip them a few times right after opening a session — before you've actually said anything — each restart used to leave behind an empty, identical session in your history. Now an empty session (one where only the hidden setup has run) restarts cleanly with no "Summarize & Restart vs. Just Restart" prompt, and the throwaway session is removed instead of piling up. If you had renamed that session, the name carries over to the restarted one. ([src/sidebar.ts](src/sidebar.ts), [src/sessions.ts](src/sessions.ts))
11
+
12
+
### Fixes
13
+
14
+
-**History dropdown no longer opens clipped off the right edge.** Opening the session-history popover quickly (before its rows had finished loading) could position it too far right, so it spilled past the panel edge and only looked right after closing and reopening. The popover is now right-aligned to the panel (respecting the edge padding) and grows leftward, so it stays fully on-screen no matter how its contents resize as sessions load in. In a narrow panel it also caps its width to fit, so a long session name truncates with an ellipsis instead of pushing the popover off the left edge. Resizing the panel while the dropdown is open now re-fits it live (no need to close and reopen), and switching to another panel tab or extension closes it so it can't reappear mis-sized when you come back. ([media/chat.js](media/chat.js))
15
+
16
+
### Internal
17
+
18
+
-**Opt-in performance simulation for the history popover.** A new `npm run test:perf` suite (kept out of `npm test` and CI) builds a 5000-session in-memory store and asserts the access-count improvement: first open drops file reads from 5000 to 100 (~98%), a repeat open does zero reads (modification-time cache), and search warms the catalog once then stays read-free — with a modeled-latency projection and a real in-memory parse-cost wall-clock. ([test/sessions.perf.ts](test/sessions.perf.ts), [vitest.perf.config.ts](vitest.perf.config.ts), [package.json](package.json))
19
+
20
+
### Docs
21
+
22
+
- Documented the pagination design in [docs/architecture.md](docs/architecture.md) (§ History at scale) and [CLAUDE.md](CLAUDE.md) (§ History pagination), and updated the *Session history* feature note in the [README](README.md).
Copy file name to clipboardExpand all lines: README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -170,9 +170,9 @@ There's also no longer a long silent pause before that first response. Plan Mode
170
170
</details>
171
171
172
172
<details>
173
-
<summary><strong>Session history</strong> — resume, rename, or delete any past session</summary>
173
+
<summary><strong>Session history</strong> — resume, rename, delete, or clear past sessions</summary>
174
174
175
-
The clock icon lists every session the CLI saved for this project. Click a row to resume — Grok replays the conversation, with inline images, plans, and reasoning intact. Hover to rename (pencil) or delete (trash); names default to the first message. Renames are stored by the extension and never touch Grok's own files.
175
+
The clock icon lists the sessions the CLI saved for this project, most recent first. Click a row to resume — Grok replays the conversation, with inline images, plans, and reasoning intact. Hover to rename (pencil) or delete (trash); names default to the first message. The list loads the **most recent 100** and pulls in older ones as you **scroll**, and the **search box** filters by name across your whole history — so it stays fast even with thousands of sessions. **Clear all history** at the bottom of the dropdown removes every session for this project in one step (after a confirm), keeping the one you're currently in. Renames are stored by the extension and never touch Grok's own files.
@@ -196,6 +196,41 @@ The full pedagogical write-up lives in
196
196
|[media/chat.{js,css}](../media/)| Webview UI |
197
197
|[media/webview-helpers.js](../media/webview-helpers.js)| Pure webview helpers (file-ref detection, relative-time, mic-button state machine, trailing send-phrase highlight, math extraction `splitMath`/`stripUnsupportedTex`, and the deferred subagent classifier `isSubagentToolCall`/`subagentLabel`) — shared between webview and tests |
198
198
199
+
## History at scale
200
+
201
+
The history dropdown lists every session the CLI saved for this workspace, and that
202
+
store can grow into the thousands. The old path read and `JSON.parse`d *every*
203
+
`summary.json` on every open, then rendered every row — linear cost that stalled the
204
+
popover at scale. It now loads **one page at a time** (`SESSION_PAGE_SIZE = 100`,
205
+
newest-first), built from two pure primitives in
206
+
[src/sessions.ts](../src/sessions.ts):
207
+
208
+
-`indexSessions` does **one `stat` per session dir, no reads** — it orders every id
209
+
newest-first by `summary.json`**mtime**. mtime is the cheap last-activity proxy:
210
+
grok rewrites that file (it holds `updated_at`) on every turn. We sort by mtime
211
+
*because the id is a UUIDv7 whose timestamp is creation, not last activity* — an
212
+
id-sort would order by when the session was first opened, which is wrong.
213
+
-`readSessionEntries` reads + parses `summary.json` for **exactly the visible page's
214
+
ids** and applies name overrides.
215
+
216
+
The host (`postSessionsList` in [src/sidebar.ts](../src/sidebar.ts)) orders everything
217
+
cheaply with `indexSessions`, then drives an **mtime-keyed read cache** so a re-open /
0 commit comments