mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
fix: 修复 buddy 命令 ESC 关闭后进入永久 loading 状态
CancelRequestHandler 先于 BuddyPanel 的 ESC handler 拦截按键, 仅清除面板但未 resolve processSlashCommand 中的 Promise, 导致 queryGuard 卡在 dispatching 状态。通过在 setToolJSX 中增加 onDismiss 回调,在面板被外部清除时同步 resolve Promise。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,6 +112,9 @@ export type SetToolJSXFn = (
|
||||
isImmediate?: boolean
|
||||
/** Set to true to clear a local JSX command (e.g., from its onDone callback) */
|
||||
clearLocalJSX?: boolean
|
||||
/** Called when the panel is dismissed externally (e.g. ESC via CancelRequestHandler).
|
||||
* Must resolve the underlying Promise in processSlashCommand.tsx. */
|
||||
onDismiss?: () => void
|
||||
} | null,
|
||||
) => void
|
||||
|
||||
|
||||
@@ -1288,6 +1288,9 @@ export function REPL({
|
||||
shouldContinueAnimation?: true;
|
||||
showSpinner?: boolean;
|
||||
isLocalJSXCommand: true;
|
||||
/** Called when the panel is dismissed externally (ESC via CancelRequestHandler).
|
||||
* Resolves the underlying Promise in processSlashCommand.tsx. */
|
||||
onDismiss?: () => void;
|
||||
} | null>(null);
|
||||
|
||||
// Wrapper for setToolJSX that preserves local JSX commands (like /btw).
|
||||
@@ -1308,6 +1311,7 @@ export function REPL({
|
||||
showSpinner?: boolean;
|
||||
isLocalJSXCommand?: boolean;
|
||||
clearLocalJSX?: boolean;
|
||||
onDismiss?: () => void;
|
||||
} | null,
|
||||
) => {
|
||||
// If setting a local JSX command, store it in the ref
|
||||
@@ -1322,6 +1326,9 @@ export function REPL({
|
||||
if (localJSXCommandRef.current) {
|
||||
// Allow clearing only if explicitly requested (from onDone callbacks)
|
||||
if (args?.clearLocalJSX) {
|
||||
// Notify the command that its panel was dismissed externally (e.g. ESC)
|
||||
// so it can resolve the underlying Promise and unblock executeUserInput.
|
||||
localJSXCommandRef.current.onDismiss?.();
|
||||
localJSXCommandRef.current = null;
|
||||
setToolJSXInternal(null);
|
||||
return;
|
||||
|
||||
@@ -313,6 +313,15 @@ export async function handlePromptSubmit(
|
||||
shouldHidePromptInput: false,
|
||||
isLocalJSXCommand: true,
|
||||
isImmediate: true,
|
||||
onDismiss: () => {
|
||||
if (doneWasCalled) return
|
||||
doneWasCalled = true
|
||||
setToolJSX({
|
||||
jsx: null,
|
||||
shouldHidePromptInput: false,
|
||||
clearLocalJSX: true,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
return
|
||||
|
||||
@@ -839,6 +839,13 @@ async function getMessagesForSlashCommand(
|
||||
showSpinner: false,
|
||||
isLocalJSXCommand: true,
|
||||
isImmediate: command.immediate === true,
|
||||
// When the panel is dismissed externally (ESC via CancelRequestHandler),
|
||||
// resolve the Promise so executeUserInput doesn't hang forever.
|
||||
onDismiss: () => {
|
||||
if (doneWasCalled) return
|
||||
doneWasCalled = true
|
||||
void resolve({ messages: [], shouldQuery: false, command })
|
||||
},
|
||||
})
|
||||
})
|
||||
.catch(e => {
|
||||
|
||||
Reference in New Issue
Block a user