Skip to content

Cod-e-Codes/marchat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

marchat πŸ§ƒ
⒀⠀⠀⠀⠀⠀⠀⠀⒀⣠⣀⣢⣢⣢⣢⣢⣢⣢⣢⣢⣦⑀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  
⣿⣷⠀⠀⣀⣀⣴⣾⣿⑿⣿⣧⣿⣢⣿⣿⣿⣽⣿⣽⣿⣷⣀⣀⣴⣢⣾⣿⣿⑿⠿⠛⠛⠿⣷⑀⒀⣀⣀⣀⣀⑀⠀⠀⠀⠀  
β ˆβ£Ώβ£Άβ£Ώβ£Ώβ£›β£Ώβ£Άβ£Ώβ£Ώβ£Ώβ£Ώβ£›β£Ώβ£­β£Ώβ£½β£Ώβ£Ήβ£Ώβ£»β£Ώβ‘Ώβ Ώβ ›β ›β ‹β ‰β €β’€β£€β£€β£€β£€β£ˆβ£Ώβ Ώβ Ώβ Ÿβ »β Ώβ’Ώβ‘‡β €β €β €  
β €β’Ήβ£Ώβ£Ώβ£Ώβ£Ώβ‘Ÿβ£Ώβ£―β£Ώβ£Ώβ£Ώβ£Ώβ’Ώβ£Ώβ’»β£Ÿβ£»β‘Ÿβ’Ώβ Ώβ£Ώβ£‡β£„β£ β£€β£΄β£Άβ£Ύβ£Ώβ‘Ώβ Ώβ Ώβ »β Ώβ ‡β €β£€β£€β£€β£€β£Έβ‘‡β €β €β €  
β €β €β’»β£Ώβ£Ώβ£Ώβ£Ώβ‘Ώβ£Ώβ‘›β£Ώβ£₯β£Ώβ£Ώβ£Ώβ£Ώβ’Ώβ‘Ώβ£Ώβ£Ώβ£·β£Ώβ£Ώβ’Ώβ£Ώβ Ώβ Ÿβ ‹β ‰β €β’€β£€β£€β£€β£€β‘˜β£Ώβ£Ώβ Ώβ Ώβ Ώβ’Ώβ‘‡β €β €β €  
β €β €β ˆβ£Ώβ‘β’Ώβ£Ώβ£·β£Ύβ£Ώβ‘Ÿβ’Ώβ£‹β£Ώβ£΄β£Ώβ£Ύβ£·β£Ώβ£·β£Ύβ£Ύβ£Ώβ‘†β €β£€β£€β£€β£Άβ£Ύβ£Ώβ Ώβ Ÿβ ›β »β Ώβ£‡β£€β£ β£€β£€β£Όβ‘‡β €β €β €  
β €β €β €β Έβ£Ώβ‘€β’»β£Ώβ£―β£Έβ£·β£Ύβ‘Ώβ Ÿβ ‹β ‰β €β €β €β €β €β €β €β ˜β£Ώβ£Ώβ Ώβ Ÿβ ›β ‰β’€β£ β£€β£€β£€β£₯⣽⑿⠿⠿⠿⠿⑇⠀⠀⠀  
β €β €β €β €β’»β£·β €β’»β£Ώβ Ÿβ ‹β β €β’€β£ β£€β£΄β£Άβ£Άβ£Άβ£Άβ£Ύβ£Άβ£Ύβ‘β£€β£€β£€β£΄β£Ύβ£Ώβ Ώβ ›β ‹β ‰β ‰β’³β£€β£€β£€β£€β£€β£·β €β €β €  
β €β €β €β €β ˆβ£Ώβ£‡β €β£Ώβ£€β£ β£΄β£Ύβ£Ώβ‘Ώβ Ÿβ ‹β ‰β ‰β €β €β €β ˆβ ‰β£Ώβ Ώβ Ÿβ ›β ‹β β’€β£€β£Άβ£Άβ£Άβ£Άβ£Ύβ Ÿβ ›β ‹β ‰β ‰β’Ώβ €β €β €  
β €β €β €β €β €β ˜β£Ώβ‘†β Έβ£Ώβ‘Ώβ Ÿβ ‹β β’€β£€β£€β£΄β£Άβ£Άβ£Άβ£Άβ£Άβ£Ύβ£‡β£€β£€β£€β£Άβ£Ύβ‘Ώβ ›β ‹β ‰β ‰β ‰β ‰β£€β£΄β£Άβ£Άβ Άβ’Ώβ£‡β €β €  
β €β €β €β €β €β €β’Ήβ£Ώβ‘€β£Ώβ‘„β£€β£€β£Ύβ‘Ώβ Ÿβ ‹β ‰β ‰β β €β €β €β €β‘Ώβ ›β ›β ›β ‰β β£€β£΄β£Ύβ£Ώβ£Ώβ£Ώβ£Ώβ‘Ÿβ ‰β €β €β£€β£€β£Ώβ‘€β €  
β €β €β €β €β €β €β €β’Ώβ£§β’Έβ£Ώβ Ÿβ ‹β β£€β£ β£€β£΄β£Άβ£Ύβ£Ώβ£Ώβ£Ώβ£Ώβ£§β£€β£€β£Άβ Ύβ Ÿβ ›β ‰β’β£€β£€β£€β£€β’°β£Άβ£Ώβ Ώβ Ώβ Ώβ Ώβ£§β €  
β €β €β €β €β €β €β €β ˆβ£Ώβ‘†β£Ώβ£ β£΄β£Ώβ£Ώβ£Ώβ Ώβ Ÿβ ›β ‰β ‰β €β €β’ β‘Ÿβ ‹β ‰β£€β£ β£΄β£Ύβ Ώβ Ώβ Ÿβ ›β ›β ›β£Ώβ β €β €β£€β£€β£€β£Ώβ‘„  
β €β €β €β €β €β €β €β €β Έβ£Ώβ£Ώβ‘Ώβ Ÿβ ‹β β €β €β €β €β €β €β €β €β Έβ£§β£Άβ Ώβ ›β ‹β β €β €β €β €β €β €β ˜β£Ώβ£΄β£Ύβ Ώβ ›β ‹β ‰β ‰β   
β €β €β €β €β €β €β €β €β €β’»β£Ώβ €β €β €β €β €β €β €β €β €β €β €β €β €β ‰β €β €β €β €β €β €β €β €β €β €β €β €β ˆβ β €β €β €β €β €β €β €  
β €β €β €β €β €β €β €β €β €β ˆβ£Ώβ£†β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €  
β €β €β €β €β €β €β €β €β €β €β Έβ£Ώβ‘€β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €  
β €β €β €β €β €β €β €β €β €β €β €β ™β ƒβ €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €  

