Files
tolaria/src/App.css
lucaronin 93d598d04c fix: MCP UI tools (highlight, open_note) now work in real-time
Root causes:
- index.js tried to start its own UI bridge server on port 9711, but
  ws-bridge.js (spawned by Tauri) already owns it → broadcastUiAction
  was a no-op. Fixed by connecting index.js as a WebSocket CLIENT that
  sends messages through the existing bridge.
- ws-bridge.js UI bridge had no relay — client messages weren't forwarded.
  Added relay so messages from the MCP server reach the React frontend.
- useAiActivity hook existed but was never imported in App.tsx.
- useAiActivity only handled highlight, not open_note/open_tab/set_filter.
- No vault_changed events after write operations.
- set_filter payload used `type` key which overwrote `type: 'ui_action'`.

Changes:
- mcp-server/index.js: connect as WS client instead of starting server;
  broadcast vault_changed after all write operations
- mcp-server/ws-bridge.js: add message relay in UI bridge; broadcast
  vault_changed after write operations; fix set_filter payload key
- useAiActivity: handle all UI actions (highlight, open_note, open_tab,
  set_filter, vault_changed); accept callbacks; auto-reconnect on close
- App.tsx: wire useAiActivity into vault/notes/selection actions; apply
  ai-highlight CSS class to editor and note list panels
- App.css: add ai-highlight-glow keyframe animation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 10:05:43 +01:00

75 lines
1.3 KiB
CSS

/* App layout - minimal CSS, most styling via Tailwind */
.app-shell {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
overflow: hidden;
box-shadow: inset 0 0 0 1px var(--border-primary);
}
.app {
display: flex;
flex: 1;
min-height: 0;
overflow: hidden;
}
.app__sidebar {
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.app__sidebar > * {
flex: 1;
}
.app__note-list {
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.app__note-list > * {
flex: 1;
}
.app__editor {
flex: 1;
min-width: 0;
min-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
}
.app__editor > * {
flex: 1;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes tab-status-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.tab-status-pulse {
animation: tab-status-pulse 1.2s ease-in-out infinite;
}
/* AI highlight animation — applied by useAiActivity when MCP calls ui_highlight */
@keyframes ai-highlight-glow {
0% { box-shadow: inset 0 0 0 2px rgba(99, 102, 241, 0.8); }
50% { box-shadow: inset 0 0 8px 2px rgba(99, 102, 241, 0.4); }
100% { box-shadow: inset 0 0 0 2px rgba(99, 102, 241, 0); }
}
.ai-highlight {
animation: ai-highlight-glow 0.8s ease-out;
}