From b3b7a2f83d99f6bcaf0d7560bd0f7e4110d87c6d Mon Sep 17 00:00:00 2001 From: Docs Test Date: Fri, 4 Sep 2026 10:08:30 -0400 Subject: [PATCH 1/4] feat: show stack position in the pull request list Maintainers working through a stack had to open each pull request to learn whether it was stacked and where it sat. The sidebar showed workspace, review, and CI indicators but nothing about stacks, so a stacked pull request looked the same as a standalone one. Each list row now carries a compact stack indicator: the stack icon followed by the pull request's position and the stack size, for example "4/7". It sits just before the CI cluster in the row's indicator group. The list API returns this placement directly so the sidebar does not fetch the full stack context for every row. Only stacks with more than one visible member are reported, matching when the detail view shows its stack chip. Members hidden as removed upstream are excluded and the remaining members are renumbered, so the list and the detail view always agree on position and size. The detail view's stack chip drops the word "Stacked" from its visible label. The icon already says that, so the chip now shows just the position and size. The accessible name keeps the full wording for screen readers. Generated with Claude Code (claude-fable-5-1) Co-authored-by: Claude Fable 5.1 --- context/platform-sync-invariants.md | 7 ++- frontend/openapi/openapi.yaml | 17 ++++++ frontend/src/lib/api/generated/schema.ts | 13 +++++ .../lib/components/detail/StackStatus.svelte | 2 +- .../lib/components/sidebar/PullItem.svelte | 27 +++++++++ .../lib/components/sidebar/PullItem.test.ts | 14 +++++ frontend/tests/e2e/stack-status.spec.ts | 11 +++- internal/apiclient/generated/client.gen.go | 10 ++++ internal/db/queries_stacks.go | 55 ++++++++++++++++++ internal/db/queries_stacks_test.go | 53 +++++++++++++++++ internal/db/types.go | 7 +++ internal/server/pullapi/handler_test.go | 58 +++++++++++++++++++ internal/server/pullapi/routes.go | 7 +++ internal/server/pullapi/types.go | 10 ++++ 14 files changed, 287 insertions(+), 4 deletions(-) diff --git a/context/platform-sync-invariants.md b/context/platform-sync-invariants.md index 00a229b747..a3bbc4c7ba 100644 --- a/context/platform-sync-invariants.md +++ b/context/platform-sync-invariants.md @@ -500,10 +500,13 @@ Repository import requests and route/query shapes should carry pushed-head refresh, manual workspace refresh, and on-demand worktree sync must check item visibility before item-specific provider access. Workspace and Fleet projections retain local records but omit removed parent metadata; - visible stack members are renumbered contiguously after filtering. + visible stack members are renumbered contiguously after filtering, and the + pull list's per-row stack placement must report the same position and size + as the detail stack context. `inaccessible` items remain visible. (`internal/server/pullapi/helpers.go::visibleMergeRequest`, - `internal/server/issueapi/mutation_handlers.go::requireVisibleIssue`) + `internal/server/issueapi/mutation_handlers.go::requireVisibleIssue`, + `internal/db/queries_stacks.go::ListStackPlacementsForMRs`) - Embedded navigation events for repo-bound routes must publish identity from parsed route state, not from global embed config. When a route carries repo identity, event payloads should include `provider`, `platform_host`, and diff --git a/frontend/openapi/openapi.yaml b/frontend/openapi/openapi.yaml index e928e88f5a..fa41f46f0d 100644 --- a/frontend/openapi/openapi.yaml +++ b/frontend/openapi/openapi.yaml @@ -5081,6 +5081,8 @@ components: type: - array - "null" + stack: + $ref: "#/components/schemas/StackPlacementResponse" workspace: $ref: "#/components/schemas/WorkspaceRef" worktree_links: @@ -8663,6 +8665,21 @@ components: - base_branch - blocked_by type: object + StackPlacementResponse: + additionalProperties: false + properties: + position: + description: 1-based position of this pull request in its stack + format: int64 + type: integer + size: + description: Number of visible pull requests in the stack + format: int64 + type: integer + required: + - position + - size + type: object StackResponse: additionalProperties: false properties: diff --git a/frontend/src/lib/api/generated/schema.ts b/frontend/src/lib/api/generated/schema.ts index c5b23ee69c..09c134774d 100644 --- a/frontend/src/lib/api/generated/schema.ts +++ b/frontend/src/lib/api/generated/schema.ts @@ -7399,6 +7399,7 @@ export interface components { repo_name: string; repo_owner: string; requested_reviewers?: string[] | null; + stack?: components["schemas"]["StackPlacementResponse"]; workspace?: components["schemas"]["WorkspaceRef"]; worktree_links: components["schemas"]["WorktreeLinkResponse"][] | null; }; @@ -8984,6 +8985,18 @@ export interface components { state: string; title: string; }; + StackPlacementResponse: { + /** + * Format: int64 + * @description 1-based position of this pull request in its stack + */ + position: number; + /** + * Format: int64 + * @description Number of visible pull requests in the stack + */ + size: number; + }; StackResponse: { health: string; /** Format: int64 */ diff --git a/frontend/src/lib/components/detail/StackStatus.svelte b/frontend/src/lib/components/detail/StackStatus.svelte index 434c363e9a..de228d359e 100644 --- a/frontend/src/lib/components/detail/StackStatus.svelte +++ b/frontend/src/lib/components/detail/StackStatus.svelte @@ -278,7 +278,7 @@ {expanded} >