DEVELOPMENT - 开发导航(Index)

June 30, 2026 · View on GitHub

本文档是本仓库的“开发入口/索引”。为避免一次性信息过载,详细规范已拆分到各模块目录下,请按需打开对应文档。

如何使用(给 Agent / 开发者)

  1. 每次任务先读本文件:获取全局硬规则、文档地图、执行方法与常用入口。
  2. 职责分层AGENTS.md 只保留关键指令、决策门槛与非协商项;具体方法、步骤和例子优先写在本文件或 docs/ 专项文档。
  3. 需要专题细节时:按文档地图继续打开对应 docs/ 文档。

开发与测试指南

核心编码原则 (Core Coding Principles)

只保留最容易在日常开发中被忽略、但一旦忽略就容易形成系统性问题的原则:

  1. 优先复用 (Prioritize Reuse): 在创建任何新代码、组件或工具函数之前,必须彻底搜索现有代码库以查找可复用组件。如无必要勿增实体,避免重复造轮子。
  2. 明确状态所有权 (State Ownership): 对会被持久化、恢复、同步或跨层传播的状态,必须明确唯一 owner 与 single source of truth。多个写入口默认视为设计风险。
  3. 边界内聚,副作用靠边 (Keep Boundaries Clean): Main / Preload / Renderer / external CLI 各司其职。状态决策不要跨层泄漏,IO / IPC / 文件系统等副作用尽量收敛在边界层。
  4. 封装横切关注点 (Encapsulate Cross-Cutting Concerns): IPC、日志、错误处理、watcher、persistence coordination 等横切逻辑要统一收口,避免调用方各自实现一份。
  5. 重复行为优先下沉到拥有者 (Logic Internalization): 若同一行为在多个调用方重复出现,优先下沉到真正拥有该行为的组件/模块,而不是在使用方复制。
  6. 把 SOLID 当作校准器,不当作教条 (Use SOLID as a Design Check):
    • S:模块如果同时承担状态决策、IO、UI、恢复策略,通常已经拆分过晚。
    • O:新增 provider / adapter / watcher 时,优先新增实现,而不是到处改稳定分发逻辑。
    • L:只有存在真实子类型替换时才考虑;不要为了“像 OO”强造继承层级。
    • Ipreload / service / bridge 接口要小而专用,不暴露大而全 API。
    • D:高层依赖抽象端口和类型,不直接依赖 Electron / PTY / CLI 细节。
  7. 结构优先于补丁 (Prefer Structural Clarity over Patch Accumulation): 不要等问题复发后才升级。只要任务本身已经暴露出 多个 mutable state owner边界/权限含混同一入口承载多套竞争语义或解释路径、或 局部修补会制造隐藏/矛盾状态,就应先收敛结构而不是继续叠 patch。
  8. Renderer 反馈统一用应用内消息,不用系统弹窗 (Use In-App Feedback, Not System Dialogs): Renderer 层禁止新增 window.alert / confirm / prompt 这类系统弹窗;统一复用应用内反馈组件,并按语义区分 info / warning / error 三个视觉层级,避免阻塞交互与平台观感割裂。

命名与前缀 (Naming)

  • 对外/协议/持久化统一使用 OpenCove / opencove(例如 window.opencoveApiOPENCOVE_*.opencove/opencove.db)。
  • UI 设计系统与样式命名空间保留 cove 前缀(例如 --cove-*data-cove-*.cove-window),作为稳定的内部约定。
  • 历史版本的 localStorage key 可能仍使用 cove:m0:* 前缀;当前实现会兼容读取并迁移。

架构执行触发器 (Architecture Execution Triggers)

