Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
638fa4b
fix(ui): group Claude list filters in the toolbar
try2love Oct 12, 2026
2cfb6e2
feat(ui): add shared pull refresh for Claude and DSH lists
try2love Oct 12, 2026
f81bfd4
fix(workbench): keep split when closing an active tool tab
try2love Oct 12, 2026
a7b1561
merge: optimize Claude list toolbar
try2love Oct 12, 2026
ff97af9
merge: add Claude and DSH list pull refresh
try2love Oct 12, 2026
8ed734b
merge: preserve split when closing tool tabs
try2love Oct 12, 2026
3e5ce02
Compact client list controls and native remove labels
try2love Oct 12, 2026
3b5433b
Quiet routine desktop client list status
try2love Oct 12, 2026
ebd3fd6
Expand desktop client lists across medium widths
try2love Oct 12, 2026
8bc9232
Clarify app icons and file transfer settings
try2love Oct 12, 2026
251c9be
Guard Claude renderer ownership and expose safe reconnect
try2love Oct 12, 2026
99fa81f
Isolate gateway login cookies by persistent namespace
try2love Oct 12, 2026
e4dc2b9
Bound automatic list failure feedback and clear stale errors
try2love Oct 12, 2026
7570cf3
Preserve pending reads through cookie name migration
try2love Oct 12, 2026
4c24e45
Merge optimization/compact-english-controls for local acceptance
try2love Oct 12, 2026
b1ef8e9
Merge optimization/quiet-client-list-status for local acceptance
try2love Oct 12, 2026
e9e85d5
Merge optimization/responsive-client-lists for local acceptance
try2love Oct 12, 2026
e55d479
Merge optimization/appearance-settings-clarity for local acceptance
try2love Oct 12, 2026
49bcc35
Dismiss recovered list error after nested success
try2love Oct 12, 2026
4dcd216
Honor signed Claude detach and guard async connector handoff
try2love Oct 12, 2026
641f7ab
Merge optimization/list-refresh-feedback for local acceptance
try2love Oct 12, 2026
35e6d05
Test same-host gateway cookie and logout isolation
try2love Oct 12, 2026
bd85e30
Keep Claude ownership while native calls remain unsettled
try2love Oct 12, 2026
c78586c
Merge optimization/gateway-cookie-isolation for local acceptance
try2love Oct 12, 2026
9db6849
Merge optimization/claude-connection-recovery for local acceptance
try2love Oct 12, 2026
01b5d7b
Recover native gateway bindings from secure device storage
try2love Oct 12, 2026
dde6164
Merge feature/mobile-binding-recovery for local acceptance
try2love Oct 12, 2026
ccb2c5c
Correct binding recovery timing note
try2love Oct 12, 2026
182ef58
Merge binding recovery timing clarification
try2love Oct 12, 2026
7ea1268
Keep client search visible with content-sized filters
try2love Oct 12, 2026
999b530
Add third-party notification settings to mobile UI
try2love Oct 12, 2026
e09e416
Merge local third-party notification configuration
try2love Oct 12, 2026
d54c369
Keep settings actions readable in one row
try2love Oct 12, 2026
bb215a9
Merge local settings action row optimization
try2love Oct 12, 2026
a9a9371
Fit selected filters beside search in 310px sidebar
try2love Oct 12, 2026
ffbb283
Fit notification actions and footer labels on phones
try2love Oct 12, 2026
412c161
Merge local content-sized chat list filters
try2love Oct 12, 2026
0e64cf9
Shorten visible chat search placeholder
try2love Oct 12, 2026
c5d5b44
Shorten visible search placeholders for local testing
try2love Oct 12, 2026
7fe29be
Keep settings labels legible at narrow phone widths
try2love Oct 12, 2026
1cfe4a8
Finish narrow settings and notification action layouts
try2love Oct 12, 2026
5993dc2
Hide notification settings in shared relay
try2love Oct 12, 2026
5f206dd
Keep notification settings within existing relay permissions
try2love Oct 12, 2026
19749ce
Verify long Claude Console input across AX viewport pages
try2love Oct 12, 2026
41aac28
Fix exact verification of long Claude Console input
try2love Oct 12, 2026
6292e3e
Document verified Claude Console accessibility fix
try2love Oct 12, 2026
0e7c528
fix(macos): verify long Claude Console input without page walking
try2love Oct 13, 2026
3d7f2e0
Prepare v2.0.3 stable release and synchronize mobile build 30
try2love Oct 13, 2026
7ff8f33
Record successful v2.0.3 cross-platform release acceptance
try2love Oct 13, 2026
f89965a
Document verified v2.0.3 release asset integrity
try2love Oct 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Agent Note: 文件传输设置在可见且已登录时读取

