- 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
60 lines
2.3 KiB
TypeScript
60 lines
2.3 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 testerMetaSchema = z.object({
|
|
passed: z.boolean().describe("true if all validation checks passed"),
|
|
});
|
|
export type TesterMeta = z.infer<typeof testerMetaSchema>;
|
|
|
|
export function testerPrompt({ threadId, nerveRoot }: { threadId: string; nerveRoot: string }): string {
|
|
return `You are testing a Nerve workflow — either newly created or recently modified.
|
|
|
|
**IMPORTANT: The Nerve workspace is at \`${nerveRoot}\`. All paths below are relative to this directory. Always \`cd ${nerveRoot}\` first.**
|
|
|
|
Read the workflow thread for context: \`nerve thread ${threadId}\`
|
|
Read the nerve-dev skill for expected file structure: \`cat ${nerveRoot}/node_modules/@uncaged/nerve-skills/nerve-dev/SKILL.md\`
|
|
|
|
Get the workflow name from the thread (the planner's output).
|
|
|
|
Verify the full lifecycle in this order:
|
|
|
|
1. **File check** — all required workflow files exist (under \`${nerveRoot}/\`):
|
|
- \`workflows/<name>/index.ts\`
|
|
- \`workflows/<name>/build.ts\`
|
|
- \`workflows/<name>/moderator.ts\`
|
|
- \`workflows/<name>/roles/\` with one \`.ts\` file per role
|
|
- \`workflows/<name>/package.json\`
|
|
|
|
2. **Build** — run inside the workflow directory:
|
|
\`\`\`
|
|
cd ${nerveRoot}/workflows/<name> && pnpm install --no-cache && pnpm build
|
|
\`\`\`
|
|
Must produce \`dist/index.js\` without errors.
|
|
|
|
3. **Config check** — \`cd ${nerveRoot} && nerve validate\` passes, confirming nerve.yaml is valid.
|
|
|
|
4. **Workflow list** — \`nerve workflow list\` shows the workflow.
|
|
|
|
5. **Trigger test** — \`nerve workflow trigger <name> --dry-run\` if available, otherwise just confirm the workflow appears in \`nerve workflow status\`.
|
|
|
|
If any step fails, include the relevant error output.
|
|
|
|
Output a clear summary: what you checked, what passed, what failed, and why.`;
|
|
}
|
|
|
|
export function createTesterRole(
|
|
adapter: AgentFn,
|
|
extract: LlmExtractorConfig,
|
|
nerveRoot: string,
|
|
): Role<TesterMeta> {
|
|
return createRole(
|
|
adapter,
|
|
async (start: StartStep) =>
|
|
testerPrompt({ threadId: start.meta.threadId, nerveRoot }),
|
|
testerMetaSchema,
|
|
extract,
|
|
);
|
|
}
|