feat(mr-issue): repo-less list via user-level endpoints
Summary
Lifts glab mr list and glab issue list from "must be inside a repo" to "works wherever you run it". When there's no -R and no --group, the commands fall through to the user-level endpoints with scope=all, so the caller sees everything they can access.
Most useful for MCP callers running outside any working tree, but the behaviour is the same for everyone — "no scope" used to mean "error out", now it means "show me what I can see".
Refactor: shared MR fan-out helper
internal/api/merge_request.go had two near-identical fan-out helpers (listMRsWithAssigneesOrReviewers for project, listGroupMRsWithAssigneesOrReviewers for group). This MR extracts fanOutMRListByAssigneeReviewer — both existing helpers now delegate to it, and the new user-level path (api.ListAllMRs) uses it too. Net: one source of truth for the per-id loop, dedupe-by-ID, and CreatedAt-desc fallback sort.
Options translation
projectListIssueOptionsToAll and projectListMROptionsToAll translate between project-scoped and user-level option types. A handful of negation fields (NotAuthorID, NotAssigneeID, NotMyReactionEmoji) flip from scalar to slice and get promoted in the process.
On querying the user-level endpoints
The user-level endpoints exist and are documented:
GET /api/v4/issues— docs.gitlab.com/api/issues#list-issuesGET /api/v4/merge_requests— docs.gitlab.com/api/merge_requests#list-merge-requests
This MR calls them via client-go's Issues.ListIssues and MergeRequests.ListMergeRequests. The endpoint's default scope is created_by_me; we explicitly set scope=all so callers see everything they can access.
A default_group config key was considered as a middle tier (repo → config → user-level) but dropped to keep the MR focused. Happy to revisit as a separate proposal if there's interest.
Context
Stack #4 of 6 split out from the closed MR !3154. Builds on !3255.
Test plan
-
go test ./internal/api/... ./internal/commands/mr/list/... ./internal/commands/issuable/list/...passes. -
TestMergeRequestList_NoRepoFallsBackToUserLevelcovers the no-filter fast path;TestMergeRequestList_NoRepoFanOutsAssigneeReviewercovers the multi-id fan-out + dedupe + sort path. - Manually run
glab mr listfrom a non-repo directory and confirm cross-project results appear withShowing N open merge requests on all accessible projects.title.