Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
219b32e
fix: supervisor race condition, store.ts error handling, and ignore .…
Chasen-Liao May 3, 2026
bbb9f73
feat: add MiniMax provider with Anthropic-compatible API
Chasen-Liao May 3, 2026
c5843e6
fix: add minimax provider to getDefaultConfig()
Chasen-Liao May 3, 2026
9eef0a2
fix: remove unnecessary await and ensure scheduleLock release
Chasen-Liao May 3, 2026
a1bd205
fix: add minimax to provider models list
Chasen-Liao May 3, 2026
895b0a7
fix: add /v1 to MiniMax base URL
Chasen-Liao May 3, 2026
1f28683
feat: add MiniMax model catalog fetch
Chasen-Liao May 3, 2026
76cb5c8
docs: align README.zh-CN.md with English version
Chasen-Liao May 3, 2026
7692e47
docs: add MiniMax to provider tables in both README files
Chasen-Liao May 3, 2026
a37ef71
fix: correct AGENT.md to AGENTS.md in .gitignore
Chasen-Liao May 3, 2026
71114a0
feat: add MiniMax endpoint selection (International/China) in setup
Chasen-Liao May 3, 2026
cc77e7a
fix: add /v1 suffix to MiniMax endpoint URLs
Chasen-Liao May 3, 2026
d7ffe6a
gitignore
Chasen-Liao May 3, 2026
9ad399d
docs: add Feishu channel design spec
Chasen-Liao May 3, 2026
907666c
git
Chasen-Liao May 3, 2026
2f6c330
docs: refine feishu implementation plan
Chasen-Liao May 3, 2026
82e29f8
docs: tighten feishu implementation plan
Chasen-Liao May 3, 2026
71cb20d
feat: add Feishu channel support (MVP)
Chasen-Liao May 3, 2026
0d87d43
docs: update Chinese README with Feishu channel documentation
Chasen-Liao May 3, 2026
b945d7f
docs: add Chinese translation for DECISIONS.md
Chasen-Liao May 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ dist/
*.tsbuildinfo
config/
soul/
memory/
memory/
.claude/

CLAUDE.md
COPILOT.md
AGENTS.md

