10a601c28b
Reflect recent changes across all docs: - README: add executor loop (fire-and-forget), task events lifecycle, pending-tasks projection, update architecture diagram, add pulse-hermes package, add RFC #58 reference - CONTRIBUTING: add task-events.ts, defs.ts, projection-engine.ts, pending-tasks-projection.ts to code structure, update architecture diagram to three-layer decoupled model, add design principles 6-7, add ui/ directory, add migrate.ts, add RFC #58 reference - DESIGN: update packages table with all current packages
239 lines
9.8 KiB
Markdown
239 lines
9.8 KiB
Markdown
# Contributing to Pulse
|
|
|
|
开发指南。
|
|
|
|
## 前置要求
|
|
|
|
- [Bun](https://bun.sh) >= 1.0(运行时 + 包管理 + 测试)
|
|
- Git
|
|
- [Cursor Agent CLI](https://docs.cursor.com/agent) (可选,用于 AI 辅助编码)
|
|
|
|
```bash
|
|
git clone https://github.com/oc-xiaoju/pulse.git
|
|
cd pulse
|
|
bun install # also installs pre-push hook
|
|
```
|
|
|
|
### Git Hooks
|
|
|
|
`bun install` 自动安装 pre-push hook(via `scripts/install-hooks.mjs`),push 前自动跑 lint + tests。
|
|
|
|
手动跑检查:`bun run precheck`
|
|
删除 `.git/hooks/pre-push` 可禁用。
|
|
|
|
## 代码结构
|
|
|
|
```
|
|
pulse/
|
|
├── packages/
|
|
│ ├── pulse/src/ ← 核心引擎(@uncaged/pulse)
|
|
│ │ ├── index.ts ← Rule 类型、composeRules、runPulse、executorLoop、rebuildSnapshot
|
|
│ │ ├── store.ts ← 存储层:events.db + vitals.db + objects/ CAS
|
|
│ │ ├── watcher.ts ← Watcher 框架:startWatcher、wakeTick、WatcherDef
|
|
│ │ ├── task-events.ts ← 任务生命周期类型(TaskState、PendingTasksData、AgentCapabilityStats)
|
|
│ │ ├── defs.ts ← Definition Layer(rule/watcher/executor 声明式定义)
|
|
│ │ ├── projection-engine.ts ← Projection Engine(基于声明式定义的 snapshot 构建)
|
|
│ │ ├── watchers/ ← P0 内置 watchers(植物神经,agent 不可改)
|
|
│ │ │ ├── system-resource.ts CPU/内存/磁盘/swap
|
|
│ │ │ ├── process-alive.ts 关键进程存活检测
|
|
│ │ │ ├── network.ts DNS + HTTP 连通性
|
|
│ │ │ ├── error-log.ts 日志关键词匹配
|
|
│ │ │ ├── pending-tasks-projection.ts 任务事件 fold → PendingTasksData + AgentCapabilityStats
|
|
│ │ │ └── index.ts
|
|
│ │ ├── rules/ ← P0 保命层(植物神经,agent 不可改)
|
|
│ │ │ ├── constants.ts ESSENTIAL_PROCESSES 白名单、阈值常量
|
|
│ │ │ ├── health.ts HealthSnapshot 类型 + rebuildHealth
|
|
│ │ │ ├── survival.ts 保命 rules(洋葱最外层)
|
|
│ │ │ ├── builtin.ts 内置 rules:clampTick、dedup 等
|
|
│ │ │ └── index.ts
|
|
│ │ └── executors/ ← 保命 executors(确定性本地命令)
|
|
│ │ ├── survival.ts
|
|
│ │ └── index.ts
|
|
│ │
|
|
│ ├── pulse-cursor/src/ ← Cursor Agent 适配器(@uncaged/pulse-cursor)
|
|
│ │ ├── index.ts re-export
|
|
│ │ └── cursor-agent.ts Cursor Agent Executor
|
|
│ │
|
|
│ ├── pulse-hermes/src/ ← Hermes Agent 适配器(@uncaged/pulse-hermes)
|
|
│ │ └── index.ts
|
|
│ │
|
|
│ ├── pulse-openclaw/src/ ← OpenClaw 适配器(@uncaged/pulse-openclaw)
|
|
│ │ ├── index.ts re-export
|
|
│ │ ├── watchers/ OC Gateway + LLM 健康探针
|
|
│ │ ├── rules/ OC 专属保命 rules
|
|
│ │ └── executors/ OC 专属 executors
|
|
│ │
|
|
│ └── upulse/src/ ← CLI 工具(@uncaged/upulse)
|
|
│ ├── cli.ts 命令路由
|
|
│ ├── daemon.ts daemon 进程管理
|
|
│ ├── init.ts upulse init
|
|
│ ├── git.ts git 操作封装
|
|
│ ├── store.ts CLI 层存储辅助
|
|
│ ├── config.ts 配置管理
|
|
│ ├── migrate.ts scoped store 迁移
|
|
│ ├── ui/ ← 内嵌 WebUI
|
|
│ │ ├── server.ts Bun HTTP server(API + 前端)
|
|
│ │ └── dashboard.ts 单文件 HTML dashboard
|
|
│ └── commands/
|
|
│ ├── daemon.ts upulse daemon start/stop
|
|
│ ├── deploy.ts upulse deploy(staging → promote)
|
|
│ ├── dev.ts upulse dev(热重载)
|
|
│ ├── gc.ts upulse gc(vitals 清理)
|
|
│ ├── init.ts upulse init
|
|
│ ├── inspect.ts upulse inspect(查看 events/vitals)
|
|
│ ├── list.ts upulse list(列出实例)
|
|
│ └── tick.ts upulse tick(手动触发一次 tick)
|
|
│
|
|
├── biome.json ← Biome linter 配置
|
|
├── package.json ← monorepo root
|
|
└── bun.lock
|
|
```
|
|
|
|
## 架构
|
|
|
|
### 核心三原语:Percept → Understand → Execute
|
|
|
|
```
|
|
Percept(感知)→ Understand(认知)→ Execute(行动)
|
|
```
|
|
|
|
| 层 | 英文 | 组件 | 输出 | 佛教映射 |
|
|
|---|---|---|---|---|
|
|
| **感知** | Percept | Watchers(六处) | Events(六入,按 sense 分类) | 六处触尘 |
|
|
| **认知** | Understand | Rules | Effects(序列化的行动参数) | 受想行 |
|
|
| **行动** | Execute | Executors | Events(执行结果) | 身口意业 |
|
|
|
|
**一切皆业**:Percept / Tick / Execute 都写 events。Events 是不可变的业的记录。
|
|
|
|
> Effects 不是行动本身,是行动的描述——序列化的参数,由 Executor 解释执行。
|
|
|
|
### 三层解耦驱动
|
|
|
|
```
|
|
Percept 层(vitals.db)
|
|
Watchers 每 5s 感知 → 写 vitals → 唤醒判定 → wakeTick()
|
|
↓
|
|
Understand 层(events.db) 中断 sleep
|
|
rebuildSnapshot → Rule Chain(洋葱)→ write effect events
|
|
└── 被 timer 或 wakeTick 唤醒 │
|
|
↓
|
|
Execute 层(executorLoop,独立循环)
|
|
scan pending effect events → execute → effect-acked/effect-failed
|
|
```
|
|
|
|
- Tick 串行不并发(加锁)
|
|
- wakeTick 可中断 sleep,tick 执行中的 wake 设 pendingWake flag
|
|
- **executorLoop 与 tick 解耦**:tick 只写 effect events,executorLoop 后台异步执行(fire-and-forget)
|
|
|
|
### 洋葱 Rule 模型
|
|
|
|
```
|
|
[panicRollback, processWatchdog, resourceGuard, ...survivalRules, ...agentRules]
|
|
└────────── 核心包硬编码,最外层 ──────────┘ └── agent engine/ ──┘
|
|
```
|
|
|
|
最外层的保命 rules 由核心包注入,agent 看不到也改不了。
|
|
|
|
### 存储模型
|
|
|
|
一切皆事件。三个存储:
|
|
|
|
| 存储 | 内容 | 生命周期 |
|
|
|---|---|---|
|
|
| `events.db` | promote/rollback/effect/effect-acked/effect-failed/error/collect/tick/task-* | 永不压缩 |
|
|
| `vitals.db` | 高频采样数据(系统资源/进程/网络/LLM) | 可 gc(archive + downsample) |
|
|
| `objects/` | CAS 内容寻址存储 | 自动去重,不可变 |
|
|
|
|
## 开发工作流
|
|
|
|
### 跑测试
|
|
|
|
```bash
|
|
# 核心引擎测试
|
|
cd packages/pulse && bun test
|
|
|
|
# 全部测试(含 E2E)
|
|
bun test
|
|
```
|
|
|
|
### Lint & 格式化
|
|
|
|
```bash
|
|
# 检查
|
|
bun run lint
|
|
|
|
# 自动修复
|
|
bun run lint:fix
|
|
```
|
|
|
|
项目使用 [Biome](https://biomejs.dev/) 做 lint 和格式化。CI 会检查。
|
|
|
|
### 分支约定
|
|
|
|
```bash
|
|
git checkout -b feat/descriptive-name # 新功能
|
|
git checkout -b fix/descriptive-name # 修复
|
|
git checkout -b chore/descriptive-name # 工具链/配置
|
|
```
|
|
|
|
### Commit 格式
|
|
|
|
```
|
|
type: short description (closes #N)
|
|
```
|
|
|
|
Types: `feat:` `fix:` `docs:` `refactor:` `chore:`
|
|
|
|
### Issue 驱动
|
|
|
|
每个改动都有 GitHub Issue。先开 issue,再写代码,commit 带 `closes #N`。
|
|
|
|
## 关键设计原则
|
|
|
|
1. **Moore 机** — 不逐事件响应,只看两次快照间的 diff。Effects 由新状态决定。
|
|
2. **保命零依赖** — 保命层不依赖 LLM、不依赖外部网络。全部确定性本地命令。
|
|
3. **Agent 不可改植物神经** — watchers/保命 rules/executors 硬编码在核心包。
|
|
4. **幂等性靠 snapshot** — Rule 只看 `(prev, curr)`,不查 events 历史。rebuildSnapshot 预重建所有需要的状态。
|
|
5. **Bypass = 短路** — 保命 rule 不调 `inner()` 时,内层业务 rules 全部跳过。
|
|
6. **Tick 与 Execute 解耦** — tick 只产生 effect events,executorLoop 独立异步执行,互不阻塞。
|
|
7. **Task 状态由事件 fold** — 任务状态从 task-* 事件序列重建,不单独存储,保证一致性。
|
|
|
|
## 测试约定
|
|
|
|
- 单测文件和源码同目录:`foo.ts` → `foo.test.ts`
|
|
- E2E 在 `packages/upulse/src/e2e/`
|
|
- Mock 使用 `bun:test` 的 `jest.fn()` / `jest.spyOn()`
|
|
- 网络/进程相关测试用依赖注入(如 `fetchFn` 参数),不做真实 IO
|
|
- Watcher 测试构造 mock store + mock wakeTick
|
|
- Rule 测试构造 mock snapshot + mock inner
|
|
|
|
## 使用 Cursor Agent 编码
|
|
|
|
项目使用 [Cursor Agent CLI](https://docs.cursor.com/agent) 作为主要编码工具:
|
|
|
|
```bash
|
|
# 分析(只读,不改文件)
|
|
agent -p "分析 watchers/ 目录的结构和数据流" \
|
|
--model claude-4.6-sonnet-medium --mode=ask --output-format text --trust
|
|
|
|
# 执行(改文件)
|
|
agent -p "实现 xxx 功能" \
|
|
--model claude-4.6-sonnet-medium --force --output-format text --trust
|
|
```
|
|
|
|
### 模型选择
|
|
|
|
| 难度 | 模型 | 场景 |
|
|
|---|---|---|
|
|
| 🟢 简单 | `gpt-5.4-mini-medium` | 单文件小改、格式化 |
|
|
| 🟡 标准 | `claude-4.6-sonnet-medium` | bug fix、新功能、重构 |
|
|
| 🔴 复杂 | `claude-4.6-opus-high-thinking` | 架构改动、多文件重构 |
|
|
|
|
## 相关资源
|
|
|
|
- [RFC #1: Pulse — Agent 的自主神经系统](https://github.com/oc-xiaoju/pulse/issues/1)
|
|
- [RFC #23: Autonomic Layer + Rule Middleware](https://github.com/oc-xiaoju/pulse/issues/23)
|
|
- [Design #27: P0 保命层](https://github.com/oc-xiaoju/pulse/issues/27)
|
|
- [RFC #58: Definition Layer + Projection Engine + Rule Projections](https://github.com/oc-xiaoju/pulse/issues/58)
|
|
- [Wiki: Pulse 架构](https://shazhou-ww.github.io/oc-wiki/shared/pulse-agent-architecture/)
|