feat: implement session rename with SQLite storage (#413)

* feat: implement session rename with SQLite storage (closes #72, fixes #358)

- Add session_names table to store custom display names per provider
- Add PUT /api/sessions/:sessionId/rename endpoint
- Replace stub updateSessionSummary with real API call
- Apply custom names across all providers (Claude, Codex, Cursor)
- Fix project rename destroying config (spread merge instead of overwrite)
- Thread provider parameter through sidebar component chain
- Add i18n error messages for rename failures (en, ja, ko, zh-CN)

* fix: address CodeRabbit review feedback for session rename

- Log migration errors instead of swallowing them silently (db.js)
- Add try/catch to applyCustomSessionNames to prevent getProjects abort
- Move applyCustomSessionNames to db.js as shared helper (DRY)
- Fix Cursor getSessionName to check session.summary for custom names
- Move edit state clearing to finally block in updateSessionSummary
- Sanitize sessionId, add 500-char summary limit, validate provider whitelist
- Remove dead applyCustomSessionNames call on empty manual project sessions

* fix: reject sessionId on mismatch instead of silent normalization

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: enable rename for all providers, add Gemini support, clean up orphans

- Enable rename UI (pencil icon) for Codex, Cursor, and Gemini sessions
- Keep delete button hidden for Cursor (no backend delete endpoint)
- Add 'gemini' to VALID_PROVIDERS and hoist to module scope
- Add sessionNamesDb.deleteName on session delete (claude, codex, gemini)
- Fix token-usage endpoint sessionId mismatch validation
- Remove redundant try/catch in sessionNamesDb methods
- Let session_names migration errors propagate to outer handler

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Haileyesus <118998054+blackmammoth@users.noreply.github.com>
This commit is contained in:
PaloSP
2026-03-03 16:11:26 +01:00
committed by GitHub
parent 4da27ae5f1
commit 198e3da89b
19 changed files with 201 additions and 42 deletions

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import type React from 'react';
import type { TFunction } from 'i18next';
import { api } from '../../../utils/api';
import type { Project, ProjectSession } from '../../../types/app';
import type { Project, ProjectSession, SessionProvider } from '../../../types/app';
import type {
AdditionalSessionsByProject,
DeleteProjectConfirmation,
@@ -405,12 +405,30 @@ export function useSidebarController({
}, [onRefresh]);
const updateSessionSummary = useCallback(
async (_projectName: string, _sessionId: string, _summary: string) => {
// Session rename endpoint is not currently exposed on the API.
setEditingSession(null);
setEditingSessionName('');
async (_projectName: string, sessionId: string, summary: string, provider: SessionProvider) => {
const trimmed = summary.trim();
if (!trimmed) {
setEditingSession(null);
setEditingSessionName('');
return;
}
try {
const response = await api.renameSession(sessionId, trimmed, provider);
if (response.ok) {
await onRefresh();
} else {
console.error('[Sidebar] Failed to rename session:', response.status);
alert(t('messages.renameSessionFailed'));
}
} catch (error) {
console.error('[Sidebar] Error renaming session:', error);
alert(t('messages.renameSessionError'));
} finally {
setEditingSession(null);
setEditingSessionName('');
}
},
[],
[onRefresh, t],
);
const collapseSidebar = useCallback(() => {