diff --git a/apps/code/src/renderer/features/onboarding/components/GitIntegrationStep.tsx b/apps/code/src/renderer/features/onboarding/components/GitIntegrationStep.tsx
index 36263396df..95bbd925a3 100644
--- a/apps/code/src/renderer/features/onboarding/components/GitIntegrationStep.tsx
+++ b/apps/code/src/renderer/features/onboarding/components/GitIntegrationStep.tsx
@@ -110,8 +110,12 @@ export function GitIntegrationStep({
isLoading: githubUserIntegrationsLoading,
} = useUserGithubIntegrations();
const hasGitIntegration = githubUserIntegrations.length > 0;
- const { repositories, isLoadingRepos } = useUserRepositoryIntegration();
+ const { repositories, isLoadingRepos, failedInstallationIds } =
+ useUserRepositoryIntegration();
const githubIntegration = githubUserIntegrations[0] ?? null;
+ const integrationIsStale =
+ !!githubIntegration &&
+ failedInstallationIds.includes(githubIntegration.installation_id);
const alternativeConnectedProjects = useMemo(() => {
if (hasGitIntegration) return [];
@@ -149,17 +153,18 @@ export function GitIntegrationStep({
const apiClient = useOptionalAuthenticatedClient();
const [disconnectConfirmOpen, setDisconnectConfirmOpen] = useState(false);
const disconnectMutation = useMutation({
- mutationFn: async () => {
+ mutationFn: async (opts: { silent?: boolean } = {}) => {
const installationId = githubIntegration?.installation_id;
if (!apiClient || !installationId) {
throw new Error("No GitHub integration to disconnect");
}
await apiClient.disconnectGithubUserIntegration(installationId);
+ return { silent: opts.silent ?? false };
},
- onSuccess: () => {
+ onSuccess: ({ silent }) => {
setDisconnectConfirmOpen(false);
invalidateGithubQueries(queryClient, selectedProjectId);
- toast.success("GitHub disconnected.");
+ if (!silent) toast.success("GitHub disconnected.");
},
onError: (e) => {
toast.error(
@@ -339,28 +344,65 @@ export function GitIntegrationStep({
{isLoading || githubUserIntegrationsLoading ? (
) : hasGitIntegration ? (
-
-
-
- Connected
+ integrationIsStale ? (
+
+ Reconnect needed
-
+ ) : (
+
+
+
+ Connected
+
+
+ )
) : null}
{hasGitIntegration ? (
-
- {isLoadingRepos
- ? "Loading repositories..."
- : repoSummary
- ? `Access to ${repoSummary}`
- : "No repositories found. Check your GitHub app settings."}
+
+ {integrationIsStale
+ ? "We can't reach GitHub with your saved authorization. The app may have been uninstalled or the token revoked. Reconnect to restore access."
+ : isLoadingRepos
+ ? "Loading repositories..."
+ : repoSummary
+ ? `Access to ${repoSummary}`
+ : "No repositories found. Check your GitHub app settings."}
-
+
+ {integrationIsStale && (
+
+ )}