Repository navigation
feat(analytics): show session detail and list participants under --experimental-auth - #1018
Merged
Merged
Conversation
Topherhindman
force-pushed
the
devx-793-cli-session-participants
branch
from
October 9, 2026 02:57
fed8275 to
4859532
Compare
Topherhindman
force-pushed
the
devx-793-cli-session-participants
branch
from
October 9, 2026 05:10
4859532 to
0800de1
Compare
Topherhindman
marked this pull request as ready for review
October 9, 2026 06:27
Picks up the session detail's participants page and connection seconds
(was connection minutes), ListSessionParticipants' sort_by and
sort_order, the split of ParticipantInfo's per-connection fields into
ParticipantDetail, and the removal of the transcript recording file
type.
Also picks up the session detail losing room_id, ParticipantInfo losing
is_active, the agent endpoint token grant, and doc comments: each
participant field's source, and Duration's wire format ("86400s", not
ISO 8601).
Nothing hand-written reads the changed types, so only oapi.gen.go
changes.
Generated from livekit/public-api-server@1124a4d
GetSession dropped the response's detail, so `lk analytics session get`
printed only the list row. It now returns the detail too, and the
command prints the totals (bandwidth and connection time), a summary of
each timeline (points, average and peak over non-empty buckets), and the
first page of participants. --json emits the API's own {session,
detail} response, every timeline point included.
A session whose detail is still being finalized prints its row and says
so. When more participants remain, a hint names `session participant
list` with the detail's cursor; when the detail couldn't read them, it
names the listing alone. Both say to run it with the same flags as this
command, which carry --experimental-auth and --project.
ListSessionParticipants returns one page of a session's participants and
the cursor for the next. ParticipantListOptions takes friendly sort names
("joined" or "left", "asc" or "desc") like SessionListOptions, and its
Validate rejects a negative limit or an unknown name before any request
is sent.
The page limit and cursor are a PageOptions, with its own negative-limit
check and the query params, so every session read that pages can share
them.
`lk analytics session participant list SESSION_ID` pages a session's
participants, one row per identity, with --limit (default 50),
--sort-by (joined or left), --sort-order and a hidden --cursor; the
cursor `session get` prints continues from its first page. Text by
default, with a hint to re-run with --cursor for the next page, and
{items, nextCursor} with --json.
The API-key analytics endpoint has no participant listing, so the
command runs only under --experimental-auth, calls the Public API with
the signed-in user's session token, and refuses to run otherwise before
reading its arguments. sessionRead builds that action from the
command's options reader and fetch function: the gate, the SESSION_ID
argument, the options, so a bad flag fails before the project lookup,
then the client and the project. pageFlags and pageOptions declare and
read --limit and --cursor.
A permission denial says the user doesn't have access to the project.
cloudAPIError would suggest API-key credentials, which this read can't
use.
The session detail's hints named `session participant list` without the `lk analytics` prefix, so they couldn't be run as printed. They now print the full command, like other lk hints (`lk skills update`).
…d names A participant chooses its own identity and name, and the session detail and the participant list printed them as they came. In a terminal an escape sequence in one, such as \x1b]0;pwned\x07 or \x1b[2J, set the window title or cleared the screen; only output that wasn't a terminal had them stripped. stripControls removes the control characters a terminal acts on: C0 controls except tab and newline, DEL, and C1 controls, so no ESC, 8-bit CSI or OSC is left to start a sequence. The participant table runs each identity and name through it. --json needs nothing: JSON escapes control characters itself.
…would A page with no participants but a next cursor printed "No participants found" and then "More participants available", in both the participant list and the session detail. The server counts a page as empty only with no items and no next cursor; renderParticipants now does too, so the empty text never sits beside a hint that there's more.
A NotFound from the participant list fell through to cloudAPIError and printed the server's message alone. The API answers an unknown session and a mistyped --project the same way, so sessionReadError now says "no session RM_... in project p_..." for it. IsNotFound recognizes the NotFound.
Topherhindman
force-pushed
the
devx-793-cli-session-participants
branch
from
October 9, 2026 20:26
0800de1 to
1b3665b
Compare
Whoever creates a room chooses its name, and the session list and the session detail printed it as it came. In a terminal an escape sequence in one, such as \x1b]0;pwned\x07 or \x1b[2J, set the window title or cleared the screen. sessionRow now runs the room name through dashText, as the participant table does with identities and names. A session's tags aren't printed in text mode, so they need nothing; the test carries escapes in them too, so a tags column can't add them back unnoticed. --json escapes both itself.
JackNDwyer
approved these changes
Oct 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes DEVX-793
Based on main.
Depends on livekit/public-api-server#48.
Under
--experimental-auth,lk analytics session getnow prints the session detail the Public API returns: totals, a summary of each timeline, and the first page of participants. The newlk analytics session participant listpages through the rest. This PR also adds the pieces the later session reads in this stack share:PageOptions,pageFlagsandsessionRead.What changed
chore(public)):oapi.gen.gois regenerated from livekit/public-api-server@1124a4d. It picks up the session detail's participants page, connection seconds (was connection minutes), the session detail losingroom_id,ListSessionParticipants'sort_byandsort_order, and the removal of the transcript recording file type. Nothing hand-written reads the changed types, so onlyoapi.gen.gochanges.feat(public)):GetSessionreturns the detail next to the list row. The detail is nil while the server is still finalizing it.ListSessionParticipantsreturns one page of a session's participants and the cursor for the next.ParticipantListOptionstakes friendly sort names (joinedorleft,ascordesc), likeSessionListOptions. ItsValidaterejects a negative limit or an unknown name before any request is sent.PageOptionsholds a page's limit and cursor, with its own negative-limit check and query params, so every session read that pages can share it.feat(analytics)):session getprints the list row, then the totals (bandwidth in and out, connection time), one row per timeline (points, and average and peak over non-empty buckets), and the first page of participants.--jsonprints the API's own{session, detail}response, every timeline point included. A session whose detail is still being finalized prints its row and says so.session getprints a hint with the fulllk analytics session participant listcommand and the detail's cursor. When the detail couldn't read them, the hint names the listing alone. Both say to use the same flags assession get, which carry--experimental-authand--project.session participant list SESSION_IDpages a session's participants, one row per identity.--jsonprints{items, nextCursor}.sessionReadbuilds the action of a session read that only the Public API serves. It refuses to run without--experimental-authbefore anything else. Then it readsSESSION_IDand the options, so a bad flag fails before the project lookup.pageFlagsandpageOptionsdeclare and read--limitand--cursor.cloudAPIErrorwould suggest API-key credentials, which this read can't use.Usage
--limitdefaults to 50, and the server caps a page at 100.--cursoris hidden. A page with more after it prints a hint to re-run with its--cursor.--experimental-auth,session participant listfails withthis command is only available under --experimental-auth (user-based auth).session getkeeps using the API-key endpoint there.session getprints the totals, then the timelines and participants, and ends with the hint when more participants remain:Since review
Testing
go build ./...,go vet ./pkg/... ./cmd/lk/andgo test ./pkg/... ./cmd/lk/pass on every commit.pkg/public:TestGetSessionReturnsDetail(the detail, and nil while finalizing),TestGetSessionMissingSession,TestListSessionParticipantsQueryandTestListSessionParticipantsRejectsBadOptions.pkg/public/render:TestSessionDetailText,TestSessionDetailTextLastParticipantsPage,TestSessionDetailTextParticipantsUnread,TestSessionDetailTextFinalizing,TestSessionDetailJSONandTestSessionParticipantsPage.cmd/lk:TestParticipantListOptions,TestParticipantListRequiresExperimentalAuth,TestFetchSessionParticipants,TestFetchSessionParticipantsErrorsandTestSessionAPIError.Before merge
main: Update actions/checkout action to v3 #48 was squash-merged. Regenerate from public-api-servermainso theGenerated fromline names amaincommit.Not in this PR