fix: resolve positional prompt argument being ignored with other flags (#9004)

This commit is contained in:
김세은
2025-09-22 06:16:21 +09:00
committed by GitHub
parent 56f394cefd
commit b4455af306
5 changed files with 49 additions and 6 deletions

View File

@@ -27,14 +27,20 @@ describe('extensions install command', () => {
});
it('should fail if both git source and local path are provided', () => {
const validationParser = yargs([]).command(installCommand).fail(false);
const validationParser = yargs([])
.command(installCommand)
.fail(false)
.locale('en');
expect(() =>
validationParser.parse('install some-url --path /some/path'),
).toThrow('Arguments source and path are mutually exclusive');
});
it('should fail if both auto update and local path are provided', () => {
const validationParser = yargs([]).command(installCommand).fail(false);
const validationParser = yargs([])
.command(installCommand)
.fail(false)
.locale('en');
expect(() =>
validationParser.parse(
'install some-url --path /some/path --auto-update',

View File

@@ -27,14 +27,14 @@ describe('extensions new command', () => {
});
it('should fail if no path is provided', async () => {
const parser = yargs([]).command(newCommand).fail(false);
const parser = yargs([]).command(newCommand).fail(false).locale('en');
await expect(parser.parseAsync('new')).rejects.toThrow(
'Not enough non-option arguments: got 0, need at least 2',
);
});
it('should fail if no template is provided', async () => {
const parser = yargs([]).command(newCommand).fail(false);
const parser = yargs([]).command(newCommand).fail(false).locale('en');
await expect(parser.parseAsync('new /some/path')).rejects.toThrow(
'Not enough non-option arguments: got 1, need at least 2',
);

View File

@@ -10,7 +10,10 @@ import yargs from 'yargs';
describe('extensions uninstall command', () => {
it('should fail if no source is provided', () => {
const validationParser = yargs([]).command(uninstallCommand).fail(false);
const validationParser = yargs([])
.command(uninstallCommand)
.fail(false)
.locale('en');
expect(() => validationParser.parse('uninstall')).toThrow(
'Not enough non-option arguments: got 0, need at least 1',
);

View File

@@ -1985,6 +1985,37 @@ describe('loadCliConfig interactive', () => {
const config = await loadCliConfig({}, [], 'test-session', argv);
expect(config.isInteractive()).toBe(false);
});
it('should not be interactive if positional prompt words are provided with other flags', async () => {
process.stdin.isTTY = true;
process.argv = ['node', 'script.js', '--model', 'gemini-1.5-pro', 'Hello'];
const argv = await parseArguments({} as Settings);
const config = await loadCliConfig({}, [], 'test-session', argv);
expect(config.isInteractive()).toBe(false);
});
it('should not be interactive if positional prompt words are provided with multiple flags', async () => {
process.stdin.isTTY = true;
process.argv = [
'node',
'script.js',
'--model',
'gemini-1.5-pro',
'--sandbox',
'Hello world',
];
const argv = await parseArguments({} as Settings);
const config = await loadCliConfig({}, [], 'test-session', argv);
expect(config.isInteractive()).toBe(false);
});
it('should be interactive if no positional prompt words are provided with flags', async () => {
process.stdin.isTTY = true;
process.argv = ['node', 'script.js', '--model', 'gemini-1.5-pro'];
const argv = await parseArguments({} as Settings);
const config = await loadCliConfig({}, [], 'test-session', argv);
expect(config.isInteractive()).toBe(true);
});
});
describe('loadCliConfig approval mode', () => {

View File

@@ -505,8 +505,11 @@ export async function loadCliConfig(
const policyEngineConfig = createPolicyEngineConfig(settings, approvalMode);
// Fix: If promptWords are provided, always use non-interactive mode
const hasPromptWords = argv.promptWords && argv.promptWords.length > 0;
const interactive =
!!argv.promptInteractive || (process.stdin.isTTY && question.length === 0);
!!argv.promptInteractive ||
(process.stdin.isTTY && !hasPromptWords && !argv.prompt);
// In non-interactive mode, exclude tools that require a prompt.
const extraExcludes: string[] = [];
if (!interactive && !argv.experimentalAcp) {