Status: implemented

## Problem

文件传输设置挂载时立即读取网关,登录前会把“请登录”留在外观面板。后续成功读取只更新输入值,没有清除这条旧错误。桌面高级面板也会在隐藏时提前请求设置。

## Decision

文件传输设置仅在面板可见、页面未隐藏且调用方已就绪时读取。Web 调用方通过已显示的登录后应用判定就绪;桌面本地调用方显式提供就绪条件。面板揭示、窗口聚焦及登录完成事件触发读取,不增加轮询。成功读取清除旧读取错误,正在编辑的值不被覆盖。

## Alternatives considered

在登录时自动重试而保留挂载时请求,触发次数更少,但仍会产生一次无意义的未授权请求,也不能覆盖桌面隐藏面板的场景。

## Consequences

未打开的设置面板不再触发读取。错误只在用户实际查看设置时出现,并会随下一次成功读取消失。独立保存按钮仍更新 clickDownloadMiB,不进入网关通用设置草稿。桌面设置测试验证隐藏挂载、揭示读取与独立保存。
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Agent Note: 网关会话 Cookie 按实例隔离

Status: implemented

## Problem

两个本地网关可以使用同一 IP 的不同端口,但浏览器和 WebView 的 Cookie 不按端口隔离。固定的 `codex_mobile_session` 名称会让后登录的网关覆盖前一个网关的登录状态。

## Decision

网关在自己的 `auth-sessions.json` 中持久保存随机 `cookieName`。它与每次启动变化的 `instanceId` 分离,也不随密码策略修改而变化。新登录只签发该名称;请求优先使用该名称,即使其值无效,也不回退到旧名称。只有旧 Cookie 的令牌仍在本机网关会话表中有效时才接受并通过下一次成功响应迁移。注销仅清除本机名称;另一个网关可能占有旧名称。

`/api/auth` 返回 `cookieName` 供原生客户端按保存的连接地址选择 Cookie。Android 和 iOS 在认证成功后记录名称;旧网关和路径隔离的中继仍使用旧名称。通知、下载、连接发现和移除流程沿用该地址的名称,不把进程临时 ID 当作持久身份。

## Alternatives considered

直接把随机 `instanceId` 放入 Cookie 名称能立即区分并发进程,但网关重启就要求手机重新配对,违反持久登录。按端口设置 Cookie 不可行,因为 Cookie 协议不隔离端口。

## Consequences

同一主机的不同网关可以并存并保留各自登录;旧令牌在有效期内有条件迁移。新增公开的 Cookie 名称不是认证秘密。原生客户端必须维护按连接地址的名称映射,且真实设备的 Cookie 存储行为仍需平台构建验证。
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Agent Note: Claude 与 DSH 列表的手动下拉刷新

Status: implemented

## Problem

Claude 与 DSH 只有自动轮询,用户无法像 Codex 一样通过下拉确认列表已更新。原刷新入口吞掉读取错误,不能直接作为手动刷新成功的判据。

## Decision

Claude 与 DSH 将共享 `ListSync` 接到实际 `.sessions` 滚动容器,复用顶部下拉阈值、横向取消及加载、成功、失败重试提示。提示位于独立列表区域,拉动内容不改变滚动区域高度,短列表和空列表也保留触摸区域。

`DesktopSessionsView.refreshList()` 只读取列表,手动刷新不触发会话详情读取、恢复、消息或审批。它与自动轮询、前台恢复共用 `sharedRead` 及当前视图的列表处理 Promise;同一轮读取不追加重复请求。列表失败会向手动刷新传递错误,断开连接的响应不显示更新成功。原有自动轮询负责定时及前台恢复,桌面客户端的 `ListSync` 不再单独启动另一套定时器。

