Skip to content

Sidebar: right-click a session with a PR → "Add label crow:merge to PR" context-menu action #502

@dhilgaertner

Description

@dhilgaertner

Summary

Add a right-click context-menu item on session rows in the left sidebar that adds the crow:merge label to the session's PR. The item should appear only when the session has an associated PR. Selecting it labels the PR so the existing auto-merge flow can pick it up — without having to leave Crow and open GitHub.

Desired behavior

  • Right-click a session row in the left pane.
  • If that session has a PR link, the context menu shows "Add label crow:merge to PR" (with an appropriate SF Symbol, e.g. tag / arrow.triangle.merge).
  • If the session has no PR, the item is hidden (not just disabled).
  • Selecting it adds the crow:merge label to that PR. Ideally disable/relabel the item while in-flight and surface failures the same way the other row actions do.

Where this goes (anchors)

UI — Packages/CrowUI/Sources/CrowUI/SessionListView.swift:

  • The shared row context menu is sessionContextMenu(_ session:) (around line 298). It's already attached via .contextMenu { sessionContextMenu(session) } for the active / in-review / completed / etc. session sections (lines ~121, 146, 199, 223). Adding the new Button inside sessionContextMenu makes it appear consistently across those sections.
  • PR presence is already computed the way we need it: SessionRow has
    private var prLink: SessionLink? {
        appState.links(for: session.id).first(where: { $0.linkType == .pr })
    }
    (SessionListView.swift:537). Use the same appState.links(for:).first(where: { $0.linkType == .pr }) lookup inside sessionContextMenu to gate the item and to get the PR URL.
  • There's already a PRBadge component (Packages/CrowUI/Sources/CrowUI/PRBadge.swift) and the row renders a PR badge when prLink != nil (line ~668) — so the "has a PR" signal is well established.

Action wiring — follow the existing callback pattern:

  • The other row actions dispatch through optional AppState closures, e.g. appState.onMarkInReview?(session.id) (line 305) and appState.onCompleteSession?(session.id) (line 314). Add a parallel closure such as appState.onAddMergeLabel?(session.id) and wire it in the app layer where onMarkInReview / onCompleteSession are assigned.

Backend — the label plumbing already exists in Sources/Crow/App/IssueTracker.swift:

  • The label constant: static let autoMergeLabel = "crow:merge" (line 112).
  • Adding labels: backend.setLabels(url:add:remove:) (used at line 559 — setLabels(url: issue.url, add: [], remove: [...])). The new handler should call setLabels(url: <prURL>, add: [Self.autoMergeLabel], remove: []).
  • Lazily ensure the label exists in the repo first: ensureMergeLabel(repo:) (line 1618), gated by backend.capabilities.contains(.autoMergeLabel) (line 1621). Mirror that gate so providers that don't support label-driven merge don't show/execute the action.

So the handler is roughly: resolve the session's .pr SessionLink → derive repoNameWithOwnerensureMergeLabel(repo:)setLabels(url: prURL, add: ["crow:merge"], remove: []).

Notes / open questions

  • Capability gating: if backend.capabilities lacks .autoMergeLabel, hide the item (consistent with how enableAutoMerge / ensureMergeLabel already bail out).
  • Already-labeled PR: consider no-op'ing (or relabeling to "Remove label crow:merge") when the PR already carries crow:merge — the auto-merge reconcile already checks pr.labels.contains(crow:merge) (line 1462), so adding it again is harmless but the menu copy could reflect current state. Adding-only is fine for a first cut.
  • Sections with inline menus: one section uses an inline destructive-only .contextMenu (around line 170) rather than sessionContextMenu. Decide whether that section's rows can have PRs and, if so, route it through the shared builder too.
  • Scope: this is a manual trigger for the same label the auto-merge watcher consumes — it does not change auto-merge semantics, only gives a one-click way to opt a PR in from the sidebar.

Acceptance criteria

  • Right-clicking a session row that has a PR shows "Add label crow:merge to PR"; rows without a PR do not.
  • Selecting it adds the crow:merge label to the correct PR (ensuring the label exists in the repo first).
  • The item is hidden when the active provider lacks the autoMergeLabel capability.
  • In-flight/failure states are handled consistently with the existing row actions.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions