fix(cli): document gitlab shortcut flags and harden cursor routing

This commit is contained in:
Tam Nhu Tran
2026-04-15 01:39:31 -04:00
parent 87d93b651b
commit 4e738ee021
6 changed files with 144 additions and 6 deletions
+14 -6
View File
@@ -65,7 +65,8 @@ import {
resolveOfficialChannelsLaunchPlan,
} from './channels/official-channels-runtime';
import { getOfficialChannelReadiness } from './channels/official-channels-store';
import { isCursorSubcommandToken } from './cursor/constants';
import { isCursorSubcommandToken, shouldUseCursorCliproxyShortcut } from './cursor/constants';
import { isCLIProxyProvider } from './cliproxy/provider-capabilities';
// Import centralized error handling
import { handleError, runCleanup } from './errors';
@@ -123,7 +124,6 @@ interface RuntimeReasoningResolution {
sourceDisplay: string | undefined;
}
const CURSOR_CLIPROXY_SHORTCUT_FLAGS = new Set(['--auth', '--logout', '--config', '--accounts']);
const CODEX_RUNTIME_REASONING_LEVELS = new Set(['minimal', 'low', 'medium', 'high', 'xhigh']);
const CODEX_NATIVE_PASSTHROUGH_FLAGS = new Set(['--help', '-h', '--version', '-v']);
@@ -149,10 +149,6 @@ function detectProfile(args: string[]): DetectedProfile {
}
}
function shouldUseCursorCliproxyShortcut(args: string[]): boolean {
return args[0] === 'cursor' && CURSOR_CLIPROXY_SHORTCUT_FLAGS.has(args[1] || '');
}
function resolveRuntimeReasoningFlags(
args: string[],
envThinkingValue: string | undefined
@@ -490,6 +486,18 @@ async function main(): Promise<void> {
return;
}
if (
typeof firstArg === 'string' &&
isCLIProxyProvider(firstArg) &&
firstArg !== 'cursor' &&
args.length > 1 &&
(args.includes('--help') || args.includes('-h'))
) {
const { showProviderShortcutHelp } = await import('./commands/help-command');
await showProviderShortcutHelp(firstArg);
return;
}
// Special case: copilot command (GitHub Copilot integration)
// Route known subcommands to command handler, keep all other args as profile passthrough.
if (firstArg === 'copilot' && args.length > 1) {
+71
View File
@@ -1,4 +1,5 @@
import packageJson from '../../package.json';
import type { CLIProxyProvider } from '../cliproxy';
import { color, dim, header, initUI, subheader } from '../utils/ui';
import {
BUILTIN_PROVIDER_SHORTCUTS,
@@ -82,10 +83,80 @@ async function showProvidersHelp(writeLine: HelpWriter): Promise<void> {
],
writeLine
);
writeCommandTable(
'GitLab Duo Flags',
[
{
name: 'ccs gitlab --auth --gitlab-token-login',
summary: 'Authenticate with a GitLab Personal Access Token',
},
{
name: 'ccs gitlab --auth --token-login',
summary: 'Legacy alias for GitLab PAT login (still supported)',
},
{
name: 'ccs gitlab --auth --gitlab-url <url>',
summary: 'Use a self-hosted GitLab base URL during OAuth or PAT auth',
},
],
writeLine
);
writeLine(` ${dim('Deep help: ccs cliproxy --help | ccs api --help')}`);
writeLine('');
}
export async function showProviderShortcutHelp(
provider: CLIProxyProvider,
writeLine: HelpWriter = console.log
): Promise<void> {
if (provider === 'kiro') {
await showKiroHelp(writeLine);
return;
}
await initUI();
const providerEntry = BUILTIN_PROVIDER_SHORTCUTS.find((entry) => entry.name === provider);
writeLine(header(`CCS ${provider} Shortcut Help`));
writeLine('');
writeLine(` ${providerEntry?.summary || 'CLIProxy OAuth provider shortcut'}.`);
writeLine('');
writeCommandTable(
'Common Commands',
[
{ name: `ccs ${provider} --auth`, summary: 'Authenticate the provider account via CLIProxy' },
{ name: `ccs ${provider} --accounts`, summary: 'List or manage stored CLIProxy accounts' },
{ name: `ccs ${provider} --config`, summary: 'Open the provider config flow' },
{ name: `ccs ${provider} "task"`, summary: 'Run Claude through this provider shortcut' },
],
writeLine
);
if (provider === 'gitlab') {
writeCommandTable(
'GitLab Duo Flags',
[
{
name: '--gitlab-token-login',
summary: 'Use a GitLab Personal Access Token instead of browser OAuth',
},
{
name: '--token-login',
summary: 'Legacy alias for `--gitlab-token-login`',
},
{
name: '--gitlab-url <url>',
summary: 'Target a self-hosted GitLab base URL',
},
],
writeLine
);
}
writeLine(` ${dim('See also: ccs help providers | ccs cliproxy --help')}`);
writeLine('');
}
async function showKiroHelp(writeLine: HelpWriter): Promise<void> {
await initUI();
writeLine(header('CCS Kiro Help'));
+27
View File
@@ -12,8 +12,35 @@ export const CURSOR_SUBCOMMANDS = [
'-h',
] as const;
export const CURSOR_CLIPROXY_SHORTCUT_FLAGS = new Set([
'--auth',
'--logout',
'--config',
'--accounts',
]);
export function isCursorSubcommandToken(token?: string): boolean {
return (
Boolean(token) && CURSOR_SUBCOMMANDS.includes(token as (typeof CURSOR_SUBCOMMANDS)[number])
);
}
export function shouldUseCursorCliproxyShortcut(args: string[]): boolean {
if (args[0] !== 'cursor') {
return false;
}
for (const token of args.slice(1)) {
if (token === '--') {
break;
}
if (CURSOR_CLIPROXY_SHORTCUT_FLAGS.has(token)) {
return true;
}
if (!token.startsWith('-')) {
return false;
}
}
return false;
}
+14
View File
@@ -99,6 +99,20 @@ describe('npm CLI', () => {
assert(output.includes('Cursor Live Probe'), 'Should render the cursor probe command output');
}
});
it('routes gitlab --help to provider shortcut help instead of starting auth', function() {
const output = execSync(`bun "${srcCcsPath}" gitlab --help`, {
encoding: 'utf8',
timeout: 3000,
env: { ...process.env, CCS_HOME: testCcsHome }
});
assert(output.includes('CCS gitlab Shortcut Help'), 'Should render provider shortcut help');
assert(output.includes('--gitlab-token-login'), 'Should document canonical GitLab PAT flag');
assert(output.includes('--token-login'), 'Should document legacy GitLab PAT alias');
assert(output.includes('--gitlab-url <url>'), 'Should document self-hosted GitLab URL flag');
assert(!output.includes('Starting GitLab Duo OAuth'), 'Should not start OAuth when help is requested');
});
});
describe('Profile handling', () => {
@@ -53,6 +53,9 @@ describe('help command parity', () => {
expect(rendered.includes('gitlab')).toBe(true);
expect(rendered.includes('codebuddy')).toBe(true);
expect(rendered.includes('kilo')).toBe(true);
expect(rendered.includes('--gitlab-token-login')).toBe(true);
expect(rendered.includes('--token-login')).toBe(true);
expect(rendered.includes('--gitlab-url <url>')).toBe(true);
});
test('kiro topic documents IDC and callback flags', async () => {
@@ -0,0 +1,15 @@
import { describe, expect, it } from 'bun:test';
import { shouldUseCursorCliproxyShortcut } from '../../../src/cursor/constants';
describe('cursor CLIProxy shortcut routing', () => {
it('accepts shortcut flags after leading generic flags', () => {
expect(shouldUseCursorCliproxyShortcut(['cursor', '--auth'])).toBe(true);
expect(shouldUseCursorCliproxyShortcut(['cursor', '--verbose', '--auth'])).toBe(true);
expect(shouldUseCursorCliproxyShortcut(['cursor', '-v', '--accounts'])).toBe(true);
});
it('stops scanning once a positional legacy runtime argument appears', () => {
expect(shouldUseCursorCliproxyShortcut(['cursor', 'write', '--auth'])).toBe(false);
expect(shouldUseCursorCliproxyShortcut(['cursor', 'status'])).toBe(false);
});
});