diff --git a/apps/web/src/components/ProjectGitHubAccountField.tsx b/apps/web/src/components/ProjectGitHubAccountField.tsx new file mode 100644 index 000000000000..14cb8c3ede3f Binary files /dev/null and b/apps/web/src/components/ProjectGitHubAccountField.tsx differ diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 58ca61720848..7b77eb0abee3 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -22,6 +22,7 @@ import { ThreadWorktreeIndicator, } from "./ThreadStatusIndicators"; import { ProjectDefaultAgentField } from "./ProjectDefaultAgentField"; +import { ProjectGitHubAccountField } from "./ProjectGitHubAccountField"; import { ProjectFavicon } from "./ProjectFavicon"; import { useAtomValue } from "@effect/atom-react"; import { autoAnimate } from "@formkit/auto-animate"; @@ -44,6 +45,7 @@ import { restrictToFirstScrollableAncestor, restrictToVerticalAxis } from "@dnd- import { CSS } from "@dnd-kit/utilities"; import { type ContextMenuItem, + type GitHubAccountRef, type ModelSelection, ProjectId, type ScopedThreadRef, @@ -1655,7 +1657,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec const clicked = await api.contextMenu.show( [ - buildTargetedItem("rename", "Rename"), + buildTargetedItem("rename", "Project settings…"), buildTargetedItem("grouping", "Group into..."), buildTargetedItem("copy-path", "Copy Path"), buildTargetedItem("delete", "Remove", { @@ -2090,6 +2092,26 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec [updateProject], ); + const updateProjectGitHubAccount = useCallback( + async (member: SidebarProjectGroupMember, account: GitHubAccountRef | null) => { + const result = await updateProject({ + environmentId: member.environmentId, + input: { projectId: member.id, gitHubAccount: account }, + }); + if (result._tag === "Failure" && !isAtomCommandInterrupted(result)) { + const error = squashAtomCommandFailure(result); + toastManager.add( + stackedThreadToast({ + type: "error", + title: "Failed to update project GitHub account", + description: error instanceof Error ? error.message : "An error occurred.", + }), + ); + } + }, + [updateProject], + ); + const closeProjectGroupingDialog = useCallback(() => { setProjectGroupingTarget(null); setProjectGroupingSelection("inherit"); @@ -2389,11 +2411,11 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec > - Rename project + Project settings {projectRenameTarget - ? `Update the title for ${projectRenameTarget.workspaceRoot}.` - : "Update the project title."} + ? `Rename ${projectRenameTarget.workspaceRoot} and choose which account new threads use.` + : "Rename the project and choose which account new threads use."} @@ -2426,6 +2448,16 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec }} /> ) : null} + {projectRenameTarget ? ( + { + void updateProjectGitHubAccount(projectRenameTarget, account); + }} + /> + ) : null}