feat(ui): add desktop git sidebar + terminal dock and improve in-app PR workflow (#362)
* feat: add unified dropdown with services content in header * feat: add right Git sidebar with resizable panel * feat: implement responsive panel auto-toggle and terminal rehydration - Auto-close the right sidebar when width is below a threshold and auto-open it when space permits - Auto-close the bottom terminal when height is below a threshold and auto-open it when enough space - Apply a dedicated rehydrated streaming configuration for terminal sessions to optimize reconnect behavior * feat: enhance PR view with status caching and annotations * feat(ui): enable chat dispatch in PullRequestSection * feat(TerminalView): adjust layout * feat: refine chat input layout and text selection menu * fix(ui): show empty state in GitView when no changes * feat(git): update PR actions styling and create PR button
This commit is contained in:
committed by
GitHub
parent
3f29b2c6a2
commit
5b0a97d170
@@ -20,6 +20,7 @@ type GitHubChecksSummary = {
|
||||
type GitHubPullRequest = {
|
||||
number: number;
|
||||
title: string;
|
||||
body?: string;
|
||||
url: string;
|
||||
state: 'open' | 'closed' | 'merged';
|
||||
draft: boolean;
|
||||
@@ -48,6 +49,13 @@ type GitHubPullRequestCreateInput = {
|
||||
draft?: boolean;
|
||||
};
|
||||
|
||||
type GitHubPullRequestUpdateInput = {
|
||||
directory: string;
|
||||
number: number;
|
||||
title: string;
|
||||
body?: string;
|
||||
};
|
||||
|
||||
type GitHubPullRequestMergeInput = {
|
||||
directory: string;
|
||||
number: number;
|
||||
@@ -208,6 +216,7 @@ export const getPullRequestStatus = async (
|
||||
const pr: GitHubPullRequest = {
|
||||
number: typeof prJson.number === 'number' ? prJson.number : 0,
|
||||
title: readString(prJson.title) || '',
|
||||
body: readString(prJson.body) || '',
|
||||
url: readString(prJson.html_url) || '',
|
||||
state,
|
||||
draft: Boolean(prJson.draft),
|
||||
@@ -326,6 +335,7 @@ export const createPullRequest = async (
|
||||
return {
|
||||
number: typeof json.number === 'number' ? json.number : 0,
|
||||
title: readString(json.title) || '',
|
||||
body: readString(json.body) || '',
|
||||
url: readString(json.html_url) || '',
|
||||
state: readString(json.state) === 'closed' ? 'closed' : 'open',
|
||||
draft: Boolean(json.draft),
|
||||
@@ -337,6 +347,62 @@ export const createPullRequest = async (
|
||||
};
|
||||
};
|
||||
|
||||
export const updatePullRequest = async (
|
||||
accessToken: string,
|
||||
directory: string,
|
||||
payload: GitHubPullRequestUpdateInput,
|
||||
): Promise<GitHubPullRequest> => {
|
||||
const repo = await resolveRepoFromDirectory(directory);
|
||||
if (!repo) {
|
||||
throw new Error('Unable to resolve GitHub repo from git remote');
|
||||
}
|
||||
|
||||
const resp = await githubFetch(`${API_BASE}/repos/${repo.owner}/${repo.repo}/pulls/${payload.number}`, accessToken, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
title: payload.title,
|
||||
...(typeof payload.body === 'string' ? { body: payload.body } : {}),
|
||||
}),
|
||||
});
|
||||
|
||||
if (resp.status === 403) {
|
||||
throw new Error('Not authorized to edit this PR');
|
||||
}
|
||||
if (resp.status === 401) {
|
||||
const error = new Error('unauthorized');
|
||||
(error as unknown as { status?: number }).status = 401;
|
||||
throw error;
|
||||
}
|
||||
|
||||
const json = await jsonOrNull<JsonRecord>(resp);
|
||||
if (!resp.ok || !json) {
|
||||
const message = readString(json?.message);
|
||||
const firstError = Array.isArray(json?.errors) && json.errors.length > 0
|
||||
? readString((json.errors[0] as JsonRecord)?.message || (json.errors[0] as JsonRecord)?.code)
|
||||
: '';
|
||||
const details = [message, firstError].filter(Boolean).join(' · ');
|
||||
throw new Error(details || 'Failed to update PR');
|
||||
}
|
||||
|
||||
const merged = Boolean(json.merged || json.merged_at);
|
||||
const state = merged ? 'merged' : (readString(json.state) === 'closed' ? 'closed' : 'open');
|
||||
|
||||
return {
|
||||
number: typeof json.number === 'number' ? json.number : payload.number,
|
||||
title: readString(json.title) || payload.title,
|
||||
body: readString(json.body) || '',
|
||||
url: readString(json.html_url) || '',
|
||||
state,
|
||||
draft: Boolean(json.draft),
|
||||
base: readString((json.base as JsonRecord | undefined)?.ref) || '',
|
||||
head: readString((json.head as JsonRecord | undefined)?.ref) || '',
|
||||
headSha: readString((json.head as JsonRecord | undefined)?.sha) || undefined,
|
||||
mergeable: typeof json.mergeable === 'boolean' ? json.mergeable : null,
|
||||
mergeableState: readString(json.mergeable_state) || undefined,
|
||||
};
|
||||
};
|
||||
|
||||
export const mergePullRequest = async (
|
||||
accessToken: string,
|
||||
directory: string,
|
||||
|
||||
Reference in New Issue
Block a user