- Convert flat project to Cargo workspace (crates/agcanvas, crates/agcanvas-mcp) - Add drawing layer: rectangles, ellipses, lines, arrows, text with select/move/resize - Add Mermaid diagram rendering via mermaid-rs-renderer - Add agcanvas-mcp: MCP server bridge for Claude Code, OpenCode, and Codex - Add toolbar UI with keyboard shortcuts (V/R/E/L/A/T) and shape interaction - Add example MCP configs for Claude Code, OpenCode, and Codex - Update README with full feature docs, MCP setup, and updated architecture
30 lines
1004 B
Rust
30 lines
1004 B
Rust
use anyhow::Result;
|
|
use futures_util::{SinkExt, StreamExt};
|
|
use tokio_tungstenite::tungstenite::Message;
|
|
|
|
pub async fn send_request(ws_url: &str, request_json: &str) -> Result<String> {
|
|
let (ws_stream, _) = tokio_tungstenite::connect_async(ws_url)
|
|
.await
|
|
.map_err(|e| {
|
|
anyhow::anyhow!(
|
|
"Cannot connect to agcanvas at {}. Is agcanvas running? Error: {}",
|
|
ws_url,
|
|
e
|
|
)
|
|
})?;
|
|
|
|
let (mut write, mut read) = ws_stream.split();
|
|
|
|
// Skip the initial Connected event
|
|
let _connected = read.next().await;
|
|
|
|
write.send(Message::Text(request_json.to_string())).await?;
|
|
|
|
match read.next().await {
|
|
Some(Ok(Message::Text(response))) => Ok(response),
|
|
Some(Ok(other)) => Err(anyhow::anyhow!("Unexpected message type: {:?}", other)),
|
|
Some(Err(e)) => Err(anyhow::anyhow!("WebSocket error: {}", e)),
|
|
None => Err(anyhow::anyhow!("Connection closed before response")),
|
|
}
|
|
}
|