feat(server): support restoring and listing archived sessions#1073
Conversation
🦋 Changeset detectedLatest commit: 267507f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1d31b4283d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- add a `:restore` session action that clears the archived flag in state.json and returns the restored session - add an `archived_only` list query param, mutually exclusive with `include_archive`, that post-filters to archived sessions - keep the implementation in the server layer as a temporary measure until agent-core exposes restore natively
1e24920 to
9f46512
Compare
Browse, search, filter by workspace, sort, and restore archived sessions from a new Archived tab in Settings, backed by the server archived_only list and :restore action.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d011fcec53
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
When a search or workspace filter empties the loaded archived page, the Load more button was hidden inside the non-empty branch, so users could not fetch older pages to find a match. Move the button out so it stays available whenever more archived pages exist.
Draining an archived_only request that starts from after_id would switch to before_id and cross the pivot, reintroducing the pivot and older sessions. Take a single filtered page for after_id instead of draining past the lower bound.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae31d4b9d6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
An archived_only request starting from after_id now keeps paging toward older sessions until it reaches the pivot, instead of treating the first page as exhaustive. The loop stops as soon as it encounters the pivot session itself, so it never reintroduces the pivot or anything older.
|
@codex review |
When the user searches, sorts, or changes the workspace filter in the Archived settings page, fetch every remaining archived page first so the client-side filter and sort run over the full set rather than only the pages loaded so far.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4da75e1250
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| drainingAll.value = true; | ||
| try { | ||
| while (archivedHasMore.value) { | ||
| await loadArchived(false); |
There was a problem hiding this comment.
Avoid spinning while archived pages are already loading
If the user changes the archived-session search, sort, or workspace filter while a Load more request is already in flight, archivedHasMore can still be true but loadArchived(false) returns immediately because archivedLoading is true. This loop then repeatedly awaits an already-resolved promise and can starve the event loop, hanging the Settings dialog instead of waiting for the in-flight page to finish.
Useful? React with 👍 / 👎.
Fetch every archived session once when the Archived settings tab opens and drop frontend pagination entirely. Search, sort and workspace filter now run over the full set, removing the empty-page and cursor bookkeeping that previously caused bugs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 267507fd6b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const nextBeforeId = page.items[page.items.length - 1]?.id; | ||
| if (nextBeforeId === undefined || nextBeforeId === beforeId) break; | ||
| beforeId = nextBeforeId; | ||
| afterId = undefined; |
There was a problem hiding this comment.
Preserve the after_id bound when draining filtered pages
When archived_only is requested with after_id and there are more than 100 newer sessions before that pivot, this clears the only copy of the pivot after the first request. The underlying after_id page does not include the pivot itself, so subsequent before_id requests can continue past the original bound and add archived sessions older than after_id, causing forward pagination to return out-of-window/duplicate rows. Keep the original pivot separately and stop before crossing it when switching to before_id pagination.
Useful? React with 👍 / 👎.
Related Issue
No linked issue; the problem is described below.
Problem
Archived sessions could be included in session listings, but server clients had no API to restore an archived session or to query only archived sessions. That blocks the web archive/resume flow, where the UI needs to bring an archived session back before resuming it.
What changed
Restore archived sessions through the server API
Problem: Clients could see archived sessions but could not restore them through the server.
What was done:
:restoresession action that clears the archived flag from the persisted session state.List only archived sessions
Problem: The existing list API could include archived sessions, but it could not filter to archived sessions only.
What was done:
archived_onlylist query parameter.include_archiveto avoid ambiguous list semantics.Validation
pnpm --filter @moonshot-ai/server typecheckpnpm --filter @moonshot-ai/server exec vitest run test/sessions.e2e.test.tsChecklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.