import { createCursorRole } from "@uncaged/nerve-workflow-utils"; import { readFileSync } from "node:fs"; import { join } from "node:path"; import { z } from "zod"; import { resolveDashScopeProvider, buildSenseExamples, getNerveYaml, NERVE_ROOT } from "../shared.js"; import type { SenseMeta } from "../types.js"; const senseExamples = buildSenseExamples(); const nerveYaml = getNerveYaml(); export async function buildPlannerRole() { const provider = await resolveDashScopeProvider(); if (provider === null) { throw new Error("Cannot create planner: set DASHSCOPE_API_KEY and DASHSCOPE_BASE_URL"); } return createCursorRole({ cwd: NERVE_ROOT, mode: "ask", prompt: async (threadId) => `You are planning a new Nerve sense. Read the workflow thread for the user's request: \`nerve thread ${threadId}\` Pick a good kebab-case name for this sense. Produce a PLAN (not code) in markdown: ## Sense Design ### Name — kebab-case ### Fields — name, type (integer/real/text), description ### Compute Logic — step-by-step, specific Node.js APIs or shell commands ### Trigger Config — group, interval, throttle, timeout Reference senses: ${senseExamples} Current nerve.yaml: \`\`\`yaml ${nerveYaml} \`\`\` Output ONLY the plan. Be precise and implementation-ready.`, extract: { provider, schema: z.object({ senseName: z.string().describe("kebab-case sense name from the plan"), }), }, }); }