# 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/)