只保留最容易在代码演化中失控、且最值得前置约束的触发器:

  1. 先分离决策与编排:状态迁移/业务判定属于 owner;IO / IPC / CLI / watcher 调用属于 orchestration。一个函数若同时承担两者,默认应先拆分。
  2. 出现以下组合时,先拆再改
    • 同一文件出现两个以上独立变更原因。
    • 同一函数同时包含 状态判定 + 外部调用 + fallback/retry + 写回
    • 同一次改动同时触及 lifecycle / persistence / hydration / resume / watcher 中两项及以上。
  3. 高风险路径先写不变量:启动、恢复、关闭、重试、fallback、异步乱序相关改动,先写 1-3 条 invariant,再决定实现位置与测试层级。
  4. 结构性风险先升级判断:以下信号任中其一,就必须按 Large Change 处理,而不是直接以最小改动修补:多个 mutable state owner边界或 authority 难以解释同一入口/输入/观测承载多套竞争语义或状态迁移局部 patch 可能制造新的矛盾状态或隐藏状态同一真相被 runtime observation 与 durable state 同时改写。是否“已经复发”只作为额外证据,不作为触发前提。
  5. 当“补丁在增加复杂度”而不是“降低复杂度”时,必须优先重构:下面任一命中,默认暂停继续堆条件/缓存/协调代码,先做结构收敛(拆 owner、收口写入口、隔离副作用):
    • 改动开始非局部扩散:一个小需求/修复需要同时修改多个模块、边界或层才能生效。
    • 真相分裂或覆盖规则不清:同一事实出现多份镜像状态/缓存/派生值,且无法明确“谁能覆盖谁”。
    • 特殊情况快速增长:修复主要靠追加分支、开关、临时状态、时序约束,而不是删除分支或合并抽象。
    • 可测试性下降:无法写出稳定回归测试或不变量,必须依赖真实时序/IO/全局环境才能复现。
    • 同类问题短期内反复出现:同一类故障在一个迭代内出现多次,说明边界/owner/不变量未收敛。
    • 需要具体案例时,参考:docs/cases/CASE_STUDY_CANVAS_JITTER_AND_TERMINAL_DURABILITY.md

架构契约变更 Gate (Architecture Contract Change Gate)

本节只记录必须遵守的入口规则。详细 checklist 和 guard 行为见 harness/architecture/README.md

  • 契约文档包括:docs/architecture/ARCHITECTURE.mddocs/architecture/CONTROL_SURFACE.mddocs/architecture/RECOVERY_MODEL.md
  • 如果改动影响依赖方向、层职责、进程边界、allowlist、禁止 import/API 或 severity,必须同步 harness/architecture/ 的规则、分析器、测试和结果。
  • 如果只是措辞、错别字或说明性例子,必须在 review/提交说明中声明 no executable-rule impact
  • 本地 staged guard:pnpm arch:doc-sync

高风险问题预防策略(只列最容易漏的)

以下内容是前文原则的落地建模方式;正式检查项统一见后文“风险与合规检查”,这里不重复展开检查清单。

  1. 先写状态/所有权表,再写流程:对跨 Main / Preload / Renderer / PTY / persistence / external CLI 的改动,先明确四列:stateownerwrite entryrestart source of truth。若同一真相存在多个写入口,默认高风险。
  2. 严格区分四类状态:建模时至少先区分 用户意图 / 持久化事实 / 运行时观测 / UI 派生展示 四类状态;owner、恢复语义与写回约束按后文“风险与合规检查”执行。
  3. 优先验证不变量,不堆场景:每个高风险改动至少先写出 1-3 条不变量。测试优先证明“哪些错误不会发生”,而不是只证明 happy path 能跑通。
  4. 默认过一遍故障模型:重点考虑 await 中途关闭窗口/退出 app、事件重复/乱序/延迟、fallback 或 cleanup 比 happy path 更早写状态、部分成功/部分失败、旧数据恢复,以及跨平台路径/shell/权限差异。
  5. 测试按风险层分配,不按文件平均分配
    • Unit:状态迁移、normalize、纯逻辑不变量。
    • Contract:IPC payload、跨层边界、输入校验。
    • Integration:hydration、persistence、restart、lifecycle、watcher 协作。
    • E2E:关键用户路径与真实交互链路。
    • UI 手段选择、Playwright、截图 / 录屏等细节,统一见后文“UI 自动化与验证”。
  6. 结构分析先于实现:凡命中结构性风险信号,实现前至少产出一份最小分析:mutable state owner 表边界/路由图(按场景可对应事件、消息、watcher、lifecycle)1-3 条 invariants,以及 局部 patch vs 抽象收敛 的 trade-off 说明。缺少这些信息时,不进入编码。
  7. 边界驱动系统先识别 source / route / owner:涉及事件、消息、watcher、回调、lifecycle 或其他边界驱动系统的冲突时,先明确 谁发出谁路由谁拥有默认行为谁拥有状态写权。任何需要靠隐式副作用才能维持正确性的实现,都默认视为结构问题。
  8. 每个真实 bug 都要资产化:至少沉淀为以下之一:回归测试、运行时断言、文档规则、抽象收敛。若在分析阶段已经能看出同一结构弱点会导出多个相邻故障模式,就必须直接升级为系统性治理任务,目标是合并 owner、消除重复写入口或收敛交互抽象,而不是等待再次复发。

