Turns the manual rm -rf recovery from host's EEXIST message into a
verb, behind the same gates cmd_close uses: own-basename glob, no
symlinks, ownership check, and a dead socket. Live parties are skipped
with a pointer to party close.
party list already shows invite-only parties; knock closes the loop.
The knocker can't run any tmux command against the server, so the
channel is write(1), the same one invite uses toward guests, except
here delivery failure is surfaced: the ping is the whole feature.
Bare 'party host' now walks staff, users, wheel, party and gates on
the first group the caller belongs to, announcing the pick. Boxes
where people already share a system group need no setup; the curated
'party' group remains the fallback and the explicit --group /
TMUX_PARTY_GROUP paths are unchanged. Caller membership is the only
probe (id -nG, portable everywhere); whether a guest is a member stays
an invite-time warning, where it can actually be answered.
One liveness primitive instead of two. The PID argument was a vestige
(format-checked, never probed, since the kill -0 removal); dropping it
means a roster with a garbage SERVER_PID can no longer mask a live
socket in host/moderation/role resolution.
Punctuation sweep across README, ROADMAP, and the script's comments:
em-dashes become colons, commas, or parentheses; bold list labels take
the colon inside the bold with lowercase text after. Comments only in
the script, no code changes.
Review flagged the 'access not allowed' substring:
if tmux's denial text drifts while keeping exit 0, unauthorized
connections would classify as ok and the false-joined status/leave
misreporting would silently return. A clean authorized list-clients
writes nothing to stderr (verified 3.3a/3.5a/3.6-SunOS, incl. invited
read-only clients), so rc 0 plus any stderr output now classifies as
unauthorized: no message text consulted. Drift in any direction
degrades to a hidden party, never to a false ok.
tmux refuses new-session from read-only clients ('client is
read-only'), so an active join for an -r invitee died under set -eu
with a raw tmux error. Detect the R flag on the caller's ACL line in
the existing preflight and fall back to the mirrored view.
tmux answers non-allowlisted users with 'access not allowed' on stderr
and exit 0 for every command (verified 3.3a/3.5a, two users), so
has-session reports any target as existing. party status claimed
uninvited group members were joined, party leave silently 'succeeded',
and party list printed bogus '0 attendee(s)' rows. New party_conn_state
(ok/unauthorized/dead) classifies by message content; list now shows
'invite-only (ask <host>)'.
A host of two or more parties was told 'pass a name' by commands that
accepted no name flag, making moderation impossible. Mirrors the
--party flag invite already had.
The script was committed mode 100644; a fresh clone could not run
./party, and the bats suite fails with EACCES 126 wherever it invokes
"$PARTY_BIN" directly. Makefile installs masked this via install -m 0755.
tmux session_check_name() silently rewrites '.' to '_', so a dotted
party name desyncs from its tmux session and every -t lookup fails
(verified on tmux 3.3a through 3.6b). Leading-dash names can never be
addressed through the CLI parsers.
tmux-party: share a tmux session with people on the same UNIX host.
Single-file POSIX shell (party) with a filesystem + tmux server-access
trust model. See README.md.