Skip to main content

Overview

The jarvis-social crate provides social and collaboration features:
  • Presence tracking (who’s online)
  • Real-time chat
  • Channels and direct messages
  • Game invites and pokes
  • Experimental: Voice chat, screen sharing, pair programming

Public API

Identity

Represents the local user.
use jarvis_social::Identity;

let identity = Identity {
    user_id: "user_123".to_string(),
    display_name: "Alice".to_string(),
};

PresenceClient

Manages presence tracking via Supabase Realtime.
use jarvis_social::{PresenceClient, PresenceConfig};

let config = PresenceConfig {
    supabase_url: "https://xxx.supabase.co".to_string(),
    supabase_anon_key: "eyJ...".to_string(),
    channel_name: "jarvis:presence".to_string(),
};

let client = PresenceClient::new(config);
client.connect(identity).await?;
PresenceConfig
struct

PresenceEvent

Events emitted by the presence system.
PresenceEvent
enum
  • UserJoined { user: OnlineUser } — A user came online
  • UserLeft { user_id: String } — A user went offline
  • UserUpdated { user: OnlineUser } — A user’s status/activity changed
  • Snapshot { users: Vec<OnlineUser> } — Full list of online users

Protocol Types

UserStatus

User presence status.
UserStatus
enum
  • Online — Available
  • Idle — Away from keyboard
  • InGame — Playing a game
  • InSkill — Using an AI skill
  • DoNotDisturb — Do not disturb
  • Away — Away

OnlineUser

Information about an online user.
OnlineUser
struct

Chat

ChatHistory

Manages chat message history.
use jarvis_social::{ChatHistory, ChatHistoryConfig, ChatMessage};

let config = ChatHistoryConfig {
    max_messages: 1000,
    persist_to_disk: true,
};

let mut history = ChatHistory::new(config);
history.add_message(ChatMessage {
    user_id: "user_123".to_string(),
    display_name: "Alice".to_string(),
    content: "Hello!".to_string(),
    timestamp: chrono::Utc::now().to_rfc3339(),
});
ChatMessage
struct

Channels

ChannelManager

Manages multiple chat channels.
use jarvis_social::{ChannelManager, Channel};

let mut manager = ChannelManager::new();
manager.create_channel("general".to_string());
manager.join_channel("general");
Channel
struct
Represents a chat channel.

Broadcast Payloads

These payloads are sent via Supabase Realtime broadcasts.

ActivityUpdatePayload

ActivityUpdatePayload
struct

GameInvitePayload

GameInvitePayload
struct

PokePayload

PokePayload
struct

ChatMessagePayload

ChatMessagePayload
struct

Experimental Features

These features require the experimental-collab feature flag.

Voice Chat

#[cfg(feature = "experimental-collab")]
use jarvis_social::{VoiceManager, VoiceConfig, VoiceRoom};

let config = VoiceConfig::default();
let manager = VoiceManager::new(config);

Screen Sharing

#[cfg(feature = "experimental-collab")]
use jarvis_social::{ScreenShareManager, ScreenShareConfig, ShareQuality};

let config = ScreenShareConfig {
    quality: ShareQuality::High,
    frame_rate: 30,
};
let manager = ScreenShareManager::new(config);

Pair Programming

#[cfg(feature = "experimental-collab")]
use jarvis_social::{PairManager, PairConfig, PairRole, PairSession};

let config = PairConfig::default();
let manager = PairManager::new(config);
PairRole
enum
  • Driver — Has control of the terminal
  • Navigator — Can view and suggest

Usage Example

use jarvis_social::{
    PresenceClient, PresenceConfig, PresenceEvent,
    Identity, UserStatus
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = PresenceConfig {
        supabase_url: std::env::var("SUPABASE_URL")?,
        supabase_anon_key: std::env::var("SUPABASE_KEY")?,
        channel_name: "jarvis:presence".to_string(),
    };
    
    let identity = Identity {
        user_id: "alice_123".to_string(),
        display_name: "Alice".to_string(),
    };
    
    let mut client = PresenceClient::new(config);
    client.connect(identity).await?;
    
    // Update status
    client.update_status(UserStatus::Online, Some("Coding in Rust")).await?;
    
    // Listen for events
    while let Some(event) = client.next_event().await {
        match event {
            PresenceEvent::UserJoined { user } => {
                println!("{} joined", user.display_name);
            }
            PresenceEvent::UserLeft { user_id } => {
                println!("User {} left", user_id);
            }
            _ => {}
        }
    }
    
    Ok(())
}