docs/superpowers/*
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ RESEARCH.md
.env.example
*.log
.DS_Store
*.tsbuildinfo
*.tsbuildinfo
CLAUDE.md
79 changes: 79 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## 项目概述

Mercury 是一个 soul-driven 的 AI agent,运行在 Node.js 上,使用 Vercel AI SDK 的 `generateText()` 实现 10 步 agentic loop。支持 CLI 和 Telegram 两种通道,通过权限系统(filesystem scoping + shell blocklist)实现 permission-hardened tools。

## 常用命令

```bash
npm run build # 构建 (tsup)
npm run dev # 开发模式 (tsup --watch)
npm run lint # 类型检查 (tsc --noEmit)
npm run test # 测试 (vitest run)
npm run test:watch # 测试 (watch 模式)
```

单文件构建验证:
```bash
npx tsc --noEmit
```

## 架构要点

### 核心循环(Agent Loop)
`generateText({ tools, maxSteps: 10 })` → LLM 决定 respond 或 call tool → 权限检查 → 执行 → 继续或返回

### 通道系统(Channels)
- `src/channels/cli.ts` — Readline 交互,内联权限提示
- `src/channels/telegram.ts` — grammY 框架,流式响应,inline keyboard
- `src/channels/registry.ts` — 通道管理器

### 工具注册(Capabilities)
- 所有工具通过 `src/capabilities/registry.ts` 注册
- 权限检查在 tool 执行前进行(filesystem scope / shell blocklist)
- 子命令上下文通过 `capabilities.getChatCommandContext()` 传递给 channel

### 内存层级
- `ShortTermMemory` — 每轮对话的 JSON 文件
- `LongTermMemory` — 自动提取的事实(JSONL)
- `EpisodicMemory` — 带时间戳的事件日志(JSONL)
- `UserMemoryStore`(Second Brain)— SQLite + FTS5,10 种记忆类型,自主学习

### 子 Agent 系统(Subagents)
- `src/core/sub-agent.ts` — 独立 worker,隔离的 agentic loop
- `src/core/supervisor.ts` — 协调器,负责 spawn/halt/queue
- `src/core/file-lock.ts` — 读写锁(多读单写),自动释放,死锁检测
- `src/core/task-board.ts` — 共享任务状态,持久化到磁盘

### Provider 系统
`src/providers/registry.ts` — 多 provider 自动 fallback(DeepSeek → OpenAI → Anthropic → ...)

### Soul 系统
`soul/*.md` 文件定义人格,只有 name + description 加载到启动时,full instructions 按需加载。

### 编程模式
`/code plan` → 分析代码库,呈现方案,不写代码
`/code execute` → 逐步执行计划,build/test 后提交

## 运行时数据位置

所有数据在 `~/.mercury/`,不是项目目录:
- `~/.mercury/mercury.yaml` — 主配置
- `~/.mercury/soul/*.md` — Soul 文件
- `~/.mercury/memory/` — 记忆存储
- `~/.mercury/permissions.yaml` — 权限清单
- `~/.mercury/schedules.yaml` — 定时任务

## 配置结构

`src/utils/config.ts` 中的 `MercuryConfig` 接口定义了所有配置项,包括:
- `identity` — 名称、所有者、创建者
- `providers` — 多个 LLM provider 配置
- `channels.telegram` — Telegram bot token 和访问控制
- `memory.secondBrain` — Second Brain 配置
- `subagents` — 子 agent 并发配置
- `spotify` — Spotify OAuth 配置
- `github` — GitHub 集成配置
2 changes: 2 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

> Architecture Decision Records. New ones appended as we go.

[中文版](./DECISIONS.zh-CN.md)

## ADR-001: TypeScript + Node.js

- **Context**: Need a runtime for 24/7 headless agent with future GUI, mobile, and chat integrations.
Expand Down
85 changes: 85 additions & 0 deletions DECISIONS.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Mercury — 架构决策

> 架构决策记录。新的决策将随时追加。

[English](./DECISIONS.md)

## ADR-001: TypeScript + Node.js

- **背景**: 需要一个 24/7 无头代理运行时,同时考虑未来集成 GUI、移动端和聊天渠道。
- **决策**: 使用 TypeScript + Node.js。
- **结果**: 最佳的 AI SDK 生态系统(Vercel AI SDK)、Ink 用于 TUI、grammY 用于 Telegram,最易扩展至所有未来渠道。

## ADR-002: Ink 用于 TUI

- **背景**: CLI 需要生动有趣 — 动画、进度条、打字机效果。
- **决策**: Ink + React 用于终端 UI。
- **结果**: 比 Commander 学习曲线更陡,但体验卓越。初期 CLI 使用 readline;Ink 在第二阶段引入。

## ADR-003: 平面文件存储

- **背景**: 内存需要简单、可检查、对 Git 友好。
- **决策**: 长期/情景记忆用 JSONL,短期记忆用 JSON。
- **结果**: 易于调试,无需数据库依赖。后续可能需要 SQLite 实现语义搜索。

## ADR-004: grammY 用于 Telegram

- **背景**: 需要 Telegram 集成,支持流式输出和打字状态。
- **决策**: grammY + @grammyjs/stream + @grammyjs/auto-retry。
- **结果**: 最好的 TypeScript Telegram 框架。内置流式支持,社区活跃。

## ADR-005: Vercel AI SDK 用于 LLM

- **背景**: 需要支持多个提供商(OpenAI、Anthropic、DeepSeek)并实现流式输出。
- **决策**: 使用 Vercel AI SDK(`ai` 包)配合各提供商适配器。
- **结果**: 统一 API、内置流式输出、工具调用。切换提供商只需改一行代码。

## ADR-006: Soul 分离为独立 Markdown 文件

- **背景**: 代理人格需要可编辑、可版本化、令牌高效。
- **决策**: 四个独立 Markdown 文件:soul.md、persona.md、taste.md、heartbeat.md。每次请求只注入 soul + persona;taste + heartbeat 选择性注入。
- **结果**: 身份基线约 350 tokens。主人可以在不修改代码的情况下编辑人格。

## ADR-007: Agent Skills 规范

- **背景**: Skills 需要模块化、可运行时安装、令牌高效。
- **决策**: 采用 Agent Skills 规范(agentskills.io)。Skills 使用带有 YAML frontmatter 的 `SKILL.md` + markdown 说明。存储在 `~/.mercury/skills/`。渐进披露:启动时只加载 name + description;调用时才加载完整说明。
- **结果**: Skills 是人类可读的 markdown,无需代码。令牌预算保持低位。通过粘贴内容或 URL 安装。

## ADR-008: 支持 YAML 持久化的调度器

- **背景**: Mercury 需要设置提醒、执行周期性任务、按计划触发 skills。
- **决策**: 将 `schedule_task`、`list_scheduled_tasks`、`cancel_scheduled_task` 暴露为 AI 可调用工具。将计划任务持久化到 `~/.mercury/schedules.yaml`。启动时恢复。任务作为内部(非渠道)消息通过代理循环触发。
- **结果**: Mercury 可以自主调度工作。任务在重启后存活。内部执行使计划任务对渠道不可见,除非代理显式发送输出。

## ADR-009: 自定义混合Daemon化方案

- **背景**: Mercury 24/7 运行但目前仅前台模式。关闭终端会终止进程,导致 Telegram、定时任务和心跳中断。非技术用户不应需要手动安装 PM2/forever/systemd 脚本。
- **决策**: 在 Mercury 中原生构建自定义混合 daemon 管理器。无外部依赖。分三层:
1. **后台启动** — `child_process.spawn({detached: true})` + PID 文件 + 日志重定向。通过 `mercury start -d` 激活。
2. **看门狗** — 内置指数退避崩溃恢复(基础 1s,1.25 倍,最多 10 次重启/60s)。仅在 daemon 模式激活。
3. **平台服务生成器** — `mercury service install` 检测操作系统并生成相应配置:Linux 上为 `systemd --user` unit,macOS 上为 `~/Library/LaunchAgents` plist,Windows 上为启动快捷方式。Mac/Linux 无需 root。
- **备选方案考虑**:
- `node-windows/mac/linux` 三件套 — 部分已停止维护,Mac 上需要 sudo,node-linux 已停止开发
- PM2 作为依赖 — 15MB,50+ 依赖,AGPL-3.0 许可证
- PM2 作为用户安装 — 要求非技术用户学习单独工具
- `forever` — 已被官方弃用
- 仅原生后台模式 — 无崩溃恢复,无启动自启
- **结果**: 核心 daemon 化零外部依赖。启动服务为用户级(Mac/Linux 无需 sudo)。Windows 获取后台模式 + 文档化的 PM2 路径。前台模式不变 — daemon 模式为可选。在 daemon 模式下,CLI 变为仅日志;Telegram(或其他远程渠道)为交互界面。

## ADR-010: 第二大脑 — SQLite 支持的自主结构化记忆

- **背景**: Mercury 需要一个持久的用户模型,从对话中学习。此前的 LongTermMemory(平面 JSONL)太简单 — 仅关键字搜索,无结构,无合并,无冲突处理,无层级。第二大脑已有部分实现(用于 SQLite 的 second-brain-db.ts,用于 JSON 的 user-memory.ts),但两者都是断开的死代码。
- **决策**: 使用 SQLite(better-sqlite3)作为存储后端,结合 UserMemoryStore 业务逻辑层构建统一第二大脑。关键原则:
- **自主**: 无审核队列,无用户审批。记忆通过置信度自动存储、合并、去冲突。弱记忆以低分保留,自然衰减。
- **自动冲突解决**: 检测到极性冲突时(如"偏好 X"vs"不偏好 X"),高置信度记忆静默胜出。置信度相等时 → 较新的胜出。
- **自动分层**: 目标和项目等记忆类型初始为 `active`(有时限);身份和偏好初始为 `durable`。强化 3+ 次的记忆从 active 晋升为 durable。
- **过期清理**: 21 天未见的 active 推断记忆被清除。120 天无强化的 durable 推断记忆置信度衰减;低于 0.3 时被清除。
- **对用户不可见**: 记忆提取在响应发送后作为后台任务执行。代理循环中无工具调用,无状态消息。用户无需等待。
- **10 种记忆类型**: identity、preference、goal、project、habit、decision、constraint、relationship、episode、reflection。
- **FTS5 全文搜索** 用于 `/memory search` 命令。
- **备选方案考虑**:
- 仅 JSON(UserMemoryStore 原样)— 逻辑好但无搜索,扩展性差
- 仅 SQLite(SecondBrainDB 原样)— 存储好但无合并/冲突/反思逻辑
- 向量嵌入 — 对当前规模过于奢侈,增加重量级依赖
- **结果**: WAL 模式的 SQLite 为提示注入提供快速读取(微秒级)。FTS5 支持快速搜索。业务逻辑(合并、冲突、反思、分层、过期)继承自 UserMemoryStore。一个原生依赖(better-sqlite3)。用户的唯一控制:观察(概览、最近、搜索)、暂停/恢复学习、清除全部。
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</p>

<p align="center">
Remembers what matters. Asks before it acts. Runs 24/7 from CLI or Telegram. 31 built-in tools, extensible skills, SQLite-backed Second Brain memory.
Remembers what matters. Asks before it acts. Runs 24/7 from CLI, Telegram, or Feishu. 31 built-in tools, extensible skills, SQLite-backed Second Brain memory.
</p>

<p align="center">
Expand Down Expand Up @@ -39,7 +39,7 @@ npm i -g @cosmicstack/mercury-agent
mercury
```

First run triggers the setup wizard — enter your name, an API key, and optionally a Telegram bot token. Takes 30 seconds.
First run triggers the setup wizard — enter your name, an API key, and optionally Telegram/Feishu tokens. Takes 30 seconds.

To reconfigure later (change keys, name, settings):

Expand Down Expand Up @@ -127,6 +127,13 @@ In daemon mode, Telegram becomes your primary channel — CLI is log-only since
| `mercury telegram promote <id>` | Promote a Telegram member to admin |
| `mercury telegram demote <id>` | Demote a Telegram admin to member |
| `mercury telegram reset` | Clear all Telegram access and start fresh |
| `mercury feishu list` | List approved and pending Feishu users |
| `mercury feishu approve <openId>` | Approve a pending Feishu access request |
| `mercury feishu reject <openId>` | Reject a pending Feishu access request |
| `mercury feishu remove <openId>` | Remove an approved Feishu user |
| `mercury feishu promote <openId>` | Promote a Feishu member to admin |
| `mercury feishu demote <openId>` | Demote a Feishu admin to member |
| `mercury feishu reset` | Clear all Feishu access and start fresh |
| `mercury service install` | Install as system service (auto-start on boot) |
| `mercury service uninstall` | Uninstall system service |
| `mercury service status` | Show system service status |
Expand Down Expand Up @@ -172,6 +179,7 @@ Type these during a conversation — they don't consume API tokens. Work on both
|---------|----------|
| **CLI** | Readline prompt, arrow-key command menus, real-time text streaming with markdown re-rendering, permission mode picker |
| **Telegram** | HTML formatting, editable streaming messages, file uploads, typing indicators, multi-user access with admin/member roles |
| **Feishu** | Private chat support, auto-allowed user list, multi-user access with admin/member roles |

### Telegram Access

Expand All @@ -185,6 +193,18 @@ Mercury uses an **organization access model** with admins and members.

CLI commands: `mercury telegram list|approve|reject|remove|promote|demote|reset`

### Feishu Access

Feishu uses the same **organization access model** with admins and members.

- **First-time setup:** During `mercury setup`, enter your Feishu App ID and App Secret. Optionally add comma-separated user IDs to auto-allow.
- **Additional users:** Users send a message to your Feishu bot. Admins approve or reject from the CLI with `mercury feishu approve <openId>`.
- **Roles:** Admins can approve/reject requests, promote/demote users, and reset access. Members can chat with Mercury.
- **Reset:** Run `mercury feishu reset` in the CLI to clear all access and start fresh.
- Private chats only — group messages are not supported in MVP.

CLI commands: `mercury feishu list|approve|reject|remove|promote|demote|reset`

## Scheduler

- **Recurring**: `schedule_task` with cron expressions (`0 9 * * *` for daily at 9am)
Expand Down Expand Up @@ -236,6 +256,7 @@ Configure multiple LLM providers. Mercury tries them in order and falls back aut
| **DeepSeek** | deepseek-chat | `DEEPSEEK_API_KEY` | Default, cost-effective |
| **OpenAI** | gpt-4o-mini | `OPENAI_API_KEY` | GPT-4o, o3, etc. |
| **Anthropic** | claude-sonnet-4 | `ANTHROPIC_API_KEY` | Claude Sonnet, Haiku, Opus |
| **MiniMax** | (dynamic) | `MINIMAX_API_KEY` | Anthropic-compatible, dynamic model fetch |
| **Grok (xAI)** | grok-4 | `GROK_API_KEY` | OpenAI-compatible endpoint |
| **Ollama Cloud** | gpt-oss:120b | `OLLAMA_CLOUD_API_KEY` | Remote Ollama via API |
| **Ollama Local** | gpt-oss:20b | No key needed | Local Ollama instance |
Expand Down
Loading
Loading