本地多 Agent 会话统一管理器 —— 把 pi / claude / codex 散落在本机的会话,收敛到一个界面里浏览、搜索、并一键恢复继续干。
| 状态 | v1.0 已验收通过(11/11) |
| 后端 | Python 3.12+,零第三方依赖(标准库 http.server + sqlite3 + FTS5) |
| 前端 | Vue 3 + Vite + TypeScript |
| 形态 | 单进程本地应用,一个命令即用 |
| 平台 | Windows 为主(开发机),Linux/macOS 不阻断 |
本机长期同时使用多个 AI 编码 CLI(pi、claude、codex),它们各自把会话以 jsonl 存放在不同目录、不同命名规则下:
~/.pi/agent/sessions/*.jsonl
~/.claude/projects/<encoded>/*.jsonl
~/.codex/sessions/*.jsonl
于是:
- 想找回「某个项目里某次对话」,得分别翻三个工具;
- 想恢复某个会话继续工作,得手动拼命令、手动选权限模式。
本项目把「找会话 → 看内容 → 接着干」这条链路,从跨多个工具的手动操作,收敛到一个本地 Web 界面。
- 统一扫描归一化:解析三个 agent 的 jsonl,归一化为统一的
Session模型。 - 差分式索引同步:基于
(mtime, size)指纹做全量差分,未变化文件零解析、零写入;外部删除的会话也能正确清理。 - 全文搜索:基于 SQLite FTS5(
unicode61,兼容中文),命中标题与会话内容。 - 双视图列表:按项目聚合(跨 agent 归并到同一项目下)/ 全局时间线,可按 agent 筛选。
- 会话详情:完整消息流渲染,区分 user 消息 / assistant 文本 / tool 调用(折叠),支持 Markdown。
- 一键恢复会话:按权限档位(
default/full)新开终端窗口唤起对应 CLI。 - 项目别名:可给长路径项目起短名,内联改名。
- 纯本地:只监听
127.0.0.1,不上云、不远程、不多用户。
- Python 3.12+(后端无需
pip install任何包,复制目录即可运行) - Node.js(仅前端开发 / 构建时需要)
- 本机已有 pi / claude / codex 的会话数据(否则列表为空属正常)
# 1) 构建前端(首次或前端改动后执行)
cd frontend
npm install
npm run build # 产物输出到 frontend/dist/
# 2) 启动后端(serve dist + 提供 API + 自动开浏览器)
cd ../backend
python -m asm浏览器会自动打开 http://127.0.0.1:8000。
若未构建前端就启动,页面会显示一个占位提示(后端检测到
frontend/dist不存在时的兜底),API 仍可正常访问,例如http://127.0.0.1:8000/api/stats。
两个终端分别跑:
# 终端 A:前端 dev server(:5173),自动 proxy /api → :8000
cd frontend && npm run dev
# 终端 B:后端 API(:8000)
cd backend && python -m asm开发时访问 http://127.0.0.1:5173(Vite HMR 生效)。
┌──────────────────────────────────────────────┐
│ 浏览器 (localhost:8000) │
│ Vue 3 SPA (Vite 构建产物) │
└─────────────────────┬────────────────────────┘
│ HTTP /api/*
┌─────────────────────▼────────────────────────┐
│ Python 后端 (单进程, http.server) │
│ 静态资源 serve │ API 路由 │ resume(开终端) │
│ scanner / indexer (差分同步) │
│ adapters: pi / claude / codex │
│ SQLite (data/asm.db + FTS5) │
└─────────────────────┬────────────────────────┘
│ 读取
~/.pi ~/.claude ~/.codex
四层分层,单向依赖,职责隔离:
| 层 | 模块 | 职责 |
|---|---|---|
| 表现层 | frontend/ + server.py |
UI + HTTP 路由 |
| 应用层 | scanner.py / indexer.py / resume.py |
扫描调度 / 差分同步 / 恢复调度 |
| 适配层 | adapters/{pi,claude,codex}.py |
解析各家 jsonl + 构造 resume 命令 |
| 基础设施层 | models.py / config.py / db.py |
数据模型 / 路径与注册表 / SQLite |
新增一个 agent 只需加一个 adapter 文件 + 注册表加一行,其余层零改动(见下文「扩展」)。
agent_session_manager/
├─ backend/
│ ├─ asm/
│ │ ├─ main.py # 入口:建库 → 首次同步 → 起 HTTP → 开浏览器
│ │ ├─ __main__.py # 支持 python -m asm
│ │ ├─ server.py # HTTP 路由 + 静态资源 serve
│ │ ├─ scanner.py # 扫描调度(聚合各 adapter)
│ │ ├─ indexer.py # 差分同步(全量差分 / 增量差分)
│ │ ├─ resume.py # 恢复调度(开新终端窗口执行 CLI)
│ │ ├─ models.py # Session/Message 数据模型、枚举
│ │ ├─ config.py # 路径常量、AGENT_REGISTRY
│ │ ├─ db.py # SQLite 连接、建表迁移、底层 CRUD
│ │ └─ adapters/ # base.py + pi/claude/codex.py
│ ├─ data/asm.db # 运行时数据库(gitignore)
│ └─ pyproject.toml
├─ frontend/ # Vue 3 + Vite
│ ├─ src/ # App.vue / views / components / stores / api
│ ├─ dist/ # 构建产物(gitignore,由后端 serve)
│ └─ package.json
└─ docs/ # 需求 / 架构 / 验收等设计文档
恢复时提供统一两档(权限是 resume 操作的参数,非会话属性;同一会话可按不同档位恢复):
| 档位 | 含义 |
|---|---|
default |
各 agent 默认行为,按其自身配置走 |
full |
完全访问:绕过权限检查 / 沙箱,自由执行命令与读写 |
各 agent 命令映射(隔离在 adapter 内):
| Agent | default |
full |
有独立 full 档 |
|---|---|---|---|
| pi | pi --session <id> |
— | 否(按钮置灰) |
| claude | claude --resume <id> |
claude --resume <id> --dangerously-skip-permissions |
是 |
| codex | codex resume <id> |
codex resume <id> -s danger-full-access |
是 |
点击恢复后,后端通过 subprocess 新开一个终端窗口执行对应命令(Web 后端无 TTY,故不在当前进程内运行)。full 按钮旁有固定风险提示,pi 无独立 full 档时按钮置灰并 tooltip 说明。仅 localhost 请求生效。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/sessions |
?view=project|timeline&agent=pi,claude&q=词 |
| GET | /api/sessions/{id} |
会话详情(含完整消息流) |
| POST | /api/sessions/{id}/resume |
body {"level":"default"|"full"} → 开终端 |
| POST | /api/reindex |
全量差分同步,返回 DiffStat |
| POST | /api/sync |
增量差分同步(v1.1) |
| GET | /api/stats |
索引状态:按 agent 计数等 |
| GET | /api/projects |
项目目录聚合(含别名 + agent 构成) |
| PUT | /api/projects/{path}/alias |
设置 / 清除项目别名(路径 URL 编码) |
backend/asm/adapters/cursor.py实现Adapter抽象接口(discover/fingerprint/parse/read_messages/build_resume_command/supports_full_access)。backend/asm/config.py的AGENT_REGISTRY加一行"cursor": CursorAdapter。- 前端
types/models.ts的 Agent 枚举加值(可选,筛选器会自动渲染)。 - 其他层零改动。
models.py的PermissionLevel加值。- 各 adapter 的
build_resume_command加映射分支。 - 前端恢复区按枚举渲染按钮。
- 后端零第三方依赖:刻意只用 Python 标准库。好处是复制目录即可运行、无原生编译风险、内存常驻约 25MB。代价是纯标准库无文件事件监听,增量同步仍需遍历目录(真正事件驱动增量需引入 watchdog,列为后续可选)。
- 前端采用构建模式:Vue/Vite 引入 Node 构建链(仅开发期),换取组件化与可维护性;构建产物为纯静态文件,部署期后端仍零依赖、单进程。后端只依赖
/api/*+ 静态目录,前端可整体替换(如换 React)而不动后端。 - 路由用 hash 模式(
#/、#/session/:id),免去后端 history fallback 配置。
完整的需求、架构、验收细节见 docs/:
docs/REQUIREMENTS.md— 需求文档(PRD)docs/ARCHITECTURE.md— 技术架构文档docs/SYSTEM_DESIGN.md— 系统设计docs/ACCEPTANCE.md— v1.0 验收报告(11/11)
| 版本 | 范围 |
|---|---|
| v1.0(当前) | 扫描归一化 + 全量差分索引 + 列表/搜索/详情 + 权限档位恢复 + Vue 前端 |
| v1.1 | 增量差分索引 + 水位线 + 全量校准兜底 + 同步统计展示 |
| v2.0+ | 导出(MD/HTML)、watchdog 实时监听、更多 agent、中间权限档位、打包分发 |