通用参考学习与方案生成法(Research -> Synthesize -> Adapt -> Verify)

凡是行业内大概率已有成熟做法、主流产品 / 框架 / 库已有先例、或问题明显不是 OpenCove 独有时,都应主动查找外部参考,再结合本仓约束提出方案,而不是等用户点名要求后才去看。

  1. 先识别问题类,不先写实现:先写一句 这是哪一类已有行业先例的问题,再写一句 OpenCove 当前真正不稳定 / 不清晰的承诺是什么
  2. 按四层查参考
    • 产品 / 帮助文档 / 规范:确认外部世界对该问题类承诺的稳定行为。
    • 官方示例 / 源码 / 测试 / RFC:确认默认策略、owner、边界和 fallback。
    • issue / discussion / changelog / maintainer comment:确认 trade-off、平台差异和已知坑。
    • 本仓现有实现:确认哪些抽象可以复用,避免平行再造。
  3. 每个参考只提炼五类信息承诺state / authority owner1-3 invariantsfallback / overridetrade-off / 不直接照搬的部分
  4. 提出方案时必须做转译:按 行业共识 -> 可迁移原则 -> OpenCove 约束 -> 本地设计 输出,不直接把外部实现贴进来。
  5. 自动化 / 启发式默认保守:涉及 auto-detect / auto-switch / auto-retry / auto-recover / heuristic 时,高置信才切换,歧义保持稳定,并保留显式兜底。
  6. 验证仍遵循本文件前文的按风险分层原则:重点把从外部参考提炼出的规则、不变量和 trade-off 落到最低 meaningful layer;UI 侧手段选择统一见后文“UI 自动化与验证”。
  7. 最后资产化:把结论沉淀到 专项文档 + 测试 + owner / invariant 说明 + review 要点;否则视为未完成学习闭环。

风险与合规检查(Risk & Compliance System)

本节是前文状态、边界、owner 与恢复语义原则的正式检查清单。对 Large Change 或任何命中运行时高风险的改动,在进入实现前至少显式过一遍以下检查项:

关键稳定性检查(Critical Stability Checklist)

  • Async Gap Safety:所有 await 边界都要考虑组件卸载、窗口关闭、app 退出、对象失效后的行为。
  • Concurrency & Race:防止快速连续输入、重复事件、异步乱序、重复回调带来的竞争与边界漂移。
  • State Ownership:对持久化、恢复、同步或跨层传播的状态,必须明确唯一 authoritative owner,避免多层抢写同一真相。
  • Restart Semantics:严格区分用户意图、durable fact、runtime observation、UI projection;关闭、watcher 噪声或 fallback 不得默默把可恢复状态降级成终态。
  • IPC Security:Renderer 到 Main 的输入必须校验,禁止 blind trust。
  • Resource Lifecycle:事件监听、订阅、child process、watcher、disposable 必须成对清理。
  • Performance:避免阻塞 Main 线程;关注高频输入、重渲染、布局抖动、大文件和重 IO 路径。
  • Data Integrity:任何持久化结构、schema 或恢复语义变动都必须考虑兼容、迁移与回滚。

