wraith/src-tauri/src/mcp/mod.rs
Vantz Stockwell bc608b0683
Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Failing after 15s
feat: copilot QoL — resizable panel, SFTP tools, context, error watcher
Resizable panel:
- Drag handle on left border of copilot panel
- Pointer events for smooth resize (320px–1200px range)

SFTP MCP tools:
- sftp_list: list remote directories
- sftp_read: read remote files
- sftp_write: write remote files
- Full HTTP endpoints + bridge tool definitions

Active session context:
- mcp_get_session_context command returns last 20 lines of scrollback
- Frontend can call on tab switch to keep AI informed

Error watcher:
- Background scanner runs every 2 seconds across all sessions
- 20+ error patterns (permission denied, OOM, segfault, disk full, etc.)
- Emits mcp:error events to frontend with session ID and matched line
- Sessions auto-registered with watcher on connect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:30:12 -04:00

46 lines
1.3 KiB
Rust

//! MCP (Model Context Protocol) infrastructure for Wraith.
//!
//! Provides programmatic access to active sessions so AI tools running in the
//! copilot panel can read terminal output, execute commands, and enumerate
//! sessions.
pub mod scrollback;
pub mod server;
pub mod error_watcher;
use std::sync::Arc;
use dashmap::DashMap;
use crate::mcp::scrollback::ScrollbackBuffer;
/// Registry of scrollback buffers keyed by session ID.
/// Shared between SSH/PTY output loops (writers) and MCP tools (readers).
#[derive(Clone)]
pub struct ScrollbackRegistry {
buffers: DashMap<String, Arc<ScrollbackBuffer>>,
}
impl ScrollbackRegistry {
pub fn new() -> Self {
Self { buffers: DashMap::new() }
}
/// Create and register a new scrollback buffer for a session.
pub fn create(&self, session_id: &str) -> Arc<ScrollbackBuffer> {
let buf = Arc::new(ScrollbackBuffer::new());
self.buffers.insert(session_id.to_string(), buf.clone());
buf
}
/// Get the scrollback buffer for a session.
pub fn get(&self, session_id: &str) -> Option<Arc<ScrollbackBuffer>> {
self.buffers.get(session_id).map(|entry| entry.clone())
}
/// Remove a session's scrollback buffer.
pub fn remove(&self, session_id: &str) {
self.buffers.remove(session_id);
}
}