sharkord

repository·development·Indexed 23 days ago

https://github.com/sharkord/sharkord

A lightweight, self-hosted real-time communication platform in alpha providing Discord-like voice, video, and screen sharing. Includes a plugin SDK (@sharkord/plugin-sdk) for ecosystem development and a React-based client with components for text and voice channels, device management, and role assignment.

Tokens
38.1K
Snippets
32
Records
235
Agent score
80%

What's inside sharkord

  1. Run Sharkord using Docker

    development

    You can deploy Sharkord using Docker by mapping the necessary TCP and UDP ports for communication and mounting a volume for persistent configuration data.

    Required port mappings:

    • 4991/tcp: Main service port
    • 40000/tcp and 40000/udp: Media ports (for voice/video/screen sharing)
    • Volume: ./data mapped to /home/bun/.config/sharkord for configuration persistence.
    docker run \
      -p 4991:4991/tcp \
      -p 40000:40000/tcp \
      -p 40000:40000/udp \
      -v ./data:/home/bun/.config/sharkord \
      --name sharkord \
      sharkord/sharkord:latest
  2. Install and run Sharkord on Linux

    development

    To run Sharkord as a standalone binary on Linux x64, download the latest release, make it executable, and run it.

    Important Security Note: Upon the first launch, Sharkord generates a secure owner token and prints it to the console. This token provides full owner access to the server. Store this token securely and do not lose it.

    curl -L https://github.com/sharkord/sharkord/releases/latest/download/sharkord-linux-x64 -o sharkord
    chmod +x sharkord
    ./sharkord
  3. Access the Sharkord client interface

    development

    Once the Sharkord server is running, you can access the client interface via a web browser.

    • If running locally: Navigate to http://localhost:4991
    • If running on a remote server: Navigate to http://<SERVER_IP_OR_DOMAIN>:4991
  4. Set up the Sharkord development environment

    development

    To set up a local development environment for Sharkord, ensure you have Bun installed. Follow these steps:

    1. Clone the repository.
    2. Install dependencies by running bun install.
    3. Start the application using one of the following methods:
      • With tmux: Run ./start.sh.
      • Without tmux: Open two terminal sessions and run bun dev in both apps/client and apps/server.

    Note on Data Persistence: Development data (database and uploaded files) is stored in apps/server/data. To perform a clean reset of your development environment, delete the apps/server/data folder.

  5. Use the @sharkord/ui component library

    development

    The @sharkord/ui package provides a collection of reusable UI components and utility functions. You can import individual components directly from the package entry point.

    Available components include:

    • Layout & Containers: Card, Group, Separator, Sheet, Tabs
    • Form Inputs: Button, Checkbox (via Switch), Input, Label, Select, Slider, Textarea, Calendar
    • Feedback & Overlays: Alert, AlertDialog, Dialog, Popover, DropdownMenu, ContextMenu, Tooltip, Sonner (toast notifications)
    • Data Display: Avatar, Badge, Icon, IconButton, LoadingCard, Skeleton
    • Status & Loading: Spinner, LoadingCard, Skeleton
    • Utilities: utils from ./lib/utils
  6. Register UI Components in Plugin Slots

    development

    Sharkord allows plugins to inject React components into specific UI locations called PluginSlots.

    Available slots include:

    • connect_screen (CONNECT_SCREEN)
    • home_screen (HOME_SCREEN)
    • chat_actions (CHAT_ACTIONS)
    • topbar_right (TOPBAR_RIGHT)
    • full_screen (FULL_SCREEN)

    Components are mapped via TPluginComponentsMap, where each plugin provides a mapping of PluginSlot to an array of TPluginReactComponents.

    export enum PluginSlot {
      CONNECT_SCREEN = 'connect_screen',
      HOME_SCREEN = 'home_screen',
      CHAT_ACTIONS = 'chat_actions',
      TOPBAR_RIGHT = 'topbar_right',
      FULL_SCREEN = 'full_screen'
    }
    
    export type TPluginReactComponent = React.ComponentType;
    
    export type TPluginComponentsMapBySlotId = {
      [slot in PluginSlot]?: TPluginReactComponent[];
    };
    
    export type TPluginComponentsMap = {
      [pluginId: string]: TPluginComponentsMapBySlotId;
    };
  7. Understand HTTP error response formats

    development

    The server uses specific JSON structures for error responses depending on the error type encountered during request processing.

    Validation Errors (400 Bad Request): When a ZodError or HttpValidationError occurs, the server returns an errors object where keys are the field names and values are the error messages.

    {
      "errors": {
        "field_name": "error message"
      }
    }

    Generic Errors (400 Bad Request): For malformed requests where the pathname cannot be parsed:

    {
      "error": "Bad request"
    }

    Internal Server Errors (500 Internal Server Error): For unhandled exceptions:

    {
      "error": "Internal server error"
    }

    Not Found (404 Not Found): When no route matches the request:

    {
      "error": "Not found"
    }
  8. How command suggestion filtering works

    development

    When a user types a query after the trigger character, the CommandSuggestion.items function filters the available commands stored in editor.storage.slashCommands.

    Filtering Logic

    1. Search Criteria: A command is included if the query matches its name, pluginId, or description (case-insensitive).
    2. Sorting:
      • Prefix Matches: Commands where the name starts with the query are prioritized.
      • Exactness: Among prefix matches, shorter names are sorted first (e.g., /help before /help-me).
      • Fallback: If no prefix matches exist, the original order is maintained.
    3. Limit: The function returns a maximum of 10 items.
  9. Understand the PluginCommandNode Tiptap extension

    development

    The PluginCommandNode is a Tiptap extension that allows users to insert interactive, command-based nodes into an editor. These nodes represent plugin commands (e.g., /command arg1 arg2) and provide a UI for users to edit command arguments directly within the editor via input fields or select menus.

    Node Attributes

    The node relies on the following attributes to function:

    • pluginId: The unique identifier for the plugin providing the command.
    • commandName: The name of the command (e.g., myCommand).
    • args: A JSON-serialized array of TCommandArg objects defining the expected arguments (name, type, required status).
    • values: A JSON-serialized object containing the current values assigned to the arguments.

    Serialization Behavior

    When rendered to HTML, the node serializes into a <span> with data- attributes. The text content of the node is generated using serializePluginCommandText, which produces a slash-prefixed command string (e.g., /commandName "arg1" 123 true).