feat: debug logging macro + MCP tools inject button in copilot
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m58s
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m58s
Debug logging: - wraith_log!() macro available in all modules, writes to wraith.log - SSH connect/auth, PTY spawn, RDP connect all log with session IDs - MCP startup panic now shows the actual error message Copilot "Tools" button: - Shows when a PTY session is active in the copilot panel - Injects a formatted list of all 18 MCP tools into the chat - Groups tools by category: session, terminal, SFTP, network, utilities - Includes parameter signatures so the AI knows how to call them Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5d1aeb5fe3
commit
357491b4e8
@ -1,3 +1,12 @@
|
||||
// Global debug log macro — must be declared before modules that use it
|
||||
#[macro_export]
|
||||
macro_rules! wraith_log {
|
||||
($($arg:tt)*) => {{
|
||||
let msg = format!($($arg)*);
|
||||
let _ = $crate::write_log(&$crate::data_directory().join("wraith.log"), &msg);
|
||||
}};
|
||||
}
|
||||
|
||||
pub mod db;
|
||||
pub mod vault;
|
||||
pub mod settings;
|
||||
|
||||
@ -89,6 +89,7 @@ impl PtyService {
|
||||
scrollback: &ScrollbackRegistry,
|
||||
) -> Result<String, String> {
|
||||
let session_id = uuid::Uuid::new_v4().to_string();
|
||||
wraith_log!("[PTY] Spawning shell: {} (session {})", shell_path, session_id);
|
||||
let pty_system = native_pty_system();
|
||||
|
||||
let pair = pty_system
|
||||
|
||||
@ -88,6 +88,7 @@ impl RdpService {
|
||||
|
||||
pub fn connect(&self, config: RdpConfig) -> Result<String, String> {
|
||||
let session_id = uuid::Uuid::new_v4().to_string();
|
||||
wraith_log!("[RDP] Connecting to {}:{} as {} (session {})", config.hostname, config.port, config.username, session_id);
|
||||
let width = config.width;
|
||||
let height = config.height;
|
||||
let hostname = config.hostname.clone();
|
||||
|
||||
@ -87,6 +87,7 @@ impl SshService {
|
||||
|
||||
pub async fn connect(&self, app_handle: AppHandle, hostname: &str, port: u16, username: &str, auth: AuthMethod, cols: u32, rows: u32, sftp_service: &SftpService, scrollback: &ScrollbackRegistry, error_watcher: &ErrorWatcher) -> Result<String, String> {
|
||||
let session_id = uuid::Uuid::new_v4().to_string();
|
||||
wraith_log!("[SSH] Connecting to {}:{} as {} (session {})", hostname, port, username, session_id);
|
||||
let config = Arc::new(russh::client::Config::default());
|
||||
let handler = SshClient { host_key_store: HostKeyStore::new(self.db.clone()), hostname: hostname.to_string(), port };
|
||||
|
||||
@ -150,6 +151,8 @@ impl SshService {
|
||||
}
|
||||
}
|
||||
|
||||
wraith_log!("[SSH] Connected and authenticated: {}", session_id);
|
||||
|
||||
// Create scrollback buffer for MCP terminal_read
|
||||
let scrollback_buf = scrollback.create(&session_id);
|
||||
error_watcher.watch(&session_id);
|
||||
|
||||
@ -37,6 +37,14 @@
|
||||
>
|
||||
Kill
|
||||
</button>
|
||||
<button
|
||||
v-if="connected"
|
||||
class="px-2 py-0.5 text-[10px] rounded border border-[var(--wraith-border)] text-[var(--wraith-text-muted)] hover:text-[var(--wraith-text-primary)] cursor-pointer"
|
||||
title="Inject available MCP tools into the chat"
|
||||
@click="injectTools"
|
||||
>
|
||||
Tools
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -226,6 +234,44 @@ async function launch(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function injectTools(): void {
|
||||
if (!sessionId || !connected.value) return;
|
||||
const toolsPrompt = [
|
||||
"You have access to these Wraith MCP tools via the wraith-mcp-bridge:",
|
||||
"",
|
||||
"SESSION MANAGEMENT:",
|
||||
" list_sessions — List all active SSH/RDP/PTY sessions",
|
||||
"",
|
||||
"TERMINAL:",
|
||||
" terminal_read(session_id, lines?) — Read recent terminal output (ANSI stripped)",
|
||||
" terminal_execute(session_id, command, timeout_ms?) — Run a command and capture output",
|
||||
" terminal_screenshot(session_id) — Capture RDP session as PNG",
|
||||
"",
|
||||
"SFTP:",
|
||||
" sftp_list(session_id, path) — List remote directory",
|
||||
" sftp_read(session_id, path) — Read remote file",
|
||||
" sftp_write(session_id, path, content) — Write remote file",
|
||||
"",
|
||||
"NETWORK:",
|
||||
" network_scan(session_id, subnet) — Discover devices on subnet (ARP + ping sweep)",
|
||||
" port_scan(session_id, target, ports?) — Scan TCP ports",
|
||||
" ping(session_id, target) — Ping a host",
|
||||
" traceroute(session_id, target) — Traceroute to host",
|
||||
" dns_lookup(session_id, domain, record_type?) — DNS lookup",
|
||||
" whois(session_id, target) — Whois lookup",
|
||||
" wake_on_lan(session_id, mac_address) — Send WoL magic packet",
|
||||
" bandwidth_test(session_id) — Internet speed test",
|
||||
"",
|
||||
"UTILITIES (no session needed):",
|
||||
" subnet_calc(cidr) — Calculate subnet details",
|
||||
" generate_ssh_key(key_type, comment?) — Generate SSH key pair",
|
||||
" generate_password(length?, uppercase?, lowercase?, digits?, symbols?) — Generate password",
|
||||
"",
|
||||
].join("\n");
|
||||
|
||||
invoke("pty_write", { sessionId, data: toolsPrompt + "\r" }).catch(() => {});
|
||||
}
|
||||
|
||||
function kill(): void {
|
||||
if (sessionId) {
|
||||
invoke("disconnect_pty", { sessionId }).catch(() => {});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user