Install
$ agentstack add skill-wangyendt-wayne-skills-cross-comm ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Pywayne Cross Comm
pywayne.cross_comm.CrossCommService provides WebSocket-based real-time communication between Python and other languages, with built-in file transfer via Aliyun OSS.
Prerequisites
OSS Configuration (required for file/image/folder transfer):
File transfers use Aliyun OSS. Set these environment variables:
# .env file
OSS_ENDPOINT=your-oss-endpoint
OSS_BUCKET_NAME=your-bucket-name
OSS_ACCESS_KEY_ID=your-access-key
OSS_ACCESS_KEY_SECRET=your-access-secret
For more OSS details, see pywayne-aliyun-oss skill.
Quick Start
import asyncio
from pywayne.cross_comm import CrossCommService, CommMsgType
# Server
server = CrossCommService(role='server', ip='0.0.0.0', port=9898)
await server.start_server()
# Client
client = CrossCommService(role='client', ip='localhost', port=9898, client_id='my_client')
await client.login()
Server
Initialize server
server = CrossCommService(
role='server',
ip='0.0.0.0', # Listen on all interfaces
port=9898,
heartbeat_interval=30, # Seconds between heartbeats
heartbeat_timeout=60 # Seconds before marking offline
)
Register message listeners
@server.message_listener(msg_type=CommMsgType.TEXT)
async def handle_text(message):
print(f"From {message.from_client_id}: {message.content}")
@server.message_listener(msg_type=CommMsgType.FILE, download_directory="./downloads")
async def handle_file(message):
print(f"File downloaded: {message.content}")
Start server
await server.start_server() # Blocks until server stops
Get online clients
online_clients = server.get_online_clients() # Returns list of client IDs
Client
Initialize client
client = CrossCommService(
role='client',
ip='localhost', # Server address
port=9898,
client_id='my_client', # Optional: auto-generated if omitted
heartbeat_interval=30,
heartbeat_timeout=60
)
Login and logout
success = await client.login()
if success:
print("Connected!")
# ... communicate ...
await client.logout()
Send messages
# Broadcast to all
await client.send_message("Hello!", CommMsgType.TEXT)
# Send to specific client
await client.send_message("Private", CommMsgType.TEXT, to_client_id='target_id')
# JSON message
await client.send_message('{"key": "value"}', CommMsgType.JSON)
# Dict message
await client.send_message({"type": "data", "value": 123}, CommMsgType.DICT)
# Bytes (auto base64 encoded)
await client.send_message(b"binary", CommMsgType.BYTES)
# File (auto uploads to OSS)
await client.send_message("/path/to/file.txt", CommMsgType.FILE)
# Image (auto uploads to OSS)
await client.send_message("/path/to/image.jpg", CommMsgType.IMAGE)
# Folder (auto uploads to OSS)
await client.send_message("/path/to/folder", CommMsgType.FOLDER)
Get client list
# All clients (online + offline)
all_clients = await client.list_clients(only_show_online=False)
# Returns: {'clients': [...], 'total_count': N, 'only_show_online': False}
# Online only
online = await client.list_clients(only_show_online=True)
Message Types
CommMsgType enum (use these, not strings):
| Type | Description | |------|-------------| | CommMsgType.TEXT | Plain text | | CommMsgType.JSON | JSON string | | CommMsgType.DICT | Python dict | | CommMsgType.BYTES | Binary data | | CommMsgType.IMAGE | Image file | | CommMsgType.FILE | Regular file | | CommMsgType.FOLDER | Folder |
Internal types (auto-handled): HEARTBEAT, LOGIN, LOGOUT, LISTCLIENTS, LISTCLIENTSRESPONSE, LOGINRESPONSE
Message Listener Decorator
# Listen to specific type
@service.message_listener(msg_type=CommMsgType.TEXT)
async def handler(message):
pass
# Listen from specific sender
@service.message_listener(msg_type=CommMsgType.FILE, from_client_id='specific_client')
async def handler(message):
pass
# Listen to all types
@service.message_listener()
async def handler(message):
pass
Note: Listeners automatically filter out messages sent by yourself.
File Download Control
File downloads are controlled via the listener's download_directory parameter:
# Auto-download files to ./downloads
@client.message_listener(msg_type=CommMsgType.FILE, download_directory="./downloads")
async def handle_file(message):
# message.content contains downloaded file path
print(f"Downloaded: {message.content}")
# No auto-download - saves bandwidth
@client.message_listener(msg_type=CommMsgType.FILE, from_client_id='low_priority')
async def handle_file(message):
# message.content contains OSS key, not downloaded
print(f"File available: {message.oss_key}")
# Optionally: client.download_file_manually(message.oss_key, "./manual_downloads/")
Manual download
success = client.download_file_manually(
oss_key="cross_comm/sender_id/123456_file.txt",
save_directory="./downloads"
)
Message Object
@dataclass
class Message:
msg_id: str # Unique message ID
from_client_id: str # Sender ID
to_client_id: str # 'all' or specific client ID
msg_type: CommMsgType # Message type enum
content: Any # Message content
timestamp: float # Unix timestamp
oss_key: Optional[str] # OSS key for file transfers
def to_dict(self) -> Dict: # Convert to dict
@classmethod
def from_dict(cls, data) -> 'Message': # Create from dict
Client ID Generation
If client_id is not specified, it's auto-generated using MAC address + UUID:
- Format:
{mac_address}_{uuid_suffix} - Example:
a1b2c3d4e5f6_abc12345
Command Line
# Run server
python -m pywayne.cross_comm server
# Run client
python -m pywayne.cross_comm client
Important Notes
- File transfer: Requires OSS environment variables; files auto-upload on send
- Async required: All operations are async; use
asyncio.run()orawaitin async context - Heartbeat: Auto-managed; adjust intervals for network conditions
- Message filtering: Use
download_directoryto control auto-downloads and save bandwidth - State persistence: Server saves client status to
cross_comm_clients.yaml - Role-specific methods: Server has
start_server(),get_online_clients(); client haslogin(),logout(),send_message(),list_clients()
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: wangyendt
- Source: wangyendt/wayne-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.