feat: Add Cursor CLI types and models

- Introduced new types and interfaces for Cursor CLI configuration, authentication status, and event handling.
- Created a comprehensive model definition for Cursor models, including metadata and helper functions.
- Updated existing interfaces to support both Claude and Cursor models in the UI.
- Enhanced the default model configuration to include Cursor's recommended default.
- Updated type exports to include new Cursor-related definitions.
This commit is contained in:
Shirone
2025-12-28 00:37:07 +01:00
parent 2fae948edb
commit 8b1f5975d9
8 changed files with 246 additions and 27 deletions

View File

@@ -0,0 +1,114 @@
import type { CursorModelId } from './cursor-models.js';
/**
* Cursor CLI configuration file schema
* Stored in: .automaker/cursor-config.json
*/
export interface CursorCliConfig {
defaultModel?: CursorModelId;
models?: CursorModelId[]; // Enabled models
mcpServers?: string[]; // MCP server configs to load
rules?: string[]; // .cursor/rules paths
}
/**
* Cursor authentication status
*/
export interface CursorAuthStatus {
authenticated: boolean;
method: 'login' | 'api_key' | 'none';
hasCredentialsFile?: boolean;
}
/**
* NOTE: Reuse existing InstallationStatus from provider.ts
* The existing type already has: installed, path, version, method, hasApiKey, authenticated
*
* Add 'login' to the method union if needed:
* method?: 'cli' | 'npm' | 'brew' | 'sdk' | 'login';
*/
/**
* Cursor stream-json event types (from CLI output)
*/
export interface CursorSystemEvent {
type: 'system';
subtype: 'init';
apiKeySource: 'env' | 'flag' | 'login';
cwd: string;
session_id: string;
model: string;
permissionMode: string;
}
export interface CursorUserEvent {
type: 'user';
message: {
role: 'user';
content: Array<{ type: 'text'; text: string }>;
};
session_id: string;
}
export interface CursorAssistantEvent {
type: 'assistant';
message: {
role: 'assistant';
content: Array<{ type: 'text'; text: string }>;
};
session_id: string;
}
export interface CursorToolCallEvent {
type: 'tool_call';
subtype: 'started' | 'completed';
call_id: string;
tool_call: {
readToolCall?: {
args: { path: string };
result?: {
success?: {
content: string;
isEmpty: boolean;
exceededLimit: boolean;
totalLines: number;
totalChars: number;
};
};
};
writeToolCall?: {
args: { path: string; fileText: string; toolCallId?: string };
result?: {
success?: {
path: string;
linesCreated: number;
fileSize: number;
};
};
};
function?: {
name: string;
arguments: string;
};
};
session_id: string;
}
export interface CursorResultEvent {
type: 'result';
subtype: 'success' | 'error';
duration_ms: number;
duration_api_ms: number;
is_error: boolean;
result: string;
session_id: string;
request_id?: string;
error?: string;
}
export type CursorStreamEvent =
| CursorSystemEvent
| CursorUserEvent
| CursorAssistantEvent
| CursorToolCallEvent
| CursorResultEvent;

View File

