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 */