客户端切换、账号读取失效、登出及页面隐藏重置手势与提示;刷新修订号保证旧请求不能修改新提示或解除新请求的忙碌状态。现有 generation、读取 epoch 继续约束数据结果。渲染使用最新搜索和筛选,保留所选会话、草稿及可保留的列表位置;列表中部优先按首个可见会话锚定,数据插入后仍保持该会话的相对位置,锚点消失时保留可用的滚动偏移。

已有列表时,前两次自动读取失败保持旧列表且不弹出提示;连续第三次失败显示可点击重试。手动失败和没有旧列表的首次失败立即提示。当前身份与修订号核验通过的任何列表成功读取都会清除旧错误,包括手势之外的列表入口;过期结果不能清除它。认证失败交给登录流程,不作为列表重试提示。

历史决策检索未发现活跃笔记中已有同一 ListSync/手动下拉刷新契约。本记录落实本地 v2 优化评审第 4 项,不引入连接管理或写操作的重试策略。

## Alternatives considered

- 各客户端独立实现手势:能单独调整体验,但会重复阈值、取消与提示逻辑,现有共享组件已覆盖这些行为。
- 直接调用原轮询入口:能复用现有读取流程,但还会读取已选会话详情且吞掉错误,无法准确反馈手动列表刷新结果。
- 整页重新加载:容易实现,但会丢失阅读状态并触发无关初始化,不采用。

## Testing

Node 回归覆盖并发读取合并、等待完成、失败与断开连接重试、筛选和草稿保留、客户端与账号失效、旧请求不得解锁新请求。隔离浏览器检查 390/844/1440px 下两个客户端的长列表、短列表、空列表、顶部手势、中部滚动、横向取消及失败重试;使用合成数据,不操作真实账号或任务。

另有 ListSync 回归覆盖短暂自动失败不打断旧列表、连续失败提示、其他入口成功清除错误、认证失败与过期结果保护。

## Consequences

三个客户端共享手势及结果反馈,手动确认不增加写操作或重复轮询。代价是共享组件需要维护可重置的请求修订号,列表读取与轮询编排分开。浏览器验证不代替 Android/iOS 真机 WebView 的回弹体验验收。
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Agent Note: 原生设备绑定恢复

Status: implemented

## Problem

手机原生壳的 WebView Cookie 可能在应用升级或系统清理后丢失。服务器仍保留已认证、可撤销的设备会话,但原生壳没有独立的安全副本,用户因此需要重新登录或扫码。

## Decision

两端只备份已通过 `/api/auth` 确认的 `trustedDevice` 会话令牌,按保存的电脑地址索引。Android 使用 AndroidKeyStore 的 AES-GCM 密钥加密副本,密文保存在应用私有偏好设置;iOS 使用 `WhenUnlockedThisDeviceOnly` Keychain 项。令牌仍由网关或中继的现有会话表撤销,不新增密码、二维码或不可撤销的第二套凭据。

WebView 加载前,如 Cookie 缺失或与安全副本不符,原生端用只读、同源、禁止重定向、限时限量的 `/api/auth` 检查当前 Cookie 和安全副本。首次登录时先记录完整 Cookie 快照,待网关返回 `cookieName` 后才选择对应令牌;旧名迁移只接受同一令牌,不因同主机其他网关的 Cookie 误存。当前 Cookie 有效则保留并在正常认证回调中更新副本;安全副本被服务器确认有效且其 Cookie 名称属于该网关时才恢复。无 `cookieName` 的旧直连网关及中继仅接受旧 Cookie 名。明确无效时删除副本,网络错误时保留以供下次尝试。已打开页面收到 401 时,每次失效周期只触发一次原生校验和只读页面重新加载;恢复不重放消息或写请求。异步校验完成时再次检查设备凭据、页面代际和当前 Cookie,避免退出或移除后的迟到结果复活会话。显式退出与移除删除该地址的安全副本及对应 Cookie。

