Commit graph

32 commits

Author SHA1 Message Date
veg
c28101e2e8 refactor: direct roster lookups in cmd_role and cmd_who
cmd_role's TMUX-socket match and cmd_who's --socket branch each walked
every roster via roster_list to find the one record they already knew
the path to. Read that record directly instead. roster_read still
validates the dir basename and ownership, so a non-party socket falls
through to cmd_role's existing fallback loop.
2026-09-21 09:42:03 +00:00
veg
fb92ea1ae7 refactor: extract guest session helpers
The __party_guest_$user session name was spelled out in cmd_join,
cmd_leave, cmd_status, cmd_role, and _disconnect_user. Add
guest_session_name to print it consistently. Add ensure_guest_session
for the has-session/new-session snippet duplicated in cmd_join and
cmd_role. Add caller_present_on for the client-or-guest-session OR
duplicated in cmd_leave and cmd_status.
2026-09-21 09:41:31 +00:00
veg
9544f605a6 refactor: extract resolve_joinable_party from join and knock
cmd_join and cmd_knock both resolved an optional name argument to a
live party via find_party_by_name/pick_live_party with identical error
handling. Share it in one helper.
2026-09-21 09:37:42 +00:00
veg
c789f4985b refactor: log_notify delegates to the generated .party-notify script
log_notify re-implemented the client-fanout loop that .party-notify
(written at host time) already provides. Call that script instead.
Wording changes from "logging this party" to "logging the party" to
match the script's "$user $verb the party" template.
2026-09-21 09:37:13 +00:00
veg
45368232b4 refactor: extract rescue_transcript helper from close and clean
cmd_close and cmd_clean each rescued <party dir>/log to
$HOME/party-<name>-<timestamp>.log before removing the dir, with
close's drain poll as the only difference. Share the mechanism in one
helper and keep each caller's own messages and control flow.
2026-09-21 09:36:49 +00:00
veg
9980d2918a refactor: reuse user_in_group helper for membership checks
cmd_join, cmd_invite, and cmd_list each inlined the id -nG | tr | grep
pipeline instead of calling the existing user_in_group helper. cmd_list
also re-forked id once per party in its loop; now the caller's groups
are captured once before the loop. Also fold user_in_party_group (one
caller) into require_caller_in_group and drop the wrapper.
2026-09-21 09:35:39 +00:00
veg
698fff91ee fix: consistent usage errors for list, leave, status, who, log
list ignored --help and listed parties; leave and status ignored stray
arguments; who silently kept the last of several positionals; log took
a positional name that neither its usage nor the man page documents.
All now follow the parser convention of the other subcommands: help on
-h, exit 2 on an unknown flag or unexpected argument.
2026-09-21 09:33:36 +00:00
veg
9b85485ee8 fix: party list tags the group only when parties differ on it
The tag was shown whenever a party's group differed from
TMUX_PARTY_GROUP, which falls back to 'party' when unset. Since host
time auto-selects the group, a box gating on 'staff' tagged every
line. Compare the visible parties with each other instead.
2026-09-21 09:32:48 +00:00
veg
851cef6941 fix: a signal during party host rolls back and stops
The rollback trap was armed on EXIT INT TERM HUP with a body that did
not exit. After a signal the shell ran the cleanup, then resumed
cmd_host and kept configuring the party dir it had just removed.
Keep the cleanup on EXIT and make the signal traps exit with the
conventional 128+n status.
2026-09-21 09:32:01 +00:00
veg
6c48777553 fix: party log --stop closes only the pipes it opened
Start already skipped panes the host had piped for other purposes,
but --stop swept every pane, killing pipes party log never owned.
Record the pane ids we pipe in .log-panes inside the per-party dir
and close exactly those on --stop; the file dies with the dir.
2026-07-11 16:54:57 +00:00
veg
df9c1cb0dc fix: polish transcript rescue and doc drift from review
Guard HOME for set -u in the rescue paths, surface a failed rescue mv
instead of silently dropping the transcript, and never delete the
party dir after a failed save in either close or clean (close now
refuses to delete and exits nonzero on a failed rescue too, matching
clean, since a message promising the transcript survived followed by
rm -rf was a false assurance). Also stop log --stop from announcing a
stop that never started, and sync README's knock/log/write(1) wording
with the actual behavior.
2026-07-11 13:21:20 +00:00
veg
8d10e62779 feat: party clean rescues an orphaned transcript before deleting
A server crash mid-logged-party is the one case close's rescue can
never have run, and host's EEXIST message funnels the host straight
into clean. Deleting the night's log there is exactly the accident
class the close-time rescue exists for, so clean applies the same
rescue: no quiescence poll needed, the liveness gate just proved the
writers are gone.
2026-07-11 13:13:05 +00:00
veg
aea7ef58b6 feat: party log records a group-readable transcript
tmux pipe-pane on every pane of the party session, appending into
<party dir>/log (0640, party group) so any attendee can grab a copy.
Start and stop are announced to everyone attached; close rescues a
non-empty transcript to the host's home before removing the dir.
Panes opened later are picked up by re-running party log (a
pane_pipe check keeps already-piped panes single-piped, since tmux's
pipe-pane -o toggles an existing pipe closed rather than skipping it).
Raw output, escapes included. Close polls the transcript for size
stability before rescuing it, since a cross-filesystem mv is
copy+unlink and could otherwise drop bytes still draining from the
pipe-pane writers.
2026-07-11 12:59:41 +00:00
veg
a011e4b03c feat: party clean removes the caller's own crash leftovers
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.
2026-07-11 12:32:39 +00:00
veg
6799a57405 feat: party knock asks an invite-only party's host for an invite
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.
2026-07-11 12:24:31 +00:00
veg
7770289d85 feat: auto-select the gating group; 'party' becomes the fallback
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.
2026-07-11 12:20:35 +00:00
veg
6b94255245 refactor: fold is_party_alive into party_conn_state
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.
2026-07-11 12:07:13 +00:00
veg
be3fb049d2 style: reword em-dashes; put colons inside bold run-in labels
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.
2026-07-11 11:57:04 +00:00
veg
938491df1e fix: classify unauthorized by stderr presence, not denial wording
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.
2026-07-04 14:03:53 +00:00
veg
b44a3b705f fix: harden party_self_path; pin (U,R) ACL format; widen breakage comments 2026-07-04 10:42:58 +00:00
veg
44b97e9d6b docs: sync usage() and man page with actual CLI surface 2026-07-04 10:26:44 +00:00
veg
587a462e3c fix: read-only invitees auto-join passive
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.
2026-07-04 10:00:01 +00:00
veg
f3209e39d1 fix: classify unauthorized tmux connections; stop misreporting membership
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>)'.
2026-07-04 09:55:47 +00:00
veg
6cac86bb15 fix: guard non-tty join picker; refuse whitespace PARTY_SOCKET_DIR 2026-07-04 09:50:35 +00:00
veg
0d1b5ef796 fix: exec join attach with quoted args, not an unquoted string 2026-07-04 09:47:04 +00:00
veg
e174226651 fix: quote embedded paths in status-right widget 2026-07-04 09:44:32 +00:00
veg
2ef4eb49ce fix: pin absolute script path in status-right widget
The #() body runs with the tmux server's PATH; a bare 'party' silently
broke the widget for uninstalled or non-standard-prefix hosts.
2026-07-04 09:39:45 +00:00
veg
7d95850461 fix: .party-notify uses PARTY_TMUX, not bare tmux from PATH 2026-07-04 09:25:27 +00:00
veg
fc366f48fa fix: let voice/mute/kick/detach take --party
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.
2026-07-04 09:14:19 +00:00
veg
9117f73423 fix: track the executable bit on party
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.
2026-07-04 08:34:12 +00:00
veg
f06c599ea7 fix: reject '.' and leading '-' in party names
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.
2026-07-04 07:51:38 +00:00
veg
6be0ac1877 Initial pre-release
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.
2026-06-01 15:31:54 +00:00