- Rename build* → create* workflow factories - Workflow factories accept adapters: Record<string, AgentFn> - Each role file exports createXxxRole(adapter, ...) factory - _shared/workspace-committer accepts adapter as first param - All adapter imports moved to index.ts (injection point) - solve-issue roles also updated Closes #15
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
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<typeof reviewerMetaSchema>;
|
|
|
|
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<ReviewerMeta> {
|
|
return createRole(
|
|
adapter,
|
|
async (start: StartStep) =>
|
|
reviewerPrompt({ threadId: start.meta.threadId, nerveRoot }),
|
|
reviewerMetaSchema,
|
|
extract,
|
|
);
|
|
}
|