β–‘β–ˆβ–ˆβ–ˆ     β–‘β–ˆβ–ˆβ–ˆ                                β–‘β–ˆβ–ˆ                      β–‘β–ˆβ–ˆ    
β–‘β–ˆβ–ˆβ–ˆβ–ˆ   β–‘β–ˆβ–ˆβ–ˆβ–ˆ                                β–‘β–ˆβ–ˆ                      β–‘β–ˆβ–ˆ    
β–‘β–ˆβ–ˆβ–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆβ–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–‘β–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ   β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 
β–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆβ–ˆβ–ˆ β–‘β–ˆβ–ˆ       β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆ     β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ       β–‘β–ˆβ–ˆ     β–‘β–ˆβ–ˆ    
β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–‘β–ˆβ–ˆ      β–‘β–ˆβ–ˆ        β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ     β–‘β–ˆβ–ˆ    
β–‘β–ˆβ–ˆ       β–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆ   β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆ      β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆ   β–‘β–ˆβ–ˆ     β–‘β–ˆβ–ˆ    
β–‘β–ˆβ–ˆ       β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆ β–‘β–ˆβ–ˆ       β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–‘β–ˆβ–ˆ    β–‘β–ˆβ–ˆ  β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆ     β–‘β–ˆβ–ˆβ–ˆβ–ˆ 

Go CI MIT License GitHub Repo Go Version cloudflared

Table of Contents


What is this?

marchat is a minimalist terminal-based group chat app designed for real-time, distraction-free conversations. Whether you're pair programming, self-hosting a LAN party, or just chatting from two terminals, it's lightweight, hackable, and built for fun.

Why Marchat?

