十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Happy 竞争研究笔记成文:Superset 的编排层(Orchestration)架构——从 PTY 多代理协调、Electric SQL 云同步到命令队列的完整拆解

Happy 竞争研究笔记成文:Superset 的编排层(Orchestration)架构——从 PTY 多代理协调、Electric SQL 云同步到命令队列的完整拆解 Happy 竞争研究笔记成文Superset 的编排层Orchestration架构——从 PTY 多代理协调、Electric SQL 云同步到命令队列的完整拆解【免费下载链接】happyMobile and Web client for Codex and Claude Code, with realtime voice, encryption and fully featured项目地址: https://gitcode.com/gh_mirrors/happy20/happy本文是 Happy 仓库竞争研究模块对开源桌面端编程代理 Superset 的深度调研成文核心围绕docs/competition/superset/README.md及其配套研究sync-architecture.md、electric-sql.md、terminal-sync.md、sources.md展开。Superset 与 Happy 的最大分野在于它不做协议解析、不做终端模拟、不做流式事件管道只做编排——在真实 PTY 中启动各类 Agent、通过 hook 观察其生命周期、用 git worktree 做任务隔离。读完本文你将掌握 Superset 的 monorepo 包边界设计、四层状态所有权与三层同步栈、基于云数据库的命令队列远程控制、manifest 持久化 host-service以及这些模式对 Happy 自身同步方案docs/realtime-sync-and-rpc.md、docs/cli-architecture.md的对照价值。Superset 是谁以编排为核心的 Coding Agent 平台Superset研究时点 2026-04-08仓库superset-sh/superset许可为 Elastic License 2.0 / ELv2是一款桌面优先的编程代理客户端。研究笔记给出的定位非常鲜明它不试图理解 Agent 的输出——而是把 Claude、Codex、Gemini 等当作不透明进程启动在真实 PTY 终端里通过 hook 观察其生命周期并用 git worktree 完成跨任务协调。几点研究结论3 人团队、持续 5 个多月每日发版研究记录为 2,100 commits、80 releases属于典型的小团队高迭代样本包边界极其清晰host-service与部署形态解耦零 Electron 感知、panes布局引擎与框架解耦、同步层分层干净CLI 可以经由云端数据库命令队列远程控制桌面应用无需 CLI 与桌面之间建立直连 WebSocketAgent 无关Claude、Codex、Gemini 等一律作为黑盒进程启动。该研究的current take强调Superset 是orchestration-layer design编排层设计的最强参考——即如何在不拥有 Agent 协议的前提下协调多个 Agent其 host-service 抽取模式可注入 provider、无 Electron 感知与 Electric SQL 云到本地同步均被标记为值得 Happy 深入研究的模式。Monorepo 结构Turborepo Bun 下的包边界Superset 采用 Turborepo Bun 的 monorepo研究记录将其拆为 Apps7与 Packages15两层Appsapps/desktop— Electron 桌面应用主产品React 19 xterm.jsapps/api— Next.js 云端 APINeon Postgres、Better Auth、tRPCapps/web— Next.js Web 控制台apps/electric-proxy— Cloudflare Worker代理 Electric SQL shape 流apps/mobile— Expo React Native 移动端apps/admin、apps/docs、apps/marketing。Packages核心后端与库superset/host-service—核心后端。Hono HTTP WebSocket管理 workspace、终端node-pty、文件系统、git、AI chat、PR自带 SQLiteDrizzle better-sqlite3零 Electron 感知通过createApp()工厂接受注入的 providersuperset/workspace-client— React 客户端库指向某个 host-service 实例的 tRPC React Query 客户端superset/shared— Agent 定义、命令构建、任务模板零框架依赖superset/cli— Bun 编译的 CLI基于superset/cli-framework做文件式命令路由命令覆盖 auth、devices、host、tasks、workspacessuperset/local-db— 桌面本地 SQLiteDrizzle存 projects、worktrees、workspaces、settings另有经 Electric SQL 镜像云端 Postgres 的同步表superset/db— 云端 Postgres schemaDrizzletasks、users、orgs、agent commands、device presencesuperset/panes—独立的二叉树窗格布局引擎Zustand vanilla store框架无关核心 React 绑定支持 tabs、splits、拖拽、resizesuperset/workspace-fs— 文件系统操作、模糊搜索VS Code scorer 移植、文件监听parcel/watcher、resource URIsuperset/mcp— MCP 服务器用于远程设备控制创建/删除 workspace、启动 Agent 会话、切换 workspace、列出设备superset/chat— AI 聊天运行时client/server/shared。两个最值得注意的架构取向host-service 的部署无关性可独立部署、不感知 Electron与panes 引擎的框架无关性Zustand vanilla store 支撑独立核心。这正是研究笔记中excellent package boundaries判断的来源——具体源码引用清单见 sources.md。同步架构四层状态所有权与分层同步栈原文档标题为three distinct layers但实际展开为 4 个 Layer配合 sync-architecture.md 的完整状态所有权映射可归纳为四份独立存储、各自有明确 owner 与同步策略。状态所有权地图1. 云端 Postgres共享数据的 source of truth— owner 为 API server任何客户端经 tRPC mutation 写入Auth 表auth.*users、sessions、accounts、organizations、members、invitations、OAuth clients/tokens/consents、API keys、device codes、JWKs、verifications业务表tasks含 Linear/GitHub 同步的external_provider/external_id、taskStatuses、integrationConnectionsOAuth 令牌、subscriptionsStripe 计费、devicePresence在线设备lastSeenAt用于命令路由、agentCommandsCLI→桌面命令队列、projects、workspacestype 枚举local | cloud JSON 配置、secrets按项目加密的环境变量、sandboxImages、chatSessionssessionHosts、usersSlackUsersv2 新架构表v2Projects、v2Hosts、v2Clients、v2UsersHosts、v2WorkspacesGitHub 表githubInstallations、githubRepositories、githubPullRequests摄取表ingest.*webhookEventsLinear/GitHub/Slack 原始载荷带pending/processed/failed/skipped状态机。2. 桌面本地 SQLite~/.superset/local.db— owner 为 Electron main 进程纯本地不云同步projects、worktrees、workspaces、workspaceSections、settings终端预设、Agent 预设、铃声、字体、分支前缀模式、browserHistory带访问计数的 URL 自动补全。3. Host-service SQLite~/.superset/host/{orgId}/host.db— 每个 org 一个 host-service 进程独有terminalSessionsPTY 生命周期跟踪、projects仓库元数据、pullRequestsPR 缓存、workspacesworktree 路径映射使用better-sqlite3开启 WAL journal 与外键。4. Renderer localStorage— 纯客户端v2SidebarProjects、v2WorkspaceLocalState最近一次窗格布局、v2SidebarSections经 TanStack DB 的localStorageCollectionOptions Zod schema 管理。一个极具辨识度的命名约定即边界标记camelCase列 仅本地snake_case列 经 Electric SQL 从云端同步。同一张本地库里projects这类 camelCase 本地表与users、organizations、tasks这类 snake_case 同步表并存。四层同步栈Layer 1本地 SQLite每台设备的桌面状态schema 见packages/local-db/src/schema/schema.tsLayer 2Electric SQL云到本地的实时同步。electric-proxyWorker 负责鉴权并代理 shape 流桌面端用electric-sql/clienttanstack/db订阅并写入本地 SQLite从而获得对组织数据、任务、用户的离线可用访问Layer 3WebSocket EventBushost-service 的实时事件两类消息——git:changedgit 状态变化自动广播300ms 防抖与fs:events按需的每客户端文件系统订阅。客户端侧引用计数、指数退避自动重连1s–30sLayer 4tRPCHTTP 上的请求-响应host-service 暴露/trpc/*路由health、chat、filesystem、git、github、PRs、workspaces。三条数据流路径读路径云 → 客户端Postgres → WAL tail逻辑复制→ ElectricElixir按表产 shape→ Electric ProxyCloudflare WorkerJWKS 校验 JWT、按表注入WHERE org_id ?行级安全、剥离敏感列、透传live/offset/cursor参数→ TanStack Electric Collection内存响应式 store→ React 组件useLiveQuery()。桌面端每组织订阅22 个 shapetasks、taskStatuses、projects、v2* 系列、members、users、invitations、agentCommands、integrationConnections、subscriptions、apiKeys、chatSessions、sessionHosts、githubRepositories、githubPullRequests 等移动端只订阅 6 个 shape且走 API server 的/api/electric/v1/shape而非独立代理鉴权用 cookie 而非 Bearer。写路径客户端 → 云UI 操作 → TanStack Collection 乐观本地更新 → tRPC mutation → Postgres INSERT/UPDATE → Electric WAL tail 拾取 → shape 流广播到所有订阅者 → Collection 依据 tRPC 返回的txid确认乐观写入。关键设计写入是不对称的——写走 tRPCElectric 只读冲突解决因此被明确划归写路径自担。实时事件路径磁盘 git 目录变化 →fs.watch(gitDir, {recursive:true})→ 300ms 防抖 →EventBus.broadcast({type:git:changed, workspaceId})→ WebSocket 推给所有客户端 →useGitChangeEvents()触发 React Query 失效。客户端对每个 hostUrl 只建单例 WebSocket指数退避重连1s 基、30s 上限重连后重发全部fs:watch订阅GitWatcher 每 30 秒重扫 DB 以自动发现新 workspace、回收已删除者的 watcher。与 Happy 的对照Happy 的实时同步与 RPC 同样是一条长连接承载同步与点对点控制的思路但选型是 Socket.IO单一/v1/updates端点、user-scoped/session-scoped/machine-scoped三种连接作用域、基于 room 的扇形广播与rpc:userId:method注册房间详见 docs/realtime-sync-and-rpc.md。对照 Superset 可发现两种哲学差异Happy 用长连接 room 模型实现事件扇出与 RPC 定位Superset 则把结构化数据同步下沉给 Electric SQL、把实时事件单独交给 WebSocket EventBus——后者将读路径缓存化、事件路径去状态化的切分正是 electric-sql.md 中评估read-heavy 模式与 CDN 缓存天然契合的动机。Electric SQL读路径同步引擎评估electric-sql.md 对 Superset 底层同步引擎做了独立评估。Electric SQL 是一个读路径同步引擎——独立 Elixir 服务tail Postgres WAL 并通过 HTTP 向客户端流式推送表的子集Shapes。它不是数据库、不是Postgres 扩展、也不是写路径方案研究记录License Apache-2.0GA 1.0 于 2025 年 3 月发布另有托管版 Electric Cloud。服务端仅需一个 Docker 容器electric: image: electricsql/electric:latest environment: DATABASE_URL: postgresql://user:passhost:5432/db ELECTRIC_SECRET: your-secret ports: - 3000:3000前提Postgres 14、wal_levellogical、用户具备REPLICATION角色。Electric 会自建 publicationelectric_publication_default、replication slotelectric_slot_default并对同步表设置REPLICA IDENTITY FULL无需扩展。客户端两种用法// React hooks import { useShape } from electric-sql/react function TaskList() { const { isLoading, data } useShapeTask({ url: http://localhost:3000/v1/shape, params: { table: tasks, where: org_id 123, columns: id,title,status }, }) if (isLoading) return divLoading.../div return ul{data.map(t li key{t.id}{t.title}/li)}/ul }// Vanilla TypeScript import { ShapeStream, Shape } from electric-sql/client const stream new ShapeStream({ url: http://localhost:3000/v1/shape, params: { table: tasks, where: org_id 123 }, }) const shape new Shape(stream) const rows await shape.rows shape.subscribe(({ rows }) console.log(Updated:, rows))原始 HTTP API 支持初始全量offset-1、live 长轮询livetruehandle...offset0_5、SSE 模式live_ssetrue与增量模式logchanges_only响应形如{offset:0_0,value:{...},key:\public\.\tasks\/\1\,headers:{operation:insert}}并以{headers:{control:up-to-date}}表示已追平当前状态。Shapes 的能力边界支持单表 WHERE、列选择、SQL 运算符/布尔逻辑/LIKE/IN/比较、参数化查询$1/$2、实验性子查询、ORDER BY/LIMIT/OFFSET渐进加载、分区表不支持JOIN只能多 shape 客户端侧拼接、聚合COUNT/SUM/AVG、WHERE 中的非确定性函数now()、random()且 shape 不可变切换上下文即新订阅。写路径必须 BYO自带配合 TanStack DB 的onInsert返回{ txid }实现乐观写确认。研究记录的性能数据官方测试口径优化 WHERE 下 live 更新延迟约6ms3ms PG 3ms Electric非优化 WHERE 在 1 万 shape 规模约 100ms写吞吐 4,000–6,000 行/秒生产规模 10 万–100 万并发用户。CDN 缓存是其扩展秘诀初始同步响应可 HTTP 缓存live 长轮询被 CDN 折叠N 个等待客户端 1 个上游请求。与 Custom WS、Supabase Realtime、PowerSync、CRDTs 的对比结论是Electric 在结构化数据同步 CDN 扇出 低复杂度上胜出适合做读多写少的场景。对 Happy 而言把 Agent 状态流式推到 UI正是典型 read-heavy 模式但需自建写路径、多维护一个服务、并接受无 JOIN 与 shape 不可变的约束。CLI 控制桌面云数据库命令队列Superset 最巧妙的远程控制机制CLI 到桌面之间没有任何直连 WebSocket云端 Postgres 的agentCommands表就是汇合点rendezvous point。CLI/MCP 工具插入一行status: pending、tool、params、targetDeviceId、timeoutAtMCP server每 500ms 轮询该行等待完成桌面端经 Electric SQL 同步拿到 pending 命令本地执行executeTool(tool, params)把状态更新为completed/failed并附结果MCP server 看到完成即返回结果。桌面侧是响应式的Electric SQLuseLiveQuery过滤statuspending AND targetDeviceId不轮询轮询只发生在 MCP server 侧。可执行工具清单createWorkspace、deleteWorkspace、getAppContext、getWorkspaceDetails、listProjects、listWorkspaces、startAgentSession、startAgentSessionWithPrompt、switchWorkspace、updateWorkspace。对照 HappyHappy 的远程驱动走 Socket.IO 上的 RPC——服务端rpcHandler.ts依rpc:userId:method房间解析目标机器侧 daemon 注册spawn-session等处理器移动端/Web 由此驱动本地会话docs/cli-architecture.md、docs/realtime-sync-and-rpc.md。Superset 的DB 即队列方案优势在于跨网络天然可用、无需维持长连接Happy 的 RPC 方案优势在于点对点延迟低、且复用既有实时链路。Happy 当前机器调用仍使用一次性 caller socket见 packages/happy-agent/src/machineRpc.tsmachineRpc.ts的优化被列为 docs/realtime-sync-and-rpc.md 中的sharp edge。Host-service 持久性manifest 清单与进程收养Host-service能扛住应用重启。生成时写入 manifest 文件~/.superset/host/orgId/manifest.json含{pid, endpoint, authToken, startedAt, protocolVersion}另有serviceVersion写入权限0o600下次启动时HostServiceManager扫描 manifests、健康检查 PID、收养仍在运行的实例正常退出时 detach 而不杀死服务。完整生命周期见 sync-architecture.md生成Electron fork Node 子进程ELECTRON_RUN_AS_NODE1→ 子进程经 IPC 上报{type:ready, port}→ 父进程写 manifest重启discoverAndAdoptAll()扫描~/.superset/host/→process.kill(pid, 0)探活 →GET {endpoint}/trpc/health.check3s 超时→ 协议版本校验 → 全过则收养不再起新进程正常退出releaseAll()detach IPCKEEP_ALIVE_AFTER_PARENT1保活manifest 留盘供下次收养崩溃对被收养进程每 5s 存活轮询发现死亡标记 degraded 并调度重启指数退避min(1000 * 2^restartCount, 30000)ms。这与 Happy 的 daemon 模型形成有趣的镜像Happy 的~/.happy/daemon.state.json记录 PID 控制端口 版本startDaemon()校验版本、获取锁文件、注册机器、启动本地 control serverdocs/cli-architecture.md。区别在于 Happy 的 daemon 是独立常驻进程 本地 HTTP control server而 Superset 的 host-service 是每 org 一个、manifest 驱动的可收养服务——研究笔记明确建议把injectable providers zero Electron awareness manifest-based durability这套抽取模式引入 Happy 的 CLI/server 拆分。Agent 编排模型不解析输出只观察生命周期Superset 的核心洞察是它从不解析或理解 Agent 的输出流。与之配套的五条设计git worktree 隔离每个任务拥有独立 worktreeAgent 无关启动Agent 就是真实 PTY 终端里启动的 CLI 命令字符串——claude --dangerously-skip-permissions、codex --bypass...、gemini --yolo等生命周期观察而非控制用 notify hooks 与 git watcher 得知 Agent 何时启动/停止/需要关注但从不注入 stdin/stdout任务→Agent 映射buildAgentCommand()把任务元数据渲染进 prompt 模板写入.superset/task-slug.md经--resume或 stdin 传入窗格布局即编排面二叉树布局类 tmux Zustand多个 Agent 分处不同 pane/tab。Agent 生命周期 hooks以 Claude 为例把 hook 定义合并进~/.claude/settings.json回调notify.sh脚本 → 请求GET http://localhost:port/hook/complete→ Express server 接收、校验并经notificationsEmitter广播——这就是桌面端获知Agent 需要关注的方式。研究笔记对此的评论是这与 OpenCode/Claude 的深度解析输出路线完全相反值得权衡——代价是无法结构化理解 Agent 内部状态收益是协议无关、可同时驱动任意 Agent 全家桶。横向定位见 comparison-matrix.mdOpenCode 是最优端到端协议参考Codex 是最优后端协议参考Claude 是最成熟 agent-team 工作流参考而 Superset 是最优编排层参考——不拥有协议、只负责协调配以 3 人 5 个月 2,100 commits 的惊人迭代速度。终端状态同步V1 daemon 与 V2 WebSocket 双架构terminal-sync.md 记录了 Superset两套并存的终端架构V1桌面 daemon本地终端成熟路径PTY 跑在独立子进程pty-subprocess.js用自定义 5 字节帧协议1 字节类型 4 字节长度帧类型含 Ready/Spawned/Data/Exit/Error/Spawn/Write/Resize/Kill/Signal/Dispose经 stdout 传输 →Session解码后经 Unix domain socket~/.superset/terminal-host.sockNDJSON 共享 token 鉴权广播 →TerminalHostClient每 daemon 维护 controlSocket请求/响应 RPC与 streamSocket单向事件流双 socket → Electron main 经 tRPC subscription 中继到 renderer。点睛之笔是HeadlessEmulatordaemon 内跑一个无头 xtermxterm/headlessxterm/addon-serialize镜像全部 PTY 输出跟踪 5000 行 scrollback、14 个终端 mode 标志DECSET/DECRST、CWDOSC-7与 alt screen 状态重挂时产出TerminalSnapshotsnapshotAnsi rehydrateSequences modes cwd dimensions可忠实还原 vim/htop 等 TUI 应用。背压控制emulator 写队列超 1MB 暂停 PTY 读EMULATOR_WRITE_QUEUE_HIGH_WATERMARK_BYTES、250KB 恢复子进程 stdin 队列上限 2MB。V2host-service WebSocket远程/云 workspace 简化路径host-service 内直接node-pty.spawn()经/terminal/:terminalIdWebSockethono/node-ws传 JSON 消息服务端→客户端data|replay|error|exit客户端→服务端input|resize|dispose。设计原则是PTY 生命周期与 socket 生命周期相互独立断连时 PTY 继续跑输出写入64KB 内存环形缓冲MAX_BUFFER_BYTES重连时一次性{type:replay}回放自动重连指数退避500ms 基、10s 上限、10 次。terminalSessions表id/origin_workspace_id/status: active|exited|disposed/created_at/last_attached_at/ended_at支撑完整生命周期Create → Attach/Detach同终端新连接以 4000 关闭码顶替旧 socket→ ExitPTY onExit 置exited→ Dispose → List。多窗格管理上TerminalRuntimeRegistry以terminalId为键管理 xterm 实例与 WebSocket 传输pane 挂载/卸载即registry.attach/registry.detachruntime 独立于 DOM 持久化——detach 时 xterm buffer 序列化进 localStorage上限 1000 行重挂时恢复。加上 xterm.js 5000 行 live scrollback、HeadlessEmulator 5000 行权威源、64KB ring buffer、localStorage 1000 行、V1 cold restore 全屏快照共构成5 层 scrollback 保存应用/daemon 重启后的冷恢复以只读 scrollback Session Contents Restored 分隔线呈现useTerminalColdRestorehook用户可在同一 CWD 启动新 shell。对 Happy 的直接启示研究笔记原话PTY 放子进程的隔离模式值得在 Happy 直接跑 PTY 时参考HeadlessEmulator 的xterm/headless serialize 方案可忠实还原 TUI 状态64KB ring buffer 重连回放是简单而有效的模式PTY 生命周期与 UI 生命周期解耦与 Happy daemon 现有工作方式一致。对 Happy 的可借鉴结论综合 README.md 与全套配套研究Happy takeaways可归结为五点host-service 抽取模式injectable providers、零 Electron 感知、manifest 持久化直接适用于 Happy 的 CLI/server 拆分对照 docs/cli-architecture.md 的 daemon control server 模型Electric SQL 云到本地同步生产验证过的模式值得对照 Happy 当前同步方案docs/realtime-sync-and-rpc.md评估取舍云数据库命令队列CLI→桌面控制无需直连、跨网络可用是 RPC 长连接之外的另一条可行路径不解析 Agent 输出、只观察生命周期哲学与 OpenCode/Claude 路线相反权衡点值得深入理解可结合 comparison-matrix.md 四家横向对比阅读panes 独立包 Zustand vanilla store任何 Happy 布局引擎工作都可借鉴的框架无关设计。若需追查原始证据链研究笔记的审查日期、上游仓库、关键文件清单如host-service-manager.ts、event-bus.ts、git-watcher.ts、electric.ts、schema.ts等均记录在 sources.md该目录的组织规范见 docs/competition/AGENTS.md——竞品 checkout 留在仓库外、只沉淀结论与小型证据正是这套竞争研究得以长期保持高质量的原因。【免费下载链接】happyMobile and Web client for Codex and Claude Code, with realtime voice, encryption and fully featured项目地址: https://gitcode.com/gh_mirrors/happy20/happy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表