Cursor harness reference
CursorCliOpts (packages/core/src/cursor-cli.ts) configures the cursor() harness factory (CursorOpts is an alias for the same type) for headless/worker use. Pass it as cursor(opts); every field is optional.
CursorCliOpts
| Option | Type | Default | When to set |
|---|---|---|---|
binary | string | 'cursor-agent' (resolved via PATH) | Worker environments (systemd, containers) with a minimal PATH; pass an absolute path. |
model | CursorModel | Cursor CLI default | Pin a default model for all turns from this harness instance; per-turn run.model/opts.model overrides it. |
apiKey | string | inherits CURSOR_API_KEY from process.env if unset | Headless auth without relying on ambient environment. Forwarded to the child process as CURSOR_API_KEY, never as an argv flag. |
defaultTimeoutMs | number | 1_800_000 (30 min) | Change the default per-turn timeout for this harness instance; per-call run.timeoutMs still overrides it. |
Current cursor-agent releases no longer expose Orchard's previous trust/headers/workspace/addDirs/pluginDirs/sandbox/approveMcps flags. Orchard intentionally does not retain compatibility shims for those removed options.
Cursor currently has no stable headless sandbox flag in this wrapper. Orchard still accepts the shared access: 'read' | 'edit' intent for harness-neutral task code, but Cursor turns use the supported headless flags directly.
Per-run options (CursorRunOpts)
These are set per runUnstructuredTurn/runStructuredTurn call via HarnessTurnOptions (the harness-agnostic options harnessCall accepts), not on CursorCliOpts:
| Option | Type | Notes |
|---|---|---|
cwd | string | Required; working directory for the CLI process. |
force | boolean | Defaults to true; passes --trust for headless workspace trust. |
resume | string | Resumes a prior session by ID (used for same-session structured-output repair). |
model | HarnessModel | Per-turn override of CursorCliOpts.model. |
timeoutMs | number | Per-turn override of defaultTimeoutMs. |
onEvent | (event: unknown) => void | Receives parsed raw cursor-agent --output-format stream-json events for progress reporting. |
Example
import { DEFAULT_CURSOR_MODEL, cursor } from '@snevins/orchard-core/harness'
const harness = cursor({
binary: '/usr/local/bin/cursor-agent',
model: DEFAULT_CURSOR_MODEL,
defaultTimeoutMs: 900_000,
})Supported model catalog
SUPPORTED_CURSOR_MODELS currently covers the Cursor first-party models Orchard routes to directly: Auto, Composer 2.5, and Grok 4.5 variants from cursor-agent models.
Current entries: auto, composer-2.5, composer-2.5-fast, grok-4.5-medium, grok-4.5-fast-medium, grok-4.5-high, grok-4.5-fast-high, grok-4.5-xhigh, and grok-4.5-fast-xhigh.
The CursorModel type includes those known values while still accepting custom strings so account-specific or newly released Cursor models continue to pass through to cursor-agent.
Failure classification
cursor-agent failures are classified by classifyCursorFailure(exitCode, stderr) into a CursorCliError with a kind ('auth' | 'usage' | 'timeout' | 'crash' | 'agent' | 'spawn') and retryable flag:
'auth'and'usage'failures are not retryable (bad credentials or CLI flags will not succeed on retry).'crash'(non-zero exit without a recognized auth/usage pattern) is retryable.'timeout'(the run exceededtimeoutMs) is retryable.'spawn'(binary not found) is not retryable.'agent'(the CLI itself reportedis_error: truein its result event) is retryable.
cursor() prefixes both retryable and non-retryable failures with cursor: and rethrows non-retryable CursorCliErrors as NonRetryableHarnessError so the runtime does not retry unrecoverable failures. See Handle Orchard errors.