nerve-workspace/workflows/_shared/cursor-ask-adapter.ts
小橘 🍊(NEKO Team) 56ce22fb1b Migrate workflows to WorkflowSpec-style roles (RFC-003)
Replace createCursorRole/createHermesRole with adapter + prompt + zod meta.

Add shared compileRoleSpec, cursor ask adapter, nerve.yaml extract defaults.

Refs #248

Made-with: Cursor
2026-04-29 09:23:55 +00:00

47 lines
1.3 KiB
TypeScript

import { cursorAgent } from "@uncaged/nerve-adapter-cursor";
import type { AgentFn, WorkflowContext } from "@uncaged/nerve-core";
const DEFAULT_MS = 300_000;
function throwCursorError(error: {
kind: string;
exitCode?: number;
stdout?: string;
stderr?: string;
message?: string;
}): never {
if (error.kind === "non_zero_exit") {
throw new Error(
`cursor-agent: exitCode=${error.exitCode} stdout=${error.stdout} stderr=${error.stderr}`,
);
}
if (error.kind === "timeout") {
throw new Error("cursor-agent: timeout");
}
if (error.kind === "aborted") {
throw new Error("cursor-agent: aborted");
}
throw new Error(`cursor-agent: ${error.message ?? error.kind}`);
}
/** Cursor CLI in `--mode=ask` (planner-style roles). */
export function createAskCursorAdapter(config: { model: string; timeout: number | null }): AgentFn {
const timeoutMs = config.timeout ?? DEFAULT_MS;
return async (prompt: string, context: WorkflowContext): Promise<string> => {
const run = await cursorAgent({
prompt,
mode: "ask",
model: config.model,
cwd: context.workdir,
env: null,
timeoutMs,
dryRun: context.start.meta.dryRun,
abortSignal: context.signal,
});
if (!run.ok) {
throwCursorError(run.error);
}
return run.value;
};
}