The AI chat panel (AiPanel → useAiAgent) was sending each message as a
standalone request with no prior context. Root cause: useAiAgent.sendMessage
called streamClaudeAgent with raw text, never embedding history.
- Add agentMessagesToChatHistory() to convert AiAgentMessage[] to ChatMessage[]
- Embed trimmed history in each agent request via formatMessageWithHistory
- Use messagesRef/statusRef to avoid stale closures in async callbacks
- Also fix useAIChat (dead code path) with same ref pattern
- Update mock layers to detect history presence for testability
- Add Playwright smoke tests verifying history accumulates and resets
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
contextRef (useRef) was initialized at mount time and synced via useEffect,
which runs after paint. If contextPrompt was empty at mount (tab content
not yet loaded), sendMessage could read stale/empty context during the
window between paint and effect. Removing the ref and reading contextPrompt
directly in the useCallback closure eliminates the race entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
detectFileOperation silently failed when tool input was undefined (timing
issues with NDJSON event ordering). Added onVaultChanged callback as fallback:
when Write/Edit/Bash tools complete but specific file can't be determined,
vault.reloadVault() is triggered. Also added safety net in onDone handler.
Threaded onVaultChanged through AiPanel → EditorRightPanel → Editor → App.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>