@@ -0,0 +1,99 @@
/**
* Cursor CLI Model IDs
* Reference: https://cursor.com/docs
*/
export type CursorModelId =
| 'auto' // Auto-select best model
| 'claude-sonnet-4' // Claude Sonnet 4
| 'claude-sonnet-4-thinking' // Claude Sonnet 4 with extended thinking
| 'gpt-4o' // GPT-4o
| 'gpt-4o-mini' // GPT-4o Mini
| 'gemini-2.5-pro' // Gemini 2.5 Pro
| 'o3-mini'; // O3 Mini
/**
* Cursor model metadata
*/
export interface CursorModelConfig {
id: CursorModelId;
label: string;
description: string;
hasThinking: boolean;
tier: 'free' | 'pro';
}
/**
* Complete model map for Cursor CLI
*/
export const CURSOR_MODEL_MAP: Record<CursorModelId, CursorModelConfig> = {
auto: {
id: 'auto',
label: 'Auto (Recommended)',
description: 'Automatically selects the best model for each task',
hasThinking: false,
tier: 'free',
},
'claude-sonnet-4': {
id: 'claude-sonnet-4',
label: 'Claude Sonnet 4',
description: 'Anthropic Claude Sonnet 4 via Cursor',
hasThinking: false,
tier: 'pro',
},
'claude-sonnet-4-thinking': {
id: 'claude-sonnet-4-thinking',
label: 'Claude Sonnet 4 (Thinking)',
description: 'Claude Sonnet 4 with extended thinking enabled',
hasThinking: true,
tier: 'pro',
},
'gpt-4o': {
id: 'gpt-4o',
label: 'GPT-4o',
description: 'OpenAI GPT-4o via Cursor',
hasThinking: false,
tier: 'pro',
},
'gpt-4o-mini': {
id: 'gpt-4o-mini',
label: 'GPT-4o Mini',
description: 'OpenAI GPT-4o Mini (faster, cheaper)',
hasThinking: false,
tier: 'free',
},
'gemini-2.5-pro': {
id: 'gemini-2.5-pro',
label: 'Gemini 2.5 Pro',
description: 'Google Gemini 2.5 Pro via Cursor',
hasThinking: false,
tier: 'pro',
},
'o3-mini': {
id: 'o3-mini',
label: 'O3 Mini',
description: 'OpenAI O3 Mini reasoning model',
hasThinking: true,
tier: 'pro',
},
};
/**
* Helper: Check if model has thinking capability
*/
export function cursorModelHasThinking(modelId: CursorModelId): boolean {
return CURSOR_MODEL_MAP[modelId]?.hasThinking ?? false;
}
/**
* Helper: Get display name for model
*/
export function getCursorModelLabel(modelId: CursorModelId): string {
return CURSOR_MODEL_MAP[modelId]?.label ?? modelId;
}
/**
* Helper: Get all cursor model IDs
*/
export function getAllCursorModelIds(): CursorModelId[] {
return Object.keys(CURSOR_MODEL_MAP) as CursorModelId[];
}

View File

@@ -105,3 +105,7 @@ export type {
BacklogPlanRequest,
BacklogPlanApplyResult,
} from './backlog-plan.js';
// Cursor types
export * from './cursor-models.js';
export * from './cursor-cli.js';

View File

@@ -5,22 +5,23 @@
* and thinking levels used throughout the application UI.
*/
import type { AgentModel, ThinkingLevel } from './settings.js';
import type { AgentModel, ThinkingLevel, ModelProvider } from './settings.js';
import type { CursorModelId } from './cursor-models.js';
/**
* ModelOption - Display metadata for a model option in the UI
*/
export interface ModelOption {
/** Model identifier */
id: AgentModel;
/** Model identifier (supports both Claude and Cursor models) */
id: AgentModel | CursorModelId;
/** Display name shown to user */
label: string;
/** Descriptive text explaining model capabilities */
description: string;
/** Optional badge text (e.g., "Speed", "Balanced", "Premium") */
badge?: string;
/** AI provider (currently only "claude") */
provider: 'claude';
/** AI provider (supports 'claude' and 'cursor') */
provider: ModelProvider;
}
/**

View File

@@ -12,6 +12,7 @@ export const CLAUDE_MODEL_MAP: Record<string, string> = {
*/
export const DEFAULT_MODELS = {
claude: 'claude-opus-4-5-20251101',
cursor: 'auto', // Cursor's recommended default
} as const;
export type ModelAlias = keyof typeof CLAUDE_MODEL_MAP;

View File

@@ -68,7 +68,7 @@ export type PlanningMode = 'skip' | 'lite' | 'spec' | 'full';
export type ThinkingLevel = 'none' | 'low' | 'medium' | 'high' | 'ultrathink';
/** ModelProvider - AI model provider for credentials and API key management */
export type ModelProvider = 'claude';
export type ModelProvider = 'claude' | 'cursor';
/**
* WindowBounds - Electron window position and size for persistence