Proposal: Native pi-coding-agent Integration in Lovcode
背景 / Background
Lovcode 目前原生支持 Claude Code 和 Codex CLI 作为 AI 编码工具来源 (SourceProvider ∈ {"claude","codex"})。pi-coding-agent (https://github.com/earendil-works/pi-coding-agent) 是该生态中第三款主流 CLI, 拥有原生 JSONL 会话存储、SDK、RPC 子进程接口、subagent 嵌套执行能力。本提案将 pi 作为对等的 SourceProvider 接入。
目标 / Goals
- 在 Lovcode 侧栏与回放视图中按 cwd 分组 展示 pi 会话, 与现有 Claude/Codex 体验一致。
- 复用现有 Tantivy 全文搜索 索引 pi JSONL。
- 通过 Notify 文件监听 提供增量会话更新, 与 Claude 项目监听对齐。
- 复用现有 TaskNotificationCard 模式 在父消息流内嵌渲染 pi subagent。
非目标 / Non-Goals (基于 Parity 原则)
Claude / Codex 当前没有的功能, pi 也不引入 —— 保持架构对称, 避免单向债务。
- ❌ Session 重命名 (rename) — Claude/Codex 无
- ❌ Secret 脱敏 (scrub) — Claude/Codex 无
- ❌ 遥测开关面板 — Claude/Codex 无
- ❌ 调度 / Mission / 异步任务监管 — Lovcode 非职责, 且 pi-subagents 是 in-process 扩展, 不可外部 API 化
- ❌ 设置页 Claude/Codex/pi 统一面板 — Claude/Codex 当前也未提供
调研结论 / Research Findings
Pi 会话存储路径
~/.pi/agent/sessions/
--<cwd-slug>--/ ← per-cwd scope, 绝对路径 / → -
<ISO-timestamp>_<uuid>.jsonl ← 根 session
<ISO-timestamp>_<uuid>/ ← 父 session 含 subagent
<8hex>/run-0/session.jsonl ← 子 session, 自带 header
- Slug 算法 (
dist/core/session-manager.js:242-250): /${cwd} 前缀剥离, /\: 替换为 -, 包裹 --...--. 不归一化到 git toplevel.
- 同一项目从不同 cwd / worktree 启动 → 多个 sibling 子目录. Lovcode 第一级 group 严格按 cwd, 不做归并.
- 全局视图通过
SessionManager.listAll() 提供.
- Schema 版本
version:3, 需在读时校验.
JSONL Schema (实测, 当前环境 ~36 个 session)
Header (line 1):
{"type":"session","version":3,"id":"<uuid>","timestamp":"<ISO>","cwd":"<abs-path>"}
Entry 通用字段: id (8-hex), parentId (DAG链), timestamp (ISO ms Z)
Entry type 全集:
session (header)
message — body 含 message.role + message.content[]
model_change, thinking_level_change, session_info
custom_message, custom — 后者带 customType discriminator
Message role: 仅 user, assistant, toolResult
Content block type: text, thinking, toolCall, toolResult
已观察到的 customType: caveman-level, obs-turn, todo-progress-state, pi-codex-goal, subagent-notify
集成面
| 面 |
路径 |
用途 |
| SDK |
@earendil-works/pi-coding-agent import |
进程内 typed API (SessionManager.list/open/getEntries/getTree) — 适合只读视图 |
| RPC |
pi --mode rpc subprocess, LF-delimited JSONL over stdio |
适合 live 进度事件, 隔离重启 |
| File-watch |
JSONL under ~/.pi/agent/sessions/ |
增量监听, 与 Claude 一致 |
推荐: 只读视图走 SDK (Node child) 或直接 Rust 文件解析; live 监听走 notify crate.
pi-subagents (扩展) 处理
- 非 API 化:
~/.pi/agent/npm/node_modules/pi-subagents/ 是 in-process extension, 整个代码假设活在运行中的 pi session 里 (peer-deps pi-agent-core / pi-ai / pi-tui). 无法 import 当库用, 也无独立 RPC.
- 检测策略: 仅探测
~/.pi/agent/npm/node_modules/pi-subagents/package.json (新路径). 不兼容旧路径 ~/.pi/agent/extensions/subagent/.
- UI 行为: 装着 → 显示"委托给 pi"affordance; 未装 → 隐藏. 仅信号探测, 不做功能调用.
遥测默认行为
pi 默认 enableInstallTelemetry=true 上报到 pi.dev. Spawn 子进程时统一设置 PI_OFFLINE=1 + PI_TELEMETRY=0 (无 UI 开关, 与 Claude/Codex 对齐).
实现方案 / Implementation Plan
ID 格式: S<n>-<m> 连续编号. Sprint 1 = 9 项, Sprint 2 = 8 项, 总 17 项.
Sprint 1 — P0 基础数据流通
| ID |
功能 |
落点 |
| S1-1 |
pi 路径探测 (get_pi_dir) |
src-tauri/src/app/pi_paths.rs 新模块 |
| S1-2 |
pi 版本探测 + capabilities |
pi_version_info Tauri 命令 |
| S1-3 |
JSONL v3 schema 解析 + version:3 校验 |
src-tauri/src/app/session_parsing.rs 新增 pi parser |
| S1-4 |
全局 session 列表 (listAll() 语义) |
src-tauri/src/app/session_listing.rs 加 list_all_pi_chats |
| S1-5 |
Session 回放 (DAG via parentId) |
src-tauri/src/app/session_messages.rs 加 load_pi_messages |
| S1-6 |
Header 字段 (cwd / id / timestamp / name) 暴露 |
共享类型层 |
| S1-7 |
SourceProvider 加 "pi" 枚举值 |
src/types/agent.ts, src/types/index.ts |
| S1-8 |
Sidebar 按 cwd 分组, 副标题显示 cwd |
src/views/Chat/SessionList.tsx, ProjectList.tsx |
| S1-9 |
pi 主题图标 (warm academic 风格) |
lucide-react 新图标 |
Sprint 2 — P1 体验对齐
| ID |
功能 |
落点 |
| S2-1 |
压缩 (compaction) + 分支 (branch_summary) 渲染 |
MessageView.tsx |
| S2-2 |
custom entry 白名单渲染 (todo-progress-state, obs-turn 等) |
ContentBlockRenderer.tsx |
| S2-3 |
custom_message 渲染器 |
同上 |
| S2-4 |
Session archive / pin |
复用 jotai pinnedSessionIdsAtom |
| S2-5 |
Live 文件监听 (notify crate, 500ms debounce) |
src-tauri/src/app/run.rs 加 pi watcher |
| S2-6 |
全文搜索 (Tantivy 扩展 pi JSONL 流式索引) |
src-tauri/src/app/search.rs |
| S2-7 |
Subagent 内嵌卡片 (仿 TaskNotificationCard) |
SubagentNotificationCard.tsx 新组件, 解析 session_info.name = subagent-<type>-<uuid>-<runidx> |
| S2-8 |
pi-subagents UI affordance (探测信号驱动) |
settings / sidebar 信号 |
显式不做 (Parity 决策)
- Session 重命名 (rename)
- Secret 脱敏 (scrub)
- 遥测开关面板 (telemetry toggle)
- 设置页 Claude/Codex/pi 统一面板
- 调度 / mission / async run 监管
- 旧路径 pi-subagents 兼容 (~/.pi/agent/extensions/subagent/)
数据流 / Data Flow
~/.pi/agent/sessions/--<cwd-slug>--/<ts>_<uuid>.jsonl
│
├─ notify watcher (Rust) ──── 增量 emit 'pi-sessions-changed'
│ ↓
│ React Query invalidate
│ ↓
├─ session_listing.rs ──→ Sidebar cwd-grouped list
│
└─ session_messages.rs ──→ MessageView (DAG via parentId)
↓
SubagentNotificationCard
(解析 session_info.name)
↓
run-0/session.jsonl 跳转
兼容与风险 / Compatibility & Risks
| 风险 |
缓解 |
| 格式漂移 (v1→v3, 未来 v4) |
读时校验 entry.version, pin pi 版本到 package.json |
| 并发写 (pi TUI + Lovcode 同读) |
append-only 容忍 + since cursor 重读 |
| 大文件 (压缩后保留全历史, 多 MB) |
流式 JSONL 解析 + 虚拟列表 (复用 VirtualChatList) |
| 密钥泄露 (bash 输出含 env) |
不做 scrub (parity 决定), 仅文档提示用户 |
| 遥测默认开 |
spawn env 强制 PI_OFFLINE=1 + PI_TELEMETRY=0 |
| cwd 路径含特殊字符 |
slug 算法对 / \: 替换, - 字面保留 |
验证 / Validation
- 本地: 复现当前环境 36 个 session 的列表 + 回放 + 搜索 + subagent 跳转
- 格式兼容: 加载 v1/v2/v3 各一份样本 (需社区提供旧样本)
- Live:
pi --mode rpc 跑一个新 session, 验证 sidebar 增量刷新
- CI: 新增
tests/pi_session_parsing.rs 单测覆盖 header / 3 种 message role / custom entry / compaction
参考 / References
- pi session 格式:
docs/session-format.md (@earendil-works/pi-coding-agent)
- pi SDK:
docs/sdk.md
- pi RPC:
docs/rpc.md
- Lovcode 现有 Claude 集成参考:
src/views/Chat/TaskNotificationCard.tsx, src-tauri/src/app/session_listing.rs
- 现有 Codex 集成参考:
src-tauri/src/app/codex_commands.rs
贡献意愿 / Contribution
作者 @playmaker 愿意主导实现. 期望:
- 社区先 review 此提案的范围与 parity 决策
- 确认后按 Sprint 1 → Sprint 2 顺序提交 PR, 每个 Sprint 一个 PR 便于 review
- 旧 JSONL 样本 (v1/v2) 可由社区提供用于兼容性测试
cc: 维护者团队. 等待反馈后启动 Sprint 1.
Proposal: Native pi-coding-agent Integration in Lovcode
背景 / Background
Lovcode 目前原生支持 Claude Code 和 Codex CLI 作为 AI 编码工具来源 (
SourceProvider ∈ {"claude","codex"})。pi-coding-agent(https://github.com/earendil-works/pi-coding-agent) 是该生态中第三款主流 CLI, 拥有原生 JSONL 会话存储、SDK、RPC 子进程接口、subagent 嵌套执行能力。本提案将 pi 作为对等的 SourceProvider 接入。目标 / Goals
非目标 / Non-Goals (基于 Parity 原则)
调研结论 / Research Findings
Pi 会话存储路径
dist/core/session-manager.js:242-250):/${cwd}前缀剥离,/\:替换为-, 包裹--...--. 不归一化到 git toplevel.SessionManager.listAll()提供.version:3, 需在读时校验.JSONL Schema (实测, 当前环境 ~36 个 session)
Header (line 1):
{"type":"session","version":3,"id":"<uuid>","timestamp":"<ISO>","cwd":"<abs-path>"}Entry 通用字段:
id(8-hex),parentId(DAG链),timestamp(ISO ms Z)Entry type 全集:
session(header)message— body 含message.role+message.content[]model_change,thinking_level_change,session_infocustom_message,custom— 后者带customTypediscriminatorMessage role: 仅
user,assistant,toolResultContent block type:
text,thinking,toolCall,toolResult已观察到的 customType:
caveman-level,obs-turn,todo-progress-state,pi-codex-goal,subagent-notify集成面
@earendil-works/pi-coding-agentimportSessionManager.list/open/getEntries/getTree) — 适合只读视图pi --mode rpcsubprocess, LF-delimited JSONL over stdio~/.pi/agent/sessions/推荐: 只读视图走 SDK (Node child) 或直接 Rust 文件解析; live 监听走 notify crate.
pi-subagents (扩展) 处理
~/.pi/agent/npm/node_modules/pi-subagents/是 in-process extension, 整个代码假设活在运行中的 pi session 里 (peer-deps pi-agent-core / pi-ai / pi-tui). 无法import当库用, 也无独立 RPC.~/.pi/agent/npm/node_modules/pi-subagents/package.json(新路径). 不兼容旧路径~/.pi/agent/extensions/subagent/.遥测默认行为
pi 默认
enableInstallTelemetry=true上报到pi.dev. Spawn 子进程时统一设置PI_OFFLINE=1+PI_TELEMETRY=0(无 UI 开关, 与 Claude/Codex 对齐).实现方案 / Implementation Plan
Sprint 1 — P0 基础数据流通
get_pi_dir)src-tauri/src/app/pi_paths.rs新模块pi_version_infoTauri 命令version:3校验src-tauri/src/app/session_parsing.rs新增 pi parserlistAll()语义)src-tauri/src/app/session_listing.rs加list_all_pi_chatsparentId)src-tauri/src/app/session_messages.rs加load_pi_messagesSourceProvider加"pi"枚举值src/types/agent.ts,src/types/index.tssrc/views/Chat/SessionList.tsx,ProjectList.tsxlucide-react新图标Sprint 2 — P1 体验对齐
compaction) + 分支 (branch_summary) 渲染MessageView.tsxcustomentry 白名单渲染 (todo-progress-state,obs-turn等)ContentBlockRenderer.tsxcustom_message渲染器pinnedSessionIdsAtomnotifycrate, 500ms debounce)src-tauri/src/app/run.rs加 pi watchersrc-tauri/src/app/search.rsSubagentNotificationCard.tsx新组件, 解析session_info.name = subagent-<type>-<uuid>-<runidx>显式不做 (Parity 决策)
数据流 / Data Flow
兼容与风险 / Compatibility & Risks
entry.version, pin pi 版本到 package.jsonsincecursor 重读PI_OFFLINE=1+PI_TELEMETRY=0/\:替换,-字面保留验证 / Validation
pi --mode rpc跑一个新 session, 验证 sidebar 增量刷新tests/pi_session_parsing.rs单测覆盖 header / 3 种 message role / custom entry / compaction参考 / References
docs/session-format.md(@earendil-works/pi-coding-agent)docs/sdk.mddocs/rpc.mdsrc/views/Chat/TaskNotificationCard.tsx,src-tauri/src/app/session_listing.rssrc-tauri/src/app/codex_commands.rs贡献意愿 / Contribution
作者 @playmaker 愿意主导实现. 期望:
cc: 维护者团队. 等待反馈后启动 Sprint 1.