Refactor workflow-generator: multi-file DIP + Role Factory + esbuild bundle #3

Closed
opened 2026-04-28 08:41:16 +00:00 by xiaoju · 0 comments
Owner

Context

sense-generator has been refactored to use the Role Factory pattern with separate role directories, DIP, and esbuild bundle to dist/. workflow-generator is still a ~500-line monolith in a single index.ts using old APIs.

Tasks

1. Split into multi-file structure

Target structure (matching sense-generator):

workflows/workflow-generator/
├── index.ts            # entry: read env, call build(), export default
├── build.ts            # buildWorkflowGenerator() factory
├── moderator.ts        # moderator function + WorkflowMeta type
├── roles/
│   ├── planner/
│   │   ├── index.ts    # buildPlannerRole() using createLlmRole
│   │   └── prompt.ts   # plannerPrompt() pure function
│   ├── coder/
│   │   ├── index.ts    # buildCoderRole() using createCursorRole
│   │   └── prompt.ts   # coderPrompt()
│   ├── tester/
│   │   ├── index.ts    # buildTesterRole() using createCursorRole
│   │   └── prompt.ts   # testerPrompt()
│   └── committer/
│       ├── index.ts    # buildCommitterRole() using createHermesRole
│       └── prompt.ts   # committerPrompt()
├── package.json
└── tsconfig.json

2. Use Role Factory pattern

  • planner: createLlmRole (uses DashScope for structured extraction)
  • coder: createCursorRole (writes code)
  • tester: createCursorRole (dry-run review in ask mode)
  • committer: createHermesRole (git commit + push)

Reference sense-generator for the exact factory API.

3. Clean up old APIs

Remove usage of:

  • readNerveYaml() — not needed, let agents read it themselves
  • nerveAgentContext — same, delegate to skill
  • cfgGet() — use process.env directly
  • isDryRun() — factories handle this internally
  • buildSenseGeneratorReference() — let agents read files themselves

4. esbuild bundle to dist/

  • Add esbuild build script in package.json
  • Bundle to dist/index.js
  • Daemon loads dist/index.js

5. Prompt files

Each role prompt.ts exports a pure function returning a string. Move all prompt construction out of the role logic.

6. DIP — dependencies injected

index.ts reads env vars and throws if missing, then calls buildWorkflowGenerator({ provider, cwd }) which constructs all roles.

Reference

  • Current sense-generator structure: workflows/sense-generator/
  • Role factories: @uncaged/nerve-workflow-utils (createCursorRole, createLlmRole, createHermesRole)

Non-goals

  • Changing workflow behavior or role logic
  • Adding new features
  • This is a pure structural refactor
## Context `sense-generator` has been refactored to use the Role Factory pattern with separate role directories, DIP, and esbuild bundle to `dist/`. `workflow-generator` is still a ~500-line monolith in a single `index.ts` using old APIs. ## Tasks ### 1. Split into multi-file structure Target structure (matching sense-generator): ``` workflows/workflow-generator/ ├── index.ts # entry: read env, call build(), export default ├── build.ts # buildWorkflowGenerator() factory ├── moderator.ts # moderator function + WorkflowMeta type ├── roles/ │ ├── planner/ │ │ ├── index.ts # buildPlannerRole() using createLlmRole │ │ └── prompt.ts # plannerPrompt() pure function │ ├── coder/ │ │ ├── index.ts # buildCoderRole() using createCursorRole │ │ └── prompt.ts # coderPrompt() │ ├── tester/ │ │ ├── index.ts # buildTesterRole() using createCursorRole │ │ └── prompt.ts # testerPrompt() │ └── committer/ │ ├── index.ts # buildCommitterRole() using createHermesRole │ └── prompt.ts # committerPrompt() ├── package.json └── tsconfig.json ``` ### 2. Use Role Factory pattern - **planner**: `createLlmRole` (uses DashScope for structured extraction) - **coder**: `createCursorRole` (writes code) - **tester**: `createCursorRole` (dry-run review in ask mode) - **committer**: `createHermesRole` (git commit + push) Reference `sense-generator` for the exact factory API. ### 3. Clean up old APIs Remove usage of: - `readNerveYaml()` — not needed, let agents read it themselves - `nerveAgentContext` — same, delegate to skill - `cfgGet()` — use `process.env` directly - `isDryRun()` — factories handle this internally - `buildSenseGeneratorReference()` — let agents read files themselves ### 4. esbuild bundle to dist/ - Add esbuild build script in package.json - Bundle to `dist/index.js` - Daemon loads `dist/index.js` ### 5. Prompt files Each role prompt.ts exports a pure function returning a string. Move all prompt construction out of the role logic. ### 6. DIP — dependencies injected `index.ts` reads env vars and throws if missing, then calls `buildWorkflowGenerator({ provider, cwd })` which constructs all roles. ## Reference - Current sense-generator structure: `workflows/sense-generator/` - Role factories: `@uncaged/nerve-workflow-utils` (`createCursorRole`, `createLlmRole`, `createHermesRole`) ## Non-goals - Changing workflow behavior or role logic - Adding new features - This is a pure structural refactor
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: xiaoju/nerve-workspace#3
No description provided.