Skip to content

feat(app): restore and browse archived sessions#32337

Open
shoootyou wants to merge 4 commits into
anomalyco:devfrom
shoootyou:feat/unarchive-sessions
Open

feat(app): restore and browse archived sessions#32337
shoootyou wants to merge 4 commits into
anomalyco:devfrom
shoootyou:feat/unarchive-sessions

Conversation

@shoootyou

@shoootyou shoootyou commented Jun 14, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #24153, #26078, #13463, #29517. Fixes #24850.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Archiving a session was one-way: it vanished from the sidebar with no restore path, and there was no way to find archived sessions again. This adds unarchive support and a discovery dialog, and fixes two count/visibility bugs along the way.

The restore mechanism clears the time_archived timestamp. setArchived accepts null to clear it; the projector writes SET time_archived = NULL (Drizzle omits undefined, so the value is coerced to null); and the PATCH payload schema accepts NullOr so the clear signal survives decoding. On the client, the event reducer tracks archived root ids in a small archivedRoots map so sessionTotal increments/decrements exactly once per stable id — without it, a restored session showed an inconsistent count and disappeared from the sidebar until restart (#29517).

The UI exposes a toggleable Archive/Restore action in the file picker, message timeline, and TUI session list, plus a new global dialog that lists archived sessions across all projects and restores one on selection.

Separately, listByProject (the sidebar query) had no archived filter, so archived rows consumed LIMIT slots and pushed active sessions out of view (#24850). It now excludes archived sessions by default, matching the existing guard in listGlobal.

I'm aware #15250 and #27510 touched parts of this area earlier; this PR implements the full round-trip (server clear + schema + reducer + UI + sidebar fix) as one coherent change.

How did you verify your code works?

Unit tests added/exercised:

Screenshots / recordings

To be added — the discovery dialog and the restore action are the user-facing surfaces.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

shoootyou and others added 4 commits June 14, 2026 13:19
Widen the unarchive path so a null/cleared archived timestamp reactivates a
session end to end: UpdatePayload accepts time.archived = null, setArchived
converts null to undefined before patch/publish, the core projector coerces
time_archived to null on update, and the app event-reducer increments
sessionTotal exactly once per stable root id on unarchive (and decrements
idempotently on archive), tracked via a new optional State.archivedRoots map.

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
Add an unarchive action across the app and TUI: the layout exposes a shared
unarchiveSession helper that clears the archived timestamp and navigates to the
restored session, wired into the file picker and session list. Includes i18n
strings for all locales and the supporting layout helpers.

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
Add a global discovery dialog that lists archived sessions across all projects
and restores one on selection. The cross-project list is fetched once on open
and cached, with a distinct loading state, an explicit in-dialog error surface,
and a single error toast per failure.

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
listByProject (the instance-scoped Session.list used by the sidebar) had no
time_archived filter, so archived sessions consumed LIMIT-window slots and
pushed active sessions out of the sidebar (anomalyco#24850). Add an archived?: boolean
to ListInput and filter out archived sessions unless explicitly requested,
mirroring the existing guard in listGlobal.

Closes anomalyco#24850

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:title labels Jun 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title feat(session,app,tui): restore and browse archived sessions doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on the search results, I found potential duplicate/related PRs:

Related PRs:

  1. feat(app): view archived sessions & unarchive #15250 - feat(app): view archived sessions & unarchive

    • This appears to be a prior attempt at the same feature (viewing and unarchiving archived sessions)
  2. fix(session): allow clearing archived timestamp via HTTP API #27510 - fix(session): allow clearing archived timestamp via HTTP API

    • This covers part of the restore mechanism (clearing archived timestamp), which is a component of the current PR

These PRs are related to the core functionality in PR #32337 (archiving/unarchiving sessions and viewing archived sessions). The current PR appears to be a comprehensive solution that builds upon or supersedes the earlier attempts by combining UI, core session logic, and the browse/discovery functionality into one integrated feature.

@shoootyou shoootyou changed the title feat(session,app,tui): restore and browse archived sessions feat(app): restore and browse archived sessions Jun 14, 2026
@github-actions github-actions Bot removed needs:title needs:compliance This means the issue will auto-close after 2 hours. labels Jun 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant