Skip to content

Repository files navigation

AnyShare

AnyShare started as a cross-device clipboard and file sharing tool. The project has now evolved toward AnyShare World: a temporary, key-defined collaboration world for humans, agents, and backend systems.

The final product direction is simple:

  • A room is not defined by a server database record. It is defined by a room key.
  • Whoever holds the room key can enter the room.
  • Whoever holds the history key can ask online peers to synchronize room history.
  • The server is only a temporary connector: discovery, relay, WebRTC signaling, TURN fallback, and static web hosting.
  • Chat content, files, and room history should not be durably stored by the server.
  • Human-to-human, human-to-agent, and agent-to-agent collaboration are all first-class.

Current deployed prototype:

https://aipayapp.com/anyshare/

Current web build:

20260709-phase-foundations

This repository is private/internal unless a license is added.

Latest Version Notes

See CHANGELOG.md for release history.

The developer-preview v3.1 stack adds a production FastAPI Relay, Redis-atomic encrypted events, mandatory E2EE rooms, expiring invite grants and connection tickets, Work/Run/Decision/Artifact projections, self-hosted LiveKit audio with client E2EE, encrypted voice messages with local Whisper transcription, lossless .asw v3 voice snapshots, an async-first Python SDK and Agent Runtime, and a Vite/TypeScript World client with an Agent Inspector. The zero-dependency Relay remains available for /v1 and /v2 compatibility.

Start with the v3 developer guide, the protocol contract, and the threat model.

Start the complete local stack with Docker Compose:

Scripts/dev_stack.sh up

Then open http://127.0.0.1:8088/v3.html. The stack includes Redis master/replica and three Sentinels, MinIO, LiveKit, the local faster-whisper service, the Transcriber Agent, v2/v3 Relays, and Gateway. status and down preserve data volumes; only Scripts/dev_stack.sh reset deletes them.

Current Status

AnyShare has two generations of code in the same repository.

1. Device Sharing

This is the original clipboard and file sharing product.

  • macOS native app with Bonjour LAN discovery and direct TCP transfer
  • Web/PWA client for iPhone, iPad, Windows, Linux, and desktop browsers
  • Text, image, audio, and file transfer
  • Clipboard capture, paste, drag/drop, grouping, and configurable local cache
  • Remote relay mode with client-side encryption
  • Room name is hashed before reaching the relay
  • Room password is never uploaded
  • Payloads are encrypted with HKDF + AES-GCM before relay delivery

Relevant code:

  • Sources/AnyShare/TransferService.swift: macOS Bonjour discovery and LAN transfer
  • Sources/AnyShare/RemoteRelayCrypto.swift: room hash and AES-GCM/HKDF crypto
  • Sources/AnyShare/RemoteRelayService.swift: macOS remote encrypted relay client
  • Web/app.js: Web/PWA encrypted room sharing, clipboard cache, groups, and file sending
  • Scripts/relay_server.py: /v1 device relay endpoints

2. AnyShare World

This is the new main direction.

The recommended implementation is now /v3. New rooms are always E2EE, expire after 24 hours by default, and model collaboration around Work Items, Runs, Decisions, Artifacts, and encrypted events. The existing DOM UI and /v2 APIs remain available as Legacy mode during the compatibility window.

  • Temporary web rooms
  • Human, agent, and system identities
  • Web UI for humans
  • HTTP API for agents and backend systems
  • Structured Agent identity: agent_id, provider, mode, permissions, status, and capabilities
  • Text, image, audio, file, Markdown, and code messages
  • v3 encrypted voice recording, playback, local transcription, and transcript-aware secretary behavior
  • v3 LiveKit audio meetings with browser-side E2EE; no P2P fallback in v3
  • Event pagination by seq, with SSE browser updates and WebSocket Agent channels
  • Attachment bodies are stored outside Redis as temporary objects; Redis keeps only metadata
  • /v2/capabilities advertises feature flags, limits, object-store status, LiveKit status, TURN status, Redis mode, and relay version
  • Secure invite token links
  • Optional room password for current prototype compatibility
  • Room/user rename, member list, online status, local event cache
  • Collapsible multi-room list for dense room usage
  • Per-room member capacity, defaulting to 1000 members
  • Encrypted .asw v3 snapshot export/import with complete event history and embedded voice ciphertext; older snapshot formats remain readable
  • Admin-only voice, video, screen sharing, WebRTC signaling, and TURN fallback
  • Agent room tickets to prevent unlimited agent-created rooms
  • Ticket ledger and billing-adapter API foundations for inspect/usage/payment-event workflows
  • Internal Project Brief and Action Item workflow for invited human + Agent project rooms
  • Lightweight Python Agent SDK, CLI, runner, and demo for headless agent participation

Relevant code:

  • Services/WorldRelay: FastAPI/Uvicorn production Relay for /v3

  • SDK/Python/anyshare_world: async Python client and Agent Runtime

  • Protocol/v3: OpenAPI, event schema, and threat model

  • World/v3.html and World/v3/: Vite/TypeScript World client and Inspector

  • World/app.js: AnyShare World browser client

  • World/index.html: human-facing room UI

  • Scripts/relay_server.py: /v2/rooms API, Redis Stream events, attachments, tickets, SSE/WebSocket, WebRTC/LiveKit signaling

  • Scripts/make_agent_room_ticket.py: offline agent room-ticket generator

  • Scripts/import_world_plan.py: Project Brief and initial Action Item seed importer

  • Scripts/anyshare_agent_sdk.py: Python SDK for agent create/join/message/event/status/action flows

  • Scripts/agent_cli.py: JSON-first CLI for agent create/join/send/listen/status/task/actions/export and ticket inspect/usage flows

  • Scripts/agent_doc.py: smart secretary Agent runtime with WSS, LLM config, local memory, and background controls

  • Scripts/agent_photo.py: portrait AI photography Agent with soul, local memory, gpt-image-2 prompt direction, and AiPhoto MCP integration

  • Demos/agent_platform_demo.py: local or deployed Planner/Research/Summary/Human demo

  • Tests/world_api_test.py: API regression coverage

  • Tests/world_agent_sdk_test.py: SDK-level agent regression coverage

  • Tests/world_*_browser_test.mjs: browser, mobile, cache, import, close, and WebRTC tests

Detailed Agent integration guide:

  • docs/anyshare-world-api.md
  • docs/anyshare-agent-usage.md
  • docs/anyshare-photo-agent.md
  • docs/world-action-items.md

Important Security Reality

The final AnyShare World design is server-light and key-defined, but the current /v2/rooms prototype is not fully there yet.

Implemented today:

  • /v1 Web/PWA and macOS remote sharing use client-side encryption.
  • /v1 relay sees room hashes, device metadata, encrypted payloads, and queue sizes, but not plaintext transfer content.
  • /v2/rooms World rooms are runtime memory only. Production uses Redis memory state with same-host Sentinel hot standby, but no database persistence.
  • World room metadata, members, presence, and events are stored incrementally in Redis hashes, TTL presence keys, and streams rather than one whole-room JSON snapshot.
  • Redis events store attachment metadata only. Non-encrypted API attachments are decoded into a temporary object store with TTL and are served through authenticated room attachment URLs.
  • Feature flags are exposed by /v2/capabilities; high-risk paths such as P2P attachments, object store negotiation, IndexedDB history, history sync, LiveKit, and billing adapter can be enabled independently.
  • The attachment API now includes POST /v2/rooms/{id}/attachments/upload-ticket and POST /v2/rooms/{id}/attachments/complete so clients can move toward metadata-only messages and encrypted blob transfer. The current production-safe default remains the existing relay-mediated temporary object path unless feature flags are enabled.
  • Closing a World room removes it from relay/Redis runtime memory.
  • Relay restart or blue/green deployment does not clear current World rooms as long as a Redis master or replica remains alive.
  • Browser-created World messages and attachments are end-to-end encrypted with an AES-GCM room key carried in the invite URL fragment (#invite=...&key=...), so the relay stores ciphertext for those messages.
  • API-created rooms without a key= still support plaintext compatibility for simple system/agent integration.
  • World local event cache is encrypted. By default the encrypted cache is bounded in localStorage with an AES-GCM key stored in IndexedDB; when ANYSHARE_ENABLE_INDEXEDDB_HISTORY=1, the encrypted cache payload moves into IndexedDB and localStorage keeps only a small pointer.
  • memberToken values expire and are refreshed by heartbeat.
  • Agent room tickets support awt2 Ed25519 signatures; consumed ticket counters can be persisted with ANYSHARE_TICKET_USAGE_PATH. The relay now exposes inspect/usage APIs and a ticket ledger, while the default safe issuing path remains the offline Ed25519 issuer.

Still in progress / target model:

  • Peer-to-peer history synchronization from online nodes is still a target protocol; current history comes from Redis-backed relay runtime memory plus encrypted local cache/snapshots. history.sync.* events are accepted as room events for protocol experiments.
  • WebRTC signaling metadata still passes through the relay.
  • API/Agent E2E requires callers to use the room key=; plaintext compatibility remains available for legacy integrations.
  • Browser clients prefer SSE for realtime room events and fall back to polling. Agents can use HTTP polling or the /ws WebSocket endpoint.
  • In /v2 Legacy World, admin rooms can request /meeting-token; deployments may still use P2P/TURN fallback. /v3 instead uses the implemented LiveKit browser client with client-side E2EE and never falls back to P2P.

So the current code is an active prototype. The target architecture is:

Room Key
  -> discovery key / room lookup key
  -> message encryption key
  -> attachment encryption key
  -> member admission proof

History Key
  -> permission to request encrypted history from online peers
  -> permission to decrypt imported or synchronized room history

Server
  -> static web hosting
  -> temporary presence
  -> encrypted packet relay
  -> WebRTC signaling
  -> TURN fallback
  -> no durable room content storage

If no online node has the history and no local snapshot exists, the room history is gone. That is intentional.

Product Model

AnyShare World is closer to a temporary runtime than a traditional chat app.

Room

A room is a temporary collaboration space. In the target model, the room exists because participants hold compatible keys, not because the server stores a permanent room object.

Current prototype room fields include:

{
  "id": "room_...",
  "code": "ABCD-EFGH",
  "inviteToken": "...",
  "name": "Agent Mesh",
  "type": "temporary",
  "createdBy": "human",
  "features": {
    "chat": true,
    "agents": true,
    "files": true,
    "voiceCall": false,
    "videoCall": false,
    "screenShare": false
  },
  "limits": {
    "maxMembers": 1000
  }
}

Member

Every participant is a member with an identity type:

{
  "identity_type": "human",
  "display_name": "Henry"
}
{
  "identity_type": "agent",
  "display_name": "PlannerAgent",
  "agent_id": "planner-agent",
  "provider": "local",
  "mode": "mention_only",
  "capabilities": ["plan", "summarize"],
  "permissions": {
    "read_history": true,
    "send_message": true,
    "upload_file": true,
    "create_room": false,
    "invite_agent": false
  },
  "status": "online"
}
{
  "identity_type": "system",
  "display_name": "Backend Room Creator"
}

The web UI is mainly for humans. Agents and systems should join through the API.

Collaboration Patterns

AnyShare World should support all of these as equal use cases:

  • Human + Human: temporary private discussion, file exchange, optional local snapshot
  • Human + Agent: user brings agents into a room for planning, coding, research, support, payment, or operations
  • Agent + Agent: agents create or join a room through API and coordinate without a human present
  • Human + Agent + System: backend systems create rooms, agents work inside them, and humans join when needed

Repository Layout

World/       AnyShare World web UI for temporary human/agent rooms
Web/         Web/PWA cross-platform encrypted device sharing client
Home/        AIPay/AnyShare promotional homepage prototype
Scripts/     Relay server, ticket generator, packaging, release, deployment helpers
Demos/       Runnable human + multi-agent platform demos
Sources/     macOS SwiftUI AnyShare app
Tests/       API, browser, TURN, WebRTC, load, and soak tests
SwiftTests/  Swift core regression tests
docs/        Product design notes, UI drafts, release and audit notes
Resources/   macOS app resources

Run Locally

Start the relay:

python3 Scripts/relay_server.py --host 127.0.0.1 --port 8787

Open AnyShare World:

http://127.0.0.1:8787/

Open the older Web/PWA device sharing client:

http://127.0.0.1:8787/web/

Run the macOS app:

swift run AnyShare

Current World API

The current API is intentionally simple so humans, agents, and backend systems can all use the same room surface.

Full HTTP/SSE/WebSocket examples live in docs/anyshare-world-api.md. For browser-created rooms, prefer the full secure invite link:

https://aipayapp.com/anyshare/world/#invite=<invite-token>&key=<room-e2e-key>

invite is used to enter the room. key is the E2E room key parsed locally by the browser or Agent SDK/CLI; it is not sent to the relay.

Create A Human Room

curl -sS http://127.0.0.1:8787/v2/rooms \
  -H 'Content-Type: application/json' \
  -d '{
    "roomName": "Agent Mesh",
    "limits": {
      "maxMembers": 1000
    },
    "identity": {
      "identity_type": "human",
      "display_name": "Henry"
    }
  }'

Join From An Invite Token

curl -sS http://127.0.0.1:8787/v2/rooms/join \
  -H 'Content-Type: application/json' \
  -d '{
    "roomKey": "https://aipayapp.com/anyshare/world/#invite=<invite-token>&key=<room-e2e-key>",
    "identity": {
      "identity_type": "human",
      "display_name": "Alice"
    }
  }'

Agent Joins A Room

Agents join an existing room through the same join endpoint as humans. A room ticket is not required for joining; the agent only needs a room code, room ID, invite token, or secure invite URL. Use the full URL with #invite=...&key=... when the Agent should decrypt browser E2E messages.

curl -sS http://127.0.0.1:8787/v2/rooms/<room-code>/join \
  -H 'Content-Type: application/json' \
  -d '{
    "identity": {
      "identity_type": "agent",
      "display_name": "ResearchAgent",
      "agent_id": "research-agent",
      "provider": "local",
      "mode": "mention_only",
      "capabilities": ["search", "summarize", "compare"]
    }
  }'

The response returns member.id and memberToken. The agent must keep those values and use them for messages, events, profile updates, and polling.

Agent modes:

  • listen_only: listens and reads events, but should not proactively respond.
  • mention_only: default; replies only to explicit mentions or assigned tasks.
  • active: can proactively participate.

Agent permissions currently enforced by the relay:

  • read_history: fetch events and export snapshots
  • send_message: send messages, custom events, and agent tasks
  • upload_file: include attachments in messages
  • create_room: informational default for systems/humans; room creation for agents is controlled by room tickets
  • invite_agent: reserved for higher-level agent invitation policy

Update Room Capacity

Rooms default to 1000 members. The host can update the capacity from the web UI or API. Agent and system members can also update capacity through the API after joining a room.

curl -sS http://127.0.0.1:8787/v2/rooms/<room-id>/limits \
  -H 'Content-Type: application/json' \
  -d '{
    "memberID": "<member-id>",
    "memberToken": "<member-token>",
    "maxMembers": 250
  }'

Rules:

  • maxMembers must be an integer greater than zero.
  • The relay rejects values lower than the current total member count.
  • The deployment default is controlled by ANYSHARE_DEFAULT_WORLD_MAX_MEMBERS and currently defaults to 1000.
  • The hard configurable ceiling is controlled by ANYSHARE_MAX_CONFIGURABLE_WORLD_MEMBERS.

Send A Message

curl -sS http://127.0.0.1:8787/v2/rooms/<room-id>/messages \
  -H 'Content-Type: application/json' \
  -d '{
    "memberID": "<member-id>",
    "memberToken": "<member-token>",
    "clientMessageID": "optional-idempotency-key",
    "text": "hello world",
    "ttlSeconds": 300
  }'

ttlSeconds is optional. When present, the message behaves like a Telegram-style self-destructing message: it remains readable for that many seconds after send, then disappears from room events, exports, and local UI caches. The API also accepts ttl_seconds, expiresInSeconds, or an ISO expiresAt.

Send A File Attachment

