refactor(workflow-meta): align develop prompts with flat workspace layout
Remove nonexistent @uncaged/nerve-skills references; document root build, roles/*.ts, verb-first workflow names, and CONVENTIONS/.knowledge sources. Extend .knowledge/workflow.md and adapter.md with workspace layout and createLlmAdapter. Fixes #287 Made-with: Cursor
This commit is contained in:
+22
-1
@@ -28,8 +28,29 @@ For long-running or incremental agent outputs:
|
||||
|---------|---------|------|
|
||||
| `@uncaged/nerve-adapter-cursor` | `cursorAdapter` / `createCursorAdapter()` | cursor-agent CLI |
|
||||
| `@uncaged/nerve-adapter-hermes` | `hermesAdapter` / `createHermesAdapter()` | hermes chat CLI |
|
||||
| `@uncaged/nerve-workflow-utils` | `createLlmAdapter(provider)` | OpenAI-compatible HTTP chat (single-turn) |
|
||||
|
||||
Each exports a **default instance** (sensible defaults) and a **factory** for custom config.
|
||||
The Cursor and Hermes adapter packages each export a **default instance** (sensible defaults) and a **factory** for custom config. `createLlmAdapter` is a factory on `@uncaged/nerve-workflow-utils` only.
|
||||
|
||||
## createLlmAdapter
|
||||
|
||||
`createLlmAdapter` builds an `AgentFn` from an `LlmProvider` (`baseUrl`, `apiKey`, `model`). One chat completion per role step: **system** = the string passed by `createRole` (your prompt); **user** = `ctx.start.content` (the thread’s start frame). On failure it throws with a formatted LLM error.
|
||||
|
||||
```ts
|
||||
import { createLlmAdapter, createRole } from "@uncaged/nerve-workflow-utils";
|
||||
import { z } from "zod";
|
||||
|
||||
const metaSchema = z.object({ ok: z.boolean() });
|
||||
|
||||
const planner = createRole(
|
||||
createLlmAdapter({ baseUrl: "https://api.example.com/v1", apiKey: "…", model: "gpt-4o-mini" }),
|
||||
"You are a planner…",
|
||||
metaSchema,
|
||||
extractConfig,
|
||||
);
|
||||
```
|
||||
|
||||
Use this when you want a role backed by an HTTP LLM instead of a subprocess CLI adapter.
|
||||
|
||||
## Usage in Workflows
|
||||
|
||||
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
Stateful multi-step execution driven by Roles and a Moderator.
|
||||
|
||||
## Workspace Layout (authoring)
|
||||
|
||||
User Nerve workspaces use a **flat** build: one root `package.json`, one root bundle script (typically `scripts/build.mjs` wired from `scripts.build`), and **no** per-workflow `package.json` or `tsconfig.json`.
|
||||
|
||||
| Location | Purpose |
|
||||
|----------|---------|
|
||||
| `workflows/<name>/index.ts` | Default export: `WorkflowDefinition` (moderator + role map). |
|
||||
| `workflows/<name>/roles/<role>.ts` | One module per role — schemas, prompts, `createRole` factories, or hand-written async role functions. |
|
||||
| `dist/workflows/<name>/index.js` | Emit of the root build; this is what the daemon loads. |
|
||||
|
||||
**Naming:** Workflow ids should be **verb-first** kebab-case phrases (e.g. `deploy-staging`, `scan-dependencies`), not opaque nouns alone.
|
||||
|
||||
Senses follow the same flat pattern: `senses/<name>/src/*.ts`, `migrations/`, root build → `dist/senses/<name>/index.js`. See `.knowledge/sense.md`.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
- **Workflow** — definition with concurrency strategy
|
||||
|
||||
@@ -10,7 +10,7 @@ export type CoderMeta = z.infer<typeof coderMetaSchema>;
|
||||
|
||||
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\`
|
||||
Read conventions: \`CONVENTIONS.md\` if present; \`.knowledge/sense.md\` if present. Do **not** reference \`@uncaged/nerve-skills\`.
|
||||
|
||||
## Your task
|
||||
|
||||
@@ -20,21 +20,21 @@ Implement (or fix) the sense the planner designed. If there is tester feedback i
|
||||
|
||||
You do NOT need to finish everything in one pass. You may return \`done: false\` to continue in the next iteration.
|
||||
|
||||
## File structure for each sense
|
||||
## File structure for each sense (flat workspace)
|
||||
|
||||
- \`senses/<name>/src/index.ts\` — TypeScript compute source; import schema as \`./schema.ts\`
|
||||
The workspace has **one root** \`package.json\` and root \`scripts/build.mjs\` (or equivalent) that bundles all senses. There is **no** per-sense \`package.json\`. Bundled output is \`dist/senses/<name>/index.js\` after a root build.
|
||||
|
||||
- \`senses/<name>/src/index.ts\` — compute entry; import schema as \`./schema.ts\`
|
||||
- \`senses/<name>/src/schema.ts\` — Drizzle schema (TypeScript)
|
||||
- \`senses/<name>/migrations/\` — Drizzle migration files (at sense root, not inside src/)
|
||||
- \`senses/<name>/package.json\` — with esbuild build script
|
||||
- \`senses/<name>/index.js\` — bundled output generated by \`pnpm build\` (do NOT edit by hand)
|
||||
- \`senses/<name>/migrations/\` — SQL migration files (at sense root, not inside \`src/\`)
|
||||
|
||||
Look at existing senses for the package.json template and patterns.
|
||||
Look at existing senses for patterns.
|
||||
|
||||
## When to return done: true
|
||||
|
||||
Return \`done: true\` ONLY when ALL of the following are true:
|
||||
- All required files are created
|
||||
- \`pnpm install --no-cache && pnpm build\` succeeds (run it!)
|
||||
- From the **workspace root**, \`pnpm run build\` or \`npm run build\` succeeds (run it!) and \`dist/senses/<name>/index.js\` exists
|
||||
- \`nerve.yaml\` is updated with the sense config
|
||||
|
||||
Return \`done: false\` if you made progress but there is still work to do.`;
|
||||
|
||||
@@ -12,7 +12,7 @@ export function plannerPrompt({ threadId }: { threadId: string }): string {
|
||||
return `You are planning a new Nerve sense.
|
||||
|
||||
Read the workflow thread for the user's request: \`nerve thread ${threadId}\`
|
||||
Read the nerve-dev skill for sense conventions: \`cat node_modules/@uncaged/nerve-skills/nerve-dev/SKILL.md\`
|
||||
Read conventions: \`CONVENTIONS.md\` if present; \`.knowledge/sense.md\` if present. Skills may live under \`.cursor/skills/\` — there is **no** \`@uncaged/nerve-skills\` npm package.
|
||||
Also look at existing senses in the \`senses/\` directory for patterns.
|
||||
|
||||
Pick a good kebab-case name for this sense. Produce a PLAN (not code) in markdown:
|
||||
|
||||
@@ -17,21 +17,20 @@ export function testerPrompt({
|
||||
**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\`
|
||||
Read \`${nerveRoot}/CONVENTIONS.md\` and \`${nerveRoot}/.knowledge/sense.md\` if they exist. Do **not** use \`@uncaged/nerve-skills\`.
|
||||
|
||||
Verify the full lifecycle in this order:
|
||||
|
||||
1. **File check** — all required sense files exist:
|
||||
1. **File check** — all required sense files exist (no per-sense \`package.json\`):
|
||||
- \`senses/<name>/src/index.ts\`
|
||||
- \`senses/<name>/src/schema.ts\`
|
||||
- \`senses/<name>/migrations/\`
|
||||
- \`senses/<name>/package.json\`
|
||||
|
||||
2. **Build** — run inside the sense directory:
|
||||
2. **Build** — from the workspace root:
|
||||
\`\`\`
|
||||
cd ${nerveRoot}/senses/<name> && pnpm install --no-cache && pnpm build
|
||||
cd ${nerveRoot} && pnpm run build
|
||||
\`\`\`
|
||||
Must produce \`index.js\` at sense root without errors.
|
||||
(or \`npm run build\` per root \`package.json\`.) Must produce \`${nerveRoot}/dist/senses/<name>/index.js\` without errors.
|
||||
|
||||
3. **Config check** — \`nerve validate\` passes, confirming nerve.yaml is valid.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export type CoderMeta = z.infer<typeof coderMetaSchema>;
|
||||
|
||||
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\`
|
||||
Read conventions: \`CONVENTIONS.md\` if present; \`.knowledge/workflow.md\` if present. Skills may live under \`.cursor/skills/\` — do **not** reference \`@uncaged/nerve-skills\`.
|
||||
Also look at existing workflows in the \`workflows/\` directory for patterns.
|
||||
|
||||
## Your task
|
||||
@@ -29,15 +29,13 @@ You do NOT need to finish everything in one pass. You may return \`done: false\`
|
||||
2. Second pass: implement role logic
|
||||
3. Third pass: fix build/lint errors
|
||||
|
||||
## Workflow file structure
|
||||
## Workflow file structure (flat workspace)
|
||||
|
||||
The workspace has **one root** \`package.json\` and **one** root build (\`pnpm run build\` or \`npm run build\`), implemented by \`scripts/build.mjs\`, which emits bundles under \`dist/workflows/<name>/index.js\`. There is **no** per-workflow \`package.json\` or \`tsconfig.json\`.
|
||||
|
||||
Each workflow must have:
|
||||
- \`workflows/<name>/index.ts\` — WorkflowDefinition default export
|
||||
- \`workflows/<name>/build.ts\` — factory function
|
||||
- \`workflows/<name>/moderator.ts\` — moderator + meta types
|
||||
- \`workflows/<name>/roles/<role>.ts\` — meta schema and prompt function per role
|
||||
- \`workflows/<name>/package.json\` — with esbuild build script
|
||||
- \`workflows/<name>/tsconfig.json\` — TypeScript config
|
||||
- \`workflows/<name>/index.ts\` — default export \`WorkflowDefinition\` (moderator and meta types typically live here or are imported from co-located modules)
|
||||
- \`workflows/<name>/roles/<role>.ts\` — one TypeScript file per role (schemas, prompts, \`createRole\` wiring, or plain async role functions)
|
||||
|
||||
For **new workflows**, also update \`nerve.yaml\` with \`workflows.<name>\`.
|
||||
|
||||
@@ -53,7 +51,7 @@ For **new workflows**, also update \`nerve.yaml\` with \`workflows.<name>\`.
|
||||
|
||||
Return \`done: true\` ONLY when ALL of the following are true:
|
||||
- All changes from the plan are implemented
|
||||
- \`cd workflows/<name> && pnpm install --no-cache && pnpm build\` succeeds (run it!)
|
||||
- From the **workspace root**, \`pnpm run build\` or \`npm run build\` succeeds (run it!) so \`dist/workflows/<name>/index.js\` is produced
|
||||
- No lint or type errors remain
|
||||
|
||||
Return \`done: false\` if you made progress but there is still work to do, or if build/lint has errors you plan to fix in the next iteration.`;
|
||||
|
||||
@@ -12,18 +12,18 @@ export function plannerPrompt({ threadId }: { threadId: string }): string {
|
||||
return `You are a Nerve workflow planner. You can **create new workflows** or **modify existing ones**.
|
||||
|
||||
Read the workflow thread for the user's request: \`nerve thread ${threadId}\`
|
||||
Read the nerve-dev skill for workflow conventions: \`cat node_modules/@uncaged/nerve-skills/nerve-dev/SKILL.md\`
|
||||
Read conventions: \`CONVENTIONS.md\` at the workspace root if it exists; if \`.knowledge/workflow.md\` exists (e.g. Nerve monorepo), read it for layout and engine behavior. Optional Cursor skills live under \`.cursor/skills/\` — there is **no** \`@uncaged/nerve-skills\` npm package.
|
||||
List existing workflows: \`ls workflows/\`
|
||||
|
||||
## Determine the task type
|
||||
|
||||
1. If the user wants to **modify an existing workflow** — read its current code (\`cat workflows/<name>/moderator.ts\`, \`cat workflows/<name>/build.ts\`, \`ls workflows/<name>/roles/\`, etc.) and understand its current structure before planning changes.
|
||||
1. If the user wants to **modify an existing workflow** — read its current code (\`cat workflows/<name>/index.ts\`, \`ls workflows/<name>/roles/\`, \`cat workflows/<name>/roles/<role>.ts\`, etc.) and understand its current structure before planning changes.
|
||||
2. If the user wants to **create a new workflow** — look at existing workflows in \`workflows/\` for patterns to follow.
|
||||
|
||||
## Produce a PLAN (not code) in markdown
|
||||
|
||||
For **new workflows**:
|
||||
- Workflow name (kebab-case)
|
||||
- Workflow name — **verb-first** kebab-case phrase (e.g. \`review-pull-request\`, \`deploy-staging\`), not a bare noun
|
||||
- Roles list (name, purpose, tool)
|
||||
- Flow transitions / moderator routing logic
|
||||
- Validation loops design
|
||||
|
||||
@@ -17,24 +17,22 @@ export function testerPrompt({
|
||||
**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\`
|
||||
Read \`${nerveRoot}/CONVENTIONS.md\` and \`${nerveRoot}/.knowledge/workflow.md\` if they exist. Do **not** use \`@uncaged/nerve-skills\`.
|
||||
|
||||
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}/\`):
|
||||
1. **File check** — all required workflow sources 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\`
|
||||
- \`workflows/<name>/roles/\` with one \`.ts\` file per role (flat files, not per-role packages)
|
||||
- **No** \`workflows/<name>/package.json\` or \`tsconfig.json\` expected
|
||||
|
||||
2. **Build** — run inside the workflow directory:
|
||||
2. **Build** — from the workspace root:
|
||||
\`\`\`
|
||||
cd ${nerveRoot}/workflows/<name> && pnpm install --no-cache && pnpm build
|
||||
cd ${nerveRoot} && pnpm run build
|
||||
\`\`\`
|
||||
Must produce \`dist/index.js\` without errors.
|
||||
(or \`npm run build\` if that is what the root \`package.json\` defines.) Must produce \`${nerveRoot}/dist/workflows/<name>/index.js\` without errors.
|
||||
|
||||
3. **Config check** — \`cd ${nerveRoot} && nerve validate\` passes, confirming nerve.yaml is valid.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user