mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 18:18:21 +00:00
feat(cursor): split legacy bridge from cliproxy provider
This commit is contained in:
1 parent
1bad3b0305
commit
3b5941c60b
36 files changed
+974
-155
No files matched your search
@@ -74,7 +74,7 @@ describe('cursor daemon lifecycle smoke', () => {
|
||||
};
|
||||
expect(anthropicBody.type).toBe('error');
|
||||
expect(anthropicBody.error?.type).toBe('authentication_error');
|
||||
expect(anthropicBody.error?.message).toContain('Run `ccs cursor auth` first');
|
||||
expect(anthropicBody.error?.message).toContain('Run `ccs legacy cursor auth` first');
|
||||
|
||||
const stopResult = await stopDaemon();
|
||||
expect(stopResult.success).toBe(true);
|
||||
|
||||
@@ -87,17 +87,22 @@ describe('npm CLI', () => {
|
||||
});
|
||||
|
||||
it('routes cursor probe through the cursor command handler', function() {
|
||||
let output = '';
|
||||
try {
|
||||
execSync(`bun "${srcCcsPath}" cursor probe`, {
|
||||
output = execSync(`bun "${srcCcsPath}" cursor probe`, {
|
||||
encoding: 'utf8',
|
||||
stdio: 'pipe',
|
||||
timeout: 3000,
|
||||
env: { ...process.env, CCS_HOME: testCcsHome }
|
||||
});
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
assert(!output.includes("Profile 'cursor' not found"), 'Should not fall through to profile lookup');
|
||||
assert(output.includes('Cursor Live Probe'), 'Should render the cursor probe command output');
|
||||
output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
}
|
||||
assert(!output.includes("Profile 'cursor' not found"), 'Should not fall through to profile lookup');
|
||||
assert(
|
||||
output.includes('Cursor Live Probe') || output.includes('legacy cursor probe'),
|
||||
'Should route through the legacy cursor compatibility handler'
|
||||
);
|
||||
});
|
||||
|
||||
it('routes gitlab --help to provider shortcut help instead of starting auth', function() {
|
||||
|
||||
@@ -202,7 +202,14 @@ describe('ProfileDetector', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should detect cursor as a first-class runtime profile when enabled', () => {
|
||||
it('should detect cursor as a CLIProxy provider shortcut', () => {
|
||||
const result = detector.detectProfileType('cursor');
|
||||
expect(result.type).toBe('cliproxy');
|
||||
expect(result.name).toBe('cursor');
|
||||
expect(result.provider).toBe('cursor');
|
||||
});
|
||||
|
||||
it('should detect legacy-cursor as a first-class runtime profile when enabled', () => {
|
||||
const isUnifiedModeSpy = spyOn(unifiedConfigLoader, 'isUnifiedMode').mockReturnValue(true);
|
||||
const getCursorConfigSpy = spyOn(unifiedConfigLoader, 'getCursorConfig').mockReturnValue({
|
||||
enabled: true,
|
||||
@@ -213,9 +220,9 @@ describe('ProfileDetector', () => {
|
||||
});
|
||||
|
||||
try {
|
||||
const result = detector.detectProfileType('cursor');
|
||||
const result = detector.detectProfileType('legacy-cursor');
|
||||
expect(result.type).toBe('cursor');
|
||||
expect(result.name).toBe('cursor');
|
||||
expect(result.name).toBe('legacy-cursor');
|
||||
expect(result.cursorConfig?.auto_start).toBe(true);
|
||||
} finally {
|
||||
isUnifiedModeSpy.mockRestore();
|
||||
@@ -223,7 +230,7 @@ describe('ProfileDetector', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should merge default cursor fields when enabled via partial unified config', () => {
|
||||
it('should merge default legacy cursor fields when enabled via partial unified config', () => {
|
||||
const originalCcsHome = process.env.CCS_HOME;
|
||||
process.env.CCS_HOME = tempDir;
|
||||
const ccsDir = path.join(tempDir, '.ccs');
|
||||
@@ -235,7 +242,7 @@ describe('ProfileDetector', () => {
|
||||
|
||||
try {
|
||||
const localDetector = new ProfileDetector();
|
||||
const result = localDetector.detectProfileType('cursor');
|
||||
const result = localDetector.detectProfileType('legacy-cursor');
|
||||
expect(result.type).toBe('cursor');
|
||||
expect(result.cursorConfig).toEqual({
|
||||
enabled: true,
|
||||
@@ -253,7 +260,7 @@ describe('ProfileDetector', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw a helpful error when cursor profile is disabled', () => {
|
||||
it('should throw a helpful error when legacy cursor profile is disabled', () => {
|
||||
const isUnifiedModeSpy = spyOn(unifiedConfigLoader, 'isUnifiedMode').mockReturnValue(true);
|
||||
const getCursorConfigSpy = spyOn(unifiedConfigLoader, 'getCursorConfig').mockReturnValue({
|
||||
enabled: false,
|
||||
@@ -264,7 +271,9 @@ describe('ProfileDetector', () => {
|
||||
});
|
||||
|
||||
try {
|
||||
expect(() => detector.detectProfileType('cursor')).toThrow(/Cursor profile is not enabled/);
|
||||
expect(() => detector.detectProfileType('legacy-cursor')).toThrow(
|
||||
/Legacy Cursor profile is not enabled/
|
||||
);
|
||||
} finally {
|
||||
isUnifiedModeSpy.mockRestore();
|
||||
getCursorConfigSpy.mockRestore();
|
||||
|
||||
@@ -140,6 +140,15 @@ describe('completion backend', () => {
|
||||
expect(suggestionValues(['cliproxy'])).toEqual(expect.arrayContaining(['remove', '--backend']));
|
||||
});
|
||||
|
||||
test('treats cursor as a provider shortcut in completion', () => {
|
||||
const values = suggestionValues(['cursor']);
|
||||
expect(values).toEqual(
|
||||
expect.arrayContaining(['--auth', '--accounts', '--config', '--logout'])
|
||||
);
|
||||
expect(values).not.toContain('probe');
|
||||
expect(values).not.toContain('start');
|
||||
});
|
||||
|
||||
test('filters suggestions by the current token prefix', () => {
|
||||
const values = suggestionValues([], 'do');
|
||||
expect(values).toEqual(expect.arrayContaining(['docker', 'doctor']));
|
||||
|
||||
@@ -322,7 +322,9 @@ describe('handleCursorCommand', () => {
|
||||
expect(exitCode).toBe(0);
|
||||
expect(errors).toHaveLength(0);
|
||||
expect(logs.some((line) => line.includes('Legacy Cursor Compatibility'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes('Usage: ccs cursor <subcommand>'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes('Usage: ccs legacy cursor <subcommand>'))).toBe(
|
||||
true
|
||||
);
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
console.error = originalError;
|
||||
@@ -423,7 +425,9 @@ describe('renderCursorStatus', () => {
|
||||
true
|
||||
);
|
||||
expect(logs.some((line) => line.includes('Next steps:'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes(' - Help: ccs cursor help'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes(' - Help: ccs legacy cursor help'))).toBe(
|
||||
true
|
||||
);
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
@@ -483,11 +487,15 @@ describe('renderCursorHelp', () => {
|
||||
const exitCode = renderCursorHelp();
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(logs.some((line) => line.includes('Usage: ccs cursor <subcommand>'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes('Legacy Cursor Compatibility'))).toBe(true);
|
||||
expect(logs.some((line) => line.includes('Deprecated: prefer CLIProxy-backed Cursor auth'))).toBe(
|
||||
expect(logs.some((line) => line.includes('Usage: ccs legacy cursor <subcommand>'))).toBe(
|
||||
true
|
||||
);
|
||||
expect(logs.some((line) => line.includes('Legacy Cursor Compatibility'))).toBe(true);
|
||||
expect(
|
||||
logs.some((line) =>
|
||||
line.includes('Deprecated: `ccs cursor` now belongs to the CLIProxy Cursor provider.')
|
||||
)
|
||||
).toBe(true);
|
||||
expect(logs.some((line) => line.includes('probe Run a live authenticated runtime probe'))).toBe(
|
||||
true
|
||||
);
|
||||
@@ -495,7 +503,7 @@ describe('renderCursorHelp', () => {
|
||||
logs.some((line) => line.includes('ccs cursor --auth'))
|
||||
).toBe(true);
|
||||
expect(
|
||||
logs.some((line) => line.includes('ccs cursor [claude args]'))
|
||||
logs.some((line) => line.includes('ccs legacy cursor [claude args]'))
|
||||
).toBe(true);
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
|
||||
@@ -82,6 +82,21 @@ describe('image-analysis-backend-resolver', () => {
|
||||
expect(status.resolutionSource).toBe('profile-backend');
|
||||
});
|
||||
|
||||
it('treats cliproxy cursor as a provider-backed profile rather than a legacy bridge alias', () => {
|
||||
const status = resolveImageAnalysisStatus(
|
||||
{
|
||||
profileName: 'cursor',
|
||||
profileType: 'cliproxy',
|
||||
cliproxyProvider: 'cursor',
|
||||
},
|
||||
DEFAULT_IMAGE_ANALYSIS_CONFIG
|
||||
);
|
||||
|
||||
expect(status.backendId).toBe('cursor');
|
||||
expect(status.resolutionSource).toBe('cliproxy-provider');
|
||||
expect(status.reason).toContain('no image-analysis model configured');
|
||||
});
|
||||
|
||||
it('uses the fallback backend for an unmapped third-party settings profile', () => {
|
||||
const status = resolveImageAnalysisStatus(
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user