# Temporary Session Group Design

## Problem

The desktop sidebar currently treats every non-empty directory under
`~/.pi/agent/sessions` as a normal workspace. Pi test processes and other
short-lived invocations create session directories whose recorded workspace is
under the operating system temporary directory. On the inspected Windows
installation, 181 temporary workspaces containing 210 session files therefore
appear beside four normal workspaces.

The existing filter only checks encoded directory names for
`pi-gui-workspace`, `pi-gui-git-workspace`, and `worktrees`. It does not
recognize the system temporary directory and cannot cover arbitrary temporary
workspace names.

## Goals

- Keep temporary session history accessible without letting it dominate the
  normal workspace list.
- Default the temporary group to collapsed.
- Avoid loading or rendering every temporary workspace while the group is
  collapsed.
- Preserve current-workspace, hidden-workspace, search, resume, and launch
  behavior.
- Do not delete or modify any session history.

## Non-Goals

- Cleaning old session files from disk.
- Adding retention settings or automatic deletion.
- Guessing temporary workspaces from names such as `pi-*`.
- Changing how pi creates or stores sessions.

## Architecture

### Backend classification

Add a small path utility that determines whether a decoded workspace path is
inside the operating system temporary directory. Compare normalized path
boundaries rather than using substring matching. On Windows, compare
case-insensitively and accept both the raw `os.tmpdir()` value and its canonical
real path so short paths such as `ADMINI~1` and long paths such as
`Administrator` are both recognized.

`getWorkspaces()` continues to enumerate and sort non-empty session
directories, but each result gains an `isTemporary` boolean. The current
encoded-directory name exclusions remain as defense for known generated
worktrees. No session files are opened solely to classify a workspace; the
already decoded path is sufficient and avoids reading large JSONL histories.

### Frontend grouping

The sidebar partitions non-current workspaces in this order:

1. Explicitly hidden workspaces.
2. Visible temporary workspaces.
3. Visible normal workspaces.

Explicit hiding takes precedence, so a temporary workspace hidden by the user
still appears under the existing hidden-workspaces control. The current
workspace remains in the current-workspace section even if its path is under
the temporary directory.

After normal workspaces, render one `Temporary sessions` row above the hidden
workspace bar. It shows aggregate workspace and session counts and starts
collapsed on each window load. Expanding it reveals the existing workspace
rows, ordered by the backend's most-recently-active sort. Individual workspace
rows retain their existing lazy session loading, launch button, context menu,
and read-only thread behavior.

### Search and performance

When the temporary group is collapsed, thread search must not auto-expand it,
render its workspace rows, or issue `get-workspace-sessions` requests for its
members. Normal and already loaded workspace search behavior remains unchanged.
After the user expands the group, temporary workspace rows become available;
individual expansion continues to load only the selected workspace outside a
search. This keeps the common path proportional to normal workspaces rather
than to accumulated test sessions.

## Interaction Details

- Use a chevron and folder/clock-style icon consistent with existing sidebar
  workspace rows.
- Add English and Simplified Chinese labels through the existing i18n table.
- The group summary uses plural-neutral numeric interpolation:
  `{workspaces} workspaces / {sessions} sessions` and its Chinese equivalent.
- Group expansion is window-local UI state. It is not persisted to settings.
- If no temporary workspaces exist, render no temporary group.

## Error Handling

- If canonicalizing the system temporary directory fails, retain the raw
  `os.tmpdir()` root and use normalized lexical comparison.
- Invalid or empty workspace paths are classified as non-temporary.
- Existing directory enumeration error handling remains unchanged.

## Verification

- Unit-test path-boundary classification, including the temp root itself,
  children, sibling-prefix false positives, case handling on Windows, raw and
  canonical roots, and empty values.
- Verify `getWorkspaces()` exposes `isTemporary` in initial and refreshed
  payloads.
- Verify the sidebar partitions hidden, normal, and temporary workspaces,
  starts the temporary group collapsed, shows aggregate counts, and does not
  auto-fetch collapsed temporary sessions during search.
- Run the full `npm run check` suite and `git diff --check`.
