Enhance session sidebar with PR worktree support (#342)
* feat: refactored sessions sidebar to be workspaces centric - Add createWorktreeOnly helper and status checks - Add createWorktreeOnly to create a standalone worktree for the active project - Show error toasts when no active project or not a Git repository - Refresh session list and show success toast with created worktree details * feat: show attention indicator and status marker in SessionSidebar - Show unread attention indicator for sessions with pending updates - Display status marker combining streaming and unread indicators in the session row - Introduce attention diamond pulse animation and associated CSS for the new indicator * fix(SessionSidebar): reserve header actions space when repo state is known * chore(doc): add PR status colors to custom themes
This commit is contained in:
committed by
GitHub
parent
d5a2e49ae8
commit
7d99aea6cc
@@ -229,6 +229,70 @@ export function isCreatingWorktree(): boolean {
|
||||
return isCreatingWorktreeSession;
|
||||
}
|
||||
|
||||
export async function createWorktreeOnly(): Promise<string | null> {
|
||||
if (isCreatingWorktreeSession) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const activeProject = useProjectsStore.getState().getActiveProject();
|
||||
if (!activeProject?.path) {
|
||||
toast.error('No active project', {
|
||||
description: 'Please select a project first.',
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
const projectDirectory = activeProject.path;
|
||||
let isGitRepo = false;
|
||||
try {
|
||||
isGitRepo = await checkIsGitRepository(projectDirectory);
|
||||
} catch {
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!isGitRepo) {
|
||||
toast.error('Not a Git repository', {
|
||||
description: 'Worktrees can only be created in Git repositories.',
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
isCreatingWorktreeSession = true;
|
||||
startConfigUpdate('Creating new worktree...');
|
||||
|
||||
try {
|
||||
const projectRef: ProjectRef = { id: activeProject.id, path: projectDirectory };
|
||||
const preferredName = generateBranchName();
|
||||
const setupCommands = await getWorktreeSetupCommands(projectRef);
|
||||
const metadata = await createSdkWorktree(projectRef, {
|
||||
preferredName,
|
||||
setupCommands,
|
||||
});
|
||||
|
||||
const rootBranch = await getRootBranch(projectRef.path).catch(() => undefined);
|
||||
const status = await getWorktreeStatus(metadata.path).catch(() => undefined);
|
||||
|
||||
const branchLabel = metadata.branch || metadata.label || metadata.name;
|
||||
toast.success('Worktree created', {
|
||||
description: branchLabel
|
||||
? `${branchLabel}${rootBranch ? ` from ${rootBranch}` : ''}`
|
||||
: status?.isDirty ? 'Created (dirty)' : 'Ready',
|
||||
});
|
||||
|
||||
await useSessionStore.getState().loadSessions();
|
||||
return metadata.path;
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Failed to create worktree';
|
||||
toast.error('Failed to create worktree', {
|
||||
description: message,
|
||||
});
|
||||
return null;
|
||||
} finally {
|
||||
finishConfigUpdate();
|
||||
isCreatingWorktreeSession = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new session with a worktree for a specific branch.
|
||||
* Unlike createWorktreeSession(), this allows specifying the project and branch explicitly.
|
||||
|
||||
Reference in New Issue
Block a user