触发式合规门槛(Triggered Compliance Gates)

  • Architecture:禁止 Main / Preload / Renderer 逻辑越界;边界暴露统一走 preload 或契约层。
  • Type Safety:避免 any,IPC payload、跨层 DTO、边界返回值都要保持可校验、可推断。
  • Security:保持 Context Isolation;Renderer 禁止 Node Integration;能启用 Sandbox 的路径不要随意放弃。

UI 自动化与验证(UI Automation & Verification)

对 UI 改动,尤其是 Large Change、高交互风险改动、或真实体验比纯逻辑更重要的改动,按以下方式选择验证手段:

  • Web/Renderer 优先用 Playwright:主路径走 pnpm test:e2e 或最低 meaningful layer 的 Playwright 用例。
  • 用户可感知变化必须跑 E2E:新增功能、UX 改动、修复 bug、默认行为变化等,至少跑一条覆盖本次变更的 Playwright 用例(通常直接跑 pnpm test:e2e;或统一跑 pnpm pre-commit)。
  • 主题/样式改动必须遵守 UI 规范:新增颜色走 token,Light/Dark 都要验收可读性;优先在 E2E 中附带截图。详见 docs/ui/README.md
  • 复杂交互辅以截图 / 录屏:当行为依赖拖拽、滚动、动画、命中点或视觉反馈时,用截图或录屏帮助确认真实体验。
  • 提交前做一次 smoke 验证:至少确认核心用户路径、关键视觉状态和交互目标没有回归。
  • 开发中用视觉调试:必要时主动看截图、边框、命中区域、选择框、hover/active 状态,而不是只看日志和断言。
  • 非用户可感知改动优先低成本验证层:纯内部重构、类型收敛、工具链/脚本调整等,优先跑目标明确的 unit/contract 测试;UI 回归风险较高时再补 E2E。

