fix(chat): enable draft auto-accept before first message (#2045)

* fix(chat): enable draft auto-accept before first message

* fix(test): use supported bun assertions

* fix(chat): apply draft auto-accept before session switch

---------

Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
This commit is contained in:
Leonid
2026-07-11 15:15:02 +03:00
committed by GitHub
co-authored by bashrusakh
parent 0242765bc8
commit 9bfc5bf0be
4 changed files with 435 additions and 15 deletions
+30 -15
View File
@@ -75,6 +75,7 @@ import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
import { createWorktreeDraft } from '@/lib/worktreeSessionCreator';
import { buildSessionTargetOptions } from '@/sync/session-worktree-contract';
import { usePermissionStore } from '@/stores/permissionStore';
import { togglePermissionAutoAccept } from './permissionAutoAccept';
import { extractGitChangedFiles } from './changedFiles';
import { useI18n } from '@/lib/i18n';
import { sessionEvents } from '@/lib/sessionEvents';
@@ -648,7 +649,7 @@ const ComposerAttachmentControls = React.memo(function ComposerAttachmentControl
type PermissionAutoAcceptButtonProps = {
footerIconButtonClass: string;
iconSizeClass: string;
permissionScopeSessionId: string | null;
isInteractive: boolean;
permissionAutoAcceptEnabled: boolean;
handlePermissionAutoAcceptToggle: () => void;
withTooltip?: boolean;
@@ -659,7 +660,7 @@ const PermissionAutoAcceptButton = React.memo(function PermissionAutoAcceptButto
const {
footerIconButtonClass,
iconSizeClass,
permissionScopeSessionId,
isInteractive,
permissionAutoAcceptEnabled,
handlePermissionAutoAcceptToggle,
withTooltip = false,
@@ -679,7 +680,7 @@ const PermissionAutoAcceptButton = React.memo(function PermissionAutoAcceptButto
className={cn(
footerIconButtonClass,
'rounded-md hover:bg-transparent',
!permissionScopeSessionId && 'opacity-30',
!isInteractive && 'opacity-30',
)}
onMouseDown={(event) => {
event.preventDefault();
@@ -1083,7 +1084,11 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
);
const newSessionDraft = useSessionUIStore((s) => s.newSessionDraft);
const newSessionDraftOpen = Boolean(newSessionDraft?.open);
const draftPermissionAutoAcceptEnabled = useSessionUIStore((s) => (
s.newSessionDraft?.open ? s.newSessionDraft.permissionAutoAcceptEnabled === true : false
));
const setNewSessionDraftTarget = useSessionUIStore((s) => s.setNewSessionDraftTarget);
const setDraftPermissionAutoAcceptEnabled = useSessionUIStore((s) => s.setDraftPermissionAutoAcceptEnabled);
const openNewSessionDraft = useSessionUIStore((s) => s.openNewSessionDraft);
const availableWorktreesByProject = useSessionUIStore((s) => s.availableWorktreesByProject);
const abortPromptSessionId = useSessionUIStore((s) => s.abortPromptSessionId);
@@ -4523,22 +4528,32 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
const permissionScopeSessionId = currentSessionId ?? currentManagementSessionId;
const permissionAutoAcceptEnabled = usePermissionStore((state) => {
if (!permissionScopeSessionId) {
return false;
return draftPermissionAutoAcceptEnabled;
}
return state.isSessionAutoAccepting(permissionScopeSessionId);
});
const isPermissionAutoAcceptInteractive = Boolean(permissionScopeSessionId || newSessionDraftOpen);
const handlePermissionAutoAcceptToggle = React.useCallback(() => {
if (!permissionScopeSessionId) {
toast.error(t('chat.chatInput.toast.openSessionFirst'));
return;
}
const nextEnabled = !permissionAutoAcceptEnabled;
setSessionAutoAccept(permissionScopeSessionId, nextEnabled).catch(() => {
toast.error(t('chat.chatInput.toast.togglePermissionAutoAcceptFailed'));
togglePermissionAutoAccept({
permissionScopeSessionId,
newSessionDraftOpen,
draftPermissionAutoAcceptEnabled,
permissionAutoAcceptEnabled,
setDraftPermissionAutoAcceptEnabled,
setSessionAutoAccept,
onOpenSessionFirst: () => toast.error(t('chat.chatInput.toast.openSessionFirst')),
onToggleFailed: () => toast.error(t('chat.chatInput.toast.togglePermissionAutoAcceptFailed')),
});
}, [permissionAutoAcceptEnabled, permissionScopeSessionId, setSessionAutoAccept, t]);
}, [
draftPermissionAutoAcceptEnabled,
newSessionDraftOpen,
permissionAutoAcceptEnabled,
permissionScopeSessionId,
setDraftPermissionAutoAcceptEnabled,
setSessionAutoAccept,
t,
]);
React.useEffect(() => {
const pendingAbortBanner = Boolean(abortPromptSessionId) && abortPromptSessionId === currentSessionId;
@@ -5296,7 +5311,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
<PermissionAutoAcceptButton
footerIconButtonClass={footerIconButtonClass}
iconSizeClass={iconSizeClass}
permissionScopeSessionId={permissionScopeSessionId}
isInteractive={isPermissionAutoAcceptInteractive}
permissionAutoAcceptEnabled={permissionAutoAcceptEnabled}
handlePermissionAutoAcceptToggle={handlePermissionAutoAcceptToggle}
/>
@@ -5364,7 +5379,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
<PermissionAutoAcceptButton
footerIconButtonClass={footerIconButtonClass}
iconSizeClass={iconSizeClass}
permissionScopeSessionId={permissionScopeSessionId}
isInteractive={isPermissionAutoAcceptInteractive}
permissionAutoAcceptEnabled={permissionAutoAcceptEnabled}
handlePermissionAutoAcceptToggle={handlePermissionAutoAcceptToggle}
withTooltip
@@ -0,0 +1,36 @@
export type PermissionAutoAcceptToggleArgs = {
permissionScopeSessionId: string | null;
newSessionDraftOpen: boolean;
draftPermissionAutoAcceptEnabled: boolean;
permissionAutoAcceptEnabled: boolean;
setDraftPermissionAutoAcceptEnabled: (enabled: boolean) => void;
setSessionAutoAccept: (sessionId: string, enabled: boolean) => Promise<void>;
onOpenSessionFirst: () => void;
onToggleFailed: () => void;
};
export const togglePermissionAutoAccept = (args: PermissionAutoAcceptToggleArgs): void => {
const {
permissionScopeSessionId,
newSessionDraftOpen,
draftPermissionAutoAcceptEnabled,
permissionAutoAcceptEnabled,
setDraftPermissionAutoAcceptEnabled,
setSessionAutoAccept,
onOpenSessionFirst,
onToggleFailed,
} = args;
if (!permissionScopeSessionId) {
if (!newSessionDraftOpen) {
onOpenSessionFirst();
return;
}
setDraftPermissionAutoAcceptEnabled(!draftPermissionAutoAcceptEnabled);
return;
}
const nextEnabled = !permissionAutoAcceptEnabled;
void setSessionAutoAccept(permissionScopeSessionId, nextEnabled).catch(onToggleFailed);
};