Built for father-son coding sessions, marchat is about sharing the joy of hacking, learning, and chatting in a terminal. It's a fun, retro-inspired project for anyone who loves the command line, real-time collaboration, or just wants a simple, self-hosted chat.


Features

  • Terminal UI (TUI): Beautiful, scrollable chat using Bubble Tea
  • Real-time WebSocket Chat: Fast, robust, and cross-platform server/client
  • Themes: Choose from patriot, retro, or modern for a unique look
  • Emoji Support: Auto-converts common ASCII emoji (e.g. :), :(, :D, <3, :P) to Unicode
  • Live User List: See who’s online in a fixed-width, styled panel (up to 20 users shown)
  • @Mention Highlighting: Messages with @username highlight for all users in the chat
  • Admin Mode: Privileged commands (like :cleardb) for authenticated admins only
  • Message Cap:
    • Only the last 100 messages are kept in memory for client performance
    • The server database automatically caps messages at 1000; oldest messages are deleted to make room for new ones
  • Configurable: Set username, server URL, and theme via config file or flags
  • Graceful Shutdown: Clean exit and robust connection handling (ping/pong heartbeat)
  • ASCII Art Banner: Server displays a beautiful banner with connection info on startup

Prerequisites

  • Install Go 1.24+ if you haven’t already
    • (Check with go version in your terminal)
  • (Optional, for remote access) Download cloudflared (cloudflared.exe on Windows)

Quick Start

πŸ› οΈ You can configure marchat via flags or a config.json. Flags override config file values.

1. Clone the repo

git clone https://github.com/Cod-e-Codes/marchat.git
cd marchat

2. Install Go dependencies

go mod tidy

3. Build the project

go build ./...

4. Run the server (port 9090, WebSocket)

go run cmd/server/main.go

Optional: Customize admin settings (admin key is the secret used to authorize admin commands):

go run cmd/server/main.go --admin-username YourName --admin-key your-admin-key

5. (Optional) Create a config file

Create config.json in the project root:

{
  "username": "Cody",
  "server_url": "ws://localhost:9090/ws",
  "theme": "patriot",
  "twenty_four_hour": true
}

If you don't have a config file, simply create a new config.json in your project root using the example above. The client will look for this file by default. You can also specify a different path with the --config flag.

6. Run the client

# With flags:
go run client/main.go --username Cody --theme patriot --server ws://localhost:9090/ws

# Or with config file (loaded from current working directory):
go run client/main.go --config config.json

If no flags or config are provided, the client uses default values.


Remote Access (Optional)

If you want to make your marchat server accessible from outside your local network (for example, to chat with friends remotely), you can use Cloudflare Tunnel with cloudflared.

1. Download cloudflared

2. Start a tunnel to your local server

cloudflared tunnel --url http://localhost:9090

This will give you a public https:// URL you can use for your client/server.

3. Update your client config

  • After running the tunnel, Cloudflare will give you a public https://your-tunnel.trycloudflare.com URL.
  • To use it in your client, convert it to a WebSocket URL by replacing https:// with wss:// and appending /ws.

Example: If Cloudflare gives you:

https://bold-forest-cat.trycloudflare.com

You should use:

wss://bold-forest-cat.trycloudflare.com/ws

in your client command like this:

go run client/main.go --username Cody --admin --admin-key your-admin-key --server wss://bold-forest-cat.trycloudflare.com/ws

Note:

  • You do not need to sign up for a Cloudflare account for temporary tunnels.
  • For persistent tunnels or custom domains, see the Cloudflare Tunnel docs.

