Following nerve-dev best practice: each role gets its own directory. Structure: index.ts — 31 lines (WorkflowDefinition + moderator) roles/planner/index.ts — 48 lines (createCursorRole) roles/coder/index.ts — 33 lines (createCursorRole) roles/tester/index.ts — 122 lines (hand-written smoke test) roles/shared.ts — 63 lines (providers, helpers) roles/types.ts — 5 lines (SenseMeta) Was: single 416-line index.ts Refs uncaged/nerve#210 小橘 🍊(NEKO Team)
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
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<SenseMeta["planner"]>({
|
|
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"),
|
|
}),
|
|
},
|
|
});
|
|
}
|