Draft: feat(orbit-cli): read graph-status from the GitLab GraphQL API

What does this MR do and why?

orbit graph-status now reads the GitLab GraphQL API, not REST graph_status. After this change, the CLI no longer calls REST graph_status, so GitLab can remove that endpoint. Design: snippet 6070846. Server side: !3034 (merged).

How it works

One query. The CLI sends one POST /api/graphql and reads the first orbit object that is not null.

query($fullPath: ID!) {
  group(fullPath: $fullPath) { orbit { ...status } }
  project(fullPath: $fullPath) { orbit { ...status } }
}
fragment status on OrbitNamespace {
  indexing { state areas { name state } projects { indexed totalKnown gaps } }
  itemCounts { domains { name entities { name count } } }
}

ID flags. --namespace-id and --project-id make one extra REST GET to read the full path. Then the CLI sends the same query.

Output. The terminal summary shows one row per indexing area, then Projects. JSON output is the GraphQL orbit object. --response-format llm prints that object as TOON.

BREAKING CHANGE: the JSON and llm output now have the GraphQL orbit shape (indexing, itemCounts), not the REST graph_status body.

Exit codes.

Exit When
0 The status was read.
1 A GraphQL error. If only fields under orbit failed, the CLI prints the data that resolved and the errors on stderr.
2 No such group or project. Or no indexing, and the status endpoint says Orbit is not available for the user.
4 No indexing, and the status endpoint says the user has Orbit, so Orbit is off for the scope or the role is below Reporter. Also an orbit that is null for the token.

The status endpoint always returns 200, so the CLI reads its body and does not use the HTTP code.

Related to #263

  • Duo Agent Platform tokens need gitlab-org/gitlab!264673 (merged). Release the CLI only after that change is deployed on gitlab.com.
  • GitLab MR 1 of the same stack raises the item count limit to 30 per minute per user.

Testing

  • cargo nextest run -p orbit-cli: 267/267. Strict clippy (--all-features -D warnings) passes.
  • Tests cover a full path, the origin remote default, both ID flags, TOON output and a missing scope.
  • They also cover both status-body branches, a null orbit, partial data with a field error, and a top-level error.
  • vm-2 e2e: the CLI output matches REST graph_status for 4 token types and 3 scope flags. The comparison checks 31 entity counts, project coverage and the state.
Token --full-path --namespace-id --project-id
PAT api equal equal equal
PAT read_api equal equal equal
OAuth ai_workflows + mcp equal equal equal
glab credential helper equal equal equal

Terminal summary, before and after, for the same group:

before:  SDLC data indexed · Code indexed · Projects 1 of 1 indexed
after:   agents, ci, code_review, container_registry, core, packages, plan,
         security, source_code: indexed · Projects 1 of 1 indexed

The "In the graph" card and the next-step line do not change.

Performance Analysis

One GraphQL request replaces one REST request. The ID flags add one small GET.

Follow-up: GitLab has no error code for a GraphQL rate limit, so a rate limit exits 1 with the message on stderr, not 5.

  • This merge request does not introduce any performance regression. If a performance regression is expected, explain why.
Agent context: long-form analysis, file-by-file walkthroughs, profiler output, alternatives considered
  • REST and GraphQL calls share one private post_json. It keeps the same auth header and base URL. The ID lookup uses the existing get_bytes.
  • A field error has a path with orbit at index 1. Errors without such a path print nothing and exit 1. The CLI does not match message text.
  • The missing-status check reuses status::select_status_output and error::build_not_found_error.
  • Nullable GraphQL fields are Option types. A null count or state reads as 0 or unknown.
  • No consumer reads the old CLI JSON keys in this repo. The e2e robot suite calls REST graph_status directly; a follow-up MR removes it with GetGraphStatus.

%{all_commits}

Edited by Michael Angelo Rivera

Merge request reports

Loading
Loading