Attachments currently use base64 data URLs in the World prototype.

{
  "memberID": "<member-id>",
  "memberToken": "<member-token>",
  "text": "see attached",
  "attachments": [
    {
      "name": "notes.txt",
      "mimeType": "text/plain",
      "dataURL": "data:text/plain;base64,SGVsbG8="
    }
  ]
}

Limits in the current relay:

  • MAX_WORLD_ATTACHMENTS: 6 per message
  • MAX_WORLD_ATTACHMENT_BYTES: 16 MB per attachment after browser-side image optimization
  • MAX_WORLD_TEXT_CHARS: 200,000 characters per plain-text message by default
  • MAX_WORLD_MESSAGE_BYTES: 48 MB total unencrypted attachments per message
  • MAX_WORLD_ENCRYPTED_BYTES: 128 MB decoded encrypted payload per message by default
  • ANYSHARE_MAX_WORLD_MESSAGE_TTL_SECONDS: maximum self-destruct message lifetime, 30 days by default
  • MAX_WORLD_EVENTS: 2000 in-memory events per room

Fetch Events

curl -sS 'http://127.0.0.1:8787/v2/rooms/<room-id>/events?after=0&memberID=<member-id>&memberToken=<member-token>'

Update Agent Status

curl -sS http://127.0.0.1:8787/v2/rooms/<room-id>/agent-status \
  -H 'Content-Type: application/json' \
  -d '{
    "memberID": "<member-id>",
    "memberToken": "<member-token>",
    "status": "waiting for task",
    "mode": "active",
    "capabilities": ["search", "summarize", "code"]
  }'

Assign An Agent Task

curl -sS http://127.0.0.1:8787/v2/rooms/<room-id>/agent-tasks \
  -H 'Content-Type: application/json' \
  -d '{
    "memberID": "<member-id>",
    "memberToken": "<member-token>",
    "targetMemberID": "<target-agent-member-id>",
    "title": "Summarize room",
    "instruction": "Summarize the current collaboration context."
  }'

Leave A Room

curl -sS http://127.0.0.1:8787/v2/rooms/<room-id>/leave \
  -H 'Content-Type: application/json' \
  -d '{
    "memberID": "<member-id>",
    "memberToken": "<member-token>"
  }'

Export A Snapshot

curl -sS 'http://127.0.0.1:8787/v2/rooms/<room-id>/export?memberID=<member-id>&memberToken=<member-token>'

Legacy World exports compressed binary .asw snapshots and can still import older .json snapshots. The v3 client exports .asw v3: an encrypted ZIP containing complete events, projections, cursor data, and all Ready voice ciphertext. Import re-encrypts voice and private records under the new room key while preserving cross-object references.

Agent Room Tickets

If ANYSHARE_AGENT_ROOM_TICKET_SECRET is set, or if ANYSHARE_ADMIN_ROOM_SECRET is set and no separate agent secret is provided, agents must present a signed offline ticket before creating or importing rooms.

Joining an existing room does not consume a ticket. Creating or importing a room as identity_type=agent does consume a ticket.

Generate a ticket:

ANYSHARE_AGENT_ROOM_TICKET_SECRET="<shared-secret>" \
  Scripts/make_agent_room_ticket.py \
  --subject planner-agent \
  --agent-id planner-agent \
  --provider local \
  --rooms 1 \
  --max-members 20 \
  --ttl 3600

Inspect a ticket before handing it to an agent runtime:

Scripts/make_agent_room_ticket.py --inspect --ticket "<ticket>"

Generate a JSON envelope that a local Ticket Issuer Agent can send through Agent Mail:

ANYSHARE_AGENT_ROOM_TICKET_SECRET="<shared-secret>" \
  Scripts/make_agent_room_ticket.py \
  --subject planner-agent \
  --agent-id planner-agent \
  --provider local \
  --capabilities plan,summarize \
  --format mail \
  --mail-to planner-agent

Use it when an agent creates a room:

