Start new workspaces from pasted pull requests (#2290)

* fix(workspaces): start pasted pull requests from their branch

Recognized pull request links now select their branch directly instead of
waiting for a separate confirmation. Ensure single-branch clones also record
the fetched branch so the new worktree can track it.

* fix(workspaces): keep pasted PR checkout target-safe

* fix(workspaces): make pasted PR resolution deterministic

* fix(workspaces): preserve explicit checkout selection

A recognized pull request selects itself only when its attachment is added. Once the user chooses a branch, later composer edits must not derive checkout state from existing attachments.

* fix(composer): ignore stale pull request lookups

A lookup may finish after the workspace target changes. Only apply its attachment and selection event when the host, working directory, client, and remote still match the target that started it.

* fix(workspaces): make checkout choices authoritative

Arm automatic pull request selection only when a new PR link is detected. An explicit picker choice cancels that pending selection, existing draft attachments never infer checkout state, and target changes suppress carried-over lookups.

* fix(workspaces): stabilize pull request auto-selection

Keep the first PR selected when one edit contains several links, and accept a completed lookup when only the transport client changed for the same host and checkout.

* fix(composer): release removed pull request lookups

Release each auto-attach invocation when its composer state is abandoned, while continuing to discard any stale response.
This commit is contained in:
Mohamed Boudra
2026-07-21 15:20:05 +02:00
committed by GitHub
parent fd4e13735c
commit 2cb1b041dd
20 changed files with 768 additions and 313 deletions
+14 -1
View File
@@ -768,6 +768,8 @@ interface ComposerProps {
submitIcon?: "arrow" | "return";
/** Externally controlled loading state. When true, disables the submit button. */
isSubmitLoading?: boolean;
/** When true, waits for pasted GitHub links to resolve before enabling submit. */
waitForGithubAutoAttachOnSubmit?: boolean;
submitBehavior?: "clear" | "preserve-and-lock";
/** When true, blurs the input immediately when submitting. */
blurOnSubmit?: boolean;
@@ -777,6 +779,8 @@ interface ComposerProps {
attachmentScopeKeys?: readonly string[];
onOpenWorkspaceAttachment?: (attachment: WorkspaceComposerAttachment) => void;
onChangeAttachments: (updater: AttachmentListUpdater) => void;
onGithubPrDetected?: () => void;
onGithubPrAutoAttach?: (item: ForgeSearchItem) => void;
cwd: string;
clearDraft: (lifecycle: "sent" | "abandoned") => void;
/** When true, auto-focuses the text input on web. */
@@ -981,6 +985,7 @@ export function Composer({
submitButtonTestID,
submitIcon = "arrow",
isSubmitLoading = false,
waitForGithubAutoAttachOnSubmit = false,
submitBehavior = "clear",
blurOnSubmit = false,
value,
@@ -989,6 +994,8 @@ export function Composer({
attachmentScopeKeys = EMPTY_ATTACHMENT_SCOPE_KEYS,
onOpenWorkspaceAttachment,
onChangeAttachments,
onGithubPrDetected,
onGithubPrAutoAttach,
cwd,
clearDraft,
autoFocus = false,
@@ -1070,6 +1077,8 @@ export function Composer({
cwd,
supportsForgeSearch,
setAttachments: setSelectedAttachments,
onPullRequestDetected: onGithubPrDetected,
onPullRequestAdded: onGithubPrAutoAttach,
});
const [cursorIndex, setCursorIndex] = useState(0);
const [isProcessing, setIsProcessing] = useState(false);
@@ -1949,7 +1958,11 @@ export function Composer({
const messageInputContainerRef = useRef<View>(null);
const isSubmitBusy = isProcessing || isSubmitLoading || isUploadingFile;
const isSubmitBusy =
isProcessing ||
isSubmitLoading ||
isUploadingFile ||
(waitForGithubAutoAttachOnSubmit && githubAutoAttach.isResolving);
// Disable drops while submitting/uploading: the submit path clears and restores attachments,
// so a drop in that window would be lost or land on a locked draft. `disabled` hides the