feat(pairing): chat-native DM sender approval

Replace the file-editing onboarding workflow with a chat-native pairing flow:

- New pairing store (nanobot/pairing/store.py) persists approved senders
  and pending codes in ~/.nanobot/pairing.json.
- DM messages from unknown senders receive a short pairing code instead of
  silent denial. Group chats remain silently ignored.
- Existing allowFrom semantics are fully preserved; approved pairing users
  are merged at runtime so no config migration is needed.
- nanobot pairing list/approve/deny/revoke CLI commands for bootstrap and
  emergency management.
- /pairing slash commands intercepted in-channel so owners can approve
  senders without leaving the chat.
- is_dm flag added to BaseChannel._handle_message; Telegram, Discord and
  WebSocket updated to pass it.

Closes #3768
This commit is contained in:
chengyongru
2026-05-15 15:46:44 +08:00
committed by Xubin Ren
parent c10ec6094e
commit 4c4a9ae590
7 changed files with 415 additions and 10 deletions
+2
View File
@@ -1254,6 +1254,7 @@ class WebSocketChannel(BaseChannel):
chat_id=default_chat_id,
content=content,
metadata={"remote": getattr(connection, "remote_address", None)},
is_dm=True,
)
except Exception as e:
self.logger.debug("connection ended: {}", e)
@@ -1399,6 +1400,7 @@ class WebSocketChannel(BaseChannel):
content=content,
media=media_paths or None,
metadata=metadata,
is_dm=True,
)
return
await self._send_event(connection, "error", detail=f"unknown type: {t!r}")