diff --git a/packages/client/src/components/hermes/chat/ChatPanel.vue b/packages/client/src/components/hermes/chat/ChatPanel.vue
index d7b4bbf..0c8386b 100644
--- a/packages/client/src/components/hermes/chat/ChatPanel.vue
+++ b/packages/client/src/components/hermes/chat/ChatPanel.vue
@@ -623,26 +623,35 @@ async function handleRenameConfirm() {
:deep(.session-item-active-spinner) {
animation: session-spin 1.1s linear infinite;
- filter: drop-shadow(0 0 6px rgba(var(--accent-primary-rgb), 0.35));
}
:deep(.session-item-live-badge) {
display: inline-flex;
align-items: center;
- justify-content: center;
+ gap: 4px;
flex-shrink: 0;
- padding: 0 8px;
- min-height: 20px;
+ padding: 1px 7px;
border-radius: 999px;
- font-size: 11px;
- line-height: 20px;
- font-weight: 700;
- letter-spacing: 0.05em;
+ font-size: 10px;
+ line-height: 16px;
+ font-weight: 600;
+ letter-spacing: 0.04em;
text-transform: uppercase;
color: $accent-primary;
- background: rgba(var(--accent-primary-rgb), 0.18);
- border: 1px solid rgba(var(--accent-primary-rgb), 0.34);
- box-shadow: 0 0 0 1px rgba(var(--accent-primary-rgb), 0.06), 0 0 10px rgba(var(--accent-primary-rgb), 0.14);
+ background: rgba(var(--accent-primary-rgb), 0.10);
+}
+
+:deep(.live-dot) {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: $accent-primary;
+ animation: live-pulse 2s ease-in-out infinite;
+}
+
+@keyframes live-pulse {
+ 0%, 100% { opacity: 1; transform: scale(1); }
+ 50% { opacity: 0.4; transform: scale(0.7); }
}
:deep(.session-item-pin) {
diff --git a/packages/client/src/components/hermes/chat/SessionListItem.vue b/packages/client/src/components/hermes/chat/SessionListItem.vue
index 4fbf0c1..ab8515e 100644
--- a/packages/client/src/components/hermes/chat/SessionListItem.vue
+++ b/packages/client/src/components/hermes/chat/SessionListItem.vue
@@ -45,7 +45,10 @@ const { t } = useI18n()
{{ session.title }}
- {{ t('chat.liveMode') }}
+
+
+ {{ t('chat.liveMode') }}
+
{{ session.model }}
diff --git a/packages/server/src/db/hermes/sessions-db.ts b/packages/server/src/db/hermes/sessions-db.ts
index dba73e7..203e564 100644
--- a/packages/server/src/db/hermes/sessions-db.ts
+++ b/packages/server/src/db/hermes/sessions-db.ts
@@ -163,6 +163,10 @@ function isNumericQuery(text: string): boolean {
return /^\d+(?:\s+\d+)*$/.test(text.trim())
}
+function hasUnsafeChars(text: string): boolean {
+ return /[^\w\s\u4e00-\u9fff\u3400-\u4dbf\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(text)
+}
+
function runLikeContentSearch(
db: { prepare: (sql: string) => { all: (...params: any[]) => Record[] } },
source: string | undefined,
@@ -358,7 +362,7 @@ export async function searchSessionSummaries(
return [...merged.values()].slice(0, limit)
}
- if (message.includes('no such table: messages_fts') && isNumericQuery(trimmed)) {
+ if (isNumericQuery(trimmed) || hasUnsafeChars(trimmed)) {
const likeRows = runLikeContentSearch(db, source, trimmed)
const merged = new Map()
for (const row of titleRows) {