When the Hermes Gateway returns X-Hermes-Session-Id, it is now
saved to settings.chatSessionId via the ChatPersistence interface.
On restart, the factory restores the session ID into the ApiClient
so subsequent requests continue the same conversation.
Changes:
- Added chatSessionId to HermesChatSettings + DEFAULT_SETTINGS
- Extended ChatPersistence with loadSessionId/saveSessionId
- Added ApiClient.setSessionId() for restoring saved IDs
- ChatView.handleSend() persists sessionId when received
- main.ts factory restores session ID and updates status bar
Fixes the 'Marco!/Bolo!' test — conversation continuity now
survives Obsidian restarts.
Font fix: setChatFontSize() was called in the view factory before
onOpen() created the DOM. querySelector returned null and the call
silently failed. Now stores _chatFontSize field — setChatFontSize()
always caches the value, and onOpen() reapplies it once the container
exists. This fixes the "font resets to default on restart" bug.
Persistence debug: added console.log in onOpen() restore loop and
onClose() save to help diagnose why messages aren't repopulating.
data.json is confirmed written correctly on disk — the debug logs
will reveal whether loadMessages() returns the saved data at all.
When onOpen() restored saved messages, each appendMessage() call
fired a fire-and-forget saveMessages() → saveData(). With N saved
messages, N overlapping saveData() writes raced against each other.
If a stale write landed last, the persisted data could be corrupted
or appear empty on next restart.
Fix: add _restoring flag. Skip saveMessages() inside appendMessage()
while restoring. Do a single clean save after the restore loop.
Also wraps the restore loop in try/catch so a rendering failure
in one message doesn't silently kill the entire restore.
setChatFontSize was setting --hermes-chat-font-size on
this.containerEl (outer Obsidian view wrapper), but the CSS
default was defined on .hermes-chat-container (inner child).
The child's explicit default overrode the inherited value,
so the font size slider had no visible effect.
Now targets .hermes-chat-container directly.
- Font size slider now calls saveSettings() instead of saveData()
so changes propagate to open views immediately
- Chat messages persist across plugin reload via chatMessages
array in plugin settings — ChatPersistence interface bridges
ChatView to Plugin data layer
- Messages auto-save on append and on close
- Chat messages now render full markdown via Obsidian's MarkdownRenderer
(headers, bold, italic, code blocks, lists, links)
- Streaming shows plain text, swaps to rendered markdown on completion
- User messages render instantly as markdown
- New Chat font size slider in plugin settings (10-24px, default 14)
- Live-applies via CSS custom property --hermes-chat-font-size
- No restart needed
- Fix context capture timing bug: snapshot active note on chat focus
instead of at send time (when activeEditor is already null).
Added workspace active-leaf-change listener to keep context fresh.
- Multi-tab: each ChatView now gets its own ApiClient instance,
enabling independent sessions per tab. Added 'Open in New Tab'
command. Removed shared ApiClient from plugin.
- Slash commands: three built-in commands (/prep-session,
/sync-content, /lint-wiki) plus JSON-configurable custom commands
in settings. On '/' trigger, shows suggestion dropdown with
arrow-key navigation, click-to-select, and Escape to close.
- Slash command resolution at send time replaces /trigger with
full prompt text.