This repository has been archived on 2026-06-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
xiaoju 8807b0ac6a fix(test): align tests with type-safety refactor
Update test expectations after workflow reflexes were removed from
YAML config and type signatures were tightened:

- core/config: workflow reflex tests now expect 'not supported' error
- cli/workflow: partitionWorkflowMessage test uses strict typed params
- daemon/crash-recovery: remove triggerPayload from resume-thread assertion
- daemon/daemon-ipc: trigger-workflow sends prompt+maxRounds
- daemon/kernel-workflow: use Sense-driven workflow trigger pattern

Fixes 12 test failures across core, cli, and daemon packages.

Refs #88, #89
2026-04-24 12:23:21 +00:00
2026-04-23 09:48:45 +00:00

nerve

Observation engine for autonomous agents — sense the world, react to changes, run workflows.

Nerve is a lightweight daemon that continuously observes external state through Senses, reacts via declarative Reflexes, and orchestrates multi-step Workflows. Built for the Uncaged agent framework.

Core Concepts

External World → Sense → Signal → Reflex → Workflow → Log
                  ↑                                     ↑
              "what to observe"                  "what to do"
Concept Metaphor Role
Sense 👁️ Perception A compute() function that samples or derives data. Each sense has its own SQLite database.
Reflex Reaction Declarative trigger — interval-based, event-driven, or both. Connects senses to actions.
Signal 📡 Notification Emitted when a sense returns non-null. Other reflexes can listen for signals.
Workflow 🔧 Action Stateful multi-step execution with Roles (actors) and a Moderator (coordinator).
Log 📝 Record Immutable audit trail. Queryable by senses, but cannot trigger reflexes (prevents feedback loops).

Three extension points, fully orthogonal — a Sense doesn't know when it runs, a Reflex doesn't know what it computes, a Workflow doesn't know why it was triggered.

Packages

Package Description
@uncaged/nerve-core Shared types and config parser
@uncaged/nerve-daemon The observation engine — kernel, sense runtime, reflex scheduler, workflow manager
@uncaged/nerve-cli CLI tool (nerve) — init, start, stop, logs, query

Quick Start

# Requirements: Node.js ≥ 22.5, pnpm
pnpm add -g @uncaged/nerve-cli

# Initialize a workspace
mkdir my-agent && cd my-agent
nerve init

# Write a sense
cat > senses/cpu-usage/compute.ts << 'EOF'
export async function compute() {
  const [load] = (await import("node:os")).loadavg();
  return load > 2.0 ? { load } : null;  // signal only when load is high
}
EOF

# Configure reflexes in nerve.yaml
cat > nerve.yaml << 'EOF'
senses:
  cpu-usage:
    group: system
    throttle: 10s

reflexes:
  - kind: sense
    sense: cpu-usage
    interval: 30s
EOF

# Run
nerve dev          # foreground (development)
nerve daemon start # background (production)
nerve status       # check health
nerve logs         # view logs

Configuration

nerve.yaml declares senses, reflexes, and workflows:

senses:
  cpu-usage:
    group: system          # senses in the same group share a worker process
    throttle: 10s          # min interval between computes
    timeout: 30s           # max compute duration
    gracePeriod: 5s        # wait before first compute after startup

reflexes:
  - kind: sense
    sense: cpu-usage
    interval: 30s          # periodic trigger
    on: [disk-pressure]    # also trigger on signals from other senses

  - kind: workflow
    workflow: cleanup
    on: [disk-pressure]    # start a workflow when signal fires

workflows:
  cleanup:
    concurrency: 1
    overflow: drop         # discard if already running
  code-review:
    concurrency: 3
    overflow: queue
    maxQueue: 20

Architecture

┌─────────────────────────────────────────────────────────┐
│  Kernel                                                 │
│                                                         │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐           │
│  │ Worker   │   │ Worker   │   │ Worker   │  (1 per   │
│  │ (group A)│   │ (group B)│   │ (group C)│   group)  │
│  │ sense-1  │   │ sense-3  │   │ sense-5  │           │
│  │ sense-2  │   │ sense-4  │   │          │           │
│  └────┬─────┘   └────┬─────┘   └────┬─────┘           │
│       │              │              │                   │
│       └──────────────┼──────────────┘                   │
│                      ▼                                  │
│              ┌──────────────┐                           │
│              │  Signal Bus  │                           │
│              └──────┬───────┘                           │
│                     ▼                                   │
│           ┌──────────────────┐                          │
│           │ Reflex Scheduler │                          │
│           └────────┬─────────┘                          │
│                    ▼                                    │
│          ┌───────────────────┐                          │
│          │ Workflow Manager  │──→ Log Store (SQLite)    │
│          └───────────────────┘                          │
└─────────────────────────────────────────────────────────┘
  • Worker processes — one per sense group, forked by the kernel. Isolated compute execution.
  • Signal Bus — in-memory pub/sub for signal distribution.
  • Reflex Scheduler — interval timers + signal subscriptions, with throttle/coalesce.
  • Workflow Manager — concurrency control (drop/queue), thread lifecycle tracking.
  • Log Store — WAL-mode SQLite via node:sqlite, with archival and retention policies.

Tech Stack

  • Zero native addons — uses Node.js built-in node:sqlite (DatabaseSync)
  • Drizzle ORM v1.0 for sense databases
  • rslib (rspack) for building
  • Biome for formatting/linting
  • Vitest for testing
  • pnpm workspaces for monorepo management

Development

git clone https://git.shazhou.work/uncaged/nerve.git
cd nerve
pnpm install
pnpm build
pnpm -r test     # run all tests

Design Documents

License

MIT

S
Description
Observation engine — Sense, Reflex, Workflow
Readme 5.4 MiB
Languages
TypeScript 97.2%
HTML 2%
JavaScript 0.5%
Shell 0.3%