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

View File

@@ -4,19 +4,19 @@
## Status Overview
| Phase | Name | Status | Test Status |
| ----- | ------------------------------------------------------------ | --------- | ----------- |
| 0 | [Analysis & Documentation](phases/phase-0-analysis.md) | `pending` | - |
| 1 | [Core Types & Configuration](phases/phase-1-types.md) | `pending` | - |
| 2 | [Cursor Provider Implementation](phases/phase-2-provider.md) | `pending` | - |
| 3 | [Provider Factory Integration](phases/phase-3-factory.md) | `pending` | - |
| 4 | [Setup Routes & Status Endpoints](phases/phase-4-routes.md) | `pending` | - |
| 5 | [Log Parser Integration](phases/phase-5-log-parser.md) | `pending` | - |
| 6 | [UI Setup Wizard](phases/phase-6-setup-wizard.md) | `pending` | - |
| 7 | [Settings View Provider Tabs](phases/phase-7-settings.md) | `pending` | - |
| 8 | [AI Profiles Integration](phases/phase-8-profiles.md) | `pending` | - |
| 9 | [Task Execution Integration](phases/phase-9-execution.md) | `pending` | - |
| 10 | [Testing & Validation](phases/phase-10-testing.md) | `pending` | - |
| Phase | Name | Status | Test Status |
| ----- | ------------------------------------------------------------ | ----------- | ----------- |
| 0 | [Analysis & Documentation](phases/phase-0-analysis.md) | `completed` | |
| 1 | [Core Types & Configuration](phases/phase-1-types.md) | `completed` | |
| 2 | [Cursor Provider Implementation](phases/phase-2-provider.md) | `pending` | - |
| 3 | [Provider Factory Integration](phases/phase-3-factory.md) | `pending` | - |
| 4 | [Setup Routes & Status Endpoints](phases/phase-4-routes.md) | `pending` | - |
| 5 | [Log Parser Integration](phases/phase-5-log-parser.md) | `pending` | - |
| 6 | [UI Setup Wizard](phases/phase-6-setup-wizard.md) | `pending` | - |
| 7 | [Settings View Provider Tabs](phases/phase-7-settings.md) | `pending` | - |
| 8 | [AI Profiles Integration](phases/phase-8-profiles.md) | `pending` | - |
| 9 | [Task Execution Integration](phases/phase-9-execution.md) | `pending` | - |
| 10 | [Testing & Validation](phases/phase-10-testing.md) | `pending` | - |
**Status Legend:** `pending` | `in_progress` | `completed` | `blocked`

View File

@@ -1,6 +1,6 @@
# Phase 1: Core Types & Configuration
**Status:** `pending`
**Status:** `completed`
**Dependencies:** Phase 0 (Analysis)
**Estimated Effort:** Small (type definitions only)
@@ -16,7 +16,7 @@ Define all Cursor-specific types and extend existing types to support the new pr
### Task 1.1: Create Cursor Model Definitions
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/cursor-models.ts`
@@ -124,7 +124,7 @@ export function getAllCursorModelIds(): CursorModelId[] {
### Task 1.2: Create Cursor CLI Types
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/cursor-cli.ts`
@@ -247,7 +247,7 @@ export type CursorStreamEvent =
### Task 1.3: Extend ModelProvider Type
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/settings.ts`
@@ -263,7 +263,7 @@ export type ModelProvider = 'claude' | 'cursor';
### Task 1.4: Add Cursor Profile Config Type
**Status:** `pending`
**Status:** `skipped` (not needed - thinking is embedded in model ID)
**File:** `libs/types/src/settings.ts`
@@ -282,7 +282,7 @@ export interface CursorProfileConfig {
### Task 1.5: Update ModelOption Interface
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/model-display.ts`
@@ -312,7 +312,7 @@ export interface ModelOption {
### Task 1.6: Extend DEFAULT_MODELS
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/model.ts`
@@ -333,7 +333,7 @@ export const DEFAULT_MODELS = {
### Task 1.7: Update Type Exports
**Status:** `pending`
**Status:** `completed`
**File:** `libs/types/src/index.ts`