v0.1.0: Electron 桌面端骨架 + pi SDK 聊天链路
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# 架构决策记录(ADR)
|
||||
|
||||
> 本文档沉淀截至 2026-09-05 的架构讨论结论,作为实现的唯一依据。后端/后台/数据库**尚未设计,本期不动**。
|
||||
|
||||
## 1. 系统形态
|
||||
|
||||
店铺运营桌面工具:**固定业务流程 + Agent 灵活编排 + 可切换纯手动**。
|
||||
|
||||
```
|
||||
本地机器(每用户) 服务器(未设计,本期不动)
|
||||
┌─ Electron App ────────────────┐ ┌─ NestJS ─────────────┐
|
||||
│ 渲染进程:React UI │ │ 账号/鉴权 │
|
||||
│ (聊天流、工具卡片、审批卡、 │ │ LLM 代理(key/用量) │
|
||||
│ 业务面板、GSAP 动效) │ │ 共享资产(可选) │
|
||||
│ ▲ IPC(contextBridge) │ └──────────┬───────────┘
|
||||
│ 主进程: │ │
|
||||
│ ├─ pi SDK(createAgentSession)│──── HTTPS ───────┘
|
||||
│ ├─ pi 插件(extensions/tools) │ 业务工具=服务器API薄封装
|
||||
│ └─ sqlite(会话/任务/业务数据) │
|
||||
│ 共享 ~/.pi(auth/models/sessions)│
|
||||
└────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 2. 关键决策
|
||||
|
||||
### D1 pi 跑本地,嵌 Electron 主进程
|
||||
- pi SDK 同进程嵌入(类型安全、`extensionFactories` 官方文档路径)。
|
||||
- Electron 37.6+ 内置 Node ≥22.19,满足 pi 运行时要求(本机系统 Node 22.15 仅用于构建)。
|
||||
- 备选降级路径:主进程 spawn `pi --mode rpc` 子进程(JSONL stdio),用于将来崩溃隔离;工具定义代码可复用。
|
||||
- 共享 `~/.pi/agent`(auth.json、models-store.json、sessions/),与用户已有的 pi CLI 配置互通(本机已确认存在)。
|
||||
|
||||
### D2 能力层唯一:Agent 与手动模式共用同一份实现
|
||||
- 每个业务功能(热点词采集、素材生成、模板生成、CDP 操作、数据分析)= `packages/agent` 中的独立模块。
|
||||
- 同时向两个方向暴露:① pi 的 `defineTool()`/extension 注册(Agent 模式,LLM 编排);② Electron IPC 直接调用(纯手动模式,UI 按钮触发)。
|
||||
- 两条路径行为一致、审计一致。这是"可切换纯手动"低成本实现的前提。
|
||||
|
||||
### D3 固定流程用 pi skills 承载 SOP,审批卡做闸门
|
||||
- SOP(完整上架流程、报活动流程等)写成 pi skill / 提示模板,agent 按剧本执行、剧本内灵活处理异常。
|
||||
- 涉及花钱/不可逆的操作(核价、报活动):extension 拦截 `tool_call` → 渲染进程弹审批卡 → 人工确认后才放行。
|
||||
- 任务状态落本地 sqlite,支持断点续跑。
|
||||
|
||||
### D4 CDP 操作本地执行
|
||||
- 店铺后台登录态在本地浏览器 cookie,CDP 控制必须发生在用户机器(这也是 D1 的根本原因之一)。
|
||||
- 浏览器操作工具按"幂等、可重试、每步截图回传确认"设计;既保流程可靠,也缓冲平台风控。
|
||||
|
||||
### D5 数据主权:本地优先,服务器极薄
|
||||
| 存哪 | 存什么 |
|
||||
|---|---|
|
||||
| 本地 sqlite | 商品数据、分析结果、热点词采集结果、生成记录、任务/断点状态、pi 会话(大文件落磁盘,库存元数据与路径) |
|
||||
| 服务器 PG | 仅账号/鉴权、LLM 代理配置与用量、(可选)团队共享词库/模板。**明确不存商品数据、分析结果等用户业务数据** |
|
||||
|
||||
后果与对策:
|
||||
- 单机即真相:无跨设备同步、无全团队聚合报表(用户已确认接受)。
|
||||
- 本地备份:sqlite 单文件 + 资产目录做"一键打包备份/恢复",排早期功能。
|
||||
- 本地 sqlite schema 必须自带版本号与迁移机制(migrations 表 + 启动时自动升级)。
|
||||
|
||||
## 3. 业务流程链(目标态,全部以 pi 插件形式内置)
|
||||
|
||||
1. 热点词采集(AI/工具采集)或手动定义
|
||||
2. 依据热点词 + 参考素材生成商品图、标题等信息
|
||||
3. 生成商家模板
|
||||
4. CDP 驱动浏览器操作店铺后台:上架、核价、流量加速、下架、报活动
|
||||
5. 数据分析
|
||||
|
||||
## 4. 范围裁剪(本期)
|
||||
|
||||
- ✅ Electron 桌面端(本仓库 `apps/desktop`)
|
||||
- ⛔ NestJS 后端、Ant Design Pro 后台、PostgreSQL —— 未设计,不创建、不实现
|
||||
- 业务插件中依赖服务器 API 的部分,先留接口占位(不依赖后端即可运行的本地能力可先行)
|
||||
@@ -0,0 +1,70 @@
|
||||
# pi SDK 集成笔记
|
||||
|
||||
> 来源:pi.dev 官方文档 + 仓库调研(2026-09-05)。
|
||||
> ⚠️ 本文是二手摘要,**写代码前必须对照已安装包的 `.d.ts` 类型定义核对 API 签名**。
|
||||
|
||||
## 1. 包与运行时
|
||||
|
||||
- 包名:`@earendil-works/pi-coding-agent`(主包自带 SDK,无需单独安装)
|
||||
- Node ≥ 22.19(Electron 37.6+ 主进程满足;系统 Node 仅跑构建)
|
||||
- MIT 协议;monorepo 结构:`pi-agent-core`(agent 运行时)/ `pi-ai`(多 Provider LLM 统一接口)/ `pi-tui` / `chord` / `telemetry`
|
||||
|
||||
## 2. SDK 三段式(嵌入 Node 应用的标准路径)
|
||||
|
||||
```ts
|
||||
const { session } = await createAgentSession({ /* options */ });
|
||||
session.subscribe((event) => { /* 处理 text_delta 等 */ });
|
||||
await session.prompt("...");
|
||||
```
|
||||
|
||||
- `prompt()` 返回 Promise,完成后 resolve;流式期间可用 `steer()` / `followUp()` 排队插话。
|
||||
- 事件流:`agent_start/end`、`message_update`(含 `text_delta` / `thinking_delta`)、`tool_execution_start/update/end`、`turn_end`、`queue_update`、压缩与自动重试事件。
|
||||
|
||||
## 3. 会话管理
|
||||
|
||||
- `SessionManager.inMemory()`(无持久化)/ `.create()` / `.continueRecent()` / `.open()`
|
||||
- 会话是树结构,支持分支(`fork()`);多会话动态替换用 `AgentSessionRuntime`(`newSession()` / `switchSession()` / `fork()` / `importFromJsonl()`,替换后需重新订阅)
|
||||
- 持久化后端可插拔:官方 `session-backends/sqlite-node`(与我们本地 sqlite 方案契合)
|
||||
- 本地文件布局(与 pi CLI / pi-web 共享):`~/.pi/agent/sessions/<encoded-cwd>/<timestamp>_<uuid>.jsonl`
|
||||
|
||||
## 4. 模型与凭据
|
||||
|
||||
- 认证解析优先级:运行时 API key → `auth.json`(API key 或 OAuth)→ 环境变量 → 自定义 provider fallback resolver
|
||||
- `setRuntimeApiKey()`(不落盘)、`InMemoryCredentialStore`、自定义 auth/models 路径、`PI_OFFLINE` 离线模式
|
||||
- 内置 Provider:OpenAI、Anthropic、Google 等;自定义模型用 `models.json`,自定义 provider 支持实现自有 API 与 OAuth(为将来"服务器 LLM 代理端点"预留)
|
||||
- 本机现状:`~/.pi/agent/` 已有 `auth.json` 与 `models-store.json`,应用零配置可直接复用
|
||||
|
||||
## 5. 定制点(SDK options)
|
||||
|
||||
| 维度 | 方式 |
|
||||
|---|---|
|
||||
| 系统提示 | `DefaultResourceLoader({ systemPromptOverride: () => "..." })` |
|
||||
| 工具 | `tools` 白名单内置工具;`excludeTools` 排除;`noTools: "all"` 全关;`defineTool()` 经 `customTools` 注入 |
|
||||
| 扩展 | `extensionFactories` 内联扩展(`pi.registerTool()` / `pi.on()` / 命令),支持命名与共享 eventBus |
|
||||
| 模型 | `getModel()` 取内置模型;`models.json` 自定义;`thinkingLevel`、`scopedModels` |
|
||||
| Skills/上下文/提示模板 | ResourceLoader 的 `skillsOverride`、`agentsFilesOverride`、`promptsOverride` |
|
||||
| 设置 | `SettingsManager.inMemory()` / `.create()`,可覆盖压缩、重试等 |
|
||||
|
||||
## 6. 安全要点
|
||||
|
||||
- pi **无内置权限系统**,工具以进程用户权限执行。业务 agent 必须 `noTools` 或白名单收窄,能力全部走 `defineTool()` 自定义工具;本地文件类操作按需开启并配 `tool_call` 拦截。
|
||||
|
||||
## 7. 扩展(Extension)API 摘要
|
||||
|
||||
- 加载:`~/.pi/agent/extensions/*.ts`(全局)、`.pi/extensions/*.ts`(项目级,需 trust)、`pi -e ./x.ts`(临时);jiti 加载 TS 免编译,`/reload` 热重载(SDK 路径用 `extensionFactories` 内联)
|
||||
- 能力:`pi.on(event, handler)`(拦截 `tool_call`、改写 `input`、`before_agent_start` 注入上下文/改提示词)、`pi.registerTool()`(typebox 参数、流式进度 `onUpdate`)、`pi.registerCommand()`、`ctx.ui` 自定义交互、`pi.appendEntry()` 会话持久化、`pi.sendMessage()`
|
||||
- 注意:自定义工具需手动截断输出(默认 50KB/2000 行)、`withFileMutationQueue()` 防并行写冲突
|
||||
|
||||
## 8. 备选集成模式
|
||||
|
||||
| 模式 | 用途 | 取舍 |
|
||||
|---|---|---|
|
||||
| SDK 同进程(主选) | 嵌入 Electron 主进程 | 类型安全、直接访问 agent state |
|
||||
| RPC 模式(`pi --mode rpc`) | 子进程隔离 | 崩溃隔离好,但失去类型安全,自管 JSONL 协议 |
|
||||
| JSON event stream | 结构化事件打印 | 观测/调试用 |
|
||||
|
||||
## 9. pi-web 可借鉴的实现细节
|
||||
|
||||
- WebSocket 事件以快照推送、60ms 节流(我们的 IPC 转发同样适用)
|
||||
- 会话列表 UI 数据:运行状态、上下文用量、成本、压缩详情
|
||||
- 双分支设计:New session(从历史消息建独立会话)/ Edit from here(当前会话内分支)
|
||||
@@ -0,0 +1,35 @@
|
||||
# 参考项目取舍
|
||||
|
||||
原则:**功能设计抄 pi-web,工程结构抄 Proma,技术选型和业务形态按我们自己的来。**
|
||||
|
||||
## agegr/pi-web(5.9k★,Next.js 本地 Web UI)
|
||||
|
||||
### 采纳
|
||||
- **与 pi 共享本地数据的集成模式**:直接读 `~/.pi/agent` 的配置/凭据/会话(`sessions/<encoded-cwd>/<时间戳>_<uuid>.jsonl`),支持 `PI_CODING_AGENT_DIR` 重定向 → 我们的应用零配置复用用户已有 pi 环境
|
||||
- **会话工作区功能清单**:按项目分组、运行状态、上下文用量/成本/压缩详情、重命名/导出/删除
|
||||
- **双分支设计**:New session(从历史消息建独立会话)/ Edit from here(会话内分支)
|
||||
- **模型配置面板**:models.json 编辑、API key、连通性测试
|
||||
- **文件访问边界**:只允许访问选定工作目录与已知项目根(安全约束)
|
||||
- 事件推送做快照 + 60ms 节流的工程细节
|
||||
|
||||
### 丢弃
|
||||
- Next.js/Web 技术栈(我们是 Electron)
|
||||
- Git worktree、通用文件浏览器等重编码功能(垂直业务场景不需要,最多降级为可选模块)
|
||||
|
||||
## proma-ai/Proma(Electron + React,本地优先 AI 桌面应用)
|
||||
|
||||
### 采纳
|
||||
- **工程结构**:`apps/electron + packages/*` 的 Electron monorepo 组织
|
||||
- **产品形态**:workspace 按业务域隔离、Skills 技能系统的组织方式、多模型 chat 的配置体验
|
||||
- **本地优先**理念(与我们 D5 数据主权决策一致)
|
||||
|
||||
### 丢弃
|
||||
- Bun monorepo → 我们用 **pnpm**(pi 生态是 npm 系;Windows 上 pnpm + electron-builder 兼容性更稳)
|
||||
- 远程机器人、通用 agent 客户端的复杂度
|
||||
- 照抄代码(结构参考为主,代码质量未逐一验证)
|
||||
|
||||
## beautifului.dev
|
||||
|
||||
- AI 原语组件的**设计参考**(Approval Card、Tool Chips、Task Rows、Streaming Text、Thinking、Prompt Bar 等 21 个)
|
||||
- copy-paste 式分发(类 shadcn),我们按此风格在 `apps/desktop` 内自实现同款组件(React + Tailwind),不引入其付费订阅
|
||||
- GSAP 用于消息入场、卡片展开等动效
|
||||
@@ -0,0 +1,36 @@
|
||||
# 路线图与版本自省
|
||||
|
||||
> 每个版本完成后在此追加"自省":缺什么、哪里不好、下一版怎么补。
|
||||
|
||||
## 版本计划
|
||||
|
||||
| 版本 | 主题 | 内容 |
|
||||
|---|---|---|
|
||||
| v0.1.0 | 骨架 + 聊天链路 | monorepo、electron-vite 三进程、pi SDK 嵌主进程、IPC 事件转发、聊天 UI(流式文本 + thinking 折叠)、停止/排队基础 |
|
||||
| v0.2.0 | 会话管理 | 会话列表/新建/恢复/重命名/删除、分支(New session / Edit from here)、运行状态与用量展示 |
|
||||
| v0.3.0 | 模型与设置 | 模型选择、Provider/API key 管理(写入 ~/.pi auth)、系统提示词自定义、连通性测试 |
|
||||
| v0.4.0 | 工具与审批 | 工具调用卡片(参数/结果折叠展示)、tool_call 拦截 → Approval Card、defineTool 业务工具骨架(本地可跑的演示工具) |
|
||||
| v0.5.0 | 打磨 | 深浅主题、GSAP 动效细节、快捷键、错误态/空态、队列可视化、自动滚动策略 |
|
||||
| 未来 | | electron-builder 打包与自动更新、i18n(中/英)、sqlite 持久化与迁移、本地备份恢复、CDP 插件、热点词/生成/模板业务插件、手动模式编排 UI、RPC 子进程隔离模式 |
|
||||
|
||||
---
|
||||
|
||||
## v0.1.0 — 骨架 + 聊天链路
|
||||
|
||||
**交付**:
|
||||
- pnpm monorepo(`apps/desktop` + `docs/`;后端/后台/数据库按约定未创建)
|
||||
- Electron 44 + electron-vite 5 + React 19 + Tailwind v4 + GSAP + lucide-react
|
||||
- 主进程 ESM(`.mjs`)内嵌 pi SDK 0.85.0(`@earendil-works/*` 全部 external,运行时从 node_modules 加载);preload 输出 `.cjs`
|
||||
- IPC:`agent:send/steer/stop/state` + `agent:event` 事件流(delta 40ms 合批,参考 pi-web 节流经验)
|
||||
- UI:侧栏(品牌/模型状态/上下文用量/成本/版本)、聊天区(用户气泡、流式助手文本 + 光标、thinking 折叠、工具卡片含参数/结果)、输入区(自适应高度、Enter 发送/Shift+Enter 换行、流式时排队提示 + 停止按钮)、空状态建议词、错误条 + 自动重试条
|
||||
- 会话复用 `~/.pi/agent`(与用户已装的 pi CLI 互通)
|
||||
- 验证:typecheck 通过、build 通过、应用启动 UI 截图核验通过、pi SDK 冒烟脚本通过(无凭据时错误干净传播)
|
||||
|
||||
**自省**(v0.1.0 → 指导 v0.2+):
|
||||
1. **真实 LLM 往返未验证**——本机 `~/.pi/agent/auth.json` 为空对象,无任何 API key;模型解析为 `unknown/unknown`(pi 的 fallback)。需要用户配 key(`pi /login` 或等 v0.3 设置界面)后复测流式/工具/思考链路。
|
||||
2. **会话管理完全缺失**——重启后不恢复历史;侧栏列表是占位框。v0.2 用 `SessionManager`(list/open/create/rename/delete + 分支)补齐,pi 会话文件在 `~/.pi/agent/sessions/<encoded-cwd>/` 下按 cwd=home 分组,要注意 cwd 策略(固定 home 还是工作区选择)。
|
||||
3. **工具面过宽**——当前默认 `read/bash/edit/write` 全开(冒烟已证实)。按架构 D2/D6,v0.4 收窄为业务工具白名单。
|
||||
4. **Markdown 渲染极简**——只有 fenced code/行内 code/加粗;标题、列表、链接、表格都没有,长回复可读性差。排 v0.5。
|
||||
5. **无 SSE 之外的流控**——超长回复没有虚拟化,消息多后可能卡;先记录,v0.5 评估虚拟滚动。
|
||||
6. **坑位记录**:pi-coding-agent 0.85.0 漏声明 `@earendil-works/pi-server` 依赖(已手动补装);electron-vite 5 需显式 `external: ['electron', /^@earendil-works\//]`;`"type":"module"` 下 preload 必须 `.cjs`;PowerShell 改写含中文的源文件会毁编码(统一用写入工具)。
|
||||
7. **交互验证受限**——computer-use 无法激活该窗口(虚拟显示),键盘链路未实测;已用截图 + Node 冒烟双层验证替代,后续版本需人工过一遍键盘操作。
|
||||
@@ -0,0 +1,38 @@
|
||||
# 技术栈
|
||||
|
||||
## 桌面端(本期实现范围)
|
||||
|
||||
| 层 | 选型 | 说明 |
|
||||
|---|---|---|
|
||||
| 框架 | Electron + electron-vite | 三进程构建(main/preload/renderer),HMR;Electron ≥37.6(内置 Node ≥22.19,满足 pi 运行时) |
|
||||
| 渲染进程 UI | React + TypeScript | |
|
||||
| 样式 | Tailwind CSS v4 | |
|
||||
| 组件 | shadcn/ui 风格自实现 + beautifului.dev 原语风格(Approval Card、Tool Chips、Task Rows、Streaming Text、Thinking、Prompt Bar) | copy-paste 式自有组件,不引入外部付费 |
|
||||
| 动效 | GSAP | 消息入场、卡片展开、状态过渡 |
|
||||
| 图标 | lucide-react | |
|
||||
| Agent 运行时 | pi SDK(`@earendil-works/pi-coding-agent`,版本精确锁定) | 嵌主进程;`save-exact` 纪律 |
|
||||
| 本地库 | sqlite3(better-sqlite3 候选,带 migrations 表 + 启动自动迁移) | v0.x 后期引入,先跑通链路 |
|
||||
|
||||
## Monorepo 布局(目标态,按版本逐步填充)
|
||||
|
||||
```
|
||||
agent-store-operations/
|
||||
├─ pnpm-workspace.yaml # apps/*, packages/*
|
||||
├─ apps/
|
||||
│ ├─ desktop/ # ✅ 本期:Electron 客户端
|
||||
│ ├─ server/ # ⛔ 未设计,不创建(NestJS)
|
||||
│ └─ admin/ # ⛔ 未设计,不创建(Ant Design Pro)
|
||||
├─ packages/
|
||||
│ ├─ shared/ # ⏳ 后端设计定稿后再建(DTO 契约)
|
||||
│ └─ agent/ # ⏳ pi 插件:业务工具 + skills + 提示词
|
||||
└─ docs/ # ✅
|
||||
```
|
||||
|
||||
> 约束:`apps/server`、`apps/admin`、数据库相关一律不创建不设计(用户明确要求)。业务插件包 `packages/agent` 中依赖服务器 API 的工具只留占位接口。
|
||||
|
||||
## 工程纪律
|
||||
|
||||
- 依赖 `save-exact=true`(.npmrc),pi 包版本浮动 = 行为漂移
|
||||
- 主进程依赖 externalize(electron-vite 默认),pi 保持 `dependencies`,打包时随 app 分发
|
||||
- 每个版本 git tag(v0.1.0 起),自省记录追加到 `docs/roadmap.md`
|
||||
- 渲染进程零敏感信息:API key、pi 凭据只存在主进程可达的 `~/.pi`,渲染进程经 IPC 交互
|
||||
Reference in New Issue
Block a user