Skip to content

Add user list, team members --json, and member role markers#250

Merged
schpetbot merged 1 commit into
mainfrom
schpet/push-zpyuquymutvk
Jul 18, 2026
Merged

Add user list, team members --json, and member role markers#250
schpetbot merged 1 commit into
mainfrom
schpet/push-zpyuquymutvk

Conversation

@schpetbot

Copy link
Copy Markdown
Collaborator

Three related gaps in member listing, plus a latent bug found along the way.

team members --json

No JSON output existed. Now emits the connection shape { nodes, pageInfo } with GraphQL field names preserved, matching label list and project list. --json respects --all rather than dumping raw results, and an empty result still emits valid JSON instead of prose.

linear user list (alias u)

There was no way to list everyone in the workspace — only per-team. This queries viewer.organization.users with full pagination.

Why a sibling command and not team members --organization: workspace members are definitionally not team members, so the flag would negate its own noun. The repo's existing scope flags (label list --workspace, project list --all-teams) keep the listed entity fixed and vary the filter. A flag that must throw when combined with the positional team key is the design telling you it's two commands. --workspace <slug> is also already a global option, so a second differently-spelled scope-widening flag would be a trap.

Role markers

Members now render (admin), (owner), and (you) alongside the existing (inactive), (guest), (not assignable), via a shared renderer used by both commands. admin and owner are independent in Linear's schema, so both can show at once.

Bug fix: team members --all was a no-op

getTeamMembers never passed includeDisabled, so Linear defaulted it to false and disabled users were never fetched. The client-side active filter was therefore narrowing a set that could never have contained them — --all could not reveal anyone. includeDisabled is now an explicit required parameter so callers can't silently inherit the default.

The regression test pins includeDisabled in the mock variables, so it fails loudly if the flag stops reaching the API. Verified load-bearing by reverting the fix and watching it fail.

Other notes

  • Pagination sorts globally after all pages are fetched, not per-page. Tests seed page 2 with a name that must sort ahead of page 1's.
  • Both pagination loops throw if Linear reports another page without advancing the cursor, rather than spinning forever.
  • Snapshot fixtures pin lastSeen: null because the renderer formats it with toLocaleString(), which varies by runner TZ/locale.

Verification

Exercised against the real API: role markers render, JSON shape is correct, and user list returns 3 workspace members against 2 team members — confirming the workspace query genuinely returns a different set.

One case could not be verified against live data: the workspace used for QA has no disabled users, so --all returns identical counts there. That path is covered by the mocked regression test only.

Follow-up (not in this PR)

Generated skill docs are not reproducible across machines — the generator's wrap width comes from Deno.consoleSize(), so regenerating on a different terminal reflows unrelated files. Only the genuinely-changed doc files are included here to avoid that churn.

Three related gaps in member listing:

`team members` had no --json output. It now emits the connection shape
({ nodes, pageInfo }) with GraphQL field names preserved, matching label list
and project list.

There was no way to list everyone in the workspace, only per-team. Adds
`linear user list` (alias `u`) querying viewer.organization.users. This is a
sibling command rather than a `team members --organization` flag: workspace
members are definitionally not team members, and a flag that has to error when
combined with the positional team key is the design saying it's two commands.

Members now show admin, owner, and you markers alongside the existing
inactive/guest/not-assignable ones, via a shared renderer.

Along the way this fixes `team members --all`, which was a no-op. getTeamMembers
never passed includeDisabled, so Linear defaulted it to false and disabled users
were never fetched — the client-side `active` filter was narrowing a set that
could not contain them. The regression test pins includeDisabled in the mock
variables, so it fails loudly if the flag stops reaching the API.

Note: the --all fix could not be exercised against real data; the workspace used
for QA has no disabled users.
@schpetbot
schpetbot merged commit 1393c70 into main Jul 18, 2026
15 checks passed
@schpetbot
schpetbot deleted the schpet/push-zpyuquymutvk branch July 18, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants