Add GitHub integration for PRs, issues and AI PR description (#205)
* feat: integrate GitHub OAuth device flow across runtimes Add GitHub OAuth device flow endpoints across runtimes Introduce GitHubSettings UI panel and sidebar entry Persist GitHub auth state in per-runtime storage * feat: add GitHub PR status and PR description generation Show PR status for the current branch in the Git view Generate a pull request description from the diff between base and head Expose prStatus, prCreate, and prMerge APIs in web and desktop clients * feat: add GitHub PR ready for review Add API to mark pull requests as ready for review Show a Ready button for draft PRs and reflect status in UI Handle token expiration and GraphQL errors when marking ready
This commit is contained in:
committed by
GitHub
parent
0e715be7d6
commit
463e9ec4e3
@@ -10,6 +10,7 @@ import type {
|
||||
GitDeleteBranchPayload,
|
||||
GitDeleteRemoteBranchPayload,
|
||||
GeneratedCommitMessage,
|
||||
GeneratedPullRequestDescription,
|
||||
GitWorktreeInfo,
|
||||
GitAddWorktreePayload,
|
||||
GitRemoveWorktreePayload,
|
||||
@@ -108,6 +109,17 @@ export const createDesktopGitAPI = (): GitAPI => ({
|
||||
return response;
|
||||
},
|
||||
|
||||
async generatePullRequestDescription(
|
||||
directory: string,
|
||||
payload: { base: string; head: string }
|
||||
): Promise<GeneratedPullRequestDescription> {
|
||||
return safeGitInvoke<GeneratedPullRequestDescription>('generate_pr_description', {
|
||||
directory,
|
||||
base: payload.base,
|
||||
head: payload.head,
|
||||
});
|
||||
},
|
||||
|
||||
async listGitWorktrees(directory: string): Promise<GitWorktreeInfo[]> {
|
||||
return safeGitInvoke<GitWorktreeInfo[]>('list_git_worktrees', { directory });
|
||||
},
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import type {
|
||||
GitHubAPI,
|
||||
GitHubAuthStatus,
|
||||
GitHubPullRequest,
|
||||
GitHubPullRequestCreateInput,
|
||||
GitHubPullRequestMergeInput,
|
||||
GitHubPullRequestMergeResult,
|
||||
GitHubPullRequestReadyInput,
|
||||
GitHubPullRequestReadyResult,
|
||||
GitHubPullRequestStatus,
|
||||
GitHubDeviceFlowComplete,
|
||||
GitHubDeviceFlowStart,
|
||||
GitHubUserSummary,
|
||||
} from '@openchamber/ui/lib/api/types';
|
||||
|
||||
export const createDesktopGitHubAPI = (): GitHubAPI => ({
|
||||
async authStatus(): Promise<GitHubAuthStatus> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubAuthStatus>('github_auth_status', {}, { timeout: 8000 });
|
||||
},
|
||||
|
||||
async authStart(): Promise<GitHubDeviceFlowStart> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubDeviceFlowStart>('github_auth_start', {}, { timeout: 8000 });
|
||||
},
|
||||
|
||||
async authComplete(deviceCode: string): Promise<GitHubDeviceFlowComplete> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubDeviceFlowComplete>('github_auth_complete', { deviceCode }, { timeout: 12000 });
|
||||
},
|
||||
|
||||
async authDisconnect(): Promise<{ removed: boolean }> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
const result = await safeInvoke<{ removed: boolean }>('github_auth_disconnect', {}, { timeout: 8000 });
|
||||
return { removed: Boolean(result?.removed) };
|
||||
},
|
||||
|
||||
async me(): Promise<GitHubUserSummary> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubUserSummary>('github_me', {}, { timeout: 8000 });
|
||||
},
|
||||
|
||||
async prStatus(directory: string, branch: string): Promise<GitHubPullRequestStatus> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubPullRequestStatus>('github_pr_status', { directory, branch }, { timeout: 12000 });
|
||||
},
|
||||
|
||||
async prCreate(payload: GitHubPullRequestCreateInput): Promise<GitHubPullRequest> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubPullRequest>('github_pr_create', payload, { timeout: 20000 });
|
||||
},
|
||||
|
||||
async prMerge(payload: GitHubPullRequestMergeInput): Promise<GitHubPullRequestMergeResult> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubPullRequestMergeResult>('github_pr_merge', payload, { timeout: 20000 });
|
||||
},
|
||||
|
||||
async prReady(payload: GitHubPullRequestReadyInput): Promise<GitHubPullRequestReadyResult> {
|
||||
const { safeInvoke } = await import('../lib/tauriCallbackManager');
|
||||
return safeInvoke<GitHubPullRequestReadyResult>('github_pr_ready', payload, { timeout: 20000 });
|
||||
},
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import { createDesktopPermissionsAPI } from './permissions';
|
||||
import { createDesktopDiagnosticsAPI } from './diagnostics';
|
||||
import { createDesktopNotificationsAPI } from './notifications';
|
||||
import { createDesktopToolsAPI } from './tools';
|
||||
import { createDesktopGitHubAPI } from './github';
|
||||
|
||||
const activeTerminalConnections = new Set<string>();
|
||||
|
||||
@@ -39,6 +40,7 @@ export const createDesktopAPIs = (): RuntimeAPIs & { cleanup?: () => void } => {
|
||||
settings: createDesktopSettingsAPI(),
|
||||
permissions: createDesktopPermissionsAPI(),
|
||||
notifications: createDesktopNotificationsAPI(),
|
||||
github: createDesktopGitHubAPI(),
|
||||
diagnostics: createDesktopDiagnosticsAPI(),
|
||||
tools: createDesktopToolsAPI(),
|
||||
cleanup: () => {
|
||||
|
||||
Reference in New Issue
Block a user