diff --git a/party b/party index 6c435a4..f2812c7 100755 --- a/party +++ b/party @@ -30,16 +30,19 @@ Usage: party [args] Hosting: host [name] [--group ] Start a party on a dedicated tmux server. - close Tear down the party you host. + Names: letters, digits, '_', '-' (max 63). + close [name] Tear down the party you host (name it when + you host several). Joining: join [name] [--passive] Join a party. Without name: auto-pick or numbered prompt. --passive lands in the host's session (mirrored view). + Read-only invitees always join passive. leave Detach from the party you joined. role [active|passive|switch] Flip your clients between guest session and host session. -Moderation (host only): +Moderation (host only; --party disambiguates multiple parties): invite [-r] Add user to allowlist (read/write; -r for read-only). voice Promote user to read/write (alias: rw). mute Demote user to read-only (alias: ro). @@ -48,7 +51,8 @@ Moderation (host only): Info: list List discoverable parties on this host. - who [--short] Show invited and attached users for the active party. + who [--short] [--party ] + Show invited and attached users for a party. status Show the caller's own party state. --help This message. --version Print version. @@ -113,8 +117,10 @@ user_in_party_group() { } # Soft assertion: caller is in TMUX_PARTY_GROUP. Fails loudly with -# remediation instructions when not. Used by every subcommand that -# touches the roster or socket. +# remediation instructions when not. Called by cmd_host before any +# filesystem work; the other subcommands don't need it — non-members +# are stopped by the FS perimeter itself (EACCES at the per-party dir) +# and get the friendlier group-gate message in cmd_join. require_caller_in_group() { if ! user_in_party_group "$USER"; then cat >&2 <&2; exit 2 ;; diff --git a/party.1 b/party.1 index b7c06b2..114c207 100644 --- a/party.1 +++ b/party.1 @@ -23,18 +23,23 @@ .Cm invite .Ar user .Op Fl r +.Op Fl -party Ar name .Nm .Cm voice .Ar user +.Op Fl -party Ar name .Nm .Cm mute .Ar user +.Op Fl -party Ar name .Nm .Cm kick .Ar user +.Op Fl -party Ar name .Nm .Cm detach .Ar user +.Op Fl -party Ar name .Nm .Cm role .Op Cm active | passive | switch @@ -43,6 +48,7 @@ .Nm .Cm who .Op Fl -short +.Op Fl -party Ar name .Nm .Cm status .Sh DESCRIPTION @@ -99,6 +105,16 @@ server. With no .Ar name , a random one is generated. +Names may use letters, digits, +.Ql _ +and +.Ql - , +up to 63 characters. +Dots are not accepted: +.Xr tmux 1 +silently rewrites +.Ql \&. +in session names, which would desync the party name from its session. Only the host is on the allowlist; invite others explicitly with .Cm invite . Group precedence: @@ -128,9 +144,15 @@ The read-only boundary is set at attach time and is not toggled by later .Cm role changes. +An invitee added with +.Cm invite Fl r +is read-only and always joins passive: +.Xr tmux 1 +refuses session creation from read-only clients, so an active join is +not possible. .It Cm leave Detach from the current party and clean up the per-guest session. -.It Cm invite Ar user Op Fl r +.It Cm invite Ar user Op Fl r Op Fl -party Ar name Add .Ar user to the allowlist as read/write. @@ -141,30 +163,40 @@ invites as a watcher. Best-effort .Xr write 1 ping is sent if available. +.Fl -party Ar name +selects the party when you host more than one. Host-only. -.It Cm voice Ar user +.It Cm voice Ar user Op Fl -party Ar name Promote .Ar user to read/write. Alias: .Cm rw . +.Fl -party Ar name +selects the party when you host more than one. Host-only. -.It Cm mute Ar user +.It Cm mute Ar user Op Fl -party Ar name Demote .Ar user to read-only. Alias: .Cm ro . +.Fl -party Ar name +selects the party when you host more than one. Host-only. -.It Cm kick Ar user +.It Cm kick Ar user Op Fl -party Ar name Revoke .Ar user Ns 's invite, disconnect their client, and kill their guest session. +.Fl -party Ar name +selects the party when you host more than one. Host-only. -.It Cm detach Ar user +.It Cm detach Ar user Op Fl -party Ar name Disconnect .Ar user Ns 's client and kill their guest session, but keep them on the allowlist. +.Fl -party Ar name +selects the party when you host more than one. Host-only. .It Cm role Op Cm active | passive | switch Flip your clients between the guest session and the host session. @@ -181,10 +213,18 @@ has no read-only flag .Pc . .It Cm list List live parties on this host from the roster. -.It Cm who Op Fl -short +Parties whose +.Cm server-access +allowlist does not include you are shown as +.Ql invite-only +with the host to ask; a party you cannot see at all is either dead or +outside your group. +.It Cm who Op Fl -short Op Fl -party Ar name Show invited and attached users for the current party. .Fl -short emits a compact form suitable for a status-line widget. +.Fl -party Ar name +selects a party you are not currently hosting. .It Cm status Show the caller's own state: hosting, attached, or idle. .El @@ -208,6 +248,9 @@ Where each party's per-party private directory (and its socket and roster) is created. Default .Pa /tmp . +Must not contain whitespace; +.Cm host +refuses such a directory. .It Ev PARTY_TMUX .Xr tmux 1 binary to use.