Skip to content

feat(ui): session unarchive flows with undo toast#110605

Merged
steipete merged 3 commits into
mainfrom
claude/session-unarchive-feature-1c3666
Jul 18, 2026
Merged

feat(ui): session unarchive flows with undo toast#110605
steipete merged 3 commits into
mainfrom
claude/session-unarchive-feature-1c3666

Conversation

@steipete

Copy link
Copy Markdown
Contributor

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:

  • Toast with Undo: a new minimal shared toast host (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 one sessions.patch { archived: false, pinned: true-if-pinned } and re-selects the session if it was active.
  • Sidebar "View archived" entry: quiet footer row in the sessions zone navigating to /settings/sessions?showArchived=1.
  • Composer Restore button: an archived session's chat previously showed only "Restore this session to send messages." as dead text; it now has an inline Restore button.
  • Sessions page Active | Archived segment: replaces the buried "Archived only" checkbox chip with a two-button segment (same URL param, route unchanged).
  • Delete all archived…: danger action in the archived view; re-enumerates archived sessions server-side (bounded fetch, limit 1000, tradeoff noted in code) so it is not limited to the rendered page, confirms with the exact count, and passes the protocol's archivedOnly: true guard through sessions.delete.

The stale sessionsView.archivedOnly i18n 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, real openai/gpt-5.6-sol turns; screenshots via Playwright against the running Control UI — the mock harness cannot load the Sessions page, a pre-existing gap):

Before After
before sidebar after sidebar

Archive → toast with Undo (undo round-trip verified live: row returned to the sidebar after clicking Undo):

toast
undo restored

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):

archived view
restore menu
composer restore

Validation:

  • node scripts/run-vitest.mjs over 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 with archivedOnly guard, composer restore action.
  • pnpm ui:i18n:baseline clean; git diff --check clean.
  • Autoreview (Codex gpt-5.6-sol, xhigh): 2 rounds; fixed segment-switch loading mask, delete-all page-bound enumeration, and silent non-throwing restore failure in chat. Remaining P2 asking for unbounded pagination in delete-all consciously rejected as the code-commented 1000-row bounded-fetch tradeoff; confirm dialog states the exact count.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: L maintainer Maintainer-authored PR labels Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 18, 2026, 7:46 AM ET / 11:46 UTC.

Summary
The PR adds archive recovery and management in the Control UI through undo toasts, archived-session navigation and restore controls, and a guarded bulk deletion action.

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
Persistent data-model change detected: serialized state: ui/src/lib/sessions/index.test.ts, serialized state: ui/src/lib/sessions/index.ts, serialized state: ui/src/pages/sessions/sessions-page.test.ts, serialized state: ui/src/pages/sessions/sessions-page.ts, serialized state: ui/src/pages/sessions/view.test.ts, serialized state: ui/src/pages/sessions/view.ts, and 6 more. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Obtain a Control UI owner decision on the archive-management workflow and the 1,000-session deletion cap.
  • [P2] Rebase onto current main and let required checks validate the resulting merge head.

Mantis proof suggestion
A short web UI chat proof could independently demonstrate restoring an archived current chat and re-enabling its composer, which is a visible part of this change. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis web UI chat proof: verify that restoring an archived current session re-enables the composer and returns the session to the active view.

Risk before merge

  • [P1] The new “Delete all archived…” control is intentionally bounded to 1,000 re-enumerated rows; the dialog reports the exact selected count, but a Control UI owner should explicitly accept that cap and its wording before merge.
  • [P1] This branch is behind current main; required checks and final merge-result review should gate the exact rebased head rather than treating the stale base as a correctness finding.

Maintainer options:

  1. Confirm bounded deletion semantics (recommended)
    Before merge, have a Control UI owner confirm that a control labeled “Delete all archived…” may intentionally operate on at most 1,000 newly enumerated rows while stating the exact affected count.
  2. Narrow the initial release
    Remove or defer the bulk-delete control and retain the reversible undo, navigation, and restore changes if maintainers do not want a capped destructive workflow.

Next step before merge

  • [P2] A human Control UI/product decision is required for the new archive-management workflow and its intentionally bounded destructive operation; there is no narrow mechanical repair to dispatch.