Usage

  • Send messages: Type and press Enter
  • Quit: Press ctrl+c or Esc to exit the chat
  • Themes: patriot, retro, modern (case-insensitive), or leave blank for default
  • Emoji support: Common ASCII emoticons (e.g. :), :(, :D, <3, :P) automatically convert to Unicode.
    • Supported: :), :(, :D, <3, :P
  • Scroll: Use Up/Down arrows or your mouse to scroll chat
  • Switch theme: Type :theme <name> and press Enter (persists in config)
  • Toggle timestamp format: Type :time and press Enter (persists in config)
  • ASCII art banner: Displays connection info on server startup; can be disabled via config or flag
  • Clear chat (client only): Type :clear and press Enter (clears your local buffer only β€” does not affect others)
  • Clear all messages (wipe DB): Type :cleardb and press Enter (admin only β€” wipes entire database for all users)
  • Banner: Status and error messages appear above chat
  • Mentions: Use @username to highlight a user (full-message highlight, not partial)
  • User List: Up to 20 users are shown in a fixed-width panel, with a styled +N more indicator if more are online

Project Structure

marchat/
β”œβ”€β”€ client/           # TUI client (Bubble Tea)
β”‚   β”œβ”€β”€ main.go
β”‚   └── config/
β”‚       └── config.go
β”œβ”€β”€ cmd/server/       # Server entrypoint
β”‚   └── main.go
β”œβ”€β”€ server/           # Server logic (DB, handlers, WebSocket)
β”‚   β”œβ”€β”€ db.go
β”‚   β”œβ”€β”€ handlers.go
β”‚   β”œβ”€β”€ client.go
β”‚   β”œβ”€β”€ hub.go
β”‚   └── schema.sql
β”œβ”€β”€ shared/           # Shared types
β”‚   └── types.go
β”œβ”€β”€ config.json       # Example or user config file (see Quick Start)
β”œβ”€β”€ go.mod
β”œβ”€β”€ go.sum
└── README.md

Modular architecture: client, server logic, and shared types are separated for clarity and maintainability.


Admin Mode: Privileged Commands & Security

Admin commands like :cleardb require:

  • The --admin flag and a valid --admin-key (case-insensitive username match)
  • Only users listed as admins on the server (via repeated --admin flags) can authenticate as admin
  • All admin actions are performed over WebSocket (no HTTP endpoints)

⚑ Important: Do not use the default admin key (changeme) in production. Change it immediately to avoid security risks.

  • To launch the server with multiple admins:
    go run cmd/server/main.go --admin Cody --admin Crystal --admin-key your-admin-key
  • To connect as admin (WebSocket):
    go run client/main.go --username Cody --admin --admin-key your-admin-key --server wss://localhost:9090/ws
  • Only authenticated admins can use privileged commands like :cleardb.
  • Admin usernames are case-insensitive (e.g. Cody, cody, and CODY are equivalent).
  • The admin key is only sent at handshake, not with every command.
  • The /clear HTTP endpoint and all real_user logic have been removed for security and simplicity.

Security

Production deployment checklist:

  • Change the default admin key (changeme) to a secure value
  • Use wss:// (secure WebSocket) URLs in production, not ws://
  • Ensure firewall rules allow your chosen port (default: 9090)
  • Consider using a reverse proxy (nginx, etc.) for additional security

Tech Stack

Platform Support: Runs on Linux, macOS, and Windows terminals supporting ANSI escape sequences.


Troubleshooting

  • Panic: close of closed channel
    • Fixed: The client now guards against double-close of internal channels.
  • Client fails to connect with http:// URL
    • Use a WebSocket URL: ws://localhost:9090/ws or wss://... for remote.
    • URL schemes: Use ws:// for local development, wss:// for production (secure WebSocket)
  • Mentions not highlighted
    • Use @username exactly (word boundary, not substring).
  • User list not updating
    • Ensure server and client are both up to date and using compatible protocols.
  • Messages not showing or chat not updating
    • Check your WebSocket connection and server logs for errors.
  • Old messages missing from chat history
    • The server database only keeps the most recent 1000 messages. Older messages are automatically deleted.
  • Too many users in user list
    • Only up to 20 users are shown, with a styled +N more indicator if more are online.
  • Cross-platform: Runs on Linux, macOS, and Windows terminals
  • Firewall/Port: Ensure port 9090 is open for remote connections
  • Admin commands
    • All admin commands (like :cleardb) are now fully functional for authenticated admins.

If reporting a bug, please include your version or commit hash.


Contributing

See CONTRIBUTING.md and CODE_OF_CONDUCT.md.


Automation

  • Dependency Updates: marchat uses Dependabot to automatically check for and propose updates to Go module dependencies.
  • Continuous Integration: All pushes and pull requests are checked by GitHub Actions for build, test, and linting. Please ensure your PR passes CI before requesting review.

License

This project is licensed under the MIT License.

About

Terminal-based chat app for remote pair programming, built with Go, Bubble Tea, and pure Go SQLite.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages