feat(ui): session unarchive flows with undo toast#110605
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ed43a1ee15
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try { | ||
| // One options snapshot for every page: filter edits made while pages load | ||
| // must not mix enumeration populations. | ||
| const listOptions = this.sessionListOptions(); |
There was a problem hiding this comment.
Don't reuse deep-link options for bulk archive deletion
When the Sessions page is opened with the supported ?session=...&showArchived=1 deep link, sessionListOptions() still includes the hidden search and agent narrowing for that one session. Reusing it here means the new “Delete all archived…” flow only enumerates and deletes the deep-linked archived session, while the button text promises all archived sessions in the view; this is reachable from the archived chat’s “open checkpoints/sessions” navigation and from direct URLs. Build the bulk-delete list options without the deep-link search filter.
Useful? React with 👍 / 👎.
|
Codex review: needs maintainer review before merge. Reviewed July 18, 2026, 7:46 AM ET / 11:46 UTC. Summary PR surface: Source +539, Tests +254. Total +793 across 22 files. Reproducibility: not applicable. as a bug reproduction: the submitted screenshots and live-run description directly demonstrate the new archive, undo, restore, and archived-session UI flows rather than a failing current-main defect. Review metrics: none identified. Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Accept or narrow the archive-management product direction, explicitly confirm the bounded bulk-delete behavior is appropriate, then rebase and merge only after the current head retains the demonstrated archive, undo, restore, and deletion safeguards. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction: the submitted screenshots and live-run description directly demonstrate the new archive, undo, restore, and archived-session UI flows rather than a failing current-main defect. Is this the best way to solve the issue? Unclear: the branch cleanly reuses existing session RPCs and provides strong real behavior proof, but whether this complete archive-management surface and its capped bulk deletion are the best product solution requires a Control UI owner decision. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model internal, reasoning high; reviewed against f98bcb7fa73c. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +539, Tests +254. Total +793 across 22 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Archiving from the web UI was silent and one-way. Adds a shared single-slot toast with Undo (restores archive state, pin, and active selection), a sidebar 'View archived' entry into Settings -> Sessions, an Active|Archived segment replacing the buried archived-only chip, an inline Restore button on archived chats' disabled composer, and a guarded 'Delete all archived' bulk action that fully re-enumerates archived sessions (paginated, aborts on any abnormal page) and passes the protocol archivedOnly guard. No gateway/protocol changes.
ed43a1e to
fa9bc41
Compare
|
Merged via squash.
|
* feat(ui): session unarchive flows with undo toast Archiving from the web UI was silent and one-way. Adds a shared single-slot toast with Undo (restores archive state, pin, and active selection), a sidebar 'View archived' entry into Settings -> Sessions, an Active|Archived segment replacing the buried archived-only chip, an inline Restore button on archived chats' disabled composer, and a guarded 'Delete all archived' bulk action that fully re-enumerates archived sessions (paginated, aborts on any abnormal page) and passes the protocol archivedOnly guard. No gateway/protocol changes. * test(ui): adapt archive undo sidebar harness * fix(ui): unexport ToastOptions and widen test mock casts for CI gates
* feat(ui): session unarchive flows with undo toast Archiving from the web UI was silent and one-way. Adds a shared single-slot toast with Undo (restores archive state, pin, and active selection), a sidebar 'View archived' entry into Settings -> Sessions, an Active|Archived segment replacing the buried archived-only chip, an inline Restore button on archived chats' disabled composer, and a guarded 'Delete all archived' bulk action that fully re-enumerates archived sessions (paginated, aborts on any abnormal page) and passes the protocol archivedOnly guard. No gateway/protocol changes. * test(ui): adapt archive undo sidebar harness * fix(ui): unexport ToastOptions and widen test mock casts for CI gates
What Problem This Solves
Archiving a session from the web UI was a one-way door: the session silently vanished from the sidebar with no feedback, no undo, and no discoverable place to find it again. The restore RPC (
sessions.patch { archived: false }) and the archived list (sessions.list { archived: true }) have existed all along — the Sessions page even had a hidden "Archived only" filter chip — but nothing in the product led users there. Accidental archives looked like data loss.Why This Change Was Made
Users need a recovery path that matches how archiving actually behaves (a reversible metadata flag). This PR adds the missing UI on top of existing gateway contracts — no backend, protocol, or schema changes:
ui/src/lib/toast.ts, single-slot, auto-dismiss,role="status") shown after archiving from the sidebar (single + batch) and the Sessions page. Undo restores archive state and pin in onesessions.patch { archived: false, pinned: true-if-pinned }and re-selects the session if it was active./settings/sessions?showArchived=1.archivedOnly: trueguard throughsessions.delete.The stale
sessionsView.archivedOnlyi18n key was removed; new English keys added and the keyless raw-copy baseline regenerated. Foreign locale bundles are reconciled by the post-merge workflow as usual.User Impact
Archiving is now recoverable and discoverable end to end: immediate Undo at the moment of archiving, a visible path to the archived list, one-click restore from the list or straight from an archived chat, and honest bulk cleanup of archived sessions. Pinned sessions restored via Undo keep their pin; pinning stays disabled while archived.
Evidence
Live verification on a scratch dev gateway (isolated
OPENCLAW_STATE_DIR, port 19533, realopenai/gpt-5.6-solturns; screenshots via Playwright against the running Control UI — the mock harness cannot load the Sessions page, a pre-existing gap):Archive → toast with Undo (undo round-trip verified live: row returned to the sidebar after clicking Undo):
Archived view with segment + Delete all archived, row Restore menu (pin correctly disabled), and the composer Restore button (clicking it re-enabled the composer live):
Validation:
node scripts/run-vitest.mjsover all touched test files: toast (3), sidebar (109), composer (15), sessions lib (31), sessions page suite (78), chat pane (36), chat view (172) — all green. New coverage: toast behavior, sidebar archive/undo incl. pin restore + active reselection, delete-all re-enumeration witharchivedOnlyguard, composer restore action.pnpm ui:i18n:baselineclean;git diff --checkclean.