mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 12:15:57 +00:00
167 lines
5.7 KiB
TypeScript
167 lines
5.7 KiB
TypeScript
import { describe, expect, it } from 'bun:test';
|
|
import {
|
|
DroidCommandRouterError,
|
|
routeDroidCommandArgs,
|
|
} from '../../../src/targets/droid-command-router';
|
|
|
|
describe('droid-command-router', () => {
|
|
it('keeps interactive mode for plain profile launches', () => {
|
|
const route = routeDroidCommandArgs([]);
|
|
|
|
expect(route.mode).toBe('interactive');
|
|
expect(route.argsForDroid).toEqual([]);
|
|
expect(route.autoPrependedExec).toBe(false);
|
|
expect(route.duplicateReasoningDisplays).toEqual([]);
|
|
});
|
|
|
|
it('keeps explicit droid subcommands untouched', () => {
|
|
const route = routeDroidCommandArgs(['mcp', '--help']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('mcp');
|
|
expect(route.argsForDroid).toEqual(['mcp', '--help']);
|
|
expect(route.autoPrependedExec).toBe(false);
|
|
expect(route.duplicateReasoningDisplays).toEqual([]);
|
|
});
|
|
|
|
it('auto-prepends exec for exec-only flags provided after profile', () => {
|
|
const route = routeDroidCommandArgs(['--skip-permissions-unsafe']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual(['exec', '--skip-permissions-unsafe']);
|
|
expect(route.autoPrependedExec).toBe(true);
|
|
expect(route.duplicateReasoningDisplays).toEqual([]);
|
|
});
|
|
|
|
it('does not auto-prepend exec for root help flag', () => {
|
|
const route = routeDroidCommandArgs(['--help']);
|
|
|
|
expect(route.mode).toBe('interactive');
|
|
expect(route.argsForDroid).toEqual(['--help']);
|
|
expect(route.autoPrependedExec).toBe(false);
|
|
expect(route.duplicateReasoningDisplays).toEqual([]);
|
|
});
|
|
|
|
it('normalizes --effort alias to --reasoning-effort for explicit exec', () => {
|
|
const route = routeDroidCommandArgs(['exec', '--effort', 'xhigh', 'fix test flake']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual(['exec', '--reasoning-effort', 'xhigh', 'fix test flake']);
|
|
expect(route.reasoningSourceDisplay).toBe('--effort xhigh');
|
|
});
|
|
|
|
it('normalizes --thinking alias when exec is auto-prepended', () => {
|
|
const route = routeDroidCommandArgs(['--auto', 'high', '--thinking=medium', 'summarize logs']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual([
|
|
'exec',
|
|
'--auto',
|
|
'high',
|
|
'--reasoning-effort',
|
|
'medium',
|
|
'summarize logs',
|
|
]);
|
|
expect(route.autoPrependedExec).toBe(true);
|
|
expect(route.reasoningSourceDisplay).toBe('--thinking=medium');
|
|
});
|
|
|
|
it('still auto-prepends exec when --effort appears before exec-only flags', () => {
|
|
const route = routeDroidCommandArgs([
|
|
'--effort',
|
|
'xhigh',
|
|
'--skip-permissions-unsafe',
|
|
'fix flaky test',
|
|
]);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual([
|
|
'exec',
|
|
'--reasoning-effort',
|
|
'xhigh',
|
|
'--skip-permissions-unsafe',
|
|
'fix flaky test',
|
|
]);
|
|
expect(route.autoPrependedExec).toBe(true);
|
|
expect(route.reasoningSourceDisplay).toBe('--effort xhigh');
|
|
});
|
|
|
|
it('auto-prepends exec for non-ambiguous short exec flags', () => {
|
|
const route = routeDroidCommandArgs(['-m', 'custom:gpt-5.3-codex', 'fix flaky test']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual(['exec', '-m', 'custom:gpt-5.3-codex', 'fix flaky test']);
|
|
expect(route.autoPrependedExec).toBe(true);
|
|
});
|
|
|
|
it('routes -r to exec when value matches reasoning effort level', () => {
|
|
const route = routeDroidCommandArgs(['-r', 'high', 'summarize logs']);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual(['exec', '--reasoning-effort', 'high', 'summarize logs']);
|
|
expect(route.autoPrependedExec).toBe(true);
|
|
});
|
|
|
|
it('keeps interactive mode for ambiguous -r resume-style usage', () => {
|
|
const route = routeDroidCommandArgs(['-r', 'session-1234']);
|
|
|
|
expect(route.mode).toBe('interactive');
|
|
expect(route.argsForDroid).toEqual(['-r', 'session-1234']);
|
|
expect(route.autoPrependedExec).toBe(false);
|
|
});
|
|
|
|
it('dedupes mixed reasoning flags with first occurrence precedence', () => {
|
|
const route = routeDroidCommandArgs([
|
|
'exec',
|
|
'--reasoning-effort',
|
|
'high',
|
|
'--thinking',
|
|
'low',
|
|
'--effort=xhigh',
|
|
'summarize logs',
|
|
]);
|
|
|
|
expect(route.mode).toBe('command');
|
|
expect(route.command).toBe('exec');
|
|
expect(route.argsForDroid).toEqual(['exec', '--reasoning-effort', 'high', 'summarize logs']);
|
|
expect(route.reasoningSourceDisplay).toBe('--reasoning-effort high');
|
|
expect(route.duplicateReasoningDisplays).toEqual(['--thinking low', '--effort=xhigh']);
|
|
});
|
|
|
|
it('throws for missing reasoning value in command mode (alias)', () => {
|
|
expect(() => routeDroidCommandArgs(['exec', '--effort'])).toThrow(DroidCommandRouterError);
|
|
});
|
|
|
|
it('throws for missing reasoning value in command mode (native)', () => {
|
|
expect(() => routeDroidCommandArgs(['exec', '--reasoning-effort'])).toThrow(
|
|
DroidCommandRouterError
|
|
);
|
|
});
|
|
|
|
it('records malformed duplicate reasoning flags when first value is already selected', () => {
|
|
const route = routeDroidCommandArgs([
|
|
'exec',
|
|
'--thinking',
|
|
'medium',
|
|
'--reasoning-effort',
|
|
'--skip-permissions-unsafe',
|
|
'summarize logs',
|
|
]);
|
|
|
|
expect(route.argsForDroid).toEqual([
|
|
'exec',
|
|
'--reasoning-effort',
|
|
'medium',
|
|
'--skip-permissions-unsafe',
|
|
'summarize logs',
|
|
]);
|
|
expect(route.duplicateReasoningDisplays).toEqual(['--reasoning-effort <missing-value>']);
|
|
});
|
|
});
|