Skip to main content
Glama
mkXultra
by mkXultra
DataScanner.ts3.17 kB
import { promises as fs } from 'fs'; import { join } from 'path'; import { RoomScanResult, FileStats, PresenceData } from './types/management.types'; import { getDataDirectory } from '../../utils/dataDir'; export class DataScanner { private dataDir: string; constructor(dataDir: string = getDataDirectory()) { this.dataDir = dataDir; } async scanRoomDirectory(roomName: string): Promise<RoomScanResult> { const messagesPath = join(this.dataDir, 'rooms', roomName, 'messages.jsonl'); const presencePath = join(this.dataDir, 'rooms', roomName, 'presence.json'); // Get file stats and message count const messageStats = await this.getFileStats(messagesPath); const messageCount = messageStats.exists ? await this.countLines(messagesPath) : 0; // Get online users count const onlineUsers = await this.countOnlineUsers(presencePath); return { messageCount, onlineUsers, storageSize: messageStats.size }; } async getFileStats(filePath: string): Promise<FileStats> { try { const stats = await fs.stat(filePath); return { size: stats.size, exists: true }; } catch (error) { // File doesn't exist return { size: 0, exists: false }; } } async countLines(filePath: string): Promise<number> { try { const content = await fs.readFile(filePath, 'utf8'); if (!content.trim()) { return 0; } const lines = content.trim().split('\n'); let validCount = 0; for (const line of lines) { try { JSON.parse(line); validCount++; } catch { // Skip invalid JSON lines } } return validCount; } catch (error) { return 0; } } async countOnlineUsers(presencePath: string): Promise<number> { try { const content = await fs.readFile(presencePath, 'utf8'); const presence: PresenceData = JSON.parse(content); return Object.values(presence.users || {}).filter(user => user.status === 'online').length; } catch (error) { return 0; } } async getUsersData(presencePath: string): Promise<{[agentName: string]: { status: 'online' | 'offline' | 'away'; lastSeen?: string }}> { try { const content = await fs.readFile(presencePath, 'utf8'); const presence: PresenceData = JSON.parse(content); return presence.users || {}; } catch (error) { return {}; } } async getAllRooms(): Promise<string[]> { try { const roomsPath = join(this.dataDir, 'rooms.json'); const content = await fs.readFile(roomsPath, 'utf8'); const rooms = JSON.parse(content); return Object.keys(rooms.rooms || {}); } catch (error) { return []; } } async getRoomDirectories(): Promise<string[]> { try { const roomsDir = join(this.dataDir, 'rooms'); const entries = await fs.readdir(roomsDir, { withFileTypes: true }); return entries .filter(entry => entry.isDirectory()) .map(entry => entry.name); } catch (error) { return []; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mkXultra/agent-communication-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server