## Alternatives considered

重新保存密码或可复用扫码载荷能够再次登录,但扩大了长期秘密和配对能力。另设恢复令牌及 HTTP 端点可以与登录令牌分离,却需要新的服务器存储、撤销和中继协议;现有原生设备会话已经持久且可撤销,复用它更小。

## Consequences

Cookie 丢失后,仍有效的绑定可在加载登录界面前或已打开页面遇到 401 时恢复;服务器撤销后不能恢复。需要恢复时会增加有限时的只读校验,离线时仍进入原有页面错误路径。Android KeyStore 或 iOS Keychain 不可用时不会把明文令牌写入普通偏好设置。真实设备上的存储与系统清理行为仍需设备验证。

相关 Cookie 名称和旧版兼容规则见[网关会话 Cookie 隔离记录](../bug-fix/2026-10-13-gateway-cookie-namespace.md)。历史笔记只有该记录部分重叠;它规定网关命名,本篇规定原生安全副本与恢复时序。
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Agent Note: Claude 与 DSH 列表状态只提示需关注的结果

Status: implemented

## Problem

客户端列表在每次轮询成功后显示“已连接桌面”,并在已有缓存会话时反复显示“正在读取聊天”。这两种正常状态占用列表空间,却没有给用户新的行动信息。

## Decision

有会话的正常列表读取完成后清空列表状态;已有缓存会话时,重新读取不显示等待文案。首次无缓存读取仍显示等待状态;空列表显示无聊天提示。连接初始化、断开、失败和可操作的重试提示继续由现有连接状态流程展示。

## Alternatives considered

保留“已连接桌面”并只减小字号可以继续提供连接确认,但它仍在每次成功轮询后常驻,无法让真正的异常更突出。

## Consequences

列表更安静,空列表和连接异常仍有明确解释。连接成功本身不再是列表中的持续文案;连接状态仍由客户端管理和会话详情各自展示。桌面会话 UI 回归覆盖正常、空列表、失败与初始化状态。
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Agent Note: 手机端第三方通知配置

Status: implemented

## Problem

手机端原先只能配置 PushPlus,Bark 和 ntfy 需要回到电脑端。三个通道实际共用电脑网关的通知配置与发送器,因此手机端缺少入口会让同一份设置出现不同的操作能力。

## Decision

手机网页和 App 的「第三方通知」列出 Bark、ntfy、PushPlus,各通道详情只编辑自己的开关、服务地址、主题或密钥。通用区编辑 `includeTitle`、`clickBase`、`securityEnabled`、`addressEnabled` 和 `addressName`;全会话请求与完成通知继续由现有设置控制,原生手机通知权限与收件箱保持独立。

HTTP 在已认证与 CSRF 校验之后,通过 `/api/notifications/channels/{bark,ntfy,pushplus}` 和 `/api/notifications/channels/common` 分别限制可写字段。它复用 `bridge/features/notifications/channels.py` 的持久化、校验和发送器,读取密钥只返回是否已保存。留空密钥沿用原配置;更换 Bark 或 ntfy 服务地址时清除旧密钥。`/test` 只发送该通道已经保存的配置,只有用户按下测试按钮才会发送。旧 `/api/notifications/pushplus` 路由继续可用。

通用区读取成功之前不能保存;关闭、重新打开或进入通道详情后,旧读取结果不得回填当前表单。服务列表显示未配置、已关闭、已开启或读取失败,便于判断下一步操作。

## Alternatives considered

可以在手机端维护另一份通知配置,但会产生与桌面网关状态冲突的密钥和开关。也可以直接开放桌面设置快照,然而其中包含更多与手机端无关的网关选项,扩大可写范围。按通道与通用字段分开限制,更贴近现有权限边界。

## Consequences

手机端与电脑端修改同一份网关配置;所有已登录设备可修改这些通道。通道测试使用现有外部发送器,页面确认服务接受请求不等于手机已收到。自动入口通知仍依赖网关运行和原有入口发现逻辑。回归测试用本地模拟响应和受控 loopback HTTP,未发送真实第三方通知。
Loading
Loading