- publish/prompt.ts: require 'Fixes #N' in Ref section to auto-close issues - CONVENTIONS.md: update Role Patterns table (committer uses createRole hermesAdapter), fix Meta Convention (committed not success) - committer/prompt.ts: add defaultBranch guard before branch creation to prevent empty PR diffs - implement/prompt.ts: strengthen git commit prohibition Refs #9
155 lines
4.6 KiB
Markdown
155 lines
4.6 KiB
Markdown
# Nerve Workspace Conventions
|
|
|
|
This document defines coding and workflow conventions for the nerve-workspace (`~/.uncaged-nerve`).
|
|
All roles (planner, coder, reviewer, tester) should reference this file.
|
|
|
|
## Language & Paradigm
|
|
|
|
### Functional-first
|
|
|
|
Use `function` + `type`, not `class` + `interface`.
|
|
|
|
```typescript
|
|
// ✅ Good
|
|
type Signal = { senseId: string; value: unknown; ts: number };
|
|
function createSignal(senseId: string, value: unknown): Signal { ... }
|
|
|
|
// ❌ Bad
|
|
class Signal implements ISignal { ... }
|
|
```
|
|
|
|
### Rules
|
|
|
|
| Rule | Description |
|
|
|------|-------------|
|
|
| `type` over `interface` | All type definitions use `type` |
|
|
| `function` over `class` | Pure functions + closures, no class |
|
|
| No `this` | Functions must not depend on `this` context |
|
|
| No inheritance | No `extends`, `implements`, `abstract` |
|
|
| Composition over inheritance | Use function composition |
|
|
| No optional properties | Use `T \| null` instead of `?:` |
|
|
| No dynamic `import()` | Always static top-level `import` |
|
|
| `async/await` only | Never `.then()` chains |
|
|
|
|
### Exceptions
|
|
|
|
Classes allowed when required by a library (e.g. Drizzle `sqliteTable`) or Error subclasses.
|
|
|
|
## Naming
|
|
|
|
| Type | Style | Example |
|
|
|------|-------|---------|
|
|
| Files | kebab-case | `signal-bus.ts` |
|
|
| Types | PascalCase | `SignalBus` |
|
|
| Functions/variables | camelCase | `createSignalBus` |
|
|
| Constants | UPPER_SNAKE | `MAX_RETRY_COUNT` |
|
|
|
|
## Error Handling
|
|
|
|
- Use `Result<T, E>` for expected failures
|
|
- `throw` only for unrecoverable bugs
|
|
- No try-catch for flow control
|
|
|
|
```typescript
|
|
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
|
|
```
|
|
|
|
## Workflow Structure
|
|
|
|
Each workflow follows the multi-file pattern:
|
|
|
|
```
|
|
workflows/<name>/
|
|
index.ts — WorkflowDefinition default export (thin entry point)
|
|
build.ts — factory function with dependency injection
|
|
moderator.ts — moderator function + WorkflowMeta type
|
|
roles/
|
|
<role>/
|
|
index.ts — build function + meta schema
|
|
prompt.ts — prompt pure function (string template)
|
|
package.json — with esbuild build script
|
|
tsconfig.json
|
|
```
|
|
|
|
### Role Implementation Patterns
|
|
|
|
| Pattern | When to use | Example |
|
|
|---------|-------------|---------|
|
|
| `createCursorRole` | Needs file system access (code generation, planning) | planner, coder |
|
|
| `createHermesRole` | Needs shell + tools (testing, reviewing) | tester, reviewer |
|
|
| `createLlmRole` | Pure LLM reasoning, no tools | analysis roles |
|
|
| `createRole(hermesAdapter, …)` | Agent role with LLM + shell (branch/commit/push from thread context) | solve-issue committer, publish |
|
|
| Direct `Role<Meta>` | No LLM needed, scripted logic | thin wrappers only |
|
|
|
|
### Meta Convention
|
|
|
|
Meta is a **routing signal only** — one boolean per role:
|
|
- `{ ready: boolean }` — planner
|
|
- `{ done: boolean }` — coder
|
|
- `{ approved: boolean }` — reviewer
|
|
- `{ passed: boolean }` — tester
|
|
- `{ committed: boolean }` — committer (solve-issue: branch created, pushed)
|
|
- `{ success: boolean }` — publish (PR opened)
|
|
|
|
### Standard Flow
|
|
|
|
```
|
|
planner → coder → reviewer → tester → committer → END
|
|
```
|
|
|
|
- Reviewer rejection → back to coder (within MAX_CODER_ITERATIONS)
|
|
- Tester failure → back to coder (within MAX_CODER_ITERATIONS)
|
|
- Committer failure → back to coder (within MAX_CODER_ITERATIONS)
|
|
|
|
## Sense Structure
|
|
|
|
```
|
|
senses/<name>/
|
|
src/
|
|
index.ts — compute() function + schema
|
|
schema.ts — Drizzle table definition
|
|
migrations/ — SQLite migrations
|
|
package.json — with esbuild build script
|
|
```
|
|
|
|
## Toolchain
|
|
|
|
| Tool | Purpose |
|
|
|------|---------|
|
|
| **pnpm** | Package manager (workspace mode) |
|
|
| **TypeScript** | Type checking |
|
|
| **esbuild** | Bundling (each workflow/sense bundles independently) |
|
|
|
|
### Commands
|
|
|
|
```bash
|
|
pnpm build # build all packages
|
|
pnpm -r build # same, explicit recursive
|
|
cd workflows/<name> && pnpm build # build one workflow
|
|
```
|
|
|
|
## Git & Commit Convention
|
|
|
|
```
|
|
<type>(<scope>): <description>
|
|
|
|
type: feat | fix | refactor | docs | chore | test
|
|
scope: workflow | sense | core | ...
|
|
```
|
|
|
|
### What NOT to commit
|
|
|
|
- `node_modules/`
|
|
- `dist/` (build outputs, generated by esbuild)
|
|
- `.DS_Store`
|
|
- pnpm cache artifacts (e.g. `false/` directories from `--no-cache` misuse)
|
|
- Secrets, API keys, tokens
|
|
- Unrelated file changes outside the task scope
|
|
|
|
## Dependencies
|
|
|
|
Shared packages from the nerve monorepo:
|
|
- `@uncaged/nerve-core` — types, END constant, WorkflowDefinition
|
|
- `@uncaged/nerve-workflow-utils` — role factories, spawnSafe, llmExtract, cursorAgent
|
|
- `zod` — schema definitions for meta extraction
|