commands/omega-cursor-cli.md
--- disable-model-invocation: true --- Invoke the omega-cursor-cli skill and follow it exactly as presented to you
oimiragieo/agent-studio · GitHub
Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription.
프로젝트 폴더에서 아래 명령어를 실행하고, 설치할 에이전트를 선택하세요.
npx skills add oimiragieo/agent-studio --skill omega-cursor-cli설치 명령을 직접 실행해야 적용됩니다. 지원 에이전트와 필요한 권한·라이선스는 제작자의 안내를 확인하세요.
commands/omega-cursor-cli.md--- disable-model-invocation: true --- Invoke the omega-cursor-cli skill and follow it exactly as presented to you
hooks/post-execute.cjs'use strict';
/**
* Post-execute hook for omega-cursor-cli
* Auto-generated by enterprise-bundle-scaffolder
*
* Records metrics after skill execution.
*/
function postExecute(_context) {
// Record execution metrics
return { ok: true, skill: 'omega-cursor-cli' };
}
module.exports = { postExecute };
hooks/pre-execute.cjs'use strict';
/**
* Pre-execute hook for omega-cursor-cli
* Auto-generated by enterprise-bundle-scaffolder
*
* Validates inputs before skill execution.
*/
function preExecute(context) {
// Validate skill invocation context
if (!context || typeof context !== 'object') {
return { allow: true, message: 'omega-cursor-cli: no context to validate' };
}
return { allow: true };
}
module.exports = { preExecute };
references/antigravity.md# Antigravity surface This repo includes `.agent/skills/omega-cursor-cli/SKILL.md` for Antigravity routing to: ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "PROMPT" ```
references/auth.md# Authentication If `cursor-agent` commands fail due to authentication, run: ```bash cursor-agent login ``` If your environment prompts through an interactive flow, complete it once, then retry your headless command.
references/copilot-cli.md# Copilot CLI note This repo centers on Cursor Agent CLI headless execution. If using GitHub Copilot CLI separately, keep it independent from this wrapper. The omega-cursor-cli scripts invoke Cursor Agent, not Copilot.
references/copy-and-run.md# Copy and run To move this setup to another repo, copy at minimum: - `.claude/skills/omega-cursor-cli/` Optional host integrations: - `.cursor/` for Cursor rule routing - `.agents/` for Codex/Codex-like agents - `.agent/` for Antigravity - `.vscode/` for tasks All script paths are relative to the destination project root.
references/cursor-agent.md# Codex-like agent surface This repo includes `.agents/skills/omega-cursor-cli/SKILL.md` to route Codex/Codex-like workflows to the shared wrapper: ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "PROMPT" ``` The canonical instructions live in `.claude/skills/omega-cursor-cli/SKILL.md`.
references/cursor.md# Cursor surface Cursor rules in `.cursor/rules/` route "ask cursor" style requests to: ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "PROMPT" ``` Copy `.claude` and `.cursor` together when moving this setup.
references/headless.md# Headless Cursor Agent Use the wrapper script from project root: ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "PROMPT" ``` Direct equivalent: ```bash cursor-agent --print --output-format text "PROMPT" ``` Options supported by the wrapper: - `--model MODEL` - `--json` (`--output-format json`) - `--yolo` (`--force` / auto-approve all tool calls) - `--trust` (trust workspace without prompting, headless only) - `--timeout-ms N` - `--sandbox` (deprecated alias for `--yolo`)
references/installation.md# Installation 1. Install Node.js 18+. 2. Install Cursor Agent CLI: ```bash npm install -g @cursor/agent ``` 3. Verify setup: ```bash node .claude/skills/omega-cursor-cli/scripts/verify-setup.mjs ``` 4. Authenticate if needed: ```bash cursor-agent login ```
references/research-requirements.md# omega-cursor-cli Research Requirements Generated: 2026-02-24 ## Skill Description Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription. ## Research Areas - Current best practices for omega-cursor-cli - Industry standards and tooling - Integration patterns ## Source References - To be populated by skill-updater research phase
references/vscode.md# VS Code surface Tasks in `.vscode/tasks.json` expose: - `Ask Cursor` - `Omega Cursor: Verify setup`
rules/omega-cursor-cli.md# omega-cursor-cli Rules ## Purpose Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription. ## Best Practices - Always run verify-setup.mjs before first invocation - Cursor subscription is required -- most restrictive availability of all omega tools - Use --yolo for non-interactive headless mode (auto-approves all tool calls) - Use --trust for workspace trust without prompting - Use auto model for Cursor's intelligent model routing ## Integration Points See SKILL.md for complete documentation.
schemas/input.schema.json{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "omega-cursor-cliInput",
"description": "Input schema for Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription.",
"type": "object",
"additionalProperties": true,
"properties": {
"target": {
"type": "string",
"description": "Target file or path for the skill to operate on"
},
"options": {
"type": "object",
"description": "Additional options for skill execution",
"additionalProperties": true
}
}
}
schemas/output.schema.json{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "omega-cursor-cliOutput",
"type": "object",
"additionalProperties": true,
"properties": {
"ok": {
"type": "boolean"
},
"summary": {
"type": "string"
}
}
}
scripts/ask-cursor.mjs#!/usr/bin/env node
/**
* Headless Cursor Agent CLI wrapper.
* Usage:
* node ask-cursor.mjs "your prompt" [--model MODEL] [--json] [--yolo] [--trust] [--timeout-ms N]
* echo "prompt" | node ask-cursor.mjs [--model MODEL] [--json] [--yolo] [--trust] [--timeout-ms N]
*/
import { spawn } from 'child_process';
import path from 'path';
import { createInterface } from 'readline';
import { fileURLToPath } from 'url';
import { assertNonEmptyPrompt, parseCliArgs } from './parse-args.mjs';
const USAGE =
'Usage: node ask-cursor.mjs "prompt" [--model MODEL] [--json] [--yolo] [--trust] [--timeout-ms N]\n' +
' echo "prompt" | node ask-cursor.mjs [options] (prompt from stdin)\n' +
'Notes: --json maps to --output-format json; --yolo maps to --force (auto-approve all);\n' +
' --trust trusts the workspace without prompting (headless only);\n' +
' --sandbox is a deprecated alias for --yolo.\n' +
'Exit codes: 0 success, 1 error, 124 timeout';
const MAX_STDIN_BYTES_DEFAULT = 50 * 1024 * 1024;
const MAX_STDIN_BYTES = Number.parseInt(process.env.ASK_CURSOR_MAX_STDIN_BYTES, 10);
const EFFECTIVE_MAX_STDIN_BYTES =
Number.isInteger(MAX_STDIN_BYTES) && MAX_STDIN_BYTES > 0
? MAX_STDIN_BYTES
: MAX_STDIN_BYTES_DEFAULT;
export function buildCursorArgs({ prompt, model, outputJson, yolo, trust, approveMcps }) {
const cliArgs = ['--print', '--output-format', outputJson ? 'json' : 'text'];
if (yolo) cliArgs.push('--yolo');
if (trust) cliArgs.push('--trust');
if (approveMcps) cliArgs.push('--approve-mcps');
if (model) cliArgs.push('--model', model);
cliArgs.push(prompt.trim());
return cliArgs;
}
/**
* Escape percent signs in an argument that will be passed through cmd.exe.
* cmd.exe expands %VAR% even inside double-quoted arguments, so % must be
* doubled to %% to be passed literally to the target process.
*/
function escapeCmdExeArg(s) {
return s.replace(/%/g, '%%');
}
export function getExecutables(cliArgs, isWin) {
if (isWin) {
// Escape the prompt (last arg) so cmd.exe does not expand %VAR% references.
const safeCmdArgs = [...cliArgs.slice(0, -1), escapeCmdExeArg(cliArgs[cliArgs.length - 1])];
const configuredCursorAgentCmd = process.env.CURSOR_AGENT_CMD_PATH;
const localAppData = process.env.LOCALAPPDATA;
const userProfile = process.env.USERPROFILE;
const derivedCursorAgentCmd = localAppData
? path.win32.join(localAppData, 'cursor-agent', 'cursor-agent.cmd')
: userProfile
? path.win32.join(userProfile, 'AppData', 'Local', 'cursor-agent', 'cursor-agent.cmd')
: null;
const fallbackCursorAgentCmd =
configuredCursorAgentCmd && configuredCursorAgentCmd.trim()
? configuredCursorAgentCmd.trim()
: derivedCursorAgentCmd;
const fallbackCandidate = fallbackCursorAgentCmd
? [
{
executable: 'cmd.exe',
args: ['/d', '/s', '/c', fallbackCursorAgentCmd, ...safeCmdArgs],
notFoundPattern: /not recognized as an internal or external command/i,
},
]
: [];
return [
{
executable: 'cmd.exe',
args: ['/d', '/s', '/c', 'agent', ...safeCmdArgs],
notFoundPattern: /not recognized as an internal or external command/i,
},
{
executable: 'cmd.exe',
args: ['/d', '/s', '/c', 'cursor-agent', ...safeCmdArgs],
notFoundPattern: /not recognized as an internal or external command/i,
},
...fallbackCandidate,
{
executable: 'cmd.exe',
args: ['/d', '/s', '/c', 'npx', '-y', '@cursor/agent', ...safeCmdArgs],
notFoundPattern: /not recognized as an internal or external command/i,
},
];
}
return [
{ executable: 'agent', args: cliArgs },
{ executable: 'cursor-agent', args: cliArgs },
{ executable: 'npx', args: ['-y', '@cursor/agent', ...cliArgs] },
];
}
function runCandidate(candidate, runOptions, timeoutMs) {
return new Promise(resolve => {
let proc;
try {
proc = spawn(candidate.executable, candidate.args, runOptions);
} catch (err) {
if (err && (err.code === 'ENOENT' || err.code === 'EINVAL')) {
resolve({ enoent: true });
return;
}
resolve({
code: 1,
stdout: '',
stderr: `Failed to start ${candidate.executable}: ${err && err.message ? err.message : String(err)}`,
timedOut: false,
});
return;
}
let stdout = '';
let stderr = '';
let timedOut = false;
let timer = null;
let killPromise = null;
let settled = false;
function finish(value) {
if (settled) return;
settled = true;
resolve(value);
}
proc.stdout.setEncoding('utf8');
proc.stderr.setEncoding('utf8');
proc.stdout.on('data', chunk => {
stdout += chunk;
});
proc.stderr.on('data', chunk => {
stderr += chunk;
});
if (timeoutMs > 0) {
timer = setTimeout(() => {
timedOut = true;
if (process.platform === 'win32') {
killPromise = new Promise(done => {
if (!proc.pid) {
done();
return;
}
const killer = spawn('taskkill', ['/F', '/T', '/PID', String(proc.pid)], {
stdio: 'ignore',
});
killer.on('error', () => done());
killer.on('close', () => done());
});
} else {
proc.kill('SIGKILL');
}
}, timeoutMs);
}
proc.on('error', err => {
if (timer) clearTimeout(timer);
if (err && err.code === 'ENOENT') {
finish({ enoent: true });
return;
}
finish({
code: 1,
stdout,
stderr:
(stderr ? stderr + '\n' : '') + `Failed to run ${candidate.executable}: ${err.message}`,
timedOut,
});
});
proc.on('close', code => {
if (timer) clearTimeout(timer);
if (killPromise) {
killPromise.finally(() => {
finish({ code: code ?? 1, stdout, stderr, timedOut });
});
return;
}
finish({ code: code ?? 1, stdout, stderr, timedOut });
});
});
}
async function runWithFallback(candidates, runOptions, timeoutMs) {
for (const candidate of candidates) {
const result = await runCandidate(candidate, runOptions, timeoutMs);
if (result.enoent) continue;
const combined = [result.stderr, result.stdout].filter(Boolean).join('\n');
if (
result.code !== 0 &&
candidate.notFoundPattern &&
candidate.notFoundPattern.test(combined)
) {
continue;
}
return result;
}
return { code: 1, stdout: '', stderr: 'Cursor Agent CLI not found on PATH.', timedOut: false };
}
function printFailure(stderr, stdout, timedOut) {
const combined = [stderr, stdout].filter(Boolean).join('\n').trim();
if (timedOut) {
const msg =
'Cursor request timed out. Try a shorter prompt or set a larger timeout with --timeout-ms.';
console.error(combined ? `${msg}\n\nPartial Output:\n${combined}` : msg);
return;
}
console.error(combined);
const hint =
combined.toLowerCase().includes('not found') ||
combined.toLowerCase().includes('command not found')
? '\nHint: Is Cursor Agent CLI installed and authenticated? Run: node .claude/skills/omega-cursor-cli/scripts/verify-setup.mjs'
: '';
if (hint) console.error(hint);
}
async function run(promptText, opts) {
try {
assertNonEmptyPrompt(promptText);
} catch {
console.error(USAGE);
process.exit(1);
}
const cliArgs = buildCursorArgs({
prompt: promptText,
model: opts.model,
outputJson: opts.outputJson,
yolo: opts.yolo,
trust: opts.trust,
approveMcps: opts.approveMcps,
});
const runOptions = {
stdio: ['ignore', 'pipe', 'pipe'],
shell: false,
};
const candidates = getExecutables(cliArgs, process.platform === 'win32');
const result = await runWithFallback(candidates, runOptions, opts.timeoutMs);
if (result.code !== 0) {
printFailure(result.stderr, result.stdout, result.timedOut);
process.exit(result.timedOut ? 124 : (result.code ?? 1));
}
process.stdout.write(result.stdout);
}
export function isEntryPoint() {
if (!process.argv[1]) return false;
return path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
}
async function main() {
let opts;
try {
opts = parseCliArgs(process.argv.slice(2));
} catch (err) {
console.error(err && err.message ? err.message : String(err));
console.error(USAGE);
process.exit(1);
}
if (opts.help) {
console.log(USAGE);
process.exit(0);
}
if (opts.prompt) {
await run(opts.prompt, opts);
return;
}
const rl = createInterface({ input: process.stdin });
const lines = [];
let stdinBytes = 0;
let stdinLimitExceeded = false;
// lines.join('\n') always uses a 1-byte newline regardless of platform.
const newlineBytes = 1;
rl.on('line', line => {
if (stdinLimitExceeded) return;
const separatorBytes = lines.length > 0 ? newlineBytes : 0;
const nextBytes = stdinBytes + separatorBytes + Buffer.byteLength(line, 'utf8');
if (nextBytes > EFFECTIVE_MAX_STDIN_BYTES) {
stdinLimitExceeded = true;
rl.close();
return;
}
stdinBytes = nextBytes;
lines.push(line);
});
rl.on('close', async () => {
if (stdinLimitExceeded) {
console.error(
`Input from stdin exceeds ${(EFFECTIVE_MAX_STDIN_BYTES / (1024 * 1024)).toFixed(1)} MB limit. Provide a shorter prompt.`
);
// Use exitCode rather than process.exit() so buffered stderr is flushed
// before the process terminates naturally.
process.exitCode = 1;
return;
}
await run(lines.join('\n'), opts);
});
}
if (isEntryPoint()) {
await main();
}
scripts/main.cjs#!/usr/bin/env node
'use strict';
/**
* omega-cursor-cli - Enterprise Skill Script
* Auto-generated by enterprise-bundle-scaffolder
*/
const fs = require('fs');
const path = require('path');
// Parse arguments
const args = process.argv.slice(2);
const options = {};
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith('--')) {
const key = args[i].slice(2);
const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[++i] : true;
options[key] = value;
}
}
if (options.help) {
console.log(`
omega-cursor-cli - Enterprise Skill
Usage:
node main.cjs --check <file> Check a file against guidelines
node main.cjs --list List all guidelines
node main.cjs --help Show this help
Description:
Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription.
`);
process.exit(0);
}
if (options.list) {
console.log('Guidelines for omega-cursor-cli:');
console.log('See SKILL.md for full guidelines');
process.exit(0);
}
console.log('omega-cursor-cli skill loaded. Use with Claude for code review.');
scripts/parse-args.mjs/**
* Pure argument parser for ask-cursor.mjs.
* Strict flag handling: throws on unknown options, missing values, and invalid types.
* Exported for unit testing without spawning a process.
*/
export function assertNonEmptyPrompt(prompt) {
if (!prompt || !prompt.trim()) {
throw new Error('Prompt is required');
}
}
/**
* Parse CLI argv into structured options.
* The `--` sentinel passes everything after it verbatim as the prompt.
*
* @param {string[]} argv - process.argv.slice(2)
* @returns {{ prompt: string, model: string, outputJson: boolean, yolo: boolean, trust: boolean, approveMcps: boolean, timeoutMs: number, help: boolean }}
*/
/* eslint-disable-next-line complexity -- CLI arg parser with many flags */
export function parseCliArgs(argv) {
const opts = {
model: '',
outputJson: false,
yolo: false,
trust: false,
approveMcps: false,
timeoutMs: 0,
help: false,
prompt: '',
};
const promptParts = [];
let readPromptVerbatim = false;
for (let i = 0; i < argv.length; i++) {
const token = argv[i];
if (readPromptVerbatim) {
promptParts.push(token);
continue;
}
if (token === '--') {
readPromptVerbatim = true;
continue;
}
if (token === '--help' || token === '-h') {
opts.help = true;
continue;
}
if (token === '--json') {
opts.outputJson = true;
continue;
}
if (token === '--yolo' || token === '--sandbox') {
if (token === '--sandbox') {
process.stderr.write('Warning: --sandbox is deprecated; use --yolo instead.\n');
}
opts.yolo = true;
continue;
}
if (token === '--trust') {
opts.trust = true;
continue;
}
if (token === '--approve-mcps') {
opts.approveMcps = true;
continue;
}
if (token === '--model' || token === '-m') {
const value = argv[i + 1];
if (!value || value.startsWith('-')) {
throw new Error('Missing value for --model');
}
opts.model = value.trim();
i++;
continue;
}
if (token === '--timeout-ms') {
const value = argv[i + 1];
const parsed = Number.parseInt(value || '', 10);
if (!Number.isInteger(parsed) || parsed <= 0) {
throw new Error('Invalid value for --timeout-ms; expected a positive integer');
}
opts.timeoutMs = parsed;
i++;
continue;
}
if (token.startsWith('-')) {
throw new Error(`Unknown option: ${token}`);
}
promptParts.push(token);
}
opts.prompt = promptParts.join(' ').trim();
return opts;
}
scripts/verify-setup.mjs#!/usr/bin/env node
/**
* Verify omega-cursor-cli headless setup: Node and Cursor Agent CLI only. No MCP required.
* Exit 0 if all OK, 1 otherwise. Read-only.
* Usage: node verify-setup.mjs
*/
import { execSync } from 'child_process';
const MIN_NODE_MAJOR = 18;
function checkNode() {
const v = process.version.slice(1).split('.')[0];
const major = Number.parseInt(v, 10);
if (major >= MIN_NODE_MAJOR) return { ok: true };
return { ok: false, message: `Node ${MIN_NODE_MAJOR}+ required; current: ${process.version}` };
}
function checkCursorAgentCLI() {
const candidates = [
{ cmd: 'agent --version', how: 'agent' },
{ cmd: 'cursor-agent --version', how: 'cursor-agent' },
];
for (const { cmd, how } of candidates) {
try {
execSync(cmd, { stdio: 'pipe', timeout: 5000 });
return { ok: true, how };
} catch {
// try next candidate
}
}
try {
execSync('npx -y @cursor/agent --version', {
stdio: 'pipe',
timeout: 15000,
});
return { ok: true, how: 'npx @cursor/agent' };
} catch {
return {
ok: false,
message:
'Cursor Agent CLI not found. Install: npm install -g @cursor/agent or use npx -y @cursor/agent',
};
}
}
function main() {
const report = [];
let allOk = true;
const nodeResult = checkNode();
if (nodeResult.ok) {
report.push('OK Node: ' + process.version);
} else {
report.push('MISSING Node: ' + nodeResult.message);
allOk = false;
}
const cursorResult = checkCursorAgentCLI();
if (cursorResult.ok) {
report.push('OK Cursor Agent CLI: ' + (cursorResult.how || 'found'));
} else {
report.push('MISSING Cursor Agent CLI: ' + cursorResult.message);
allOk = false;
}
report.push(
'Headless mode: no MCP config required. Use scripts/ask-cursor.mjs to run cursor-agent.'
);
report.push('Auth: run `cursor-agent login` once if prompted, then retry.');
console.log(report.join('\n'));
process.exit(allOk ? 0 : 1);
}
main();
SKILL.md--- name: omega-cursor-cli description: Shell out to Cursor Agent CLI for headless IDE-aware code tasks. Supports multi-model routing (auto mode routes to Claude, Gemini, GPT). Requires Cursor Pro/Business subscription. version: 1.0.0 model: sonnet invoked_by: both user_invocable: true tools: [Bash, Read] args: '"PROMPT" [--model MODEL] [--json] [--yolo] [--trust] [--timeout-ms N]' best_practices: - Always run verify-setup.mjs before first invocation - Cursor subscription is required -- most restrictive availability of all omega tools - Use --yolo for non-interactive headless mode (auto-approves all tool calls) - Use --trust for workspace trust without prompting - Use auto model for Cursor's intelligent model routing error_handling: graceful streaming: not_supported verified: true lastVerifiedAt: 2026-02-24T04:26:35.324Z source: builtin trust_score: 100 provenance_sha: b58306e870296cba --- # Cursor CLI Skill <identity> Headless wrapper for Cursor Agent CLI. Passes prompt as last positional arg to `cursor-agent --print --output-format text`. Multi-model routing via --model auto. Requires paid Cursor subscription. </identity> <capabilities> - Headless Cursor Agent CLI invocation with positional prompt - Multi-model routing (auto, claude-4.6-opus, gemini-3.1-pro, gpt-5.3-codex, etc.) - JSON output mode - YOLO mode (auto-approve all tool calls for non-interactive use) - Trust mode (skip workspace trust prompts) - MCP approval mode (--approve-mcps) - Wrapper-level timeout with exit code 124 - Complex Windows PATH resolution (agent, cursor-agent, %LOCALAPPDATA%, npx fallback) - Availability verification </capabilities> ## Usage ### Ask a question (auto model selection) ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "How should I structure this React component?" --yolo --trust ``` ### Specific model ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "Review this API design" --model claude-4.6-opus --yolo --trust ``` ### With timeout ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "Refactor authentication" --yolo --trust --timeout-ms 180000 ``` ### JSON output ```bash node .claude/skills/omega-cursor-cli/scripts/ask-cursor.mjs "Generate types" --json --yolo --trust ``` ## Availability Check ```bash node .claude/skills/omega-cursor-cli/scripts/verify-setup.mjs # Exit 0 = available (CLI found) # Exit 1 = not available ``` ## When to Use - Multi-model perspective via Cursor's auto routing - IDE-aware code generation (Cursor has workspace context) - When a non-Claude, non-OpenAI perspective is desired - Tasks where Cursor's composer models excel ## Iron Laws 1. ALWAYS use --yolo --trust for headless mode (otherwise blocks on approval prompts) 2. NEVER assume CLI is available -- most restrictive subscription requirement 3. ALWAYS include --timeout-ms for production usage 4. NEVER attempt to detect subscription status programmatically (not possible) 5. ALWAYS handle WSL issues on Windows (some configurations require WSL) ## Anti-Patterns | Anti-Pattern | Why Bad | Correct Approach | | -------------------------------- | -------------------------------------- | ------------------------------------- | | Running without --yolo | Blocks on tool approval prompts | Always pass --yolo | | Running without --trust | Blocks on workspace trust prompt | Always pass --trust | | Assuming auto model is available | Depends on subscription tier | Check with cursor-agent --list-models | | Hardcoding cursor-agent path | PATH differs across OS/install methods | Wrapper handles resolution | | Ignoring WSL requirements | Some Windows installs are WSL-only | Document in setup instructions | ## Scripts | Script | Purpose | | ------------------- | ---------------------------------------------------------------- | | `ask-cursor.mjs` | Core headless wrapper -- prompt as last positional arg | | `parse-args.mjs` | Argument parser (--model, --json, --yolo, --trust, --timeout-ms) | | `verify-setup.mjs` | Availability check (multi-path resolution) | | `format-output.mjs` | Output normalization | ## Exit Codes | Code | Meaning | | ---- | --------------------------------------- | | 0 | Success | | 1 | Error (CLI failure, subscription issue) | | 124 | Timeout (--timeout-ms exceeded) | ## Integration Notes - **Subscription:** Cursor Pro or Business required for agent/headless mode - **Stdin limit:** `ASK_CURSOR_MAX_STDIN_BYTES` env var (default 50MB) - **Available models:** claude-4.6-opus, claude-4.6-sonnet, composer-1.5, gemini-3.1-pro, gpt-5.3-codex, auto - **Platform:** Partial cross-platform (WSL issues on some Windows configurations) - **PATH resolution order:** agent -> cursor-agent -> %LOCALAPPDATA%\cursor-agent\cursor-agent.cmd -> npx @cursor/agent ## Memory Protocol Before work: Read `.claude/context/memory/learnings.md` After work: Append findings to learnings or issues as needed. _Note: Use `pnpm search:code` to discover references to this skill codebase-wide._
templates/implementation-template.md# omega-cursor-cli Implementation Template ## Goal - Define target outcome and acceptance criteria. ## TDD 1. Red 2. Green 3. Refactor ## Verification - lint - format - targeted tests