跳转至

架构

T3 Code 将执行保留在拥有工作区的环境中。Web、桌面和移动客户端通过经过身份验证的 RPC 控制它。远程客户端绝不能用其自身的文件系统、提供方凭据或机器状态来替代环境的。桌面应用捆绑了一个服务器,但其渲染器遵循同样的边界。

所有权边界

提供方进程、终端、Git 和项目文件都属于服务器。共享连接和域状态位于 packages/client-runtime 中;客户端提供平台服务和 UI。保持该逻辑共享可防止 Web 和移动端之间的重连及多环境行为发生分歧。参见连接运行时和远程环境。

RPC 契约是独立版本化的客户端与服务器之间的边界。订阅发送客户端所需的状态,因此查看某个会话的客户端不会为每个会话的历史记录承担代价。对套接字的身份验证并不授权其上的每个方法。参见环境身份验证。

拉取请求链接兼容性

每个协议 2 环境都通告 threadPullRequests。一旦环境的服务端配置加载完成,客户端就会使用持久化的 pullRequests[]、多链接命令、堆栈 UI 和反向会话查找。在此之前,它们会隐藏链接操作。

环境会继续通告 threadPullRequestLinking,接受旧版元数据命令,并发出派生的 linkedPullRequest 字段,因为旧客户端仍然会读取它们。该无宿主字段仅包含会话项目自身仓库中的链接。保留旧版线上字段、投影列和重放支持。

提供方特定行为应位于适配器之后。编排使用规范化命令和事件工作,因此添加提供方不应要求贯穿整个域或客户端的分支逻辑。参见提供方约束。

设置所有权

客户端偏好设置保留在当前客户端中;环境默认值和项目覆盖设置保留在其所属服务器上。Web 和桌面设置目标是 URL 状态,并根据当前连接和项目成员身份进行解析。不可用的目标绝不能回退到另一个环境。所有环境是对已连接、已加载服务器的显式批量编辑,而非持久的全局默认值,也不是同步离线或未来环境的承诺。项目组目标同样选择已知的环境本地检出;组本身不存储继承的默认值。

持久化意图与副作用

编排状态以事件形式决定,投影一旦应用这些事件便成为事实来源。v2 编排器 序列化命令并决定事件,不执行提供方或文件系统工作。EventSink 在单个数据库事务中提交事件、持久化投影、已接受的命令回执和发件箱副作用。订阅者在提交之后接收事件。这使命令重试保持幂等,并防止持久化投影超前于事件日志。

副作用工作器 在意图记录后执行副作用,然后将结果反馈到编排中。因此,命令确认意味着意图已提交,而不意味着提供方、检查点或其他后续工作已完成。将外部 I/O 排除在命令决策和数据库事务之外。与丢失的提供方进程关联的副作用无法简单重放;恢复过程会在接纳新工作之前将其退役。

事件日志只保留活跃读者所需的内容:大约一天的历史记录,用于重连重放和命令 ID 重试。ProjectionMaintenance 会删除投影已覆盖的较旧事件,因此投影无法从日志重建。它保留每个流的最新事件(高水位标记、流版本、快照序列)、thread.created(旧版导入器的标记)、每次 running 运行更新(Codex 用量历史会读取每次尝试的第一次记录),以及被保留的子代理行所引用的提示锚点。如果客户端的光标低于其会话的最新事件和记录的剪除截止序列,则说明它错过了已剪除的事件,因此它会从快照恢复;空闲会话的光标则在没有快照的情况下恢复。恢复过程在读取重放后会重新检查该序列,因为一次传递可能在读取期间进行剪除。V2 命令回执会保留以确保幂等性:早于保留历史的重试仍会被去重,但其重放回来时不会包含已剪除的事件。一旦旧版命令的会话被导入,其回执就会被移除。

保留的事件在重放时必须保持可解码。更改模式会影响启动时的旧环境以及实时的 RPC 流量。兼容性工作必须考虑已存储的历史记录,而不只是最新客户端发送的内容。

回合完成与检查点

提供方回合结束与其后续工作落定是两个独立的里程碑。编排独立于运行终结记录提供方回合和运行状态。迟到的检查点或差异不得延长已记录的提供方持续时间,也不得让客户端继续将提供方工作显示为活动状态。完成后的 PR 发现还会检查检出是否仍与会话的非默认分支匹配,以及是否有更新的运行处于活动状态。

检查点使用隐藏的 Git 引用来捕获工作区状态,而无需向用户的分支添加提交。回滚必须协调工作区状态与提供方对话。无法回滚其对话的提供方必须在更改文件系统之前拒绝该操作。

线程结算由服务器负责。结算服务 在无连接客户端的情况下评估 PR 和非活动设置。合并通知会使缓存的 PR 状态失效并触发检查。在 T3 之外进行的合并(例如代理运行 gh pr merge)不会发送通知,因此 PR 同步反应器 会在执行了合并或关闭命令的运行结束时重新读取线程的开放链接。每个 forge 的定义都会在 changeRequestCloseCommand 中指定其 CLI 的命令。受保护的 thread.auto-settle 命令会拒绝较新的活动、显式结算覆盖以及进行中或阻塞中的工作。它会记录活动时间戳以实现稳定排序,并分离空闲的提供方会话。客户端渲染持久化的结果;它们不会根据自己的时钟或 PR 缓存推导结算。

等待异步工作

测试使用可排空工作器来等待队列及其当前任务都完成。仅靠空队列并不能证明工作器处于空闲状态。

V2 测试还会排空 effect 工作器,或等待特定的持久化事件或回执。测试信号与使分发具有幂等性的持久化命令回执是分开的。生产行为必须使用持久化状态和事件,而不是测试插桩或对经过时间的假设。

Electron shell 在异步服务启动前同步获取 DesktopPreReadyPlatform.layer。在 Linux 上,这会在 Chromium 初始化其 portal 连接之前设置桌面条目标识和全局快捷键 portal 标志。稍后在 DesktopAppIdentity 中设置标识就太晚了:Chromium 会缓存首次注册的结果,包括失败。该标识必须与 DesktopLinuxUrlHandler 管理的已安装条目匹配。预就绪设置还会在 portal 注册之前刷新该条目的 Exec 路径:AppImage 更新可能会移除之前的可执行文件,这使得旧条目即使文件名正确也会失效。后续的 URL 处理器会避免在 portal 可能正在读取条目时重写相同条目。在 Wayland 上,Electron 的同步快捷键注册结果仅确认提交,并不确认桌面同意或有效的绑定。

原生模块绝不会在启动路径上的 Electron 主进程中加载,快照功能保留的那两个模块也是隔离的:@crowecawcaw/xa11y 仅在 fork 出的 Node 模式子进程(SnapShotAccessibilityWorker、RegionSnapShotWorker)和一条工作线程中运行,ffi-rs 则在 WindowsForeground.ts 内为少量 Win32 调用延迟加载。macOS 窗口查找通过 osascript 外部进程实现,而不是使用原生插件。其中任何一个发生崩溃或停滞都不能拖垮应用,因此新的原生能力应放入带有截止时间的子进程中,而不是在主进程中进行 import。

共享术语请参阅术语表,环境搭建与检查请参阅开发手册。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 t3/t3code