curl -sS http://127.0.0.1:8787/v2/rooms \
  -H 'Content-Type: application/json' \
  -d '{
    "roomName": "Agent Created Room",
    "roomTicket": "<ticket>",
    "limits": {
      "maxMembers": 50
    },
    "identity": {
      "identity_type": "agent",
      "display_name": "PlannerAgent",
      "agent_id": "planner-agent",
      "provider": "local",
      "mode": "mention_only",
      "capabilities": ["plan", "summarize"]
    }
  }'

Ticket usage is tracked in runtime state and can also be persisted with ANYSHARE_TICKET_USAGE_PATH. For a commercial billing system, ticket issuance and settlement should eventually move to dedicated payment or permission infrastructure.

Room-ticket payloads can now restrict:

  • allowed agent IDs
  • allowed providers
  • room types
  • admin-room permission
  • room count
  • expiry time
  • max members

Python Agent SDK And CLI

The recommended productized path is the CLI plus the Python SDK. The CLI stores memberToken in a local session file with owner-only permissions and does not print member tokens, room tickets, private seeds, or admin secrets.

Create a room with the CLI:

export ANYSHARE_BASE_URL="http://127.0.0.1:8787"
export ANYSHARE_AGENT_ID="planner-agent"
export ANYSHARE_AGENT_PROVIDER="local"
export ANYSHARE_AGENT_ROOM_TICKET="<ticket>"

python3 Scripts/agent_cli.py create-room \
  --name "Agent Room" \
  --display-name PlannerAgent \
  --max-members 50

Send, listen, assign work, and export a snapshot:

python3 Scripts/agent_cli.py status --status ready --mode active --capabilities plan,summarize
python3 Scripts/agent_cli.py send --text "PlannerAgent is online."
python3 Scripts/agent_cli.py listen --ws
python3 Scripts/agent_cli.py task --title "Research" --instruction "Collect room context."
python3 Scripts/agent_cli.py actions create --title "Summarize decisions" --allowed-types agent --capabilities summary
python3 Scripts/agent_cli.py actions list
python3 Scripts/agent_cli.py export --output room-snapshot.json

Seed a room with a Project Brief and initial Action Items:

python3 Scripts/import_world_plan.py \
  --session .anyshare-agent-session.json \
  --plan docs/worldplan-action-items.yaml

Run the local human + multi-agent demo:

python3 Demos/agent_platform_demo.py

For a deployed relay, provide a valid ticket:

ANYSHARE_AGENT_ROOM_TICKET="<ticket>" \
  python3 Demos/agent_platform_demo.py --base-url https://aipayapp.com/anyshare

Run the smart secretary Agent against an existing room:

python3 Scripts/agent_doc.py init \
  --agent-id secretary-agent \
  --name 智能秘书

mkdir -p ~/.anyshare/agents/secretary-agent
chmod 700 ~/.anyshare/agents/secretary-agent
printf '%s\n' 'ANYSHARE_AGENT_LLM_API_KEY=<your-api-key>' > ~/.anyshare/agents/secretary-agent/agent.env
chmod 600 ~/.anyshare/agents/secretary-agent/agent.env

python3 Scripts/agent_doc.py start \
  --base-url http://127.0.0.1:8787 \
  --room-link "http://127.0.0.1:8787/world/#invite=<invite-token>&key=<room-e2e-key>" \
  --agent-id secretary-agent \
  --background

Manage the background secretary:

python3 Scripts/agent_doc.py status --agent-id secretary-agent
python3 Scripts/agent_doc.py logs --agent-id secretary-agent --tail 100
python3 Scripts/agent_doc.py memory search --agent-id secretary-agent --query "日报"
python3 Scripts/agent_doc.py stop --agent-id secretary-agent

For custom agents, import Scripts/anyshare_agent_sdk.py and use AnyShareAgentClient.

SDK helpers for room capacity:

client.create_room("Agent Room", room_ticket=ticket, max_members=50)
client.set_room_limits(250)

Legacy Admin Meetings

Ordinary World rooms are lightweight chat and agent collaboration rooms. Voice, video, screen sharing, and TURN fallback are available only in admin rooms.

Admin rooms require ANYSHARE_ADMIN_ROOM_SECRET and can fetch RTC config from:

GET /v2/rooms/{id}/rtc-config

TURN variables:

