fix: address pr comments

This commit is contained in:
Shirone
2026-01-12 18:41:56 +01:00
parent a0669d4262
commit f41a42010c
6 changed files with 158 additions and 36 deletions

View File

@@ -17,6 +17,7 @@ import { cn } from '@/lib/utils';
import { apiGet, apiPut, apiDelete } from '@/lib/api-fetch';
import { toast } from 'sonner';
import { useAppStore } from '@/store/app-store';
import { getHttpApiClient } from '@/lib/http-api-client';
interface WorktreesSectionProps {
useWorktrees: boolean;
@@ -217,9 +218,19 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre
<Checkbox
id="show-init-script-indicator"
checked={showIndicator}
onCheckedChange={(checked) => {
onCheckedChange={async (checked) => {
if (currentProject?.path) {
setShowInitScriptIndicator(currentProject.path, checked === true);
const value = checked === true;
setShowInitScriptIndicator(currentProject.path, value);
// Persist to server
try {
const httpClient = getHttpApiClient();
await httpClient.settings.updateProject(currentProject.path, {
showInitScriptIndicator: value,
});
} catch (error) {
console.error('Failed to persist showInitScriptIndicator:', error);
}
}
}}
className="mt-1"
@@ -246,9 +257,19 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre
<Checkbox
id="auto-dismiss-indicator"
checked={autoDismiss}
onCheckedChange={(checked) => {
onCheckedChange={async (checked) => {
if (currentProject?.path) {
setAutoDismissInitScriptIndicator(currentProject.path, checked === true);
const value = checked === true;
setAutoDismissInitScriptIndicator(currentProject.path, value);
// Persist to server
try {
const httpClient = getHttpApiClient();
await httpClient.settings.updateProject(currentProject.path, {
autoDismissInitScriptIndicator: value,
});
} catch (error) {
console.error('Failed to persist autoDismissInitScriptIndicator:', error);
}
}
}}
className="mt-1"
@@ -273,9 +294,19 @@ export function WorktreesSection({ useWorktrees, onUseWorktreesChange }: Worktre
<Checkbox
id="default-delete-branch"
checked={defaultDeleteBranch}
onCheckedChange={(checked) => {
onCheckedChange={async (checked) => {
if (currentProject?.path) {
setDefaultDeleteBranch(currentProject.path, checked === true);
const value = checked === true;
setDefaultDeleteBranch(currentProject.path, value);
// Persist to server
try {
const httpClient = getHttpApiClient();
await httpClient.settings.updateProject(currentProject.path, {
defaultDeleteBranch: value,
});
} catch (error) {
console.error('Failed to persist defaultDeleteBranch:', error);
}
}
}}
className="mt-1"

View File

@@ -18,6 +18,11 @@ export function useProjectSettingsLoader() {
const setCardBorderOpacity = useAppStore((state) => state.setCardBorderOpacity);
const setHideScrollbar = useAppStore((state) => state.setHideScrollbar);
const setWorktreePanelVisible = useAppStore((state) => state.setWorktreePanelVisible);
const setShowInitScriptIndicator = useAppStore((state) => state.setShowInitScriptIndicator);
const setDefaultDeleteBranch = useAppStore((state) => state.setDefaultDeleteBranch);
const setAutoDismissInitScriptIndicator = useAppStore(
(state) => state.setAutoDismissInitScriptIndicator
);
const loadingRef = useRef<string | null>(null);
const currentProjectRef = useRef<string | null>(null);
@@ -78,6 +83,27 @@ export function useProjectSettingsLoader() {
if (result.settings.worktreePanelVisible !== undefined) {
setWorktreePanelVisible(requestedProjectPath, result.settings.worktreePanelVisible);
}
// Apply showInitScriptIndicator if present
if (result.settings.showInitScriptIndicator !== undefined) {
setShowInitScriptIndicator(
requestedProjectPath,
result.settings.showInitScriptIndicator
);
}
// Apply defaultDeleteBranch if present
if (result.settings.defaultDeleteBranch !== undefined) {
setDefaultDeleteBranch(requestedProjectPath, result.settings.defaultDeleteBranch);
}
// Apply autoDismissInitScriptIndicator if present
if (result.settings.autoDismissInitScriptIndicator !== undefined) {
setAutoDismissInitScriptIndicator(
requestedProjectPath,
result.settings.autoDismissInitScriptIndicator
);
}
}
} catch (error) {
console.error('Failed to load project settings:', error);

View File

@@ -80,6 +80,9 @@ export type ThemeMode =
// LocalStorage key for theme persistence (fallback when server settings aren't available)
export const THEME_STORAGE_KEY = 'automaker:theme';
// Maximum number of output lines to keep in init script state (prevents unbounded memory growth)
export const MAX_INIT_OUTPUT_LINES = 500;
/**
* Get the theme from localStorage as a fallback
* Used before server settings are loaded (e.g., on login/setup pages)
@@ -1823,16 +1826,28 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
await syncSettingsToServer();
},
setPlanUseSelectedWorktreeBranch: async (enabled) => {
const previous = get().planUseSelectedWorktreeBranch;
set({ planUseSelectedWorktreeBranch: enabled });
// Sync to server settings file
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
const ok = await syncSettingsToServer();
if (!ok) {
logger.error('Failed to sync planUseSelectedWorktreeBranch setting to server - reverting');
set({ planUseSelectedWorktreeBranch: previous });
}
},
setAddFeatureUseSelectedWorktreeBranch: async (enabled) => {
const previous = get().addFeatureUseSelectedWorktreeBranch;
set({ addFeatureUseSelectedWorktreeBranch: enabled });
// Sync to server settings file
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
const ok = await syncSettingsToServer();
if (!ok) {
logger.error(
'Failed to sync addFeatureUseSelectedWorktreeBranch setting to server - reverting'
);
set({ addFeatureUseSelectedWorktreeBranch: previous });
}
},
// Worktree Settings actions
@@ -3282,14 +3297,20 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
appendInitScriptOutput: (projectPath, branch, content) => {
const key = `${projectPath}::${branch}`;
const current = get().initScriptState[key];
if (!current) return;
// Initialize state if absent to avoid dropping output due to event-order races
const current = get().initScriptState[key] || {
status: 'idle' as const,
branch,
output: [],
};
// Append new content and enforce fixed-size buffer to prevent memory bloat
const newOutput = [...current.output, content].slice(-MAX_INIT_OUTPUT_LINES);
set({
initScriptState: {
...get().initScriptState,
[key]: {
...current,
output: [...current.output, content],
output: newOutput,
},
},
});