Auto-attach pasted GitHub PR/issue URLs in the composer (#1006)

* Auto-attach pasted GitHub PR/issue URLs in the composer

Paste a GitHub PR or issue link into any composer and it shows up
as an attachment pill within a debounce tick when the URL matches
the workspace's remote. On the new-workspace screen, an attached PR
also surfaces an inline "Check out PR #N?" hint next to the picker;
one click promotes it to the checkout target through the same
syncPickerPrAttachment flow the dropdown uses.

Unifies the new-workspace picker and composer attachment picker on
one shared GitHub search hook and cache key, so both consumers (and
the auto-attach lookup) share the React Query cache.

* Fix oxfmt formatting in new-workspace-screen import
This commit is contained in:
Mohamed Boudra
2026-05-14 17:52:46 +08:00
committed by GitHub
parent 8296c797ff
commit 2e8bced707
12 changed files with 1147 additions and 130 deletions
@@ -34,18 +34,21 @@ export function syncPickerPrAttachment(input: {
return { attachments: nextAttachments, attachedPrNumber };
}
// Suggest a ref picker target derived from composer attachments alone. When the
// user attaches exactly one PR they almost always want the worktree based on
// that PR — surface it as the picker's default so the worktree isn't silently
// branched off main. The caller is responsible for letting manual picks win.
export function deriveAutoPickerItemFromAttachments(
attachments: ReadonlyArray<UserComposerAttachment>,
): PickerItem | null {
let onlyPr: Extract<UserComposerAttachment, { kind: "github_pr" }> | null = null;
for (const attachment of attachments) {
export function findCheckoutHintPrAttachment(input: {
attachments: ReadonlyArray<UserComposerAttachment>;
selectedItem: PickerItem | null;
dismissedPrNumbers: ReadonlySet<number>;
}): Extract<UserComposerAttachment, { kind: "github_pr" }> | null {
const selectedPrNumber =
input.selectedItem?.kind === "github-pr" ? input.selectedItem.item.number : null;
for (const attachment of input.attachments) {
if (attachment.kind !== "github_pr") continue;
if (onlyPr) return null;
onlyPr = attachment;
const prNumber = attachment.item.number;
if (prNumber === selectedPrNumber) continue;
if (input.dismissedPrNumbers.has(prNumber)) continue;
return attachment;
}
return onlyPr ? { kind: "github-pr", item: onlyPr.item } : null;
return null;
}