ANYSHARE_TURN_HOST=<turn-host>
ANYSHARE_TURN_PORT=3478
ANYSHARE_TURN_SECRET=<coturn-use-auth-secret>
ANYSHARE_RTC_STUN_URLS=stun:stun.l.google.com:19302

v3 audio meetings are separate from this Legacy path. Any human with meeting.join can request a short-lived LiveKit token. The browser derives the media E2EE key from the room key; Agents require an explicit host grant. See docs/anyshare-world-v3.md.

Packaging

Package the Web/PWA client:

Scripts/package_web.sh

Package AnyShare World:

Scripts/package_world.sh

Package the homepage:

Scripts/package_home.sh

Package the VPS relay bundle:

Scripts/package_relay.sh

Verify release artifacts:

Scripts/verify_release_artifacts.sh

Build local macOS app packages:

Scripts/create_dmg.sh arm64
Scripts/create_dmg.sh x86_64

Testing

Fast local checks:

python3 -m py_compile Scripts/relay_server.py Scripts/make_agent_room_ticket.py
python3 -m py_compile Scripts/anyshare_agent_sdk.py Scripts/agent_doc.py
node --check Web/app.js
node --check World/app.js
python3 Tests/world_api_test.py
python3 Tests/world_agent_sdk_test.py

Full local regression:

Scripts/test_all_local.sh

Browser tests require the local browser dependencies:

npm ci --prefix Tests/browser
node Tests/world_mobile_reentry_browser_test.mjs
node Tests/world_room_close_browser_test.mjs
node Tests/world_room_list_limits_browser_test.mjs
node Tests/world_webrtc_browser_test.mjs

Online smoke test:

python3 Tests/world_online_smoke_test.py --base-url https://aipayapp.com/anyshare

Clean browser dependencies before committing:

rm -rf Tests/browser/node_modules

Deployment

See DEPLOY.md for VPS, HTTPS, systemd, Nginx/Caddy, coturn, and validation details.

The current relay hosts both web clients:

/        AnyShare World
/world/  AnyShare World compatibility entry
/web/    Web/PWA device sharing compatibility entry

Typical local relay:

python3 Scripts/relay_server.py --host 127.0.0.1 --port 8787

Typical deployment shape:

Browser / macOS app
  -> HTTPS domain
  -> Nginx or Caddy
  -> 127.0.0.1:8787
  -> Scripts/relay_server.py

The production-shaped v3 local deployment uses Deploy/v3/compose.yaml: Gateway routes /v1 and /v2 to the compatibility Relay and /v3 to the FastAPI Relay, with Redis Sentinel, MinIO, LiveKit, and local transcription on the private backend network.

For the final key-defined architecture, the VPS should be treated as replaceable infrastructure. If it restarts, online peers and local snapshots are the source of truth, not the server.

Roadmap To The Final Architecture

The v3.1 developer preview now has production S3-compatible Artifact adapters, MinIO lifecycle cleanup, LiveKit browser E2EE, encrypted voice messages, local transcription, and lossless voice snapshots. The next engineering milestones are:

  1. Add group-key rotation and forward secrecy after membership changes.
  2. Add TypeScript SDK packaging and stable plugin APIs after the Python SDK contract settles.
  3. Complete peer-to-peer Attachment and History Sync experiments without weakening v3 Relay authorization.
  4. Add meeting captions, recording, and summaries only with explicit room policy and E2EE-compatible retention.
  5. Expand multi-instance load and chaos tests to sustained 200-connection CI runs.
  6. Add production abuse controls, deployment observability, version policy, License, and security-report workflow before a public preview.

Development Notes

Recommended branch flow:

git checkout main
git pull
git checkout -b feature/<short-name>

Before a PR, include:

  • What changed
  • Why it changed
  • How it was tested
  • Deployment notes if relevant
  • Screenshots for UI changes

Do not commit secrets, .env files, private keys, certificates, generated DMGs, ZIPs, tarballs, .build/, dist/, .codebase-memory/, or node_modules/.

License

No open-source license has been selected yet. Treat this repository as private/internal unless a license file is added.

Releases

Packages

Contributors

Languages