feat: implement worktree session creation and management
- Added `createWorktreeSession` utility to handle the creation of new sessions with auto-generated worktrees. - Introduced branch name generation utilities for creating unique and friendly branch names. - Updated `CommandPalette` to trigger worktree session creation via a command. - Refactored keyboard shortcuts to support new worktree session creation with Shift + Cmd/Ctrl + N. - Enhanced project settings to include worktree defaults (branch prefix, base branch, auto-create option). - Updated persistence logic to preserve worktree defaults when saving project settings. - Modified menu actions to initiate new worktree sessions. - Ensured proper handling of existing branches to avoid conflicts during worktree creation.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { opencodeClient } from '@/lib/opencode/client';
|
||||
import type { ProjectEntry } from '@/lib/api/types';
|
||||
import type { ProjectEntry, WorktreeDefaults } from '@/lib/api/types';
|
||||
import type { DesktopSettings } from '@/lib/desktop';
|
||||
import { updateDesktopSettings } from '@/lib/persistence';
|
||||
import { getSafeStorage } from './utils/safeStorage';
|
||||
@@ -27,6 +27,7 @@ interface ProjectsStore {
|
||||
validateProjectPath: (path: string) => ProjectPathValidationResult;
|
||||
synchronizeFromSettings: (settings: DesktopSettings) => void;
|
||||
getActiveProject: () => ProjectEntry | null;
|
||||
updateWorktreeDefaults: (projectId: string, defaults: Partial<WorktreeDefaults>) => void;
|
||||
}
|
||||
|
||||
const safeStorage = getSafeStorage();
|
||||
@@ -120,6 +121,22 @@ const sanitizeProjects = (value: unknown): ProjectEntry[] => {
|
||||
if (typeof candidate.lastOpenedAt === 'number' && Number.isFinite(candidate.lastOpenedAt) && candidate.lastOpenedAt >= 0) {
|
||||
project.lastOpenedAt = candidate.lastOpenedAt;
|
||||
}
|
||||
if (candidate.worktreeDefaults && typeof candidate.worktreeDefaults === 'object') {
|
||||
const wt = candidate.worktreeDefaults as Record<string, unknown>;
|
||||
const defaults: WorktreeDefaults = {};
|
||||
if (typeof wt.branchPrefix === 'string') {
|
||||
defaults.branchPrefix = wt.branchPrefix;
|
||||
}
|
||||
if (typeof wt.baseBranch === 'string') {
|
||||
defaults.baseBranch = wt.baseBranch;
|
||||
}
|
||||
if (typeof wt.autoCreateWorktree === 'boolean') {
|
||||
defaults.autoCreateWorktree = wt.autoCreateWorktree;
|
||||
}
|
||||
if (Object.keys(defaults).length > 0) {
|
||||
project.worktreeDefaults = defaults;
|
||||
}
|
||||
}
|
||||
|
||||
result.push(project);
|
||||
}
|
||||
@@ -434,6 +451,45 @@ export const useProjectsStore = create<ProjectsStore>()(
|
||||
}
|
||||
return projects.find((project) => project.id === activeProjectId) ?? null;
|
||||
},
|
||||
|
||||
updateWorktreeDefaults: (projectId: string, defaults: Partial<WorktreeDefaults>) => {
|
||||
if (vscodeWorkspace) {
|
||||
return;
|
||||
}
|
||||
const { projects, activeProjectId } = get();
|
||||
const target = projects.find((project) => project.id === projectId);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
const merged: WorktreeDefaults = { ...target.worktreeDefaults };
|
||||
if (defaults.branchPrefix !== undefined) {
|
||||
if (defaults.branchPrefix.trim()) {
|
||||
merged.branchPrefix = defaults.branchPrefix.trim();
|
||||
} else {
|
||||
delete merged.branchPrefix;
|
||||
}
|
||||
}
|
||||
if (defaults.baseBranch !== undefined) {
|
||||
if (defaults.baseBranch.trim()) {
|
||||
merged.baseBranch = defaults.baseBranch.trim();
|
||||
} else {
|
||||
delete merged.baseBranch;
|
||||
}
|
||||
}
|
||||
if (defaults.autoCreateWorktree !== undefined) {
|
||||
merged.autoCreateWorktree = defaults.autoCreateWorktree;
|
||||
}
|
||||
|
||||
const nextProjects = projects.map((project) =>
|
||||
project.id === projectId
|
||||
? { ...project, worktreeDefaults: Object.keys(merged).length > 0 ? merged : undefined }
|
||||
: project
|
||||
);
|
||||
|
||||
set({ projects: nextProjects });
|
||||
persistProjects(nextProjects, activeProjectId);
|
||||
},
|
||||
}), { name: 'projects-store' })
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user