How the IRC-Style Command Interface Works in Bitchat Android

Bitchat Android processes IRC-style slash commands through a centralized CommandProcessor.kt class that parses user input starting with "/" and dispatches actions to ChannelManager, PrivateChatManager, or MessageManager while providing autocomplete suggestions for commands and mentions.

Bitchat Android is an open-source mesh chat application that implements a lightweight IRC-style command line for controlling chat operations. The entire command pipeline lives in the CommandProcessor.kt class, which acts as a bridge between the Compose-based UI and the underlying mesh networking services. This architecture keeps the command logic pure and testable while cleanly separating UI concerns from mesh transport operations.

Command Entry Point and Parsing

The detection mechanism starts when the UI layer identifies user input beginning with the "/" character. The text is immediately forwarded to the processCommand() function in CommandProcessor.kt, which accepts the following parameters:

fun processCommand(
    command: String,
    meshService: MeshService,
    myPeerID: String,
    onSendMessage: (String, List<String>, String?) -> Unit,
    viewModel: ChatViewModel? = null
): Boolean

If the input string does not start with "/", the method returns false and the Compose UI treats the text as a regular chat message destined for the current transport layer (BLE mesh, Tor, or geohash channel). When a command is detected, the processor splits the string on whitespace, converts the first token to lowercase, and uses a Kotlin when clause to dispatch execution to the appropriate handler.

Core Command Handlers

The CommandProcessor implements dedicated handler functions for each supported slash command. All handlers ultimately invoke MessageManager.addMessage() to create a BitchatMessage with sender = "system", ensuring command feedback renders consistently alongside regular chat bubbles.

Channel Management (/join, /pass, /channels)

  • handleJoinCommand processes /join or /j to create or enter a channel, optionally accepting a password parameter. Upon success, it emits a system message confirming the join operation.
  • handlePassCommand allows channel creators to set or change passwords using /pass, enforcing creator-only privileges before updating the channel state.
  • handleChannelsCommand responds to /channels by listing all currently joined channels via the ChannelManager.

Private Messaging (/msg, /clear)

  • handleMessageCommand handles /msg or /m by looking up the target nickname, initiating a private chat session through PrivateChatManager, and optionally transmitting an initial message payload.
  • handleClearCommand executes /clear to purge messages from the current view, whether in a private chat, specific channel, or the global interface, depending on the active ChatState.

User Discovery and Moderation (/who, /block, /unblock)

  • handleWhoCommand implements /who or /w to display online peers for mesh channels or list participants for geohash-based location channels, emitting the results as a system message.
  • handleBlockCommand blocks a peer by nickname or displays the current block list when invoked via /block.
  • handleUnblockCommand removes a peer from the block list using /unblock or shows usage help if arguments are missing.

Action Commands (/hug, /slap)

Both commands route through handleActionCommand with predefined parameters. The /hug command sends "gives [user] a warm hug 🫂" while /slap transmits "slaps [user] around a bit with a large trout 🐟". These create styled action messages that appear distinct from standard text in the chat view.

Error Handling

When users enter an unrecognized command, handleUnknownCommand generates a system notice informing them that the command is not supported, preventing silent failures.

Autocomplete and Mention Suggestions

The processor provides two UI-friendly features to enhance usability in CommandProcessor.kt:

Command Autocomplete – updateCommandSuggestions() filters the static baseCommands list (plus channel-specific extras) against the current input string, updating ChatState.commandSuggestions so the Compose UI can render a dropdown menu.

Mention Autocomplete – updateMentionSuggestions() builds candidate lists from mesh peers or geohash participants, filtering by the text typed after the "@" symbol. Utility functions filterCommands() and filterMentionCandidates() handle deduplication and sorting before the results reach the UI layer.

UI Integration and Message Flow

The integration follows a predictable pattern across all commands:

// In the Compose ChatScreen when user taps "Send"
val input = "/join #general"
val handled = commandProcessor.processCommand(
    command = input,
    meshService = meshService,
    myPeerID = myPeerId,
    onSendMessage = { _, _, _ -> /* transport callback */ },
    viewModel = chatViewModel
)

if (!handled) {
    // Fallback: transmit as normal mesh message
}

When processCommand() returns true, the UI skips the regular message transmission path. Handlers interact with ChannelManager, PrivateChatManager, or MeshService to modify state, then generate system messages through MessageManager. This creates a consistent feedback loop where command results appear immediately in the chat history.

Summary

  • CommandProcessor.kt serves as the single entry point for all IRC-style slash commands in Bitchat Android.
  • The processCommand() function returns a Boolean distinguishing commands from regular messages based on the "/" prefix.
  • Ten core commands including /join, /msg, /who, /block, /hug, and /slap dispatch to specific handlers that manage channels, private chats, and peer moderation.
  • All handlers emit feedback through MessageManager.addMessage() using system-sender messages that blend into the chat UI.
  • Built-in autocomplete supports both command names and @mentions via updateCommandSuggestions() and updateMentionSuggestions().

Frequently Asked Questions

What file contains the IRC command logic in Bitchat Android?

The entire command interface implementation resides in CommandProcessor.kt, a pure Kotlin class located in the repository source tree. This file contains the parser, dispatch logic, and autocomplete functionality.

How does Bitchat Android distinguish between commands and regular chat messages?

The processCommand() function checks if the input string starts with "/" and returns false if it doesn't. When false is returned, the Compose UI layer treats the input as a standard chat message and sends it through the appropriate mesh transport (BLE, Tor, or geohash).

Which commands support autocomplete in the Bitchat Android interface?

All base commands (such as /join, /msg, /who, /channels) support autocomplete through updateCommandSuggestions(). Additionally, the @mention feature provides autocomplete for peer nicknames via updateMentionCandidates(), drawing from currently visible mesh peers or geohash participants.

Can users create custom IRC commands in Bitchat Android?

No, the command set is static and defined within the when clause of CommandProcessor.kt. Users cannot define custom slash commands without modifying the source code and recompiling the application, as the dispatcher relies on a closed set of handler functions mapped to specific command strings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →