From 42f943c303d33d34434c68f051d6bcfe10be1591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Wed, 29 Apr 2026 12:21:41 +0000 Subject: [PATCH] refactor: flatten role folders into single .ts files Each role's index.ts + prompt.ts merged into a single .ts file. Committer stays as re-export from _shared. Import paths updated in build.ts and moderator.ts. Closes #13 --- workflows/develop-sense/build.ts | 28 +++++++++++++------ workflows/develop-sense/moderator.ts | 10 +++---- .../roles/{coder/prompt.ts => coder.ts} | 7 +++++ workflows/develop-sense/roles/coder/index.ts | 6 ---- .../roles/committer.ts} | 2 +- .../roles/{planner/prompt.ts => planner.ts} | 7 +++++ .../develop-sense/roles/planner/index.ts | 6 ---- .../roles/{reviewer/prompt.ts => reviewer.ts} | 7 +++++ .../develop-sense/roles/reviewer/index.ts | 6 ---- .../roles/{tester/prompt.ts => tester.ts} | 7 +++++ workflows/develop-sense/roles/tester/index.ts | 6 ---- workflows/develop-workflow/build.ts | 28 +++++++++++++------ workflows/develop-workflow/moderator.ts | 10 +++---- .../roles/{coder/prompt.ts => coder.ts} | 10 +++++-- .../develop-workflow/roles/coder/index.ts | 6 ---- .../roles/committer.ts} | 2 +- .../roles/{planner/prompt.ts => planner.ts} | 7 +++++ .../develop-workflow/roles/planner/index.ts | 6 ---- .../roles/{reviewer/prompt.ts => reviewer.ts} | 7 +++++ .../develop-workflow/roles/reviewer/index.ts | 6 ---- .../roles/{tester/prompt.ts => tester.ts} | 9 +++++- .../develop-workflow/roles/tester/index.ts | 6 ---- 22 files changed, 108 insertions(+), 81 deletions(-) rename workflows/develop-sense/roles/{coder/prompt.ts => coder.ts} (87%) delete mode 100644 workflows/develop-sense/roles/coder/index.ts rename workflows/{develop-workflow/roles/committer/index.ts => develop-sense/roles/committer.ts} (70%) rename workflows/develop-sense/roles/{planner/prompt.ts => planner.ts} (78%) delete mode 100644 workflows/develop-sense/roles/planner/index.ts rename workflows/develop-sense/roles/{reviewer/prompt.ts => reviewer.ts} (86%) delete mode 100644 workflows/develop-sense/roles/reviewer/index.ts rename workflows/develop-sense/roles/{tester/prompt.ts => tester.ts} (87%) delete mode 100644 workflows/develop-sense/roles/tester/index.ts rename workflows/develop-workflow/roles/{coder/prompt.ts => coder.ts} (89%) delete mode 100644 workflows/develop-workflow/roles/coder/index.ts rename workflows/{develop-sense/roles/committer/index.ts => develop-workflow/roles/committer.ts} (70%) rename workflows/develop-workflow/roles/{planner/prompt.ts => planner.ts} (89%) delete mode 100644 workflows/develop-workflow/roles/planner/index.ts rename workflows/develop-workflow/roles/{reviewer/prompt.ts => reviewer.ts} (86%) delete mode 100644 workflows/develop-workflow/roles/reviewer/index.ts rename workflows/develop-workflow/roles/{tester/prompt.ts => tester.ts} (85%) delete mode 100644 workflows/develop-workflow/roles/tester/index.ts diff --git a/workflows/develop-sense/build.ts b/workflows/develop-sense/build.ts index 3ec5c35..7b83a02 100644 --- a/workflows/develop-sense/build.ts +++ b/workflows/develop-sense/build.ts @@ -4,15 +4,25 @@ import { hermesAdapter } from "@uncaged/nerve-adapter-hermes"; import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils"; import { createRole } from "@uncaged/nerve-workflow-utils"; -import { coderPrompt } from "./roles/coder/prompt.js"; -import { coderMetaSchema } from "./roles/coder/index.js"; -import { plannerPrompt } from "./roles/planner/prompt.js"; -import { plannerMetaSchema } from "./roles/planner/index.js"; -import { reviewerPrompt } from "./roles/reviewer/prompt.js"; -import { reviewerMetaSchema } from "./roles/reviewer/index.js"; -import { testerPrompt } from "./roles/tester/prompt.js"; -import { testerMetaSchema } from "./roles/tester/index.js"; -import { buildWorkspaceCommitterRole } from "./roles/committer/index.js"; +import { + coderMetaSchema, + coderPrompt, +} from "./roles/coder.js"; +import { + buildWorkspaceCommitterRole, +} from "./roles/committer.js"; +import { + plannerMetaSchema, + plannerPrompt, +} from "./roles/planner.js"; +import { + reviewerMetaSchema, + reviewerPrompt, +} from "./roles/reviewer.js"; +import { + testerMetaSchema, + testerPrompt, +} from "./roles/tester.js"; import { moderator } from "./moderator.js"; import type { SenseMeta } from "./moderator.js"; diff --git a/workflows/develop-sense/moderator.ts b/workflows/develop-sense/moderator.ts index 87fea65..5c5d2e5 100644 --- a/workflows/develop-sense/moderator.ts +++ b/workflows/develop-sense/moderator.ts @@ -1,10 +1,10 @@ import { END } from "@uncaged/nerve-core"; import type { Moderator } from "@uncaged/nerve-core"; -import type { PlannerMeta } from "./roles/planner/index.js"; -import type { CoderMeta } from "./roles/coder/index.js"; -import type { ReviewerMeta } from "./roles/reviewer/index.js"; -import type { TesterMeta } from "./roles/tester/index.js"; -import type { CommitterMeta } from "./roles/committer/index.js"; +import type { PlannerMeta } from "./roles/planner.js"; +import type { CoderMeta } from "./roles/coder.js"; +import type { ReviewerMeta } from "./roles/reviewer.js"; +import type { TesterMeta } from "./roles/tester.js"; +import type { CommitterMeta } from "./roles/committer.js"; export type SenseMeta = { planner: PlannerMeta; diff --git a/workflows/develop-sense/roles/coder/prompt.ts b/workflows/develop-sense/roles/coder.ts similarity index 87% rename from workflows/develop-sense/roles/coder/prompt.ts rename to workflows/develop-sense/roles/coder.ts index aa33cec..5f3c0a3 100644 --- a/workflows/develop-sense/roles/coder/prompt.ts +++ b/workflows/develop-sense/roles/coder.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const coderMetaSchema = z.object({ + filesCreated: z.boolean().describe("true if the sense files were created"), +}); +export type CoderMeta = z.infer; + export function coderPrompt({ threadId }: { threadId: string }): string { return `Read the workflow thread for the planner's sense design and any tester feedback: \`nerve thread ${threadId}\` Read the nerve-dev skill for sense file structure and conventions: \`cat node_modules/@uncaged/nerve-skills/nerve-dev/SKILL.md\` diff --git a/workflows/develop-sense/roles/coder/index.ts b/workflows/develop-sense/roles/coder/index.ts deleted file mode 100644 index caf3cb5..0000000 --- a/workflows/develop-sense/roles/coder/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const coderMetaSchema = z.object({ - filesCreated: z.boolean().describe("true if the sense files were created"), -}); -export type CoderMeta = z.infer; diff --git a/workflows/develop-workflow/roles/committer/index.ts b/workflows/develop-sense/roles/committer.ts similarity index 70% rename from workflows/develop-workflow/roles/committer/index.ts rename to workflows/develop-sense/roles/committer.ts index 5c6c98e..8c6f0ed 100644 --- a/workflows/develop-workflow/roles/committer/index.ts +++ b/workflows/develop-sense/roles/committer.ts @@ -3,4 +3,4 @@ export { committerMetaSchema, type BuildWorkspaceCommitterDeps, type CommitterMeta, -} from "../../../_shared/workspace-committer.js"; +} from "../../_shared/workspace-committer.js"; diff --git a/workflows/develop-sense/roles/planner/prompt.ts b/workflows/develop-sense/roles/planner.ts similarity index 78% rename from workflows/develop-sense/roles/planner/prompt.ts rename to workflows/develop-sense/roles/planner.ts index bb6cc73..c5fec19 100644 --- a/workflows/develop-sense/roles/planner/prompt.ts +++ b/workflows/develop-sense/roles/planner.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const plannerMetaSchema = z.object({ + senseName: z.string().describe("kebab-case sense name from the plan"), +}); +export type PlannerMeta = z.infer; + export function plannerPrompt({ threadId }: { threadId: string }): string { return `You are planning a new Nerve sense. diff --git a/workflows/develop-sense/roles/planner/index.ts b/workflows/develop-sense/roles/planner/index.ts deleted file mode 100644 index 89b32e6..0000000 --- a/workflows/develop-sense/roles/planner/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const plannerMetaSchema = z.object({ - senseName: z.string().describe("kebab-case sense name from the plan"), -}); -export type PlannerMeta = z.infer; diff --git a/workflows/develop-sense/roles/reviewer/prompt.ts b/workflows/develop-sense/roles/reviewer.ts similarity index 86% rename from workflows/develop-sense/roles/reviewer/prompt.ts rename to workflows/develop-sense/roles/reviewer.ts index ed8cdf9..9eb8414 100644 --- a/workflows/develop-sense/roles/reviewer/prompt.ts +++ b/workflows/develop-sense/roles/reviewer.ts @@ -1,3 +1,10 @@ +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. diff --git a/workflows/develop-sense/roles/reviewer/index.ts b/workflows/develop-sense/roles/reviewer/index.ts deleted file mode 100644 index b34a4a0..0000000 --- a/workflows/develop-sense/roles/reviewer/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -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; diff --git a/workflows/develop-sense/roles/tester/prompt.ts b/workflows/develop-sense/roles/tester.ts similarity index 87% rename from workflows/develop-sense/roles/tester/prompt.ts rename to workflows/develop-sense/roles/tester.ts index e4255de..7c0571e 100644 --- a/workflows/develop-sense/roles/tester/prompt.ts +++ b/workflows/develop-sense/roles/tester.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const testerMetaSchema = z.object({ + passed: z.boolean().describe("true if all e2e checks passed"), +}); +export type TesterMeta = z.infer; + export function testerPrompt({ threadId, nerveRoot }: { threadId: string; nerveRoot: string }): string { return `You are testing a newly created Nerve sense end-to-end. diff --git a/workflows/develop-sense/roles/tester/index.ts b/workflows/develop-sense/roles/tester/index.ts deleted file mode 100644 index ffed0ce..0000000 --- a/workflows/develop-sense/roles/tester/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const testerMetaSchema = z.object({ - passed: z.boolean().describe("true if all e2e checks passed"), -}); -export type TesterMeta = z.infer; diff --git a/workflows/develop-workflow/build.ts b/workflows/develop-workflow/build.ts index 8387420..b0c2b16 100644 --- a/workflows/develop-workflow/build.ts +++ b/workflows/develop-workflow/build.ts @@ -4,15 +4,25 @@ import { hermesAdapter } from "@uncaged/nerve-adapter-hermes"; import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils"; import { createRole } from "@uncaged/nerve-workflow-utils"; -import { coderPrompt } from "./roles/coder/prompt.js"; -import { coderMetaSchema } from "./roles/coder/index.js"; -import { plannerPrompt } from "./roles/planner/prompt.js"; -import { plannerMetaSchema } from "./roles/planner/index.js"; -import { reviewerPrompt } from "./roles/reviewer/prompt.js"; -import { reviewerMetaSchema } from "./roles/reviewer/index.js"; -import { testerPrompt } from "./roles/tester/prompt.js"; -import { testerMetaSchema } from "./roles/tester/index.js"; -import { buildWorkspaceCommitterRole } from "./roles/committer/index.js"; +import { + coderMetaSchema, + coderPrompt, +} from "./roles/coder.js"; +import { + buildWorkspaceCommitterRole, +} from "./roles/committer.js"; +import { + plannerMetaSchema, + plannerPrompt, +} from "./roles/planner.js"; +import { + reviewerMetaSchema, + reviewerPrompt, +} from "./roles/reviewer.js"; +import { + testerMetaSchema, + testerPrompt, +} from "./roles/tester.js"; import { moderator } from "./moderator.js"; import type { WorkflowMeta } from "./moderator.js"; diff --git a/workflows/develop-workflow/moderator.ts b/workflows/develop-workflow/moderator.ts index 156f1fa..97be239 100644 --- a/workflows/develop-workflow/moderator.ts +++ b/workflows/develop-workflow/moderator.ts @@ -1,10 +1,10 @@ import { END } from "@uncaged/nerve-core"; import type { Moderator } from "@uncaged/nerve-core"; -import type { PlannerMeta } from "./roles/planner/index.js"; -import type { CoderMeta } from "./roles/coder/index.js"; -import type { ReviewerMeta } from "./roles/reviewer/index.js"; -import type { TesterMeta } from "./roles/tester/index.js"; -import type { CommitterMeta } from "./roles/committer/index.js"; +import type { PlannerMeta } from "./roles/planner.js"; +import type { CoderMeta } from "./roles/coder.js"; +import type { ReviewerMeta } from "./roles/reviewer.js"; +import type { TesterMeta } from "./roles/tester.js"; +import type { CommitterMeta } from "./roles/committer.js"; export type WorkflowMeta = { planner: PlannerMeta; diff --git a/workflows/develop-workflow/roles/coder/prompt.ts b/workflows/develop-workflow/roles/coder.ts similarity index 89% rename from workflows/develop-workflow/roles/coder/prompt.ts rename to workflows/develop-workflow/roles/coder.ts index 85ce857..75f5d63 100644 --- a/workflows/develop-workflow/roles/coder/prompt.ts +++ b/workflows/develop-workflow/roles/coder.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const coderMetaSchema = z.object({ + done: z.boolean().describe("true if the workflow files were created and build passes"), +}); +export type CoderMeta = z.infer; + export function coderPrompt({ threadId }: { threadId: string }): string { return `Read the workflow thread to get the planner's design and any reviewer/tester/committer feedback: \`nerve thread ${threadId}\` Read the nerve-dev skill for workflow file structure and conventions: \`cat node_modules/@uncaged/nerve-skills/nerve-dev/SKILL.md\` @@ -25,8 +32,7 @@ Each workflow must have: - \`workflows//index.ts\` — WorkflowDefinition default export - \`workflows//build.ts\` — factory function - \`workflows//moderator.ts\` — moderator + meta types -- \`workflows//roles//index.ts\` — role build function -- \`workflows//roles//prompt.ts\` — prompt pure function +- \`workflows//roles/.ts\` — meta schema and prompt function per role - \`workflows//package.json\` — with esbuild build script - \`workflows//tsconfig.json\` — TypeScript config diff --git a/workflows/develop-workflow/roles/coder/index.ts b/workflows/develop-workflow/roles/coder/index.ts deleted file mode 100644 index bf527b9..0000000 --- a/workflows/develop-workflow/roles/coder/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const coderMetaSchema = z.object({ - done: z.boolean().describe("true if the workflow files were created and build passes"), -}); -export type CoderMeta = z.infer; diff --git a/workflows/develop-sense/roles/committer/index.ts b/workflows/develop-workflow/roles/committer.ts similarity index 70% rename from workflows/develop-sense/roles/committer/index.ts rename to workflows/develop-workflow/roles/committer.ts index 5c6c98e..8c6f0ed 100644 --- a/workflows/develop-sense/roles/committer/index.ts +++ b/workflows/develop-workflow/roles/committer.ts @@ -3,4 +3,4 @@ export { committerMetaSchema, type BuildWorkspaceCommitterDeps, type CommitterMeta, -} from "../../../_shared/workspace-committer.js"; +} from "../../_shared/workspace-committer.js"; diff --git a/workflows/develop-workflow/roles/planner/prompt.ts b/workflows/develop-workflow/roles/planner.ts similarity index 89% rename from workflows/develop-workflow/roles/planner/prompt.ts rename to workflows/develop-workflow/roles/planner.ts index 77e1e23..6bc344c 100644 --- a/workflows/develop-workflow/roles/planner/prompt.ts +++ b/workflows/develop-workflow/roles/planner.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const plannerMetaSchema = z.object({ + ready: z.boolean().describe("true if requirements are clear and a workflow can be implemented"), +}); +export type PlannerMeta = z.infer; + export function plannerPrompt({ threadId }: { threadId: string }): string { return `You are a Nerve workflow planner. You can **create new workflows** or **modify existing ones**. diff --git a/workflows/develop-workflow/roles/planner/index.ts b/workflows/develop-workflow/roles/planner/index.ts deleted file mode 100644 index c7c8e29..0000000 --- a/workflows/develop-workflow/roles/planner/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const plannerMetaSchema = z.object({ - ready: z.boolean().describe("true if requirements are clear and a workflow can be implemented"), -}); -export type PlannerMeta = z.infer; diff --git a/workflows/develop-workflow/roles/reviewer/prompt.ts b/workflows/develop-workflow/roles/reviewer.ts similarity index 86% rename from workflows/develop-workflow/roles/reviewer/prompt.ts rename to workflows/develop-workflow/roles/reviewer.ts index ed8cdf9..9eb8414 100644 --- a/workflows/develop-workflow/roles/reviewer/prompt.ts +++ b/workflows/develop-workflow/roles/reviewer.ts @@ -1,3 +1,10 @@ +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. diff --git a/workflows/develop-workflow/roles/reviewer/index.ts b/workflows/develop-workflow/roles/reviewer/index.ts deleted file mode 100644 index b34a4a0..0000000 --- a/workflows/develop-workflow/roles/reviewer/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -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; diff --git a/workflows/develop-workflow/roles/tester/prompt.ts b/workflows/develop-workflow/roles/tester.ts similarity index 85% rename from workflows/develop-workflow/roles/tester/prompt.ts rename to workflows/develop-workflow/roles/tester.ts index b0adb72..bc0d09a 100644 --- a/workflows/develop-workflow/roles/tester/prompt.ts +++ b/workflows/develop-workflow/roles/tester.ts @@ -1,3 +1,10 @@ +import { z } from "zod"; + +export const testerMetaSchema = z.object({ + passed: z.boolean().describe("true if all validation checks passed"), +}); +export type TesterMeta = z.infer; + export function testerPrompt({ threadId, nerveRoot }: { threadId: string; nerveRoot: string }): string { return `You are testing a Nerve workflow — either newly created or recently modified. @@ -14,7 +21,7 @@ Verify the full lifecycle in this order: - \`workflows//index.ts\` - \`workflows//build.ts\` - \`workflows//moderator.ts\` - - \`workflows//roles/\` with subdirectories + - \`workflows//roles/\` with one \`.ts\` file per role - \`workflows//package.json\` 2. **Build** — run inside the workflow directory: diff --git a/workflows/develop-workflow/roles/tester/index.ts b/workflows/develop-workflow/roles/tester/index.ts deleted file mode 100644 index ed17c3b..0000000 --- a/workflows/develop-workflow/roles/tester/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -export const testerMetaSchema = z.object({ - passed: z.boolean().describe("true if all validation checks passed"), -}); -export type TesterMeta = z.infer;