mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-03-20 11:03:08 +00:00
Feature: worktree view customization and stability fixes (#805)
* Changes from feature/worktree-view-customization * Feature: Git sync, set-tracking, and push divergence handling (#796) * Add quick-add feature with improved workflows (#802) * Changes from feature/quick-add * feat: Clarify system prompt and improve error handling across services. Address PR Feedback * feat: Improve PR description parsing and refactor event handling * feat: Add context options to pipeline orchestrator initialization * fix: Deduplicate React and handle CJS interop for use-sync-external-store Resolve "Cannot read properties of null (reading 'useState')" errors by deduplicating React/react-dom and ensuring use-sync-external-store is bundled together with React to prevent CJS packages from resolving to different React instances. * Changes from feature/worktree-view-customization * refactor: Remove unused worktree swap and highlight props * refactor: Consolidate feature completion logic and improve thinking level defaults * feat: Increase max turn limit to 10000 - Update DEFAULT_MAX_TURNS from 1000 to 10000 in settings-helpers.ts and agent-executor.ts - Update MAX_ALLOWED_TURNS from 2000 to 10000 in settings-helpers.ts - Update UI clamping logic from 2000 to 10000 in app-store.ts - Update fallback values from 1000 to 10000 in use-settings-sync.ts - Update default value from 1000 to 10000 in DEFAULT_GLOBAL_SETTINGS - Update documentation to reflect new range: 1-10000 Allows agents to perform up to 10000 turns for complex feature execution. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * feat: Add model resolution, improve session handling, and enhance UI stability * refactor: Remove unused sync and tracking branch props from worktree components * feat: Add PR number update functionality to worktrees. Address pr feedback * feat: Optimize Gemini CLI startup and add tool result tracking * refactor: Improve error handling and simplify worktree task cleanup --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Slider } from '@/components/ui/slider';
|
||||
import { ShellSyntaxEditor } from '@/components/ui/shell-syntax-editor';
|
||||
import {
|
||||
GitBranch,
|
||||
@@ -15,6 +16,8 @@ import {
|
||||
Copy,
|
||||
Plus,
|
||||
FolderOpen,
|
||||
LayoutGrid,
|
||||
Pin,
|
||||
} from 'lucide-react';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { cn } from '@/lib/utils';
|
||||
@@ -64,6 +67,10 @@ export function WorktreePreferencesSection({ project }: WorktreePreferencesSecti
|
||||
const copyFiles = copyFilesFromStore ?? EMPTY_FILES;
|
||||
const setWorktreeCopyFiles = useAppStore((s) => s.setWorktreeCopyFiles);
|
||||
|
||||
// Worktree display settings
|
||||
const pinnedWorktreesCount = useAppStore((s) => s.getPinnedWorktreesCount(project.path));
|
||||
const setPinnedWorktreesCount = useAppStore((s) => s.setPinnedWorktreesCount);
|
||||
|
||||
// Get effective worktrees setting (project override or global fallback)
|
||||
const effectiveUseWorktrees = projectUseWorktrees ?? globalUseWorktrees;
|
||||
|
||||
@@ -78,6 +85,9 @@ export function WorktreePreferencesSection({ project }: WorktreePreferencesSecti
|
||||
const [newCopyFilePath, setNewCopyFilePath] = useState('');
|
||||
const [fileSelectorOpen, setFileSelectorOpen] = useState(false);
|
||||
|
||||
// Ref for storing previous slider value for rollback on error
|
||||
const sliderPrevRef = useRef<number | null>(null);
|
||||
|
||||
// Check if there are unsaved changes
|
||||
const hasChanges = scriptContent !== originalContent;
|
||||
|
||||
@@ -115,6 +125,9 @@ export function WorktreePreferencesSection({ project }: WorktreePreferencesSecti
|
||||
if (response.settings.worktreeCopyFiles !== undefined) {
|
||||
setWorktreeCopyFiles(currentPath, response.settings.worktreeCopyFiles);
|
||||
}
|
||||
if (response.settings.pinnedWorktreesCount !== undefined) {
|
||||
setPinnedWorktreesCount(currentPath, response.settings.pinnedWorktreesCount);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (!isCancelled) {
|
||||
@@ -135,6 +148,7 @@ export function WorktreePreferencesSection({ project }: WorktreePreferencesSecti
|
||||
setDefaultDeleteBranch,
|
||||
setAutoDismissInitScriptIndicator,
|
||||
setWorktreeCopyFiles,
|
||||
setPinnedWorktreesCount,
|
||||
]);
|
||||
|
||||
// Load init script content when project changes
|
||||
@@ -507,6 +521,78 @@ export function WorktreePreferencesSection({ project }: WorktreePreferencesSecti
|
||||
{/* Separator */}
|
||||
<div className="border-t border-border/30" />
|
||||
|
||||
{/* Worktree Display Settings */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<LayoutGrid className="w-4 h-4 text-brand-500" />
|
||||
<Label className="text-foreground font-medium">Display Settings</Label>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground/80 leading-relaxed">
|
||||
Control how worktrees are presented in the panel. Pinned worktrees appear as tabs, and
|
||||
remaining worktrees are available in a combined overflow dropdown.
|
||||
</p>
|
||||
|
||||
{/* Pinned Worktrees Count */}
|
||||
<div className="group flex items-start space-x-3 p-3 rounded-xl hover:bg-accent/30 transition-colors duration-200 -mx-3">
|
||||
<div className="mt-0.5">
|
||||
<Pin className="w-4 h-4 text-brand-500" />
|
||||
</div>
|
||||
<div className="space-y-2 flex-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label
|
||||
htmlFor="pinned-worktrees-count"
|
||||
className="text-foreground cursor-pointer font-medium"
|
||||
>
|
||||
Pinned Worktree Tabs
|
||||
</Label>
|
||||
<span className="text-sm font-medium text-foreground tabular-nums">
|
||||
{pinnedWorktreesCount}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground/80 leading-relaxed">
|
||||
Number of worktree tabs to pin (excluding the main worktree, which is always shown).
|
||||
</p>
|
||||
<Slider
|
||||
id="pinned-worktrees-count"
|
||||
min={0}
|
||||
max={25}
|
||||
step={1}
|
||||
value={[pinnedWorktreesCount]}
|
||||
onValueChange={(value) => {
|
||||
// Capture previous value before mutation for potential rollback
|
||||
const prevCount = pinnedWorktreesCount;
|
||||
// Update local state immediately for visual feedback
|
||||
const newValue = value[0] ?? pinnedWorktreesCount;
|
||||
setPinnedWorktreesCount(project.path, newValue);
|
||||
// Store prev for onValueCommit rollback
|
||||
sliderPrevRef.current = prevCount;
|
||||
}}
|
||||
onValueCommit={async (value) => {
|
||||
const newValue = value[0] ?? pinnedWorktreesCount;
|
||||
const prev = sliderPrevRef.current ?? pinnedWorktreesCount;
|
||||
|
||||
// Persist to server
|
||||
try {
|
||||
const httpClient = getHttpApiClient();
|
||||
await httpClient.settings.updateProject(project.path, {
|
||||
pinnedWorktreesCount: newValue,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to persist pinnedWorktreesCount:', error);
|
||||
toast.error('Failed to save pinned worktrees setting');
|
||||
// Rollback optimistic update using captured previous value
|
||||
setPinnedWorktreesCount(project.path, prev);
|
||||
}
|
||||
}}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div className="border-t border-border/30" />
|
||||
|
||||
{/* Copy Files Section */}
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user