diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index b4c050f6..028f7bd1 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -114,6 +114,11 @@ export function BoardView() { const pipelineConfigByProject = useAppStore((state) => state.pipelineConfigByProject); // Subscribe to worktreePanelVisibleByProject to trigger re-renders when it changes const worktreePanelVisibleByProject = useAppStore((state) => state.worktreePanelVisibleByProject); + // Subscribe to showInitScriptIndicatorByProject to trigger re-renders when it changes + const showInitScriptIndicatorByProject = useAppStore( + (state) => state.showInitScriptIndicatorByProject + ); + const getShowInitScriptIndicator = useAppStore((state) => state.getShowInitScriptIndicator); const shortcuts = useKeyboardShortcutsConfig(); const { features: hookFeatures, @@ -1577,7 +1582,9 @@ export function BoardView() { /> {/* Init Script Indicator - floating overlay for worktree init script status */} - + {getShowInitScriptIndicator(currentProject.path) && ( + + )} ); } diff --git a/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx b/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx index 8a615c58..01ff77c6 100644 --- a/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx +++ b/apps/ui/src/components/views/settings-view/worktrees/worktrees-section.tsx @@ -3,7 +3,16 @@ import { Label } from '@/components/ui/label'; import { Checkbox } from '@/components/ui/checkbox'; import { Button } from '@/components/ui/button'; import { ShellSyntaxEditor } from '@/components/ui/shell-syntax-editor'; -import { GitBranch, Terminal, FileCode, Save, RotateCcw, Trash2, Loader2 } from 'lucide-react'; +import { + GitBranch, + Terminal, + FileCode, + Save, + RotateCcw, + Trash2, + Loader2, + PanelBottomClose, +} from 'lucide-react'; import { cn } from '@/lib/utils'; import { apiPost, apiPut, apiDelete } from '@/lib/api-fetch'; import { toast } from 'sonner'; @@ -24,6 +33,8 @@ interface InitScriptResponse { export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: WorktreesSectionProps) { const currentProject = useAppStore((s) => s.currentProject); + const getShowInitScriptIndicator = useAppStore((s) => s.getShowInitScriptIndicator); + const setShowInitScriptIndicator = useAppStore((s) => s.setShowInitScriptIndicator); const [scriptContent, setScriptContent] = useState(''); const [originalContent, setOriginalContent] = useState(''); const [scriptExists, setScriptExists] = useState(false); @@ -31,6 +42,11 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre const [isSaving, setIsSaving] = useState(false); const [isDeleting, setIsDeleting] = useState(false); + // Get the current show indicator setting + const showIndicator = currentProject?.path + ? getShowInitScriptIndicator(currentProject.path) + : true; + // Check if there are unsaved changes const hasChanges = scriptContent !== originalContent; @@ -181,6 +197,35 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre + {/* Show Init Script Indicator Toggle */} + {currentProject && ( +
+ { + if (currentProject?.path) { + setShowInitScriptIndicator(currentProject.path, checked === true); + } + }} + className="mt-1" + /> +
+ +

+ Display a floating panel in the bottom-right corner showing init script execution + status and output when a worktree is created. +

+
+
+ )} + {/* Separator */}
diff --git a/apps/ui/src/store/app-store.ts b/apps/ui/src/store/app-store.ts index 5479c015..974ffe87 100644 --- a/apps/ui/src/store/app-store.ts +++ b/apps/ui/src/store/app-store.ts @@ -665,6 +665,10 @@ export interface AppState { // Whether the worktree panel row is visible (default: true) worktreePanelVisibleByProject: Record; + // Init Script Indicator Visibility (per-project, keyed by project path) + // Whether to show the floating init script indicator panel (default: true) + showInitScriptIndicatorByProject: Record; + // UI State (previously in localStorage, now synced via API) /** Whether worktree panel is collapsed in board view */ worktreePanelCollapsed: boolean; @@ -1078,6 +1082,10 @@ export interface AppActions { setWorktreePanelVisible: (projectPath: string, visible: boolean) => void; getWorktreePanelVisible: (projectPath: string) => boolean; + // Init Script Indicator Visibility actions (per-project) + setShowInitScriptIndicator: (projectPath: string, visible: boolean) => void; + getShowInitScriptIndicator: (projectPath: string) => boolean; + // UI State actions (previously in localStorage, now synced via API) setWorktreePanelCollapsed: (collapsed: boolean) => void; setLastProjectDir: (dir: string) => void; @@ -1208,6 +1216,7 @@ const initialState: AppState = { codexModelsLastFetched: null, pipelineConfigByProject: {}, worktreePanelVisibleByProject: {}, + showInitScriptIndicatorByProject: {}, // UI State (previously in localStorage, now synced via API) worktreePanelCollapsed: false, lastProjectDir: '', @@ -3124,6 +3133,21 @@ export const useAppStore = create()((set, get) => ({ return get().worktreePanelVisibleByProject[projectPath] ?? true; }, + // Init Script Indicator Visibility actions (per-project) + setShowInitScriptIndicator: (projectPath, visible) => { + set({ + showInitScriptIndicatorByProject: { + ...get().showInitScriptIndicatorByProject, + [projectPath]: visible, + }, + }); + }, + + getShowInitScriptIndicator: (projectPath) => { + // Default to true (visible) if not set + return get().showInitScriptIndicatorByProject[projectPath] ?? true; + }, + // UI State actions (previously in localStorage, now synced via API) setWorktreePanelCollapsed: (collapsed) => set({ worktreePanelCollapsed: collapsed }), setLastProjectDir: (dir) => set({ lastProjectDir: dir }), diff --git a/libs/types/src/settings.ts b/libs/types/src/settings.ts index 07b4290d..7a46d4aa 100644 --- a/libs/types/src/settings.ts +++ b/libs/types/src/settings.ts @@ -595,6 +595,8 @@ export interface ProjectSettings { // UI Visibility /** Whether the worktree panel row is visible (default: true) */ worktreePanelVisible?: boolean; + /** Whether to show the init script indicator panel (default: true) */ + showInitScriptIndicator?: boolean; // Session Tracking /** Last chat session selected in this project */