/** * Cursor CLI executor using simple JSONL stream protocol. * * The simplest agent protocol - unidirectional output with auto-approval * via --force flag. Supports 11 built-in tools and MCP server integration. * * @module agents/cursor/executor */ import { BaseAgentExecutor } from "../base/base-executor.js"; import type { ExecutionTask } from "../../engine/types.js"; import type { SpawnedChild, OutputChunk, NormalizedEntry, AgentCapabilities } from "../types/agent-executor.js"; import type { CursorConfig } from "./types/config.js"; /** * Cursor CLI executor using simple JSONL stream protocol. * * This is the simplest agent executor - unidirectional output with no * bidirectional communication. The --force flag enables auto-approval * of all tool executions, making it ideal for automated workflows. * * @example Basic usage * ```typescript * const executor = new CursorExecutor({ * force: true, // Auto-approve all tools * model: 'auto' // Use default model selection * }); * * const spawned = await executor.executeTask({ * id: 'task-1', * type: 'custom', * prompt: 'Add login feature', * workDir: '/path/to/project', * config: {}, * }); * * // Process normalized output * const outputStream = executor.createOutputChunks(spawned.process); * for await (const entry of executor.normalizeOutput(outputStream, '/path/to/project')) { * console.log(entry.type.kind, entry.content); * } * ``` * * @example Session resumption * ```typescript * // Execute initial task * const spawned1 = await executor.executeTask({ * id: 'task-1', * prompt: 'Start implementing login', * workDir: '/project', * config: {}, * }); * * // ... extract session ID from output ... * const sessionId = 'sess-abc123'; * * // Resume with new prompt * const spawned2 = await executor.resumeTask({ * id: 'task-2', * prompt: 'Continue with logout feature', * workDir: '/project', * config: {}, * }, sessionId); * ``` * * @example Custom model selection * ```typescript * const executor = new CursorExecutor({ * force: true, * model: 'sonnet-4.5', // Use Claude Sonnet 4.5 * appendPrompt: '\n\nPlease include unit tests.' * }); * ``` */ export declare class CursorExecutor extends BaseAgentExecutor { private config; /** * Create a new Cursor executor. * * @param config - Configuration options */ constructor(config?: CursorConfig); /** * Execute a new task with Cursor CLI. * * Spawns cursor-agent process with the specified configuration, * sends the prompt to stdin, and immediately closes stdin * (unidirectional protocol). * * @param task - Task to execute * @returns Spawned child process * @throws {Error} If cursor-agent is not available or spawn fails * * @example * ```typescript * const spawned = await executor.executeTask({ * id: 'task-1', * type: 'custom', * prompt: 'Implement user authentication', * workDir: '/path/to/project', * config: {}, * }); * * console.log('Process PID:', spawned.process.pid); * ``` */ executeTask(task: ExecutionTask): Promise; /** * Resume a previous task session. * * Spawns cursor-agent with --resume flag to continue from a * previous session, allowing multi-turn interactions. * * @param task - Task with new prompt * @param sessionId - Session ID to resume (e.g., 'sess-abc123') * @returns Spawned child process * @throws {Error} If cursor-agent is not available or spawn fails * * @example * ```typescript * // Resume from previous session * const spawned = await executor.resumeTask({ * id: 'task-2', * type: 'custom', * prompt: 'Now add logout functionality', * workDir: '/path/to/project', * config: {}, * }, 'sess-abc123'); * ``` */ resumeTask(task: ExecutionTask, sessionId: string): Promise; /** * Normalize Cursor JSONL output to unified format. * * Parses line-delimited JSON from Cursor CLI and converts to * normalized entries. Handles streaming message coalescing, * session metadata extraction, and authentication error detection. * * @param outputStream - Stream of output chunks * @param workDir - Working directory for path resolution * @returns Async iterable of normalized entries * * @example * ```typescript * const spawned = await executor.executeTask(task); * const outputStream = executor.createOutputChunks(spawned.process); * * for await (const entry of executor.normalizeOutput(outputStream, task.workDir)) { * console.log(entry.type.kind, entry.content); * } * ``` */ normalizeOutput(outputStream: AsyncIterable, workDir: string): AsyncIterable; /** * Get Cursor executor capabilities. * * @returns Agent capabilities descriptor * * @example * ```typescript * const caps = executor.getCapabilities(); * console.log('Supports resume:', caps.supportsSessionResume); // true * console.log('Protocol:', caps.protocol); // 'jsonl' * console.log('Approvals:', caps.supportsApprovals); // false (uses --force) * ``` */ getCapabilities(): AgentCapabilities; /** * Check if Cursor CLI is available. * * Checks if cursor-agent executable exists in PATH. * * @returns True if cursor-agent is available, false otherwise * * @example * ```typescript * const available = await executor.checkAvailability(); * if (!available) { * console.error('Please install Cursor CLI: https://cursor.sh'); * } * ``` */ checkAvailability(): Promise; /** * Build command-line arguments for cursor-agent. * * @param sessionId - Optional session ID for resumption * @returns Array of command-line arguments * @private */ private buildArgs; /** * Build full prompt with optional appendPrompt. * * @param userPrompt - User's original prompt * @returns Full prompt with optional suffix * @private */ private buildPrompt; } //# sourceMappingURL=executor.d.ts.map