全局硬规则(摘要)

  • 架构基线:本项目以 DDD 划分领域,以 Clean 约束依赖;context 是一级组织单位,每个 context 强制拆为 domain / application / infrastructure / presentationapp/mainapp/preloadapp/renderer 只做组合与边界。细则见 docs/architecture/ARCHITECTURE.md
  • Small vs Large(详见 AGENTS.md):
    • Small:直接做,小步快反馈,跑针对性验证。
    • Large / 运行时高风险:遵循 Spec -> (Feasibility Check) -> Plan 流程。
      • 高风险触发器(最易漏):启动/重启恢复、hydration、持久化写回、退出生命周期、跨层状态同步、external CLI / watcher 回写、fallback/cleanup 改写状态、多写者共享同一真相、边界冲突、同一入口对应多套竞争语义。
      • Spec:明确验收标准、风险点及验证手段,等待确认。
      • Feasibility Check:针对新技术/高性能/核心重构,必须先调研并跑通 PoC。
      • Plan:制定详细执行计划,等待确认。
      • 验证:用户可感知变化必须跑 E2E;UI 变更需提供截图/录屏;重大功能需跑通 pnpm test:e2e
      • 兼容与迁移(必须可回归):改动 IPC 接口、持久化数据结构、拓扑/配置文件时,必须提供迁移或启动期修复(repair)策略,并补回归测试覆盖“已有用户数据”(缺字段/空记录/旧格式)。不要只验证“新建流程”的 happy path。
      • 跨平台兼容:开发默认应考虑 macOS / Windows / Linux 三平台;如本次只支持部分平台,必须在方案与交付说明中明确标注差异、限制与后续补齐计划。凡修复平台特有 bug,必须补对应平台的 E2E,并在 CI 的该平台 runner 上执行验证;Windows / macOS / Linux 专属用例优先使用 *.windows.spec.ts / *.mac.spec.ts / *.linux.spec.ts 命名收口。
  • 禁止手改
    • lock 文件 (pnpm-lock.yaml) 必须由命令生成/更新。
    • 生成代码(如自动生成的类型定义等)禁止手改。
  • 提交前检查(与 CI 对齐的最低门槛)
    • 运行 pnpm pre-commit 前,必须先 git add 本次改动,再执行 pnpm line-check:staged,因为行数门禁只检查 staged 文件。
    • 若 staged 文件中存在超过 500 行的文件,先重构/拆分,过门禁后再继续,不要带着超长文件直接运行 pnpm pre-commit
    • pnpm pre-commit 会执行 pnpm naming-check:staged:禁止在新代码里重新引入 cove:*(对外/协议/持久化),仅允许显式 legacy 迁移用途;UI 设计系统前缀仍保留 cove(见上文命名约定)。
    • 若本次改动包含用户可感知变化(新增功能、UX 改动、修复 bug、默认行为变化),应先提交代码并创建 PR;拿到 PR 链接/编号后,再更新 CHANGELOG.md## [Unreleased] 并单独提交(每个变化一条,尽量附 #PR 编号)。nightly tag 不要求更新 changelog;发 stable 时再把 Unreleased 结算进新版本段。
    • 创建/更新 PR 时:若本次改动包含用户可感知变化,必须跑 Playwright E2E(通常 pnpm test:e2e,或统一跑 pnpm pre-commit)。
    • 创建/更新 PR 时:必须按 .github/pull_request_template.md 的结构完整填写;若使用 gh pr create / gh pr edit,也要显式按模板组织 title/body,不得跳过必填段落。
    • PR 中的截图 / 录屏应通过 GitHub PR 描述或评论框直接上传,不要把这类评审素材作为 repo 资产提交;只有明确作为视觉回归基线的 snapshot / golden 文件,才应进入仓库并纳入测试。
    • 若本次改动涉及 Renderer 用户可见文案,必须做好 i18n:禁止新增硬编码用户文案,新增/修改文案时同步更新 src/app/renderer/i18n/locales/en.tssrc/app/renderer/i18n/locales/zh-CN.ts,并在提交前做一次对应语言的最小 smoke/测试验证。
    • 通过上述检查后,再执行 pnpm pre-commit (type, lint, format, test)。
  • 测试失败排查前置
    • 凡遇到 pnpm pre-commitpnpm test -- --runpnpm test:e2e 或单独 Playwright 用例失败,继续排查前必须先阅读 docs/development/DEBUGGING.md
    • 需要复现/定位 bug 时:先阅读 docs/development/DEBUGGING.md 选择合适的调试方法与测试层级;若没有覆盖到的合适方法,则自行探索新方法;当用户反馈“确实解决了困难问题”后,应补充对应案例到 docs/cases/,并按需更新 docs/development/DEBUGGING.md(方法+适用场景)及其它必要信息。
  • 安全(Electron Security)
    • 始终开启 Context Isolation。
    • Renderer 进程禁止开启 Node Integration。
    • IPC 通信必须校验参数类型 (validate ALL inputs)。
    • 生产环境 CSP 禁止 style-src 'unsafe-inline'(仅开发环境允许),配置入口:electron.vite.config.ts

快速开始

  • 安装依赖pnpm install
  • 启动开发环境pnpm dev
    • 默认使用独立的 userData 目录(避免污染已安装版本的数据)
    • 如需临时复用已安装包的数据:OPENCOVE_DEV_USE_SHARED_USER_DATA=1 pnpm devpnpm dev -- --shared-user-data
    • 如需自定义 dev 的数据目录:OPENCOVE_DEV_USER_DATA_DIR=/path/to/userData pnpm dev
  • 使用 Worker/Web UI(dev):先执行 pnpm build
    • Worker 进程运行 out/main/worker.js,不会随 pnpm dev 的 HMR 自动更新
    • 若遇到“恢复/同步/持久化看起来没生效,但代码明明已改”的情况,先 pnpm build 再重启 App
    • 旧数据说明(M6 mounts / locations):若你的 profile 早于 M6,引入 mounts 后首次启动会尝试自动修复旧项目数据(为缺失 mounts 的本地项目创建一个默认本地位置,并修复 Space 的 target mount 绑定)。若项目是 remote-only 且缺失位置数据,无法凭空推断远程路径,需要在项目菜单中手动添加位置后才能正常运行相关能力。
  • 运行单元测试pnpm test -- --run
  • 运行 E2E 测试pnpm test:e2e
    • 说明:pnpm test:e2e 已包含构建步骤,默认使用 offscreen 后台窗口模式;检测到 Electron 崩溃特征时,会按窗口模式链路自动降级并重跑失败用例(例如 hidden -> offscreenoffscreen -> inactive)。
    • 可通过 OPENCOVE_E2E_WINDOW_MODE 指定窗口模式(inactive / offscreen / hidden,禁止 normal 以避免抢占焦点)。
    • 如需关闭自动降级,可设置 OPENCOVE_E2E_DISABLE_CRASH_FALLBACK=1
    • 若需单独执行 Playwright(如 pnpm exec playwright test tests/e2e/xxx.spec.ts),必须先执行 pnpm build,否则可能仍会使用旧的 out/ 产物,导致结果与当前源码不一致。

