fix(cursor): deprecate legacy bridge and harden gitlab auth

This commit is contained in:
Tam Nhu Tran committed 2026-04-15 01:23:15 -04:00
1 parent 93afdb50bf
commit 87d93b651b
13 files changed
+334 -95

No files matched your search

+16 -14
View File
@@ -69,6 +69,7 @@ import {
warnPossible403Ban,
} from '../account-safety';
import { ensureCliAntigravityResponsibility } from '../antigravity-responsibility';
import { InteractivePrompt } from '../../utils/prompt';
interface PasteCallbackStartData {
url?: string;
@@ -153,20 +154,21 @@ function normalizeGitLabBaseUrl(baseUrl: string | undefined): string | undefined
return normalized ? normalized : undefined;
}
async function promptGitLabPersonalAccessToken(): Promise<string | null> {
const readline = await import('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
return new Promise<string | null>((resolve) => {
rl.question('GitLab Personal Access Token: ', (answer) => {
rl.close();
const token = answer.trim();
resolve(token.length > 0 ? token : null);
});
});
export async function promptGitLabPersonalAccessToken(): Promise<string | null> {
try {
const token = (await InteractivePrompt.password('GitLab Personal Access Token')).trim();
return token.length > 0 ? token : null;
} catch (error) {
if ((error as Error).message.includes('TTY')) {
console.log(
fail(
'GitLab Personal Access Token prompt requires an interactive TTY. Set the token explicitly or use Browser OAuth.'
)
);
return null;
}
throw error;
}
}
export function findNewTokenSnapshotForManualAuth(
+12 -2
View File
@@ -152,6 +152,14 @@ export function readOptionValue(
return { present: true, value: next.trim(), missingValue: false };
}
export function hasGitLabTokenLoginFlag(args: string[]): boolean {
return args.includes('--gitlab-token-login') || args.includes('--token-login');
}
function getGitLabTokenLoginFlagName(args: string[]): '--gitlab-token-login' | '--token-login' {
return args.includes('--gitlab-token-login') ? '--gitlab-token-login' : '--token-login';
}
/**
* Execute Claude CLI with CLIProxy (main entry point)
*
@@ -353,7 +361,7 @@ export async function execClaudeWithCLIProxy(
const addAccount = argsWithoutProxy.includes('--add');
const showAccounts = argsWithoutProxy.includes('--accounts');
const forceImport = argsWithoutProxy.includes('--import');
const gitlabTokenLogin = argsWithoutProxy.includes('--token-login');
const gitlabTokenLogin = hasGitLabTokenLoginFlag(argsWithoutProxy);
const acceptAgyRisk = hasAntigravityRiskAcceptanceFlag(argsWithoutProxy);
const incognitoFlag = argsWithoutProxy.includes('--incognito');
@@ -503,7 +511,9 @@ export async function execClaudeWithCLIProxy(
}
if ((gitlabTokenLogin || gitlabBaseUrl) && provider !== 'gitlab') {
const flagName = gitlabTokenLogin ? '--token-login' : '--gitlab-url';
const flagName = gitlabTokenLogin
? getGitLabTokenLoginFlagName(argsWithoutProxy)
: '--gitlab-url';
console.error(fail(`${flagName} is only valid for ccs gitlab`));
process.exitCode = 1;
return;
+31 -20
View File
@@ -12,37 +12,46 @@ function printLines(lines: string[]): void {
export function renderCursorHelp(): number {
printLines([
'Cursor IDE Integration',
'Legacy Cursor Compatibility',
'',
'Deprecated: prefer CLIProxy-backed Cursor auth and account management.',
'Supported auth path: ccs cursor --auth',
'Supported dashboard path: ccs config -> CLIProxy -> Cursor',
'',
'Usage: ccs cursor <subcommand>',
'',
'Subcommands:',
' auth Import Cursor IDE authentication token',
' status Show integration, authentication, and daemon status',
'Subcommands (deprecated compatibility for the local reverse-engineered bridge):',
' auth Import Cursor IDE authentication token (deprecated)',
' status Show legacy integration, authentication, and daemon status',
' probe Run a live authenticated runtime probe',
' models List available models',
' start Start cursor daemon',
' stop Stop cursor daemon',
' enable Enable cursor integration in unified config',
' disable Disable cursor integration in unified config',
' start Start local cursor daemon',
' stop Stop local cursor daemon',
' enable Enable legacy cursor integration in unified config',
' disable Disable legacy cursor integration in unified config',
' help Show this help message',
'',
'Runtime entry:',
' ccs cursor [claude args] # Run Claude via the local Cursor proxy',
'Supported CLIProxy path:',
' ccs cursor --auth # Authenticate Cursor via CLIProxy',
' ccs cursor --accounts # Manage CLIProxy Cursor accounts',
' ccs cursor --config # Open CLIProxy Cursor settings',
'',
'Auth options:',
' ccs cursor auth # Auto-detect from Cursor SQLite',
'Legacy runtime entry (deprecated compatibility):',
' ccs cursor [claude args] # Run Claude via the local Cursor bridge',
'',
'Legacy auth options:',
' ccs cursor auth # Auto-detect from Cursor SQLite (deprecated)',
' ccs cursor auth --manual --token <t> --machine-id <id>',
'',
'Quick start:',
' 1. ccs cursor enable # Enable integration',
' 2. ccs cursor auth # Import Cursor IDE token',
' 3. ccs cursor start # Start daemon',
'Legacy bridge quick start:',
' 1. ccs cursor enable # Deprecated compatibility: enable local bridge',
' 2. ccs cursor auth # Deprecated compatibility: import Cursor IDE token',
' 3. ccs cursor start # Start local daemon',
' 4. ccs cursor probe # Verify live runtime health',
' 5. ccs cursor "task" # Run Claude through Cursor',
' 5. ccs cursor "task" # Run Claude through the local bridge',
' 6. ccs cursor status # Inspect auth/daemon wiring',
'',
'Or use the web UI: ccs config -> Cursor page',
'Web UI: ccs config -> Deprecated -> Cursor IDE',
'',
]);
@@ -100,7 +109,8 @@ export function renderCursorStatus(
console.log('');
console.log('Client setup:');
console.log(` Raw settings: ${dirDisplay}/cursor.settings.json`);
console.log(' Runtime entry: ccs cursor [claude args]');
console.log(' Runtime entry: ccs cursor [claude args] (deprecated compatibility)');
console.log(' Supported auth: ccs cursor --auth');
console.log(' Live probe: ccs cursor probe');
console.log(' Status command: ccs cursor status');
console.log(' Help command: ccs cursor help');
@@ -116,7 +126,8 @@ export function renderCursorStatus(
console.log(' - Enable: ccs cursor enable');
}
if (!authStatus.authenticated || authStatus.expired) {
console.log(' - Auth: ccs cursor auth');
console.log(' - Supported: ccs cursor --auth');
console.log(' - Legacy auth: ccs cursor auth');
}
if (!daemonStatus.running) {
console.log(' - Start: ccs cursor start');
+20
View File
@@ -26,6 +26,15 @@ import {
} from './cursor-command-display';
import { ok, fail, info } from '../utils/ui';
function printLegacyCursorDeprecationNotice(): void {
console.log(
info(
'Deprecated compatibility path. Prefer CLIProxy-backed Cursor auth via `ccs cursor --auth` or the CLIProxy dashboard.'
)
);
console.log('');
}
/**
* Handle cursor subcommand.
*/
@@ -114,6 +123,7 @@ function printAutoDetectFailure(result: {
* Handle auth subcommand.
*/
async function handleAuth(args: string[]): Promise<number> {
printLegacyCursorDeprecationNotice();
const manual = args.includes('--manual');
if (manual) {
@@ -146,6 +156,7 @@ async function handleAuth(args: string[]): Promise<number> {
console.log(ok('Cursor credentials imported (manual mode)'));
console.log('');
console.log('Next steps:');
console.log(' 0. Preferred auth: ccs cursor --auth');
console.log(' 1. Enable integration: ccs cursor enable');
console.log(' 2. Start daemon: ccs cursor start');
return 0;
@@ -168,6 +179,7 @@ async function handleAuth(args: string[]): Promise<number> {
console.log(ok('Auto-detected Cursor credentials'));
console.log('');
console.log('Next steps:');
console.log(' 0. Preferred auth: ccs cursor --auth');
console.log(' 1. Enable integration: ccs cursor enable');
console.log(' 2. Start daemon: ccs cursor start');
console.log(' 3. Check status: ccs cursor status');
@@ -185,6 +197,7 @@ async function handleAuth(args: string[]): Promise<number> {
}
async function handleStatus(): Promise<number> {
printLegacyCursorDeprecationNotice();
const cursorConfig = getCursorConfig();
const authStatus = checkAuthStatus();
const daemonStatus = await getDaemonStatus(cursorConfig.port);
@@ -193,6 +206,7 @@ async function handleStatus(): Promise<number> {
}
async function handleProbe(): Promise<number> {
printLegacyCursorDeprecationNotice();
const cursorConfig = getCursorConfig();
const result = await probeCursorRuntime(cursorConfig);
renderCursorProbe(result);
@@ -200,6 +214,7 @@ async function handleProbe(): Promise<number> {
}
async function handleModels(): Promise<number> {
printLegacyCursorDeprecationNotice();
const cursorConfig = getCursorConfig();
const models = await getAvailableModels(cursorConfig.port);
const defaultModel = getDefaultModel();
@@ -211,6 +226,7 @@ async function handleModels(): Promise<number> {
* Handle start subcommand.
*/
async function handleStart(): Promise<number> {
printLegacyCursorDeprecationNotice();
const cursorConfig = getCursorConfig();
if (!cursorConfig.enabled) {
@@ -248,6 +264,7 @@ async function handleStart(): Promise<number> {
* Handle stop subcommand.
*/
async function handleStop(): Promise<number> {
printLegacyCursorDeprecationNotice();
console.log(info('Stopping cursor daemon...'));
const result = await stopDaemon();
@@ -265,6 +282,7 @@ async function handleStop(): Promise<number> {
* Handle enable subcommand.
*/
async function handleEnable(): Promise<number> {
printLegacyCursorDeprecationNotice();
mutateUnifiedConfig((config) => {
if (!config.cursor) {
config.cursor = { ...DEFAULT_CURSOR_CONFIG };
@@ -276,6 +294,7 @@ async function handleEnable(): Promise<number> {
console.log(ok('Cursor integration enabled'));
console.log('');
console.log('Next steps:');
console.log(' 0. Preferred auth: ccs cursor --auth');
console.log(' 1. Authenticate: ccs cursor auth');
console.log(' 2. Start daemon: ccs cursor start');
console.log(' 3. Check status: ccs cursor status');
@@ -287,6 +306,7 @@ async function handleEnable(): Promise<number> {
* Handle disable subcommand.
*/
async function handleDisable(): Promise<number> {
printLegacyCursorDeprecationNotice();
mutateUnifiedConfig((config) => {
if (config.cursor) {
config.cursor.enabled = false;