GitHub Import Feature: Import repositories/projects from GitHub (#1424) (#1454)

## Summary
Adds the ability to import GitHub repositories directly into Dyad from
the home screen, complementing the existing local folder import feature.
- GitHub Import Modal: New modal accessible from home screen via "Import
from Github" button with two Import methods
- Select project from GitHub repositories list
- Clone from any GitHub URL
- Advanced Options: Optional custom install/start commands (defaults to
project's package.json scripts)
- Auto AI_RULES Generation: Automatically generates AI_RULES.md if not
present in imported repo

closes #1424
    
<!-- This is an auto-generated description by cubic. -->
---

## Summary by cubic
Adds a GitHub import flow from the home screen so users can clone repos
via their list or any URL, with optional install/start commands and
automatic AI_RULES.md generation. Addresses Linear #1424 by enabling
seamless project setup from GitHub.

- **New Features**
  - Import modal with two tabs: Your Repositories and From URL.
- Advanced options for install/start commands with validation; defaults
used when both are empty.
- After cloning, navigate to chat and auto-generate AI_RULES.md if
missing.
- New IPC handler github:clone-repo-from-url with token auth support,
plus IpcClient method and preload channel.
- E2E tests cover modal open, auth, import via URL/repo list, and
advanced options.

- **Dependencies**
  - Added @radix-ui/react-tabs for the modal tab UI.

<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Adeniji Adekunle James
2025-10-14 03:10:04 +01:00
committed by GitHub
parent 7acbe73c73
commit 348521ce82
12 changed files with 934 additions and 157 deletions

View File

@@ -53,7 +53,7 @@ interface ConnectedGitHubConnectorProps {
onAutoSyncComplete?: () => void;
}
interface UnconnectedGitHubConnectorProps {
export interface UnconnectedGitHubConnectorProps {
appId: number | null;
folderName: string;
settings: any;
@@ -287,7 +287,7 @@ function ConnectedGitHubConnector({
);
}
function UnconnectedGitHubConnector({
export function UnconnectedGitHubConnector({
appId,
folderName,
settings,
@@ -342,7 +342,6 @@ function UnconnectedGitHubConnector({
const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const handleConnectToGithub = async () => {
if (!appId) return;
setIsConnectingToGithub(true);
setGithubError(null);
setGithubUserCode(null);
@@ -354,8 +353,6 @@ function UnconnectedGitHubConnector({
};
useEffect(() => {
if (!appId) return; // Don't set up listeners if appId is null initially
const cleanupFunctions: (() => void)[] = [];
// Listener for updates (user code, verification uri, status messages)
@@ -420,7 +417,7 @@ function UnconnectedGitHubConnector({
setIsConnectingToGithub(false);
setGithubStatusMessage(null);
};
}, [appId]); // Re-run effect if appId changes
}, []); // Re-run effect if appId changes
// Load available repos when GitHub is connected
useEffect(() => {
@@ -562,7 +559,7 @@ function UnconnectedGitHubConnector({
className="cursor-pointer w-full py-5 flex justify-center items-center gap-2"
size="lg"
variant="outline"
disabled={isConnectingToGithub || !appId} // Also disable if appId is null
disabled={isConnectingToGithub} // Also disable if appId is null
>
Connect to GitHub
<Github className="h-5 w-5" />