mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 04:30:48 +00:00
Merge branch 'main' into feat/mcp-tui
This commit is contained in:
commit
1542a2bdc4
114 changed files with 6943 additions and 1324 deletions
|
|
@ -242,9 +242,14 @@ describe('parseArguments', () => {
|
|||
});
|
||||
|
||||
it('should allow -r flag as alias for --resume', async () => {
|
||||
process.argv = ['node', 'script.js', '-r', 'session-123'];
|
||||
process.argv = [
|
||||
'node',
|
||||
'script.js',
|
||||
'-r',
|
||||
'123e4567-e89b-12d3-a456-426614174000',
|
||||
];
|
||||
const argv = await parseArguments();
|
||||
expect(argv.resume).toBe('session-123');
|
||||
expect(argv.resume).toBe('123e4567-e89b-12d3-a456-426614174000');
|
||||
});
|
||||
|
||||
it('should allow -c flag as alias for --continue', async () => {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,19 @@ import { loadSandboxConfig } from './sandboxConfig.js';
|
|||
import { appEvents } from '../utils/events.js';
|
||||
import { mcpCommand } from '../commands/mcp.js';
|
||||
|
||||
// UUID v4 regex pattern for validation
|
||||
const UUID_REGEX =
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
||||
|
||||
/**
|
||||
* Validates if a string is a valid UUID format
|
||||
* @param value - The string to validate
|
||||
* @returns True if the string is a valid UUID, false otherwise
|
||||
*/
|
||||
function isValidUUID(value: string): boolean {
|
||||
return UUID_REGEX.test(value);
|
||||
}
|
||||
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
import { buildWebSearchConfig } from './webSearch.js';
|
||||
import { writeStderrLine } from '../utils/stdioHelpers.js';
|
||||
|
|
@ -137,6 +150,8 @@ export interface CliArgs {
|
|||
continue: boolean | undefined;
|
||||
/** Resume a specific session by its ID */
|
||||
resume: string | undefined;
|
||||
/** Specify a session ID without session resumption */
|
||||
sessionId: string | undefined;
|
||||
maxSessionTurns: number | undefined;
|
||||
coreTools: string[] | undefined;
|
||||
excludeTools: string[] | undefined;
|
||||
|
|
@ -449,6 +464,10 @@ export async function parseArguments(): Promise<CliArgs> {
|
|||
description:
|
||||
'Resume a specific session by its ID. Use without an ID to show session picker.',
|
||||
})
|
||||
.option('session-id', {
|
||||
type: 'string',
|
||||
description: 'Specify a session ID for this run.',
|
||||
})
|
||||
.option('max-session-turns', {
|
||||
type: 'number',
|
||||
description: 'Maximum number of session turns',
|
||||
|
|
@ -535,6 +554,15 @@ export async function parseArguments(): Promise<CliArgs> {
|
|||
if (argv['continue'] && argv['resume']) {
|
||||
return 'Cannot use both --continue and --resume together. Use --continue to resume the latest session, or --resume <sessionId> to resume a specific session.';
|
||||
}
|
||||
if (argv['sessionId'] && (argv['continue'] || argv['resume'])) {
|
||||
return 'Cannot use --session-id with --continue or --resume. Use --session-id to start a new session with a specific ID, or use --continue/--resume to resume an existing session.';
|
||||
}
|
||||
if (argv['sessionId'] && !isValidUUID(argv['sessionId'] as string)) {
|
||||
return `Invalid --session-id: "${argv['sessionId']}". Must be a valid UUID (e.g., "123e4567-e89b-12d3-a456-426614174000").`;
|
||||
}
|
||||
if (argv['resume'] && !isValidUUID(argv['resume'] as string)) {
|
||||
return `Invalid --resume: "${argv['resume']}". Must be a valid UUID (e.g., "123e4567-e89b-12d3-a456-426614174000").`;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
)
|
||||
|
|
@ -899,6 +927,17 @@ export async function loadCliConfig(
|
|||
process.exit(1);
|
||||
}
|
||||
}
|
||||
} else if (argv['sessionId']) {
|
||||
// Use provided session ID without session resumption
|
||||
// Check if session ID is already in use
|
||||
const sessionService = new SessionService(cwd);
|
||||
const exists = await sessionService.sessionExists(argv['sessionId']);
|
||||
if (exists) {
|
||||
const message = `Error: Session Id ${argv['sessionId']} is already in use.`;
|
||||
writeStderrLine(message);
|
||||
process.exit(1);
|
||||
}
|
||||
sessionId = argv['sessionId'];
|
||||
}
|
||||
|
||||
const modelProvidersConfig = settings.modelProviders;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ export interface KeyBinding {
|
|||
command?: boolean;
|
||||
/** Paste operation requirement: true=must be paste, false=must not be paste, undefined=ignore */
|
||||
paste?: boolean;
|
||||
meta?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,7 +153,16 @@ export const defaultKeyBindings: KeyBindingConfig = {
|
|||
{ key: 'x', ctrl: true },
|
||||
{ sequence: '\x18', ctrl: true },
|
||||
],
|
||||
[Command.PASTE_CLIPBOARD_IMAGE]: [{ key: 'v', ctrl: true }],
|
||||
[Command.PASTE_CLIPBOARD_IMAGE]:
|
||||
process.platform === 'win32'
|
||||
? [
|
||||
{ key: 'v', command: true },
|
||||
{ key: 'v', meta: true },
|
||||
]
|
||||
: [
|
||||
{ key: 'v', ctrl: true },
|
||||
{ key: 'v', command: true },
|
||||
],
|
||||
|
||||
// App level bindings
|
||||
[Command.TOGGLE_TOOL_DESCRIPTIONS]: [{ key: 't', ctrl: true }],
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ const SETTINGS_SCHEMA = {
|
|||
label: 'Show Line Numbers in Code',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
default: true,
|
||||
description: 'Show line numbers in the code output.',
|
||||
showInDialog: true,
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue