diff --git a/package.json b/package.json index a452eb1..8c9be55 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,11 @@ "@uncaged/nerve-adapter-hermes": "link:../repos/nerve/packages/adapter-hermes", "@uncaged/nerve-core": "latest", "@uncaged/nerve-daemon": "link:../repos/nerve/packages/daemon", + "@uncaged/nerve-role-committer": "link:../repos/nerve/packages/role-committer", + "@uncaged/nerve-role-reviewer": "link:../repos/nerve/packages/role-reviewer", "@uncaged/nerve-workflow-utils": "link:../repos/nerve/packages/workflow-utils", "drizzle-orm": "latest", - "zod": "^4.3.6", - "@uncaged/nerve-role-committer": "link:../repos/nerve/packages/role-committer" + "zod": "^4.3.6" }, "devDependencies": { "drizzle-kit": "latest" @@ -32,4 +33,4 @@ "@uncaged/nerve-role-committer": "link:../repos/nerve/packages/role-committer" } } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68c1cbc..a7d2960 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,6 +31,9 @@ importers: '@uncaged/nerve-role-committer': specifier: link:../repos/nerve/packages/role-committer version: link:../repos/nerve/packages/role-committer + '@uncaged/nerve-role-reviewer': + specifier: link:../repos/nerve/packages/role-reviewer + version: link:../repos/nerve/packages/role-reviewer '@uncaged/nerve-workflow-utils': specifier: link:../repos/nerve/packages/workflow-utils version: link:../repos/nerve/packages/workflow-utils diff --git a/workflows/develop-sense/roles/reviewer.ts b/workflows/develop-sense/roles/reviewer.ts index 1a04f12..472c984 100644 --- a/workflows/develop-sense/roles/reviewer.ts +++ b/workflows/develop-sense/roles/reviewer.ts @@ -1,62 +1,3 @@ -import type { AgentFn, Role, StartStep } from "@uncaged/nerve-core"; -import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils"; -import { createRole } from "@uncaged/nerve-workflow-utils"; -import { z } from "zod"; - -export const reviewerMetaSchema = z.object({ - approved: z.boolean().describe("true if the diff is clean and ready for tester validation"), -}); -export type ReviewerMeta = z.infer; - -export function reviewerPrompt({ threadId, nerveRoot }: { threadId: string; nerveRoot: string }): string { - return `You are a **code reviewer** for Nerve workflow changes. You run after the coder and before the tester. - -**IMPORTANT: The Nerve workspace is at \`${nerveRoot}\`. Always \`cd ${nerveRoot}\` first.** - -Read the workflow thread for context: \`nerve thread ${threadId}\` -Read project conventions: \`cat ${nerveRoot}/CONVENTIONS.md\` - -## Your job — static analysis of the git diff - -Run these commands and analyze the output: - -1. **\`cd ${nerveRoot} && git diff --stat\`** — see what files changed -2. **\`cd ${nerveRoot} && git diff\`** — read the actual diff -3. **\`cd ${nerveRoot} && git status --short\`** — check for untracked files - -## Checklist - -Review the diff against CONVENTIONS.md. Key things to catch: - -### 🔴 Reject (approved: false) — tell coder exactly what to fix -- **Garbage files**: anything listed under "What NOT to commit" in CONVENTIONS.md -- **Secrets/credentials**: API keys, tokens, passwords hardcoded in the diff -- **Unrelated changes**: files modified outside the scope of the task -- **Convention violations**: patterns that contradict CONVENTIONS.md (e.g. \`interface\` instead of \`type\`, \`class\`, dynamic \`import()\`, optional properties with \`?:\`) - -### ✅ Approve (approved: true) — no comment needed -- Diff is clean, focused, follows conventions - -End with: -\`\`\`json -{ "approved": true } -\`\`\` -or -\`\`\`json -{ "approved": false } -\`\`\``; -} - -export function createReviewerRole( - adapter: AgentFn, - extract: LlmExtractorConfig, - nerveRoot: string, -): Role { - return createRole( - adapter, - async (start: StartStep) => - reviewerPrompt({ threadId: start.meta.threadId, nerveRoot }), - reviewerMetaSchema, - extract, - ); -} +import { createReviewerRole } from "@uncaged/nerve-role-reviewer"; +export { createReviewerRole }; +export type { ReviewerMeta } from "@uncaged/nerve-role-reviewer"; diff --git a/workflows/develop-workflow/roles/reviewer.ts b/workflows/develop-workflow/roles/reviewer.ts index 1a04f12..472c984 100644 --- a/workflows/develop-workflow/roles/reviewer.ts +++ b/workflows/develop-workflow/roles/reviewer.ts @@ -1,62 +1,3 @@ -import type { AgentFn, Role, StartStep } from "@uncaged/nerve-core"; -import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils"; -import { createRole } from "@uncaged/nerve-workflow-utils"; -import { z } from "zod"; - -export const reviewerMetaSchema = z.object({ - approved: z.boolean().describe("true if the diff is clean and ready for tester validation"), -}); -export type ReviewerMeta = z.infer; - -export function reviewerPrompt({ threadId, nerveRoot }: { threadId: string; nerveRoot: string }): string { - return `You are a **code reviewer** for Nerve workflow changes. You run after the coder and before the tester. - -**IMPORTANT: The Nerve workspace is at \`${nerveRoot}\`. Always \`cd ${nerveRoot}\` first.** - -Read the workflow thread for context: \`nerve thread ${threadId}\` -Read project conventions: \`cat ${nerveRoot}/CONVENTIONS.md\` - -## Your job — static analysis of the git diff - -Run these commands and analyze the output: - -1. **\`cd ${nerveRoot} && git diff --stat\`** — see what files changed -2. **\`cd ${nerveRoot} && git diff\`** — read the actual diff -3. **\`cd ${nerveRoot} && git status --short\`** — check for untracked files - -## Checklist - -Review the diff against CONVENTIONS.md. Key things to catch: - -### 🔴 Reject (approved: false) — tell coder exactly what to fix -- **Garbage files**: anything listed under "What NOT to commit" in CONVENTIONS.md -- **Secrets/credentials**: API keys, tokens, passwords hardcoded in the diff -- **Unrelated changes**: files modified outside the scope of the task -- **Convention violations**: patterns that contradict CONVENTIONS.md (e.g. \`interface\` instead of \`type\`, \`class\`, dynamic \`import()\`, optional properties with \`?:\`) - -### ✅ Approve (approved: true) — no comment needed -- Diff is clean, focused, follows conventions - -End with: -\`\`\`json -{ "approved": true } -\`\`\` -or -\`\`\`json -{ "approved": false } -\`\`\``; -} - -export function createReviewerRole( - adapter: AgentFn, - extract: LlmExtractorConfig, - nerveRoot: string, -): Role { - return createRole( - adapter, - async (start: StartStep) => - reviewerPrompt({ threadId: start.meta.threadId, nerveRoot }), - reviewerMetaSchema, - extract, - ); -} +import { createReviewerRole } from "@uncaged/nerve-role-reviewer"; +export { createReviewerRole }; +export type { ReviewerMeta } from "@uncaged/nerve-role-reviewer";