Maintainer decision needed

  • Question: Should the Control UI adopt this archive-management workflow, including a visible archived-session destination and a bulk deletion control capped at 1,000 re-enumerated archived sessions?
  • Rationale: The patch is not a mechanical repair: it creates a new recovery and destructive-management workflow whose navigation, disclosure, and bounded deletion semantics need Control UI product ownership.
  • Likely owner: steipete — The branch author is the clearest available routing contact for the proposed workflow; a current-main Control UI history pass should identify any additional owner before merge.
  • Options:
    • Sponsor the workflow (recommended): Approve the archive recovery surfaces and explicitly accept the 1,000-session bulk-delete cap after final current-head checks.
    • Keep recovery, defer bulk deletion: Land or request a narrower follow-up containing undo, archived discovery, and restore while reserving bulk deletion for a separately specified workflow.
    • Decline the new UI direction: Keep the existing archive flag and hidden filter behavior without expanding the Control UI archive-management surface.

Security
Cleared: The diff is limited to Control UI behavior, styling, i18n, and tests; it adds no dependency, workflow, secret, permission, package-resolution, or backend authorization change.

Review details

Best 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 changes

Label changes:

  • add merge-risk: 🚨 compatibility: The PR introduces new archive-management and deletion semantics for existing stored sessions, so maintainers should explicitly accept the upgrade and user-expectation behavior.

Label justifications:

  • P2: This is a useful but non-emergency Control UI workflow expansion with a bounded destructive operation requiring normal maintainer prioritization.
  • merge-risk: 🚨 compatibility: The PR introduces new archive-management and deletion semantics for existing stored sessions, so maintainers should explicitly accept the upgrade and user-expectation behavior.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): The PR body provides before/after screenshots and a live isolated-gateway archive-to-undo round trip plus restore evidence that directly shows the changed Control UI behavior.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides before/after screenshots and a live isolated-gateway archive-to-undo round trip plus restore evidence that directly shows the changed Control UI behavior.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body provides before/after screenshots and a live isolated-gateway archive-to-undo round trip plus restore evidence that directly shows the changed Control UI behavior.
Evidence reviewed

PR surface:

Source +539, Tests +254. Total +793 across 22 files.

View PR surface stats
Area Files Added Removed Net
Source 17 566 27 +539
Tests 5 280 26 +254
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 22 846 53 +793

What I checked:

  • Existing contract reuse: The branch uses the established sessions.patch archive flag and sessions.delete RPC rather than adding gateway protocol or schema changes; its client wrapper forwards archivedOnly only when explicitly requested. (ui/src/lib/sessions/index.ts:98, 0b37d8a2df40)
  • Changed user-facing paths: The branch adds undo-capable archive mutations in the sidebar, a restore action for archived chats, an archived-session view, and bulk deletion from that view. (ui/src/pages/sessions/sessions-page.ts:596, 0b37d8a2df40)
  • Real behavior evidence: The PR body supplies before/after Control UI screenshots and describes a live archive-to-undo round trip plus archived-chat restoration against an isolated dev gateway. (ui/src/lib/toast.ts:1, 0b37d8a2df40)
  • Review continuity: The previous ClawSweeper cycle at fa9bc41bcf6180baaafd04477ef203dc493f7622 recorded no remaining line-level findings; the latest head contains a narrow follow-up commit for CI mock/export compatibility. (ui/src/lib/toast.ts:1, 0b37d8a2df40)
  • Repository policy: The applicable Control UI policy permits English-string updates while leaving generated foreign locale bundles for the post-merge locale-refresh workflow. (ui/AGENTS.md:1, f98bcb7fa73c)

Likely related people:

  • steipete: Authored all three commits on the reviewed branch, including the archive-management implementation and the latest CI-compatibility follow-up; current-main history could not be fully inspected in this read-only environment. (role: proposed workflow author and recent area contributor; confidence: medium; commits: f3e086a75aba, fa9bc41bcf61, 0b37d8a2df40; files: ui/src/pages/sessions/sessions-page.ts, ui/src/components/app-sidebar-session-mutations.ts, ui/src/lib/toast.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-07-18T10:24:03.077Z sha ed43a1e :: needs maintainer review before merge. :: none
  • reviewed 2026-07-18T11:32:51.849Z sha fa9bc41 :: needs maintainer review before merge. :: none

steipete added 2 commits July 18, 2026 03:35
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.
@steipete
steipete force-pushed the claude/session-unarchive-feature-1c3666 branch from ed43a1e to fa9bc41 Compare July 18, 2026 11:29
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 18, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Jul 18, 2026
@steipete
steipete merged commit 39ddf71 into main Jul 18, 2026
100 checks passed
@steipete
steipete deleted the claude/session-unarchive-feature-1c3666 branch July 18, 2026 11:50
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

coder-master-0915 pushed a commit to coder-master-0915/openclaw that referenced this pull request Jul 18, 2026
* 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
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 19, 2026
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant