- Home
- Plugins
- UI Enhancements
- dsh-programmer-chatroom
dsh-programmer-chatroom
eavebounty/dsh-programmer-chatroom
Decentralized P2P group chat for DeepSeek Harness (DSH): every machine is a relay server, text moderated offline by an embedded DFA sensitive-word filter, with a WeChat/QQ-style DeepSeek-branded UI.
Install
dsh plugin --profile web add github:eavebounty/dsh-programmer-chatroomREADME
dsh-programmer-chatroom
English · 简体中文
A decentralized P2P group chat for DeepSeek Harness (
dsh). Every machine running DSH becomes a relay server; developers chat while their agents are busy generating. Text is moderated offline on each node by an embedded DFA sensitive-word filter, and the UI follows WeChat/QQ quality with DeepSeek's official blue-purple branding.
Contents
- Overview
- Why decentralized?
- Install
- Quick start
- How P2P works
- Content moderation
- Project layout
- Release
- Contributing
- Architecture
- Security audit
- Rendezvous site / Workers deploy
- Changelog
Overview
- Decentralized mesh: each DSH instance auto-spawns a companion relay (
dshc-relay.js) bound to0.0.0.0, making every machine a real server. Nodes pull/merge messages over HTTP with globalmsgIddedup — no central server, any online machine can relay. - Content moderation: every node filters each message offline with an embedded DFA sensitive-word
filter + Chinese lexicon. Blocked messages never enter the room and are dropped silently — no
records, no monitoring page, zero perceptible feedback (see
docs/SECURITY.md). - WeChat/QQ-style UI: chat bubbles, colored avatars, emoji picker, sticker pack, an ✨ Enjoy button, and a member roster. The panel is a fixed DeepSeek blue-white (light) theme, and the Chat view shows only messages (no node/peer chatter that distracts the conversation).
- Member identity: each machine derives a stable deviceId from its hardware fingerprint (locally unique) and gets an auto-assigned unique avatar color + random, collision-avoided nickname; editable in the Settings tab.
- Display settings: adjust bubble spacing / letter spacing / font size live from Settings (remembered).
- Two network modes: LAN (UDP beacon auto-discovers and directly connects same-subnet DSH nodes) or Internet (one-click cpolar tunnel + announce/pull a Cloudflare-Workers rendezvous site → chat across NAT).
- One-click cpolar tunnel: install command + start/stop inside the Settings tab; the plugin manages the process and stops it (and the site announce) automatically when the chat/plugin closes.
- No persistence: history lives only in the memory of online machines; it disappears when all are off.
Why decentralized?
The DSH plugin Host half exposes only ctx/harness/btoa/atob/TextEncoder/Decoder/console — no
net/dgram/crypto/ws/URL, and some deployments disable web.fetch. So the plugin cannot bind a
public interface or make outbound HTTP itself.
The fix: the plugin uses the host subprocess service to spawn an external Node companion relay
(full stdlib), which does the real networking. The plugin and relay exchange messages over file IPC
(shared filesystem). This is what makes "every machine is a server" achievable inside the DSH plugin sandbox.
Install
This is a standard DSH plugin package, installable from npm and loadable in a DSH web profile.
From npm
# install into your DSH profile (recommended)
dsh plugin --profile web add @eave_bounty/dsh-programmer-chatroom
# or install the npm package globally
npm install -g @eave_bounty/dsh-programmer-chatroom
After installing, restart DSH — the plugin loads automatically and a 💬 Chat button appears in the sidebar footer of your web profile.
From source / local path
dsh plugin --profile web add <path-to-this-repo>
# or
pnpm add file:<path-to-this-repo>
Standalone relay (LAN peers / debugging / NAT)
# run the companion relay on 0.0.0.0
node dshc-relay.js --port 39321 --bind 0.0.0.0 --name nodeA
# optional NAT traversal (STUN + rendezvous + TURN)
node dshc-relay.js --port 39321 --bind 0.0.0.0 --stun stun.l.google.com:19302 --rendezvous http://your-rendezvous:8080 --turn turn.example.com:3478
Test peer client
node dshc-relay-test-peer.js Alice "hello everyone" "sk-should-be-blocked1234567890"
Quick start
- Load the plugin in a DSH session; a 💬 Chat button appears in the sidebar footer.
- Open the floating panel. The Chat view shows only messages.
- Chat tab: read/write messages (Enter to send). Members tab: who is online. Settings tab: edit nickname/avatar color, adjust bubble spacing/letter-spacing/font-size, and switch network mode.
- LAN (default): same-subnet DSH nodes are auto-discovered and connected (UDP beacon) — no manual entry. Manual add is available under Settings → 网络模式.
- Internet (across NAT): Settings → 网络模式 → 互联网, fill your Cloudflare Workers site URL
(deploy per
docs/RENDEZVOUS.md), then 内网穿透 → install cpolar (npm i -g cpolar, free accountcpolar authtoken <token>) → 一键启动穿透. The plugin announces your public URL and pulls peers. The tunnel + announce stop automatically when the chat/plugin closes.
How P2P works
Machine A Machine B
┌────────────────────────────┐ ┌────────────────────────────┐
│ DSH plugin Host │ │ DSH plugin Host │
│ room + DFA moderation │ │ room + DFA moderation │
└──────┬─────────────────────┘ └──────┬─────────────────────┘
│ file IPC (outbox/state) │ file IPC (outbox/state)
▼ ▼
┌────────────────────────────┐ ┌────────────────────────────┐
│ companion relay 0.0.0.0:P │◄──── HTTP pull ─────►│ companion relay 0.0.0.0:P │
│ mesh (msgId dedup) │ │ mesh (msgId dedup) │
└────────────────────────────┘ └────────────────────────────┘
- Same LAN (LAN mode): each relay listens on
0.0.0.0and broadcasts a UDP beacon; discovering a same-subnet node it auto-confirms viaGET http://<ip>:<port>/healthand joins the mesh (no manual entry). Verified: relay/health→ 200. - Across NAT (Internet mode): the relay announces this machine's cpolar public URL to your Cloudflare
Workers rendezvous site and pulls other online nodes' public URLs to connect directly. See
docs/RENDEZVOUS.md. The plugin auto-stops the tunnel and its announce when the chat closes.
Content moderation
- DFA sensitive-word lexicon (embedded Chinese): politics, drugs, gambling/fraud/money-laundering, porn, violence/harassment, malware/attacks, illegal trading.
- Regex augmentation: API keys/secrets, ID-card numbers, phone numbers.
- Blocking is silent and end-to-end: a blocked message is dropped on the sending node before it
can reach any peer (never written to outbox/relay/mesh), and no record is exposed anywhere — no
monitoring page, no sender feedback. See
docs/SECURITY.md. - Edit the
LEXICONarray in the Host half and publish a new Package to change rules.
Project layout
dshc-relay.js # companion relay (full Node; 0.0.0.0; HTTP mesh + UDP beacon + file IPC)
dshc-relay-test-peer.js # LAN test peer client
workers/rendezvous.js # Cloudflare Workers rendezvous site (online node directory)
workers/wrangler.example.toml
docs/ARCHITECTURE.md # architecture & IPC protocol
docs/SECURITY.md # security audit & hardening
docs/RENDEZVOUS.md # rendezvous protocol + Workers deploy
CONTRIBUTING.md # contribution guide
CHANGELOG.md # version history
LICENSE # MIT
Release
- Bump
package.jsonand add aCHANGELOG.mdentry. - Commit and push to
main. - Tag
vX.Y.Zand create a GitHub Release with release notes.
License
MIT © EaveBounty.
修改日志
- 2026-08-20 修复启动失败:
lib/index.js直接访问ctx.harness但未在inject声明,Cordis 严格代理抛「cannot get property "harness" without inject」。改为ctx.get('harness')可选访问(服务不存在时返回 undefined、不等待),harness.handle RPC 集成保持可选。 - 2026-08-20 修复客户端加载失败:
lib/client.js的apply里ctx.styles未在 inject 声明,客户端模块加载时抛「cannot get property "styles" without inject」。移除该访问(CSS 已有document注入回退),客户端正常注册。
Related plugins
dsh-web (dsh-task-board)
zhu1090093659/dsh-web
dsh-web (dsh-web-all)
zhu1090093659/dsh-web
dsh-web-ui (dsh-task-board)
zhu1090093659/dsh-web-ui
dsh-web-ui (dsh-web-ui-all)
zhu1090093659/dsh-web-ui