mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 03:30:40 +00:00
fix(cli): make /bug easier to open in terminals without hyperlink support (#3257)
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
This commit is contained in:
parent
e4f7a7f380
commit
3c556c01f3
6 changed files with 119 additions and 20 deletions
|
|
@ -71,9 +71,19 @@ Sandbox: test
|
|||
Proxy: no proxy
|
||||
Memory Usage: 100 MB`;
|
||||
const expectedUrl =
|
||||
'https://github.com/QwenLM/qwen-code/issues/new?template=bug_report.yml&title=A%20test%20bug&info=' +
|
||||
encodeURIComponent(`\n${expectedInfo}\n`);
|
||||
'https://github.com/QwenLM/qwen-code/issues/new?template=bug_report.yml&title=A%20test%20bug&info=%0A' +
|
||||
encodeURIComponent(expectedInfo) +
|
||||
'%0A';
|
||||
|
||||
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
|
||||
{
|
||||
type: 'info',
|
||||
text: 'To submit your bug report, please open the following URL in your browser:',
|
||||
linkUrl: expectedUrl,
|
||||
linkText: 'Open GitHub bug report form',
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
expect(open).toHaveBeenCalledWith(expectedUrl);
|
||||
});
|
||||
|
||||
|
|
@ -109,6 +119,15 @@ Memory Usage: 100 MB`;
|
|||
.replace('{title}', encodeURIComponent('A custom bug'))
|
||||
.replace('{info}', encodeURIComponent(`\n${expectedInfo}\n`));
|
||||
|
||||
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
|
||||
{
|
||||
type: 'info',
|
||||
text: 'To submit your bug report, please open the following URL in your browser:',
|
||||
linkUrl: expectedUrl,
|
||||
linkText: 'Open GitHub bug report form',
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
expect(open).toHaveBeenCalledWith(expectedUrl);
|
||||
});
|
||||
|
||||
|
|
@ -161,9 +180,19 @@ Sandbox: test
|
|||
Proxy: no proxy
|
||||
Memory Usage: 100 MB`;
|
||||
const expectedUrl =
|
||||
'https://github.com/QwenLM/qwen-code/issues/new?template=bug_report.yml&title=OpenAI%20bug&info=' +
|
||||
encodeURIComponent(`\n${expectedInfo}\n`);
|
||||
'https://github.com/QwenLM/qwen-code/issues/new?template=bug_report.yml&title=OpenAI%20bug&info=%0A' +
|
||||
encodeURIComponent(expectedInfo) +
|
||||
'%0A';
|
||||
|
||||
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
|
||||
{
|
||||
type: 'info',
|
||||
text: 'To submit your bug report, please open the following URL in your browser:',
|
||||
linkUrl: expectedUrl,
|
||||
linkText: 'Open GitHub bug report form',
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
expect(open).toHaveBeenCalledWith(expectedUrl);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
type SlashCommand,
|
||||
CommandKind,
|
||||
} from './types.js';
|
||||
import { MessageType } from '../types.js';
|
||||
import { MessageType, type HistoryItem } from '../types.js';
|
||||
import { getExtendedSystemInfo } from '../../utils/systemInfo.js';
|
||||
import { getSystemInfoFields } from '../../utils/systemInfoFields.js';
|
||||
import { t } from '../../i18n/index.js';
|
||||
|
|
@ -43,13 +43,14 @@ export const bugCommand: SlashCommand = {
|
|||
.replace('{title}', encodeURIComponent(bugDescription))
|
||||
.replace('{info}', encodeURIComponent(`\n${info}\n`));
|
||||
|
||||
context.ui.addItem(
|
||||
{
|
||||
type: MessageType.INFO,
|
||||
text: `To submit your bug report, please open the following URL in your browser:\n${bugReportUrl}`,
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
const bugReportItem: Omit<Extract<HistoryItem, { type: 'info' }>, 'id'> = {
|
||||
type: MessageType.INFO,
|
||||
text: 'To submit your bug report, please open the following URL in your browser:',
|
||||
linkUrl: bugReportUrl,
|
||||
linkText: 'Open GitHub bug report form',
|
||||
};
|
||||
|
||||
context.ui.addItem(bugReportItem, Date.now());
|
||||
|
||||
try {
|
||||
await open(bugReportUrl);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,11 @@ const HistoryItemDisplayComponent: React.FC<HistoryItemDisplayProps> = ({
|
|||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'info' && (
|
||||
<InfoMessage text={itemForDisplay.text} />
|
||||
<InfoMessage
|
||||
text={itemForDisplay.text}
|
||||
linkUrl={itemForDisplay.linkUrl}
|
||||
linkText={itemForDisplay.linkText}
|
||||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'success' && (
|
||||
<SuccessMessage text={itemForDisplay.text} />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { render } from 'ink-testing-library';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { InfoMessage } from './StatusMessages.js';
|
||||
|
||||
const mockLink = vi.fn(
|
||||
({ children }: { children: React.ReactNode; url: string }): React.ReactNode =>
|
||||
children,
|
||||
);
|
||||
|
||||
vi.mock('ink-link', () => ({
|
||||
default: (props: { children: React.ReactNode; url: string }) =>
|
||||
mockLink(props),
|
||||
}));
|
||||
|
||||
describe('InfoMessage', () => {
|
||||
it('renders a clickable link label when link metadata is provided', () => {
|
||||
const url = 'https://example.com/report';
|
||||
const { lastFrame } = render(
|
||||
<InfoMessage
|
||||
text="To submit your bug report, please open the following URL in your browser:"
|
||||
linkUrl={url}
|
||||
linkText="Open GitHub bug report form"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toContain(
|
||||
'To submit your bug report, please open the following URL in your browser:',
|
||||
);
|
||||
expect(lastFrame()).toContain('Open GitHub bug report form');
|
||||
expect(mockLink).toHaveBeenCalledWith({
|
||||
children: expect.anything(),
|
||||
url,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import Link from 'ink-link';
|
||||
import stringWidth from 'string-width';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
import { RenderInline } from '../../utils/InlineMarkdownRenderer.js';
|
||||
|
|
@ -16,10 +17,13 @@ interface StatusMessageProps {
|
|||
prefixColor: string;
|
||||
textColor: string;
|
||||
children?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
}
|
||||
|
||||
interface StatusTextProps {
|
||||
text: string;
|
||||
linkUrl?: string;
|
||||
linkText?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -32,8 +36,9 @@ export const StatusMessage: React.FC<StatusMessageProps> = ({
|
|||
prefixColor,
|
||||
textColor,
|
||||
children,
|
||||
footer,
|
||||
}) => {
|
||||
if (!text || text.trim() === '') {
|
||||
if ((!text || text.trim() === '') && !footer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -44,22 +49,38 @@ export const StatusMessage: React.FC<StatusMessageProps> = ({
|
|||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text color={prefixColor}>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1}>
|
||||
<Text wrap="wrap" color={textColor}>
|
||||
<RenderInline text={text} />
|
||||
{children}
|
||||
</Text>
|
||||
<Box flexGrow={1} flexDirection="column">
|
||||
{text && text.trim() !== '' && (
|
||||
<Text wrap="wrap" color={textColor}>
|
||||
<RenderInline text={text} />
|
||||
{children}
|
||||
</Text>
|
||||
)}
|
||||
{footer}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const InfoMessage: React.FC<StatusTextProps> = ({ text }) => (
|
||||
export const InfoMessage: React.FC<StatusTextProps> = ({
|
||||
text,
|
||||
linkUrl,
|
||||
linkText,
|
||||
}) => (
|
||||
<StatusMessage
|
||||
text={text}
|
||||
prefix="●"
|
||||
prefixColor={theme.text.primary}
|
||||
textColor={theme.text.primary}
|
||||
footer={
|
||||
linkUrl && (
|
||||
<Link url={linkUrl}>
|
||||
<Text color={theme.text.link} underline>
|
||||
{linkText ?? linkUrl}
|
||||
</Text>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ export type HistoryItemGeminiThoughtContent = HistoryItemBase & {
|
|||
export type HistoryItemInfo = HistoryItemBase & {
|
||||
type: 'info';
|
||||
text: string;
|
||||
linkUrl?: string;
|
||||
linkText?: string;
|
||||
};
|
||||
|
||||
export type HistoryItemError = HistoryItemBase & {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue