2.8 KiB
2.8 KiB
Nerve Coding Conventions
Functional-First
typeoverinterface,functionoverclass- No
this, no inheritance, composition over inheritance - Immutability first:
Readonly<T>,as const
No Optional Properties
Never use ?:. Use T | null for nullable fields. Use discriminated unions for mutually exclusive fields.
// ✅ Good
type Config = { throttle: string | null }
// ❌ Bad
type Config = { throttle?: string }
Error Handling
Result<T, E>for expected failuresthrowonly for programmer errors (bugs)- No try-catch for flow control
Result<T, E> Type
Defined in @uncaged/nerve-core (packages/core/src/result.ts):
export type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
Discriminated union with tagged ok field. Helper functions:
ok(value)→{ ok: true, value }err(error)→{ ok: false, error }
Exhaustive handling: Pattern is if (!result.ok) { handle error } then access result.value.
No compiler enforcement - relies on manual discipline and TypeScript's flow control analysis.
Naming
| Type | Style |
|---|---|
| Files | kebab-case.ts |
| Types | PascalCase |
| Functions/vars | camelCase |
| Constants | UPPER_SNAKE |
Exports
- Always named exports, never default
- One module = one responsibility
Module Naming Conventions
Primary exports use descriptive, unambiguous names:
- Functions:
createXxx(),parseXxx(),xxxAgent()(e.g.,createCursorAdapter,cursorAgent) - Types: Domain-specific prefixes (e.g.,
CursorAgentOptions,SenseComputeFn,ThreadContext) - Constants:
UPPER_SNAKE_CASEwith context (e.g.,DEFAULT_SENSE_SIGNAL_RETENTION,CURSOR_ADAPTER_DEFAULT_MS)
Avoiding ambiguity:
- Package-scoped naming:
@uncaged/nerve-adapter-cursorexportscursorAgent,createCursorAdapter - Factory pattern:
createXxxAdapter()for configurable instances,xxxAdapterfor defaults - Descriptive type prefixes prevent collision (e.g.,
CursorAgentOptionsvsHermesAgentOptions)
Async
- Always
async/await, never.then()chains - Use
AbortSignalfor cancellation:AbortControllerto create signals, pass to long-running operations spawn-safe.tsand adapter functions acceptabortSignal: AbortSignal | nullparameter- On abort: child processes receive
SIGTERM, async operations should checksignal.aborted - No enforced Biome/Vitest rules for AbortSignal usage (manual discipline required)
No Dynamic Import
Static import only. Exceptions: sense-runtime.ts, workflow-worker.ts (runtime module paths).
Toolchain
pnpm + TypeScript (strict) + Biome (lint/format) + Vitest (test)
pnpm run check # biome check
pnpm test # vitest
pnpm run build # full build