Files
magpie/docs
yetone eb035e29e1 sessions: a session seen only through the gateway can be deleted: its row and recorded conversation go to magpie's trash, and Restore brings them back (lc on Discord)
lc ("只可列出?不可删除?agent claude code") saw Claude Code sessions named by
uuid under "No folder" at "0 B", with "These Claude Code sessions are read
only; magpie can list them, but cannot resume or delete them." Those rows are
gateway projections from the usage ledger: Claude Code ran with its own files
somewhere magpie can't see (another computer, a container, another config
folder), so nothing native won on the same agent+id. An agent with only such
rows was sent as not deletable, and every row was read_only, so the page had
no Delete at all.

What changed:
- sessions.DeleteGateway moves the session's recorded text folders
  (gateway-conversations/<date>/<identity hash>) into
  trash/sessions/gateway/<ts>-<hash>/files/<date> with a note marked gateway,
  and records {agent, id, last} in gateway-sessions-hidden.json.
  /api/sessions and /api/sessions/manage leave it out up to that last
  request; a newer request lists it again. The usage ledger is untouched, so
  Usage, /api/sessions/one and stats keep what it spent. A session with a
  request in the last minute is refused as active.
- Restore moves the text back (skipping what expired or was cleared, refusing
  rather than overwriting a same-day re-recording), checks each item is this
  session's identity folder inside the store, and unhides it. Delete forever
  keeps it hidden.
- The recording's promises hold in the trash: the hourly prune erases
  trashed gateway text past 7 days, "Delete saved conversations…" erases it
  too, and HasGatewayConversations counts it.
- The manage route marks an agent with gateway rows deletable and sends
  those rows deletable, with gateway: true and the size of their recorded
  text; the delete route sends gateway ids to DeleteGateway and native ones
  to Delete as before.
- Sessions page: gateway rows group under "Seen through the gateway"
  instead of "No folder", show "{size} recorded" only when something was
  recorded (no "0 B"), and the note says why they can't be resumed and what
  Delete takes and keeps. The delete dialog says the same for gateway rows
  instead of "Their files are moved…"; the Trash marks them and notes the
  7-day expiry. New strings in zh, zh-TW, ja and de.
- docs/subsystems/gateway-sessions.md describes the delete, hidden list,
  restore, expiry and clear.

Verified:
- go test -tags nogui ./... (sandbox HOME) green; gofmt -l clean; go vet
  ./...; GOOS=linux and GOOS=windows go vet -tags nogui ./internal/sessions
  ./internal/gui; go build, GOOS=linux -tags nogui and GOOS=windows builds.
- TestSessionsDeleteGatewaySession fails on the old code with "Claude Code
  with only gateway sessions isn't deletable: [{Agent:claude
  Deletable:false}]"; sessions-gateway-delete.test.cjs fails there too.
  TestGatewayDeleteTrashExpires, TestGatewayPurgeKeepsItHidden,
  TestGatewayDeleteNothingRecorded and TestGatewayRestoreRefusesForeignItems
  cover expiry, purge, an unrecorded session and a forged note.
- GUI: sessions-gateway-delete.test.cjs in Chromium and WebKit, en, zh,
  zh-TW, ja, de, at 1000 and 390px (in-app dialog, Cancel sends nothing,
  click doesn't scroll, no left-border accents, no page overflow); all
  sessions-*, gateway-conversations, checkbox-look, old-webkit,
  sess-agent-strip, i18n-keys, gui-ja, gui-de and gui-zh-tw tests pass.
- Real try: magpie web from this tree on a sandbox HOME seeded with three
  gateway-only Claude Code sessions (two recorded): deleted a recorded and an
  unrecorded one, checked the store, trash and hidden list on disk, restored
  the recorded one (its transcript reads again), purged the other (stays
  hidden). That try found the Trash page breaking on an unrecorded session's
  null items; DeleteGateway now writes [] (TestGatewayDeleteNothingRecorded
  fails without it) and the page reads a missing list as empty.
2026-10-10 09:53:38 +08:00
..