Paseo 贡献者开发指南:从仓库地图、平台门控到协议兼容的完整规范解读
【免费下载链接】paseoOrchestrate multiple coding agents from desktop and mobile项目地址https://gitcode.com/gh_mirrors/pa/paseo点击查看免费下载Paseo 是一款面向本地 AI 编程代理Agent的监控与控制应用支持从手机或桌面随时接管你的开发环境。本文以仓库根目录的 AGENTS.md 为核心系统讲解 Paseo monorepo 的结构、docs/知识库体系、快速开发命令、关键协作红线以及贯穿全仓库的平台门控与协议兼容机制同时结合packages/app/src/constants/platform.ts、scripts/dev-home.sh、docs/development.md 等源码与文档帮助贡献者、Agent 与 LLM 快速掌握如何安全地在 Paseo 仓库中开发与提交变更。一、Paseo 是什么本地 Agent 的随身控制台Paseo 是一个移动端应用用于随时随地监控和控制运行在你本机的 AI 编程代理——你的开发环境装进口袋Your dev environment, in your pocket。它直接连接到你的真实开发环境代码始终留在你自己的机器上。当前支持以下 Agent 提供商Claude CodeCodexGitHub CopilotOpenCodePi从仓库根目录的 package.json 可以看到项目自述为 voice-controlled development environment for local AI coding agents采用 Apache-2.0 许可证版本号 0.9.0-beta.2。这说明 Paseo 不只是看日志的仪表盘而是一套完整的代理编排与控制面。二、仓库地图npm workspace 单体仓库Paseo 是一个 npm workspace 单体仓库monorepo。AGENTS.md 给出了官方地图各包职责如下包职责packages/serverDaemon守护进程代理生命周期管理、WebSocket API、MCP 服务器packages/app移动端 Web 客户端Expopackages/cliDocker 风格 CLIpaseo run/ls/logs/waitpackages/relay端到端加密中继用于远程访问packages/desktopElectron 桌面包装器packages/website营销站点从根 package.json 的workspaces字段可以确认完整的 workspace 列表还包括packages/expo-two-way-audio、packages/highlight、packages/plugin、packages/protocol、packages/client。其中packages/protocol承载 WebSocket 协议消息的 Zod schemapackages/protocol/src/messages.ts是协议兼容性的核心packages/client是协议与 daemon 的 SDK 客户端负责能力声明与订阅管理packages/plugin提供插件系统的类型与运行时支持。理解这条依赖链非常重要protocol → client → server/cli/app跨包类型检查依赖dist/中生成的声明文件这也是后文构建工作区包规则存在的原因。三、docs/知识库系统级知识的唯一事实来源AGENTS.md 明确了一条纪律docs/目录是系统级与流程级知识的唯一事实来源。文档中说 the docs、check the docs永远指这个目录而不是官网。原因很直接文档捕获了无法从代码或外部资料推导出来的坑与约定。开始一项非平凡工作前应先列出docs/目录并浏览与任务相关的内容。下表是文档索引中与日常开发最相关的一部分完整表格见 AGENTS.md文档内容docs/product.mdPaseo 是什么、面向谁、未来走向docs/architecture.md系统设计、包分层、WebSocket 协议、代理生命周期、数据流docs/agent-lifecycle.md代理状态、父子关系、归档语义、标签页 vs 归档、子代理跟踪docs/data-model.md基于文件的 JSON 持久化、Zod schema、原子写入、无迁移docs/glossary.md权威术语表——以 UI 标签为准禁止同义词docs/coding-standards.md类型卫生、错误处理、状态设计、React 模式、文件组织docs/hover.mdHover 规范——规范模式与三种破坏方式docs/protocol-compatibility.mdapp/daemon 版本漂移、协议 vs 功能契约、能力门控、COMPAT 标记docs/permissions.md语义化 daemon 权限、主体、凭据、配对邀请、Hub 权威docs/development.md开发服务器、构建同步坑、CLI 参考、代理状态、Playwright MCPdocs/release.md发布手册、草稿发布、完成清单SECURITY.md中继威胁模型、端到端加密、DNS 重绑定、代理认证写作规范整合而非追加对文档知识库的维护AGENTS.md 提出了一套反直觉但实用的写作纪律整合不要追加Integrate, dont append找到拥有该主题的文档重写其中已经错误的部分。标准失败模式是任务做完后在最像的文档末尾加一段十个任务后文档就变成按发现顺序堆砌的段落——docs/custom-providers.md 就是这种失败的例子。不要记录逻辑Dont document logic复述代码的文字会与代码漂移并最终失准。要记录的是代码无法告诉你的东西为什么这样设计、花了一下午才搞定的坑、没有任何机制强制的约定、跨包或跨版本的约束。读者花两分钟打开文件就能得到的信息不要写。一事实一文档One fact, one doc其他所有提及都应是链接。如果要在两个文档写同一段话其中一处应该改成链接。尊重分层Respect the layersCONTRIBUTING.md和本文件负责命名与链接活动类文档如 docs/qa.md、docs/testing.md为某种工作设定标准主题类文档如 docs/unistyles.md完整拥有一个主题。每一层不再复述下面一层。一文档一主题One subject per doc主题一句话说不清就拆分文档。每个提供商/厂商/平台一节等于一张表加一个完整示例。删除Delete过时章节直接删除。优先用packages/app/src/thing.ts:120这样的引用而不是粘贴代码块。新增文档在上面的表格中加一行并在应该引导读者到那里的文档中加链接。代码级事实属于代码旁边的注释不属于这里。文档语气Doc voice用词平实简短第二人称。先陈述规则当理由不明显时再给理由与正在编辑的文档保持一致。明确禁止为了抛出观点而写句子它不是 X它是 Y这类铺垫式收尾只用于强调重要性的从句这一点很关键、这是它能持续工作的原因使用 honest、robust、seamless、powerful、simply、just、delightful 等词用不同的话复述已说过的内容来加强语气答案明确是就这么做时却用 generally、typically、you may want to 之类的含糊措辞清嗓子的开场Its worth noting that、In order to、This section covers。四、快速开始开发服务器、CLI 与 dev home常用命令npm run dev # 启动开发 daemon npm run dev:app # 启动 Expo 并连接开发 daemon npm run dev:desktop # 启动 Electron 桌面开发 npm run cli -- ls -a -g # 列出所有代理 npm run cli -- daemon status # 检查 daemon 状态 npm run typecheck # 每次变更后必须运行 npm run lint # 每次变更后必须运行 npm run format # 使用 Biome 自动格式化 npm run format:check # 只检查格式不写入结合 docs/development.md 可以还原这些命令背后的端口布局npm run dev:server在127.0.0.1:6768运行 daemonnpm run dev:app在http://localhost:8081运行 Expo并连接上述开发 daemonnpm run dev:desktop在从8082到8089的第一个空闲端口运行自己的 Electron 版 Expo 服务器绝不占用 8081npm run dev只是npm run dev:server的简写。从根 package.json 可以看到这些脚本的真实定义dev:server使用cross-env PASEO_LISTEN127.0.0.1:6768 ./scripts/dev-daemon.shdev:app额外设置EXPO_PORT8081cli脚本则是./scripts/dev-home.sh npx tsx packages/cli/src/index.js——即通过 dev-home 包装器从源码运行 CLI。dev home把开发状态隔离在 checkout 内AGENTS.md 强调仓库开发命令默认使用 checkout 本地状态。在本 checkout 中PASEO_HOME解析为.dev/paseo-home而npm run cli -- ...通过同一个 dev-home 包装器自动指向同一个开发 home。打包的桌面应用和生产风格 daemon 则继续使用~/.paseo与端口6767。scripts/dev-home.sh是实现这一机制的脚本从源码可以看到其核心逻辑默认PASEO_HOME为$dev_root/.dev/paseo-home其中dev_root来自PASEO_DEV_ROOT或git rev-parse --show-toplevelscripts/dev-home.shconfigure_dev_daemon_config会在config.json中写入daemon.listen PASEO_LISTEN默认127.0.0.1:6768以及cors.allowedOrigins [*]让 Expo 开发环境可以跨源访问 daemonseed_worktree_paseo_home支持从PASEO_DEV_SEED_HOME默认~/.paseo复制 agents/projects 的 JSON 元数据与config.json到 dev home且仅复制 JSON、不复制 pid/socket/log 等运行时文件。覆盖旋钮docs/development.mdPASEO_HOME~/.paseo-blue npm run dev # 显式指定 home PASEO_DEV_SEED_HOME/path/to/home npm run dev # 从另一个源 home 播种 PASEO_DEV_RESET_HOME1 npm run dev # 清空并重新播种派生的 worktree home完整的环境搭建、构建同步要求与调试方法参见 docs/development.md。五、发布分支纪律Release branches当用户说 this goes to next 时需要创建或把 PR 重新指向next并在交付全程保持该目标。创建与更新next、发布后整合、以及从 tag 发布热修复的具体流程遵循 docs/release.md 的发布分支纪律。docs/release.md 的核心要点是在main上收尾发布的同时用临时next分支承接下一个发布的工作next每次从最新origin/main创建、复用不重开、通过合并origin/main保持最新而非 rebase因为代理与打开的 PR 依赖其历史发布完成后开next → main的整合 PR并保留各 PR 提交以便生成 changelog。六、关键规则Critical rules守护 daemon 与测试纪律绝不未经许可重启 6767 端口上的主 Paseo daemon——它管理者所有运行中的代理。如果你本身是代理重启它会杀死你自己的进程。绝不假设超时意味着服务需要重启——超时可能是瞬态的。绝不在测试中添加认证检查——代理提供商自己处理认证。绝不本地运行完整测试套件。测试套件很重会冻结机器尤其当多个代理并行运行时。规则如下只运行你改动过的具体测试文件npx vitest run file --bail1除非被明确要求绝不在整个 workspace 运行npm run test必须跑宽套件时把输出管道到文件再读取npx vitest run file --bail1 /tmp/test-output.txt 21绝不重跑其他代理已跑过并报告绿色的套件——信任已有结果完整套件验证推 CI查看 GitHub Actions。测试应加入既有套件复用其 npm 脚本与 CI 任务而不是创建功能专属的新套件。typecheck、lint 与格式化每次变更后都运行 typecheck 和 lint。诊断跨包类型错误前先构建 workspace 包。本仓库跨 workspace 消费生成的声明如果某个依赖其他 workspace 的包 typecheck 失败先重建所有者栈让dist/声明保持最新npm run build:client——重建 protocol 与 client 声明npm run build:server——当 server/CLI 类型可能过期时重建 highlight、relay、protocol、client、server 与 CLI。不要为了压掉过期的声明错误而手动修补推断出的回调参数或添加本地重复类型。提交前运行npm run format。本仓库用 Biomeoxfmt格式化不要手工修格式。lint 与格式化永远走 npm 脚本不要直接运行npx eslint、npx oxfmt、npx oxlint或包内本地二进制。定向检查时把文件路径传给 npm 脚本npm run lint -- packages/app/src/components/message.tsxnpm run format:files -- CLAUDE.md packages/app/src/components/message.tsx从根 package.json 可以看到format定义为oxfmt .lint定义为oxlint与上述规则一一对应。协议兼容协议永远兼容功能不必改动packages/protocol之前必读 docs/protocol-compatibility.md。核心矛盾是app 与 daemon 是两个独立发布的产品——用户可能从应用商店/桌面自动更新升级 app却迟迟不升级 daemon于是新 app 配旧 daemon、旧 app 配新 daemon在线上都会出现。开发时两端永远同版本这正是贡献者最容易忽略的约束。由此推出两条契约协议契约永远成立旧客户端必须能解析新 daemon 的消息新 daemon 必须能解析旧 app 的消息。新字段用.optional()并给合理默认值绝不把 optional 改为 required、绝不删除字段、绝不收窄类型string改enum、可空改非空都属于收窄停止发送的字段仍然要能接收——你停止写入但不停止读取wire schema 是纯结构声明WebSocket 消息 schema 上禁止.transform()、.catch()、.preprocess()——归一化在验证后的显式 pass 中完成原因见 docs/protocol-validation.md入站验证器由代码生成生成器只编译纯 schema当每个分支共享字面量 tag 时禁止裸z.union()改用z.discriminatedUnion().default()只放原始叶子字段绝不放在大型数组内部或大型入站容器的条目 schema 上。提交 schema 变更前自问两个问题①六个月前的 app 还能解析这条消息吗②六个月前的 daemon 发送的东西当前 app 还能接受吗两个答案都是能变更才算完成。Schema 位于packages/protocol/src/messages.ts。功能契约按功能门控一次新功能通常需要新 daemon 能力旧 daemon 没有。app 检查能力标志要么运行该功能要么告诉用户更新宿主。无回退路径不要为旧 daemon 构建降级版功能不要通过遗留 RPC 扇出去模拟不存在的能力。用户要么更新要么没有这个功能。无散布的防御分支检测只在一处完成下游一律读取干净形状。能力标志位于server_info消息的features字段packages/protocol/src/messages.ts的server_infoschema。既有功能跨版本正常工作靠的是协议契约给新功能做门控永远不能替代协议契约。每个 shim 都要打标记并注明日期。为旧 app/旧 daemon 存在的兼容 shim 必须带注释说明名字、引入版本与可删除时间// COMPAT(workspaceFileEditing): added in v0.2.0, remove after 2027-01-18 once daemon floor v0.2.0.rg COMPAT\(就是完整的清理积压清单一个 shim 一个标记放在必须删除的位置给出名字、版本与删除条件/日期通常默认六个月绝不把兼容埋进未标记的??回退或可选链隧道里——未标记的向后兼容永远不会被删除因为没人找得到它。标记条件满足后在同一次变更中删除 shim 与标记。RPC 命名空间新 WebSocket 会话 RPC 使用点分命名空间方向后缀作为最后一段详见 docs/rpc-namespacing.mdcheckout.forge.set_auto_merge.request; checkout.forge.set_auto_merge.response;命名空间从左到右读域checkout→ 命名空间段forge→ 操作set_auto_merge动词而非名词→ 方向request/response。用点不用斜杠点是协议命名空间斜杠暗示路径或传输路由。普通关联 RPC 的.request应有同前缀的.responsedaemon client 可以机械推导响应类型。请求参数放在顶层响应关联数据放payload且requestId同时出现在请求与响应中作为关联键。不要新增扁平 RPC 名迁移旧 RPC 时先加新名、通过server_info.features.*门控、兼容窗口期内保留旧名、用COMPAT(...)标记并给删除日期。七、平台门控Platform gatingapp 运行在 iOS、Android、Web浏览器和 WebElectron 桌面四种表面。代码默认跨平台只在必须时门控。门控导入自/constants/platform。四类门门类型使用时机isWeb常量DOM API——document、window、div、addEventListener、ResizeObserver。这是例外不是默认isNative常量仅原生 API——Haptics、StatusBar.currentHeight、推送 token、相机/扫描器、expo-avgetIsElectron()缓存函数桌面包装器功能——文件对话框、标题栏拖拽区、daemon 管理、应用更新、dock 徽标useIsCompactFormFactor()Hook布局决策——侧栏覆盖 vs 固定、模态 vs 全屏、单面板 vs 分栏。来自/constants/layout决策矩阵我需要……使用访问 DOMdocument、window、div、addEventListenerif (isWeb)使用仅原生 APIHaptics、推送 token、相机if (isNative)使用 Electron 桥文件对话框、标题栏、更新if (getIsElectron())在手机与平板/桌面之间切换布局useIsCompactFormFactor()hover 时显示、原生端始终可见isHovered \|\| isNative \|\| isCompacthover 只在 web 有效专门针对 iOS 或 AndroidPlatform.OS ios/Platform.OS android少见保持内联源码层面的实现packages/app/src/constants/platform.ts正是 AGENTS.md 所指的唯一平台门控来源/** Browser or Electron — the JS runtime has access to the DOM. */ export const isWeb Platform.OS web; /** iOS or Android — the JS runtime is React Native. */ export const isNative Platform.OS ! web;值得注意的是getIsElectron()的缓存策略它只缓存true为false时继续检查。源码注释解释了这个设计——桌面桥可能在初始模块求值之后才加载所以检测必须可重入packages/app/src/constants/platform.ts。这意味着是否运行在 Electron 中不是模块加载时一次性确定的首次调用返回false不代表永远为false。布局方向的useIsCompactFormFactor()则基于 Unistyles 的响应式断点export function useIsCompactFormFactor(): boolean { const { rt } useUnistyles(); return rt.breakpoint xs || rt.breakpoint sm; }它被定位为reactive hook——断点变化时重新渲染组件并且注释强调永远用这个 hook而不是直接读UnistylesRuntime.breakpointpackages/app/src/constants/layout.ts。这正是 docs/unistyles.md 中禁止useUnistyles()约定的自然延伸——组件应当通过这条受控的入口获取布局形态而不是自行订阅全局运行时。规则优先用 Metro 文件扩展名而不是if默认跨平台没有具体理由就不要门控。优先用 Metro 文件扩展名而非if语句当一个模块在不同平台有本质不同的实现时用.web.ts/.native.ts文件扩展名代替运行时if (isWeb)分支。Metro 在构建期解析正确文件——未用到的平台代码根本不会被打进 bundle。if (isWeb)只留给小的、内联的检查一行或几个 prop。如果发现自己要写一大段if (isWeb) { ... } else { ... }拆成独立文件hooks/ use-audio-recorder.web.ts ← uses Web Audio API use-audio-recorder.native.ts ← uses expo-audio导入写/hooks/use-audio-recorderMetro 自动选对文件。Electron 专属 web 模块用.electron.ts/.electron.tsxElectron 仍是 Metro 的web平台但桌面开发/构建设置PASEO_WEB_PLATFORMelectronMetro 会先找.electron.*再回退普通.web.*。依赖 Electron 独有行为如webviewTag、桌面 preload API、Electron 桥时用它普通浏览器 web 放.web.*原生回退放基础文件或.native.*desktop/browser/pane/ index.electron.tsx ← Electron webview implementation index.web.tsx ← plain web fallback index.tsx ← native fallback导入/desktop/browser/paneElectron 桌面拿到.electron.tsx浏览器 web 拿到.web.tsx原生拿到原生/基础实现。交互相关的硬性禁令绝不无isWeb守卫地使用原生 DOM API——DOM API 在原生端会崩溃。把 RN ref 强转为HTMLElement是危险信号确保该块仅 web 生效。绝不在Pressable上使用onPointerEnter/onPointerLeave——它们在原生 iOS 上不触发。Hover 只在 web 上工作React Native 的Pressable的onHoverIn/onHoverOut在原生 iOS/iPad 上不会触发——底层 W3C pointer 事件被禁用的实验性 flag 挡着。对 hover 显示 UIkebab 菜单、操作按钮用isHovered || isNative || isCompact让控件在原生端始终可见、在 web 端 hover 显示。关于 hover 的正确形态docs/hover.md 提供了完整规范hover 状态放在普通View上用onPointerEnter/onPointerLeave按压缩放独立的内层Pressable上行容器固定minHeight且外层View只承担position: relative。规范实现见packages/app/src/components/sidebar-workspace-list.tsx的工作区行。三大失败模式嵌套 Pressable 争抢 hover、hover 状态改变触发器几何、被揭示内容位于触发器之外以及浮层场景的useHoverSafeZonepackages/app/src/hooks/use-hover-safe-zone.ts改动 hover 相关代码前都值得通读。不要用Platform.OS代理布局能力判断布局决策用断点不用平台检查。isWeb/isNative一律从/constants/platform导入绝不在本地写const isWeb Platform.OS web。八、调试daemon 日志完整的 daemon 日志与 trace 位于$PASEO_HOME/daemon.log。默认级别为info排查卡死状态需要完整 provider/session/agent-manager 追踪时在启动 daemon 前设置PASEO_LOG_LEVELtrace。supervisor 会轮转daemon.log持久化的log.file.rotate设置优先默认轮转为10m× 3 个文件详见 docs/development.md 的 Daemon logs 一节。九、总结贡献者的心智模型把 AGENTS.md 的规则收拢成一套可执行的心智模型先看 docsdocs/是知识唯一事实来源动手前先扫一遍相关主题文档默认跨平台能不加门控就不加必须加时用/constants/platform的四类门模块级差异优先拆.web.ts/.native.ts/.electron.tsx文件守护运行时不重启 6767 的 daemon、不乱跑全量测试、typecheck lint format 每次必跑协议意识改packages/protocol前先想清楚旧客户端能不能解析新消息、旧 daemon 满不满足新 app新功能用server_info.features.*门控一次兼容 shim 必须带COMPAT(...)标记dev home 隔离仓库内开发状态落在.dev/paseo-home与生产~/.paseo隔离CLI 自动指向当前 checkout。这套规范既服务于人类贡献者也是仓库中 Agent 协作的交通规则——它保证了多个代理在同一仓库并行开发时不会互相踩踏 daemon、测试与格式。理解它是高效、安全地为 Paseo 贡献的第一步。赞分享【免费下载链接】paseoOrchestrate multiple coding agents from desktop and mobile项目地址https://gitcode.com/gh_mirrors/pa/paseo点击查看免费下载相关推荐Apache Airflow 仓库开发规范解读写给 AI Agent 与贡献者的完整协作指南Apache Airflow 仓库开发规范解读写给 AI Agent 与贡献者的完整协作指南 Apache Airflow 是一个用于以编程方式编写auth后端Web框架NetBox 仓库协作开发指南从源码地图到贡献规范与工程实践NetBox 仓库协作开发指南从源码地图到贡献规范与工程实践 导读 本文基于 NetBox 仓库根目录下的 AGENTS.md https://link.gi后端网络数据建模Floci 仓库 AI 编码 Agent 开发指南架构约束、AWS 协议兼容与贡献规范Floci 仓库 AI 编码 Agent 开发指南架构约束、AWS 协议兼容与贡献规范 本篇技术指南以 Floci 仓库根目录的 AGENTS.md http上一篇Hydro项目Nginx反向代理配置详解下一篇OpenCopilot项目实战如何让AI助手执行后端操作创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考