diff --git a/workflows/sense-generator/roles/coder/index.ts b/workflows/sense-generator/roles/coder/index.ts index 0f1d328..5c9966d 100644 --- a/workflows/sense-generator/roles/coder/index.ts +++ b/workflows/sense-generator/roles/coder/index.ts @@ -1,8 +1,14 @@ import { createCursorRole } from "@uncaged/nerve-workflow-utils"; +import { readFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; import { resolveDashScopeProvider, NERVE_ROOT, SENSES_DIR } from "../shared.js"; import { coderMetaSchema } from "../types.js"; import type { SenseMeta } from "../types.js"; +const __dirname = dirname(fileURLToPath(import.meta.url)); +const PROMPT = readFileSync(join(__dirname, "prompt.md"), "utf-8"); + export async function buildCoderRole() { const provider = await resolveDashScopeProvider(); if (provider === null) { @@ -12,19 +18,10 @@ export async function buildCoderRole() { cwd: NERVE_ROOT, mode: "default", prompt: async (threadId) => - `Read the workflow thread for the planner's sense design: \`nerve thread ${threadId}\` - -Implement the sense. Create exactly: -1. The sense directory under ${SENSES_DIR}// -2. index.js — export async function compute(db, _peers), import schema from "./schema.ts" -3. schema.ts — drizzle-orm/sqlite-core -4. migrations/0001_init.sql — must match schema.ts -5. Update ${NERVE_ROOT}/nerve.yaml — add sense config + reflex entry - -Follow the patterns from existing senses. Create all files now.`, - extract: { - provider, - schema: coderMetaSchema, - }, + PROMPT + .replace("{{threadId}}", threadId) + .replace("{{sensesDir}}", SENSES_DIR) + .replace("{{nerveRoot}}", NERVE_ROOT), + extract: { provider, schema: coderMetaSchema }, }); } diff --git a/workflows/sense-generator/roles/coder/prompt.md b/workflows/sense-generator/roles/coder/prompt.md new file mode 100644 index 0000000..b8ac1dd --- /dev/null +++ b/workflows/sense-generator/roles/coder/prompt.md @@ -0,0 +1,10 @@ +Read the workflow thread for the planner's sense design: `nerve thread {{threadId}}` + +Implement the sense. Create exactly: +1. The sense directory under {{sensesDir}}// +2. index.js — export async function compute(db, _peers), import schema from "./schema.ts" +3. schema.ts — drizzle-orm/sqlite-core +4. migrations/0001_init.sql — must match schema.ts +5. Update {{nerveRoot}}/nerve.yaml — add sense config + reflex entry + +Follow the patterns from existing senses. Create all files now. diff --git a/workflows/sense-generator/roles/planner/index.ts b/workflows/sense-generator/roles/planner/index.ts index 9e49c4c..b52cb84 100644 --- a/workflows/sense-generator/roles/planner/index.ts +++ b/workflows/sense-generator/roles/planner/index.ts @@ -1,8 +1,13 @@ import { createCursorRole } from "@uncaged/nerve-workflow-utils"; +import { readFileSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; import { resolveDashScopeProvider, buildSenseExamples, getNerveYaml, NERVE_ROOT } from "../shared.js"; import { plannerMetaSchema } from "../types.js"; import type { SenseMeta } from "../types.js"; +const __dirname = dirname(fileURLToPath(import.meta.url)); +const PROMPT = readFileSync(join(__dirname, "prompt.md"), "utf-8"); const senseExamples = buildSenseExamples(); const nerveYaml = getNerveYaml(); @@ -15,30 +20,10 @@ export async function buildPlannerRole() { 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: plannerMetaSchema, - }, + PROMPT + .replace("{{threadId}}", threadId) + .replace("{{senseExamples}}", senseExamples) + .replace("{{nerveYaml}}", nerveYaml), + extract: { provider, schema: plannerMetaSchema }, }); } diff --git a/workflows/sense-generator/roles/planner/prompt.md b/workflows/sense-generator/roles/planner/prompt.md new file mode 100644 index 0000000..434e6ef --- /dev/null +++ b/workflows/sense-generator/roles/planner/prompt.md @@ -0,0 +1,21 @@ +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.