Add a 'Your port' field in the settings panel: empty keeps local-network mode with an ephemeral port, a value rebinds the TCP listener to a stable address for dialing over a VPN. Active conversations survive the rebind. Adds controller.set_listen_port and a rebindable transport.start(port).
91 lines
3 KiB
Markdown
91 lines
3 KiB
Markdown
# neotalk
|
|
|
|
A modern peer-to-peer (P2P) chat over IP, with a graphical interface. Inspired
|
|
by the classic Unix `talk`.
|
|
|
|
- **Negotiation** (finding each other and ringing the doorbell) goes over **UDP**.
|
|
- The **conversation** goes over a **direct TCP connection** between the two clients.
|
|
- **End-to-end** encryption (X25519 + AES-GCM).
|
|
- No servers, no accounts, no groups. Nothing is stored: closing loses it.
|
|
- **VPN friendly.** Auto-discovery works on the local network; across a VPN
|
|
(WireGuard, Tailscale…) you connect directly by address. See
|
|
[Connecting over a VPN](#connecting-over-a-vpn-wireguard-tailscale).
|
|
|
|
## Usage
|
|
|
|
```sh
|
|
uv run neotalk --alias yourname
|
|
```
|
|
|
|
Open another instance (on the same machine or another one on the local network)
|
|
and they will find each other. Pick someone from the list, type, and press Enter.
|
|
|
|
Both people must be on the **same local network** for automatic discovery.
|
|
|
|
## Connecting over a VPN (WireGuard, Tailscale…)
|
|
|
|
Automatic discovery uses multicast, which a VPN tunnel does not carry, so you
|
|
will not see each other in the list. The conversation itself is a direct TCP
|
|
connection, though, and that travels over the tunnel fine. Connect by address:
|
|
|
|
1. One of you opens the ⚙ panel and sets a fixed **Your port** (for example
|
|
`51821`) so the address is stable, then Save. Leaving it empty keeps the
|
|
local-network mode with an automatic port. (You can also pass `--port 51821`
|
|
at launch.)
|
|
2. That person shares their address: their **VPN IP** plus that port, for
|
|
example `10.8.0.2:51821`. The ⚙ panel shows your current port.
|
|
3. The other opens the ⚙ panel, types the address into **Connect to
|
|
host:port**, and presses Connect.
|
|
|
|
The conversation opens over the tunnel, end-to-end encrypted as usual.
|
|
|
|
## Running on Windows
|
|
|
|
Two options. Both need [uv](https://docs.astral.sh/uv/), installed once from
|
|
PowerShell:
|
|
|
|
```powershell
|
|
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
```
|
|
|
|
Then get the code (or download the ZIP from the repository and unzip it):
|
|
|
|
```powershell
|
|
git clone https://git.andros.dev/andros/neotalk.git
|
|
cd neotalk
|
|
```
|
|
|
|
### Option A: just run it
|
|
|
|
```powershell
|
|
uv run neotalk --alias yourname
|
|
```
|
|
|
|
uv downloads Python and every dependency the first time; later runs are instant.
|
|
|
|
### Option B: build a standalone `neotalk.exe`
|
|
|
|
```powershell
|
|
uv run --extra build pyinstaller --noconfirm --clean --distpath dist --workpath build/pyinstaller packaging/neotalk.spec
|
|
```
|
|
|
|
The result is a single file at `dist\neotalk.exe`. Double-click it to run, no
|
|
Python required, and copy it anywhere you like.
|
|
|
|
> A Windows executable must be built on Windows: PyInstaller does not
|
|
> cross-compile from macOS or Linux.
|
|
|
|
## Development
|
|
|
|
```sh
|
|
uv run --extra dev pytest # tests
|
|
uv run --extra dev ruff check # lint
|
|
```
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please see the [contribution guidelines](https://git.andros.dev/andros/contribute) for instructions on how to submit issues or pull requests.
|
|
|
|
## License
|
|
|
|
GPL-3.0-or-later.
|