常见问题(FAQ)

  • 为什么我用 pnpm dev 启动后,Worker/Web UI 相关功能表现很奇怪(恢复/同步/持久化不生效)?
    • 先检查是否启用了本机 Worker 模式(userData 目录下的 home-worker.jsonmode=local,或环境变量 OPENCOVE_WORKER_CLIENT=1)。
    • 然后执行一次 pnpm build 并重启 App,确保 out/main/worker.js 与当前源码一致。

文档地图(按问题找入口)

  • Agent 关键指令与决策门槛AGENTS.md
  • 架构标准(DDD + Clean)docs/architecture/ARCHITECTURE.md
  • 架构 harness(源码偏离检查):说明见 docs/architecture/ARCHITECTURE_HARNESS.md,工具目录见 harness/architecture/
  • Project / Space / Endpoint / Mount 能力链路docs/architecture/WORKSPACE_CAPABILITY_ARCHITECTURE.md
  • 统一控制面(command/query/event)docs/architecture/CONTROL_SURFACE.md
  • CLI 规范docs/cli/README.md
  • 外部可执行发现与解析docs/cli/EXTERNAL_EXECUTABLE_RESOLUTION.md
  • Filesystem(URI + providers + guardrails)docs/canvas/FILESYSTEM.md
  • 画布内文件编辑(Document Node)docs/canvas/DOCUMENT_NODE.md
  • 画布内浏览器能力规格docs/canvas/BROWSER_WINDOW_CAPABILITY_SPEC.md
  • 恢复模型与 owner 表docs/architecture/RECOVERY_MODEL.md
  • 持久化(SQLite schema / migrations)docs/architecture/PERSISTENCE.md
  • 终端架构文档入口docs/terminal/README.md
  • 终端多端架构(当前 owner / attach / geometry)docs/terminal/MULTI_CLIENT_ARCHITECTURE.md
  • 终端渲染基准(tactical baseline)docs/terminal/TUI_RENDERING_BASELINE.md
  • UI 开发标准
    • 总体 UI 规范:docs/ui/README.md
    • 窗口 UI 标准:docs/ui/WINDOW_UI_STANDARD.md
    • 任务 UI 标准:docs/ui/TASK_UI_STANDARD.md
    • 视口导航标准:docs/ui/VIEWPORT_NAVIGATION_STANDARD.md
  • 诊断与复盘案例
    • Issue Report 诊断包:docs/development/ISSUE_REPORT_DIAGNOSTICS.md
    • Win10 Codex Scroll:docs/cases/WIN10_CODEX_SCROLL_DIAGNOSTICS.md
    • 画布抖动与终端持久化:docs/cases/CASE_STUDY_CANVAS_JITTER_AND_TERMINAL_DURABILITY.md
  • 参考优秀项目与方案调研法docs/development/REFERENCE_RESEARCH_METHOD.md
  • 调试指南docs/development/DEBUGGING.md
  • 贡献代码指南CONTRIBUTING.md
  • API Client 生成与使用:暂无,参考 src/shared/contracts 定义。

检索建议(避免一次性读完)

  • 优先在 AGENTS.md 中查找开发及其流程规范。
  • 若问题大概率已有行业成熟做法、主流产品先例或框架惯例,先读 docs/development/REFERENCE_RESEARCH_METHOD.md
  • 涉及具体 UI/功能模块时,检索 docs/ 下的相关文档。
  • 搜索现有代码中的实现模式,遵循 "Prioritize Reuse" 原则。