diff --git a/apps/web/src/app/api/github/repositories/route.ts b/apps/web/src/app/api/github/repositories/route.ts index dcf66be0..5d94e683 100644 --- a/apps/web/src/app/api/github/repositories/route.ts +++ b/apps/web/src/app/api/github/repositories/route.ts @@ -97,6 +97,8 @@ export async function GET(request: NextRequest) { html_url: repo.html_url, default_branch: repo.default_branch, permissions: repo.permissions, + fork: repo.fork, + has_issues: repo.has_issues, })); return NextResponse.json({ diff --git a/apps/web/src/components/github/forked-repository-banner.tsx b/apps/web/src/components/github/forked-repository-banner.tsx new file mode 100644 index 00000000..785b1176 --- /dev/null +++ b/apps/web/src/components/github/forked-repository-banner.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { AlertTriangle } from "lucide-react"; +import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; +import { useGitHubAppProvider } from "@/providers/GitHubApp"; +import { repoHasIssuesEnabled } from "@/lib/repo-has-issues"; + +const GITHUB_DOCS_LINK_ENABLING_ISSUES = + "https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/disabling-issues"; + +export function IssuesRequiredBanner() { + const { selectedRepository, repositories } = useGitHubAppProvider(); + + const currentRepo = repositories.find( + (repo) => + selectedRepository && + repo.full_name === + `${selectedRepository.owner}/${selectedRepository.repo}`, + ); + + // If the repo has issues enabled, we support it. + if ( + !selectedRepository || + !currentRepo || + repoHasIssuesEnabled(currentRepo) + ) { + return null; + } + + return ( + + + Issues Must Be Enabled + +

+ Open SWE requires issues to be enabled on the repository. Please + enable issues on the repository to use Open SWE. +

+

+ See{" "} + + here + {" "} + for how to enable issues (docs show how to disable them, but the + process is the same). +

+
+
+ ); +} diff --git a/apps/web/src/components/v2/default-view.tsx b/apps/web/src/components/v2/default-view.tsx index 9942d14d..2cc03b87 100644 --- a/apps/web/src/components/v2/default-view.tsx +++ b/apps/web/src/components/v2/default-view.tsx @@ -17,6 +17,7 @@ import { ThemeToggle } from "../theme-toggle"; import { ThreadCard, ThreadCardLoading } from "./thread-card"; import { GitHubInstallationBanner } from "../github/installation-banner"; import { ApiKeyBanner } from "../api-key-banner"; +import { IssuesRequiredBanner } from "../github/forked-repository-banner"; import { QuickActions } from "./quick-actions"; import { DraftsSection } from "./drafts-section"; import { MANAGER_GRAPH_ID } from "@open-swe/shared/constants"; @@ -142,6 +143,7 @@ export function DefaultView({ threads, threadsLoading }: DefaultViewProps) {
+ {/* Terminal Chat Input */} + repo.full_name === + `${selectedRepository.owner}/${selectedRepository.repo}`, + ); + const issuesDisabled = selectedRepo && !repoHasIssuesEnabled(selectedRepo); + if (issuesDisabled) { + toast.error( + "Open SWE requires issues to be enabled on the repository. Please enable issues on the repository to use Open SWE.", + { + richColors: true, + closeButton: true, + duration: 30_000, + }, + ); + return; + } + setLoading(true); const trimmedMessage = message.trim(); diff --git a/apps/web/src/lib/repo-has-issues.ts b/apps/web/src/lib/repo-has-issues.ts new file mode 100644 index 00000000..6015c250 --- /dev/null +++ b/apps/web/src/lib/repo-has-issues.ts @@ -0,0 +1,10 @@ +import { Repository } from "@/utils/github"; + +/** + * Returns true if the repository has issues enabled + * @param repo The repository to check + * @returns True if the repository has issues enabled + */ +export function repoHasIssuesEnabled(repo: Repository): boolean { + return repo.has_issues; +} diff --git a/apps/web/src/utils/github.ts b/apps/web/src/utils/github.ts index 8ae070e3..063d737a 100644 --- a/apps/web/src/utils/github.ts +++ b/apps/web/src/utils/github.ts @@ -203,6 +203,7 @@ export interface Repository { full_name: string; description: string | null; private: boolean; + fork: boolean; html_url: string; default_branch: string; permissions: { @@ -212,6 +213,7 @@ export interface Repository { triage: boolean; pull: boolean; }; + has_issues: boolean; } /**