feat(sessions): add archive/unarchive for sessions#674
Conversation
Adds session archiving so users can hide inactive sessions from the default session picker without deleting them. - Add `archive`/`unarchive` slash command in the TUI. - Add `kimi session archive <id>` and `kimi session unarchive <id>` CLI subcommands. - Extend the session store, core RPC, and SDK to persist and surface the archived flag. - Filter archived sessions from the default picker and show an archived badge when viewing all sessions. - Add unit tests for the slash command, CLI subcommand, and picker filtering.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70215e9f45
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| sessionId: entry.sessionId, | ||
| sessionDir: entry.sessionDir, | ||
| workDir: entry.workDir, | ||
| archived: entry.archived === true, |
There was a problem hiding this comment.
Preserve archived flag when loading the session index
Although this parses archived from each JSONL entry, readSessionIndex() drops it when it stores the sanitized entry in the returned Map (the result.set(...) object only keeps sessionId, sessionDir, and workDir). Because SessionStore.listAll() filters on entry.archived before reading state.json, an archived session still appears in listSessions() calls that are not scoped to a workDir, even with includeArchived omitted.
Useful? React with 👍 / 👎.
| async archiveSession({ sessionId }: ArchiveSessionPayload): Promise<SessionSummary> { | ||
| return this.sessionStore.archive(sessionId); | ||
| } | ||
|
|
||
| async unarchiveSession({ sessionId }: UnarchiveSessionPayload): Promise<SessionSummary> { | ||
| return this.sessionStore.unarchive(sessionId); |
There was a problem hiding this comment.
Update active session metadata when archiving
When the archived session is currently open, these RPC methods write state.json through SessionStore but leave the active Session object's in-memory metadata unchanged. If the user archives/unarchives the current TUI session and then sends another prompt (or otherwise triggers SessionAPIImpl.updatePromptMetadata() / writeMetadata()), that later write spreads the stale in-memory metadata and can remove or restore the old archived value, so the archive state does not persist reliably for active sessions.
Useful? React with 👍 / 👎.
Adds session archiving so users can hide inactive sessions from the default session picker without deleting them.
Changes
archive/unarchiveslash command in the TUI.kimi session archive <id>andkimi session unarchive <id>CLI subcommands.Testing
pnpm vitest run apps/kimi-code/test/tui/commands/session.test.tspnpm vitest run apps/kimi-code/test/cli/session.test.tspnpm vitest run apps/kimi-code/test/tui/utils/session-picker-rows.test.tspnpm vitest run apps/kimi-code/test/tui/components/dialogs/session-picker.test.tspnpm run typecheckinpackages/agent-core,packages/node-sdk, andapps/kimi-code