The callback page now shows the real error message instead of a generic
"Failed to exchange" message. Token exchange tries JSON Content-Type first
(matching Claude Code's pattern) with form-encoded fallback. Full response
body logged for debugging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace mock responses in the XO copilot panel with real Wails binding
calls to the Go AIService backend:
- StartLogin now opens the browser via pkg/browser.OpenURL
- SendMessage returns ChatResponse (text + tool call results) instead of
bare error, fixing the tool-call accumulation bug in messageLoop
- Add GetModel/SetModel methods for frontend model switching
- Frontend useCopilot composable calls Go via Call.ByName from
@wailsio/runtime, with conversation auto-creation, auth checks, and
error display in the chat panel
- Store defaults to isAuthenticated=false; panel checks auth on mount
- CopilotSettings syncs model changes and logout to the backend
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OAuth PKCE flow for Max subscription auth (no API key needed)
- Claude API client with SSE streaming (Messages API v1)
- 16 tool definitions: terminal, SFTP, RDP, session management
- Tool dispatch router mapping to existing Wraith services
- Conversation manager with SQLite persistence
- Terminal output ring buffer for AI context
- RDP screenshot encoder (RGBA → JPEG with downscaling)
- Wired into Wails app as AIService
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>