Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
39e409b5e5 Add troubleshooting documentation for fixed CLI interactivity issue
Co-authored-by: pomelo-nwu <10703060+pomelo-nwu@users.noreply.github.com>
2025-08-26 12:04:03 +00:00
copilot-swe-agent[bot]
f5ee3df219 Fix CLI interactivity issue by eliminating multiple useKeypress hook conflicts
Co-authored-by: pomelo-nwu <10703060+pomelo-nwu@users.noreply.github.com>
2025-08-26 12:00:12 +00:00
copilot-swe-agent[bot]
b03daebbc1 Initial plan 2025-08-26 11:42:44 +00:00
4 changed files with 38 additions and 22 deletions

View File

@@ -69,6 +69,11 @@ This guide provides solutions to common issues and debugging tips, including top
- **Cause:** The `is-in-ci` package checks for the presence of `CI`, `CONTINUOUS_INTEGRATION`, or any environment variable with a `CI_` prefix. When any of these are found, it signals that the environment is non-interactive, which prevents the CLI from starting in its interactive mode.
- **Solution:** If the `CI_` prefixed variable is not needed for the CLI to function, you can temporarily unset it for the command. e.g., `env -u CI_TOKEN qwen`
- **CLI becomes unresponsive during interactive selection dialogs**
- **Issue:** When encountering selection dialogs with numbered options (such as shell command confirmation dialogs), the CLI appears "frozen" and does not respond to keyboard input.
- **Cause:** This was caused by multiple keyboard input handlers (`useKeypress` hooks) being active simultaneously, creating conflicts in terminal raw mode control.
- **Solution:** This issue has been fixed in recent versions. The keyboard input handling has been consolidated to prevent conflicts. If you encounter this issue, ensure you're using the latest version of Qwen Code.
- **DEBUG mode not working from project .env file**
- **Issue:** Setting `DEBUG=true` in a project's `.env` file doesn't enable debug mode for the CLI.
- **Cause:** The `DEBUG` and `DEBUG_MODE` variables are automatically excluded from project `.env` files to prevent interference with the CLI behavior.

View File

@@ -8,7 +8,6 @@ import { ToolConfirmationOutcome } from '@qwen-code/qwen-code-core';
import { Box, Text } from 'ink';
import React from 'react';
import { Colors } from '../colors.js';
import { useKeypress } from '../hooks/useKeypress.js';
import {
RadioButtonSelect,
RadioSelectItem,
@@ -31,15 +30,6 @@ export const ShellConfirmationDialog: React.FC<
> = ({ request }) => {
const { commands, onConfirm } = request;
useKeypress(
(key) => {
if (key.name === 'escape') {
onConfirm(ToolConfirmationOutcome.Cancel);
}
},
{ isActive: true },
);
const handleSelect = (item: ToolConfirmationOutcome) => {
if (item === ToolConfirmationOutcome.Cancel) {
onConfirm(item);
@@ -50,6 +40,10 @@ export const ShellConfirmationDialog: React.FC<
}
};
const handleEscape = () => {
onConfirm(ToolConfirmationOutcome.Cancel);
};
const options: Array<RadioSelectItem<ToolConfirmationOutcome>> = [
{
label: 'Yes, allow once',
@@ -96,7 +90,12 @@ export const ShellConfirmationDialog: React.FC<
<Text>Do you want to proceed?</Text>
</Box>
<RadioButtonSelect items={options} onSelect={handleSelect} isFocused />
<RadioButtonSelect
items={options}
onSelect={handleSelect}
onEscape={handleEscape}
isFocused
/>
</Box>
);
};

View File

@@ -20,7 +20,6 @@ import {
RadioSelectItem,
} from '../shared/RadioButtonSelect.js';
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
import { useKeypress } from '../../hooks/useKeypress.js';
export interface ToolConfirmationMessageProps {
confirmationDetails: ToolCallConfirmationDetails;
@@ -57,18 +56,11 @@ export const ToolConfirmationMessage: React.FC<
onConfirm(outcome);
};
useKeypress(
(key) => {
if (!isFocused) return;
if (key.name === 'escape' || (key.ctrl && key.name === 'c')) {
handleConfirm(ToolConfirmationOutcome.Cancel);
}
},
{ isActive: isFocused },
);
const handleSelect = (item: ToolConfirmationOutcome) => handleConfirm(item);
const handleEscape = () => handleConfirm(ToolConfirmationOutcome.Cancel);
const handleCancel = () => handleConfirm(ToolConfirmationOutcome.Cancel);
let bodyContent: React.ReactNode | null = null; // Removed contextDisplay here
let question: string;
@@ -283,6 +275,8 @@ export const ToolConfirmationMessage: React.FC<
<RadioButtonSelect
items={options}
onSelect={handleSelect}
onEscape={handleEscape}
onCancel={handleCancel}
isFocused={isFocused}
/>
</Box>

View File

@@ -34,6 +34,10 @@ export interface RadioButtonSelectProps<T> {
onSelect: (value: T) => void;
/** Function called when an item is highlighted. Receives the `value` of the selected item. */
onHighlight?: (value: T) => void;
/** Function called when escape key is pressed. */
onEscape?: () => void;
/** Function called when Ctrl+C is pressed. */
onCancel?: () => void;
/** Whether this select input is currently focused and should respond to input. */
isFocused?: boolean;
/** Whether to show the scroll arrows. */
@@ -55,6 +59,8 @@ export function RadioButtonSelect<T>({
initialIndex = 0,
onSelect,
onHighlight,
onEscape,
onCancel,
isFocused,
showScrollArrows = false,
maxItemsToShow = 10,
@@ -91,6 +97,18 @@ export function RadioButtonSelect<T>({
const { sequence, name } = key;
const isNumeric = showNumbers && /^[0-9]$/.test(sequence);
// Handle escape key
if (name === 'escape') {
onEscape?.();
return;
}
// Handle Ctrl+C
if (key.ctrl && name === 'c') {
onCancel?.();
return;
}
// Any key press that is not a digit should clear the number input buffer.
if (!isNumeric && numberInputTimer.current) {
clearTimeout(numberInputTimer.current);