feat: add History page for browsing Hermes sessions (v0.5.5) (#370)

Features:
- Add dedicated History page for browsing Hermes session history
- Independent session state (does not interfere with active chat)
- Auto-select first CLI session on page load
- Filter out api_server and cron sources

Components:
- New HistoryView.vue with isolated state management
- New HistoryMessageList.vue with session prop support
- Filters empty content and tool messages without toolName

Backend:
- Add GET /api/hermes/sessions/hermes endpoint (excludes api_server)
- Add GET /api/hermes/sessions/hermes/:id endpoint (404s for api_server)
- Add fetchHermesSessions() and fetchHermesSession() API functions

Cleanup:
- Remove localStorage session caching
- Simplify profile switching cache management
- Clean up废弃 cache cleanup calls

i18n:
- Add "History" translation to all 8 locales
- Add v0.5.5 changelog entries in all languages
- 🎉 Happy Labor Day!

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-05-01 11:27:43 +08:00
committed by GitHub
parent e2f35d3caf
commit 3ba76ad19b
19 changed files with 1473 additions and 47 deletions
+20 -6
View File
@@ -215,14 +215,13 @@ function isQuotaExceededError(error: unknown): boolean {
function recoverStorageQuota() {
try {
// 清理所有会话相关的旧缓存(已完全废弃)
const prefixes = [
`hermes_session_msgs_v1_${getProfileName()}_`,
`hermes_in_flight_v1_${getProfileName()}_`,
'hermes_sessions_cache_v1_',
'hermes_session_msgs_v1_',
'hermes_session_pins_v1_',
'hermes_human_only_v1_',
]
if (getProfileName() === 'default') {
prefixes.push('hermes_session_msgs_v1_')
prefixes.push('hermes_in_flight_v1_')
}
const keysToRemove: string[] = []
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
@@ -233,6 +232,9 @@ function recoverStorageQuota() {
}
}
keysToRemove.forEach(key => removeItem(key))
if (keysToRemove.length > 0) {
console.log(`Recovered storage: cleared ${keysToRemove.length} old session cache entries`)
}
} catch {
// ignore
}
@@ -538,6 +540,17 @@ export const useChatStore = defineStore('chat', () => {
if (s) s.messages.push(msg)
}
function addOrUpdateSession(session: Session) {
const existingIndex = sessions.value.findIndex(s => s.id === session.id)
if (existingIndex !== -1) {
// Update existing session
sessions.value[existingIndex] = session
} else {
// Add new session
sessions.value.push(session)
}
}
function updateMessage(sessionId: string, id: string, update: Partial<Message>) {
const s = sessions.value.find(s => s.id === sessionId)
if (!s) return
@@ -1346,6 +1359,7 @@ export const useChatStore = defineStore('chat', () => {
newChat,
switchSession,
switchSessionModel,
addOrUpdateSession,
clearProviderFromSessions,
deleteSession,
sendMessage,