Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dyoburon/jarvis/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Jarvis can send events from Rust to JavaScript in WebViews. JavaScript code registers handlers with window.jarvis.ipc.on() to receive these events.

Receiving Events

JavaScript API

// Register an event handler
window.jarvis.ipc.on('event_name', (payload) => {
    console.log('Received event:', payload);
});

Sending from Rust

use jarvis_webview::ipc::js_dispatch_message;
use serde_json::json;

// Generate JavaScript to dispatch an event
let js = js_dispatch_message(
    "event_name",
    &json!({ "key": "value" })
);

// Execute in the WebView
handle.eval(&js);

Built-in Event Types

Command Palette

palette_show

Show the command palette overlay.
event
string
default:"palette_show"
Event name.
payload
object
Command palette state.
JavaScript:
window.jarvis.ipc.on('palette_show', (data) => {
    // Render command palette UI
    window._showCommandPalette(
        data.items,
        data.query,
        data.selectedIndex,
        data.mode,
        data.placeholder
    );
});
Rust:
let js = js_dispatch_message("palette_show", &json!({
    "items": [
        {
            "label": "New Terminal",
            "keybind": "Cmd+T",
            "category": "Panels"
        },
        {
            "label": "Open Assistant",
            "keybind": "Cmd+G",
            "category": "AI"
        }
    ],
    "query": "",
    "selectedIndex": 0,
    "mode": "command",
    "placeholder": null
}));

handle.eval(&js);

palette_update

Update the command palette state (search results, selection, etc.).
event
string
default:"palette_update"
Event name.
payload
object
Same structure as palette_show.
JavaScript:
window.jarvis.ipc.on('palette_update', (data) => {
    window._updateCommandPalette(
        data.items,
        data.query,
        data.selectedIndex,
        data.mode,
        data.placeholder
    );
});
Rust:
let js = js_dispatch_message("palette_update", &json!({
    "items": filtered_items,
    "query": "new",
    "selectedIndex": 0,
    "mode": "command",
    "placeholder": null
}));

handle.eval(&js);

palette_hide

Hide the command palette.
event
string
default:"palette_hide"
Event name.
payload
{}
Empty object.
JavaScript:
window.jarvis.ipc.on('palette_hide', () => {
    window._hideCommandPalette();
});
Rust:
let js = js_dispatch_message("palette_hide", &json!({}));
handle.eval(&js);

Configuration

config_updated

Notify WebView that configuration has changed.
event
string
default:"config_updated"
Event name.
payload
object
New configuration (partial or full).
JavaScript:
window.jarvis.ipc.on('config_updated', (config) => {
    // Update theme
    if (config.theme) {
        applyTheme(config.theme);
    }
    
    // Update colors
    if (config.colors) {
        updateColors(config.colors);
    }
});
Rust:
let js = js_dispatch_message("config_updated", &json!({
    "theme": {
        "name": "tokyo-night"
    },
    "colors": {
        "primary": "#7aa2f7",
        "background": "#1a1b26"
    }
}));

handle.eval(&js);

Terminal Output

terminal_output

Send terminal output to xterm.js.
event
string
default:"terminal_output"
Event name.
payload
object
data
string
required
Terminal output data (ANSI escaped).
JavaScript:
window.jarvis.ipc.on('terminal_output', (payload) => {
    if (window._xtermInstance) {
        window._xtermInstance.write(payload.data);
    }
});
Rust:
let js = js_dispatch_message("terminal_output", &json!({
    "data": "\x1b[32mHello, World!\x1b[0m\r\n"
}));

handle.eval(&js);

AI Assistant

assistant_message

AI assistant sent a message.
event
string
default:"assistant_message"
Event name.
payload
object
role
string
required
Message role: "user", "assistant", or "system".
content
string
required
Message content.
streaming
bool
Whether this is a streaming chunk.
JavaScript:
window.jarvis.ipc.on('assistant_message', (msg) => {
    if (msg.streaming) {
        // Append to current message
        appendToLastMessage(msg.content);
    } else {
        // Add complete message
        addMessage(msg.role, msg.content);
    }
});
Rust:
let js = js_dispatch_message("assistant_message", &json!({
    "role": "assistant",
    "content": "Hello! How can I help you?",
    "streaming": false
}));

handle.eval(&js);

Presence

presence_update

User presence changed.
event
string
default:"presence_update"
Event name.
payload
object
users
array
required
Array of online users.Each user:
{
  "user_id": "user_123",
  "display_name": "Alice",
  "status": "online",
  "activity": "Playing Wordle"
}
JavaScript:
window.jarvis.ipc.on('presence_update', (data) => {
    updateUserList(data.users);
});

Custom Events

You can send custom events from Rust to JavaScript: Rust:
let js = js_dispatch_message("my_custom_event", &json!({
    "message": "Something happened!",
    "data": { "foo": "bar" }
}));

handle.eval(&js);
JavaScript:
window.jarvis.ipc.on('my_custom_event', (payload) => {
    console.log('Custom event:', payload.message);
    console.log('Data:', payload.data);
});

Event Patterns

Fire-and-Forget

Simple one-way events:
let js = js_dispatch_message("notification", &json!({
    "title": "Build Complete",
    "message": "Your project built successfully"
}));

handle.eval(&js);

Request-Response

For events that need a response, include a request ID: Rust (send request):
let req_id = generate_request_id();

let js = js_dispatch_message("get_selection", &json!({
    "_reqId": req_id
}));

handle.eval(&js);

// Wait for response via IPC message with matching _reqId
JavaScript (send response):
window.jarvis.ipc.on('get_selection', (payload) => {
    const selection = window.getSelection().toString();
    
    window.jarvis.ipc.send('response', {
        _reqId: payload._reqId,
        result: { text: selection }
    });
});

Streaming Events

For streaming data (AI responses, file downloads, etc.): Rust:
// Start stream
let js = js_dispatch_message("stream_start", &json!({
    "id": "stream_123"
}));
handle.eval(&js);

// Send chunks
for chunk in chunks {
    let js = js_dispatch_message("stream_chunk", &json!({
        "id": "stream_123",
        "data": chunk
    }));
    handle.eval(&js);
}

// End stream
let js = js_dispatch_message("stream_end", &json!({
    "id": "stream_123"
}));
handle.eval(&js);
JavaScript:
const streams = new Map();

window.jarvis.ipc.on('stream_start', (payload) => {
    streams.set(payload.id, { buffer: '' });
});

window.jarvis.ipc.on('stream_chunk', (payload) => {
    const stream = streams.get(payload.id);
    if (stream) {
        stream.buffer += payload.data;
        renderStreamContent(stream.buffer);
    }
});

window.jarvis.ipc.on('stream_end', (payload) => {
    streams.delete(payload.id);
});

See Also

Build docs developers (and LLMs) love