diff --git a/docs/02-requirements.md b/docs/02-requirements.md index 7ee4df4..96f2092 100644 --- a/docs/02-requirements.md +++ b/docs/02-requirements.md @@ -21,6 +21,7 @@ | BR-017 | 用户可以仅通过已验证的 loopback CDP 端点查看 Chub 实例的页面目标(标签页)标题、脱敏 URL 和类型;该功能不得控制页面、关闭标签页或接管外部浏览器。 | P1 | | BR-018 | Chub 运行时提供一个 Windows 通知区域图标,允许显示主窗口、刷新已保存实例状态和显式退出应用;图标及菜单不得绕过实例授权边界或泄露实例路径、URL、代理等敏感信息。 | P1 | | BR-019 | Chub 默认将本地 `config.json` 保存到正在执行的 `chub.exe` 同级目录;首次使用新位置时安全迁移旧 `%APPDATA%\\chub\\config.json`,新位置既有配置永不被旧配置覆盖。 | P1 | +| BR-020 | 用户可为无认证代理维护必填、唯一的代理名称;新建实例默认使用实际 `chub.exe` 同级 `user_data_dirs\\<稳定实例 ID>`,实例列表在用户数据目录与调试端口之间显示代理名称。 | P1 | ## 验收标准 @@ -40,6 +41,8 @@ - 实例编辑支持保存、取消和 Escape;有未保存修改时必须先确认,运行中或外部关联实例不能修改浏览器类型或 user data dir。 - 代理仅接受无认证的 `scheme://host:port` 端点。删除仍被实例引用的代理必须被拒绝;实例保存后按稳定代理 ID 解析最新端点。 - 设置页默认代理输入为空;选择下拉项后回填完整地址,保存更新当前项、未选择时新建。删除未引用项须经确认,确认取消或引用保护不能改变任何实例选择。 +- 代理名称为必填、去首尾空白且不区分大小写唯一的非敏感显示名称;名称和地址在同一次保存中校验、保存。代理选择器显示“名称 · 地址”,实例列表只显示名称或“无代理”,避免把完整地址挤入表格。 +- 点击“新建实例”后,User Data Dir 默认填入实际 `chub.exe` 同级 `user_data_dirs\\<稳定实例 ID>`,每个新实例必须得到不同子目录;不得使用当前工作目录或让多个实例共享根目录。目录不可写时保留输入并给出可恢复的权限/路径提示,用户可改用目录选择器。 - 受管运行实例点击主操作后进入关闭中,成功退出后恢复启动入口;停止失败不自动强制终止,也绝不影响其他 Chrome/Edge。 - Chub 在当前应用会话中启动的 Chrome/Edge 根进程意外退出后,实例状态立即变为“已退出”,清空运行时 PID/端口,并显示包含实例名称和浏览器类型的可关闭提示;配置与 User Data Dir 保留,关闭提示后启动入口可用。 - 用户从 Chub 发起优雅停止时,不显示“浏览器已退出”意外退出提示;外部已关联、外部占用、未知占用以及应用关闭后无法继续监控的实例均不弹出此提示。 diff --git a/docs/04-architecture.md b/docs/04-architecture.md index c53dbc6..78de7ab 100644 --- a/docs/04-architecture.md +++ b/docs/04-architecture.md @@ -42,7 +42,8 @@ UI/CLI 不直接操作 `exec.Cmd`、Win32 handle 或数据库。Application 层 - App shutdown:取消监控,不默认终止用户浏览器。 - Refresh:以 UI 传入的保存实例快照为范围,在后台读取 Chub registry、对应 profile 占用证据与已知 loopback CDP 端点,返回状态 DTO。刷新不按浏览器进程名或端口范围枚举;结果以实例 ID 与快照版本关联,UI 丢弃已删除或已编辑行的过期结果。 - Edit:UI 只提交可持久化的实例配置 DTO;运行时 PID、关联端口、占用来源和状态由刷新/启动结果返回,不作为编辑表单保存字段。编辑时保留未公开的非敏感启动选项,活跃或外部关联实例的身份约束字段保持只读。 -- Proxy:本地配置保存稳定 `proxy_id` 指向的代理库项(名称与无认证端点);启动 adapter 在后台解析为当前 `LaunchSpec.ProxyServer` 快照。代理不能含 userinfo,删除被引用项会被拒绝;修改代理只影响后续启动,不影响已运行实例。 +- Proxy:本地配置保存稳定 `proxy_id` 指向的代理库项(必填、大小写无关唯一的显示名称与无认证端点);启动 adapter 在后台解析为当前 `LaunchSpec.ProxyServer` 快照。名称与地址同次校验/保存,`proxy_id` 不因改名或改地址而改变;代理不能含 userinfo,删除被引用项会被拒绝;修改代理只影响后续启动,不影响已运行实例。Gio 列表按当前 `proxy_id` 实时解析名称,不把可变显示名反规范化写入实例配置。 +- New instance default directory:`cmd/chub` 在窗口初始化时通过 platform config 解析实际 `os.Executable()` 的目录,并把 `\\user_data_dirs\\` 作为 Gio 新建表单的默认值;UI 只使用已提供的字符串,不读取文件或检查权限。实例 ID 必须先于默认目录分配,目录在保存/启动路径中按既有绝对路径与权限规则校验。不能使用当前工作目录,也不能将 `user_data_dirs` 根目录直接分给多个实例。 - GUI stop:主操作只对 Chub registry 中可验证的托管实例调用 `StopProfile(userDataDir, false)`,随后有限等待 registry 释放。外部关联、占用和未知实例永远不调用停止接口;超时或失败不自动强制关闭。 - 受管退出监控:仅为当前会话由 Chub 启动并获得进程句柄的实例建立一个 `Wait` 监控任务。退出事件携带实例 ID、启动代次和 PID,UI 仅在三者仍匹配且当前未处于 Chub 请求的停止中时,将运行时状态改为“已退出”并排队显示提示;过期事件、外部实例和应用退出后的监控取消均不得生成意外退出提示。 - CDP 页面目标查看:UI 仅将当前已保存实例快照交给后台 adapter;adapter 只接受“运行中”或“外部已关联”的有效实际端口,先复核对应 browser kind 的 loopback `/json/version`,再读取同一端口的 `/json/list`。结果 DTO 仅含 target ID、标题、类型和脱敏 URL;UI 以实例 ID、端口和请求代次丢弃过期结果。该链路不建立 WebSocket、不开启页面控制,也不提供物理窗口 ID。 diff --git a/docs/06-tasks.md b/docs/06-tasks.md index a9e71a6..8476530 100644 --- a/docs/06-tasks.md +++ b/docs/06-tasks.md @@ -54,6 +54,7 @@ | T-401 | 已验证实例的 CDP 页面目标只读查看 | T-302,T-303,T-310 | DONE | | T-402 | Windows 通知区域入口与显式退出协调 | T-303,T-305,T-307 | TODO | | T-403 | 便携配置路径与安全 legacy 迁移 | T-202,T-309 | DONE | +| T-404 | 代理名称、独立默认目录与实例列表代理列 | T-304,T-306,T-309,T-403 | DOING | ## Backlog diff --git a/docs/07-user-stories.md b/docs/07-user-stories.md index 3db80fe..0950e53 100644 --- a/docs/07-user-stories.md +++ b/docs/07-user-stories.md @@ -16,6 +16,7 @@ | US-012 | 用户可以查看已验证运行实例的 CDP 页面目标标题、脱敏 URL 和类型,而不会向浏览器发送控制命令。 | P1 | | US-013 | 用户可以从 Windows 通知区域快速显示 Chub、刷新已保存实例状态或明确退出应用,而不会在菜单中误操作浏览器实例。 | P1 | | US-014 | 用户复制或升级 Chub 后,实例配置与程序一同保存在可执行文件目录;首次升级会安全带入旧 AppData 配置且不丢失已有新配置。 | P1 | +| US-015 | 用户可以用易读名称维护代理,并在实例列表快速确认每个实例使用的代理;新建实例会得到程序目录内独立的默认 User Data Dir。 | P1 | ## 验收场景 @@ -62,3 +63,7 @@ CLI/API 返回稳定错误码和结构化数据;未知 PID、身份不匹配 ### US-014 便携配置迁移 给定用户从 `build\\chub.exe` 或已发布目录启动 Chub,配置读取和后续保存均使用同级 `config.json`,不受启动脚本或当前工作目录影响。给定目标配置不存在且旧 `%APPDATA%\\chub\\config.json` 合法,Chub 校验旧配置并原子写入目标,旧文件作为恢复备份保留。给定目标配置已存在,Chub 只读取目标,不覆盖、合并或删除它。给定目标目录不可写或旧配置畸形,Chub 不创建新文件、不丢失旧文件,显示可恢复的配置诊断;不得静默切回 AppData 造成后续配置分叉。 + +### US-015 代理名称与独立默认目录 + +给定用户在设置中选择已有代理,Chub 回填代理名称和完整无认证地址;用户保存时必须同时通过名称必填/不区分大小写唯一和地址格式/重复校验。给定已有实例选择该代理,用户修改其名称或地址后,实例保留相同 `proxyId`,列表立即显示最新名称,后续启动使用最新地址,已运行浏览器不被修改。给定用户打开新建实例表单,Chub 先分配稳定实例 ID,再填入实际 `chub.exe` 同级 `user_data_dirs\\<实例 ID>`;每次新建得到不同子目录。目录不可写或被用户改为空/非法路径时,保留表单输入并提供可恢复提示,不创建目录、不回退到当前工作目录,也不影响已有实例。 diff --git a/docs/08-interaction-checklist.md b/docs/08-interaction-checklist.md index 3478685..b5c7ced 100644 --- a/docs/08-interaction-checklist.md +++ b/docs/08-interaction-checklist.md @@ -16,6 +16,7 @@ | IX-012 | CDP 页面目标查看 | 编辑弹层的“查看标签页”、只读目标列表与关闭 | 无可验证端口、读取中、空列表、读取失败、状态变更、Escape/焦点回归 | P1 | | IX-013 | Windows 通知区域 | 图标双击/默认显示、原生菜单刷新与退出 | 图标创建失败、Explorer 重启、窗口最小化、菜单关闭、刷新中、应用退出 | P1 | | IX-014 | 配置启动与迁移 | exe 同级配置解析、legacy 配置迁移和可恢复失败反馈 | 新配置、合法 legacy、目标优先、畸形 legacy、目标目录不可写、重复启动 | P1 | +| IX-015 | 代理名称、默认目录与列表列 | 代理名称/地址保存、下拉回填、实例默认目录、代理名称展示 | 新建、编辑、重名/重复地址、无代理、长名称、窄窗口、目录权限失败 | P1 | ## 通用规则 @@ -29,6 +30,8 @@ - 刷新和编辑是独立命令:刷新为只读状态检查,编辑只保存配置;两者均不接管外部实例。F5 与刷新按钮共用一个去重命令。 - 双击不是唯一入口:单击只选择行,Enter 和编辑图标打开对话框。打开后焦点位于名称,关闭后返回调用行;有未保存编辑时 Escape 先请求确认。 - 代理选择器必须提供“无代理”和完整地址项,能用键盘选择;设置页默认输入为空,选择项回填地址。删除前先确认完整地址;有引用时保持当前选择、输入与实例选择不变。 +- 代理设置使用显式保存:名称和地址都有可见 Label,名称必填、去首尾空白且不区分大小写唯一;地址仍为无认证端点。选择器以“名称 · 地址”区分项,设置选择会同时回填两项;保存失败时保留两项输入并在对应字段附近显示原因。实例表格的“代理”列只显示名称或“无代理”,位于“用户数据目录”与“调试端口”之间;列宽受限时省略长名称但不挤压操作列,完整值仍可从编辑表单访问。 +- 新建表单打开时,User Data Dir 预填 `\\user_data_dirs\\`,并说明它是独立 profile。目录选择或手动输入可覆盖默认值;取消/校验失败保留输入。UI 不自行读取 executable 路径、创建目录或检查权限;后台/持久化边界返回权限失败后给出文本恢复建议。新建表单、编辑弹层和列表在 600px 宽度、200% 缩放、长代理名称下保持 Label、字段与行内操作可访问;代理列不改变单击、双击、Enter 或操作图标的既有语义。 - 实例主操作根据归属和状态切换启动、停止、重新检测或禁用,并固定排在编辑和删除之前。停止中禁止重复请求;停止失败恢复原状态并保留焦点。外部关联不显示停止入口;行内图标间距与命中区必须避免误操作。 - 受管浏览器意外退出是当前会话的异步状态提示,不是用户确认决策:状态先更新为“已退出”,再显示可关闭信息弹层;弹层只含“知道了”,Escape/Enter 均可关闭,关闭后焦点回到对应启动入口。多个退出合并到一个提示;已有编辑、未保存确认或删除确认弹层时排队,不能丢弃输入或叠加模态层。Chub 发起停止、外部实例、代次/PID 不匹配和应用退出取消监控时均不提示。 - 调试端口的“建议/准备/实际/外部”必须同时以文字和数值表达,不能将首选端口称为已监听端口。创建和停止实例编辑使用首选端口输入;运行中、启动中、停止中和外部关联实例只读。推荐仅基于 Chub 保存实例,系统端口复检与 CDP 校验只在后台启动任务执行;回退不得使用其他 Chub 实例的逻辑预留端口。 diff --git a/docs/api.md b/docs/api.md index 03037ac..2810e08 100644 --- a/docs/api.md +++ b/docs/api.md @@ -25,7 +25,7 @@ type RemoteDebugTargetInspector interface { 调用者必须提供当前实例已经验证的实际端口;实现仍会复核 `/json/version` 的浏览器类型。该接口只请求 loopback HTTP `/json/list`,不公开或使用 `webSocketDebuggerUrl`,也不提供导航、关闭、创建 target 或执行脚本的接口。 -UI 编辑使用独立的 `EditableInstance` DTO(`ID`、名称、浏览器类型、User Data Dir、启动 URL、`ProxyID`),不将运行时 PID、状态、来源或实际远程调试端口写回配置。`ProxyProfile` DTO 只包含 `ID`、名称和已校验的无认证端点;不提供认证字段。状态刷新使用 `RefreshInstanceStatus(ctx, []InstanceSnapshot) ([]InstanceStatusResult, error)` 形状:每个结果以 `ID` 和快照版本对应,错误可按行返回;实现只能检查调用方提供的实例范围。 +UI 编辑使用独立的 `EditableInstance` DTO(`ID`、名称、浏览器类型、User Data Dir、启动 URL、`ProxyID`),不将运行时 PID、状态、来源或实际远程调试端口写回配置。`ProxyProfile` DTO 只包含 `ID`、必填且大小写无关唯一的显示名称、已校验的无认证端点;不提供认证字段。`InstanceRow.ProxyID` 是唯一持久关联,列表中的代理名称是按当前代理 DTO 推导的显示值,不持久化副本。状态刷新使用 `RefreshInstanceStatus(ctx, []InstanceSnapshot) ([]InstanceStatusResult, error)` 形状:每个结果以 `ID` 和快照版本对应,错误可按行返回;实现只能检查调用方提供的实例范围。 ## Application service @@ -75,9 +75,10 @@ type TrayState struct { func DefaultPath() (string, error) // \\config.json func LegacyPath() (string, error) // %APPDATA%\\chub\\config.json,仅用于一次迁移 func OpenDefault() (*Store, error) // 目标优先;必要时校验并原子迁移 legacy +func DefaultInstanceUserDataDir(instanceID string) (string, error) // \\user_data_dirs\\ ``` -调用方不得把当前工作目录作为配置来源,也不得自行复制、删除或合并 legacy 文件。`OpenDefault` 的迁移是文件级配置迁移,不迁移 `UserDataDir`、日志目录或浏览器文件;目标文件存在、legacy 缺失时均不产生写入。迁移失败返回稳定的配置错误,调用方不得改用 legacy 继续写入。 +调用方不得把当前工作目录作为配置来源,也不得自行复制、删除或合并 legacy 文件。`OpenDefault` 的迁移是文件级配置迁移,不迁移 `UserDataDir`、日志目录或浏览器文件;目标文件存在、legacy 缺失时均不产生写入。`DefaultInstanceUserDataDir` 只生成绝对默认字符串,不创建目录;调用方必须先分配稳定、唯一的实例 ID。迁移失败返回稳定的配置错误,调用方不得改用 legacy 继续写入。 ## CLI 当前合约 diff --git a/docs/current-state.md b/docs/current-state.md index af3ef90..5fa63bc 100644 --- a/docs/current-state.md +++ b/docs/current-state.md @@ -3,7 +3,7 @@ ## 快照 - 日期:2026-07-27 -- 阶段:Phase 4 CDP 只读观察与后台入口(T-301 至 T-310、T-201 至 T-208、T-401、T-403 已完成;T-402 已规划) +- 阶段:Phase 4 CDP 只读观察与后台入口(T-301 至 T-310、T-201 至 T-208、T-401、T-403 已完成;T-402 已规划,T-404 进行中) - 代码:已建立 Go module `chub`、`cmd/chub` 入口、logging 测试基座、浏览器 domain/application 合约、Chrome/Edge 参数/发现模块、启动 registry、Windows 身份/占用检查、loopback CDP 端口分配与端点校验、受限 CDP 目标读取、exe 同级 JSON 配置与 legacy 安全迁移、优雅关闭、Job Object、真实 Chrome/Edge smoke、启动恢复、CLI JSON 合约、应用内事件总线、UI 状态测试和 Windows smoke 脚本,T-001 至 T-003、T-101 至 T-104、T-201 至 T-208、T-301 至 T-310、T-401、T-403 已完成 - UI:Gio 双页 Shell 使用左侧“实例/设置”导航;实例页以等宽“新建实例 / 刷新实例状态”命令区开始,窄内容区自动堆叠。列表固定显示实例名称、浏览器类型、用户数据目录、调试端口、状态和带边框的操作列;端口列在未启动/已退出时显示“建议 {端口}”、启动中显示“准备 {端口}”、托管运行显示“实际 {端口}”、外部关联显示“外部 {端口}”,避免将持久首选端口误作监听事实。新建表单从设置的起始端口推荐最低未冲突端口,编辑停止实例可修改首选端口;启动后台优先该端口并避开其他实例的首选/实际端口,成功回退后才保存新的首选值。操作顺序固定为启动/停止(或重新检测)、编辑、删除,删除与相邻操作保持更大间距以降低误点。主操作在已退出时启动,在 Chub 托管运行或调试不可用时显示停止,在启动/停止中禁用,在外部关联、外部占用或未知占用时仅重新检测;优雅停止通过后台 adapter 验证 registry 的 PID/profile 身份并等待其释放,绝不按进程名关闭或接管外部 Chrome/Edge。刷新通过后台回调只检查已保存实例,以配置快照丢弃编辑或删除后的过期结果;它结合 Chub registry、指定 profile 的外部占用证据和 loopback CDP 端点更新状态,但不扫描、接管或关闭其他 Chrome/Edge。双击、Enter 或编辑图标打开实例编辑弹层,支持名称、浏览器类型、User Data Dir、启动 URL、首选端口、完整地址代理选择和只读实际端口;保存保留未公开启动选项,Escape 对脏表单先请求确认,活跃/外部关联实例锁定身份约束字段。设置页使用完整代理地址选择器、地址输入及保存/删除操作;选择会回填地址,保存按稳定 `proxyId` 新增或更新,删除未引用代理前必须确认,仍被实例引用的代理会被拒绝。启动通过异步回调接到 Windows 浏览器启动器:未占用目录从已保存的起始端口(空值默认 9666)选择 loopback CDP 端口,并在启动时按已选代理 ID 解析最新的 `--proxy-server` 参数;同目录外部浏览器只有在 `DevToolsActivePort` 与 CDP 端点可验证时才显示“外部已关联”,且不会接管其生命周期。删除使用确认弹层,只删除 Chub 实例配置而不删除 User Data Dir。新建、编辑和删除实例会保存到本地配置;四个设置路径有独立异步可取消搜索,切换页面后输入和任务状态保留;新建实例表单使用 Label、Windows 原生目录选择器和 Chrome/Edge RadioButton;CLI `list/events` 已可用,`start/stop/restart` 等待 BrowserManager adapter - T-307:本应用会话启动的受管 Chrome/Edge 根进程由单实例后台 `Wait` 监控;意外退出按 ID、启动代次和 PID 验证后立即变为“已退出”,清空运行时 PID/端口,并以可关闭、可合并的提示告知用户。提示关闭后焦点回到启动操作;Chub 请求停止、外部实例、过期事件和应用关闭取消监控均不提示。 @@ -14,7 +14,8 @@ - T-401:仅在运行中或外部已关联实例已有有效实际端口时,编辑弹层可打开“标签页(CDP 页面目标)”只读模态层。后台先复核 loopback `/json/version` 的浏览器类型,再读取有限的 `/json/list`;只显示 ID、类型、标题和移除 userinfo/query/fragment 的 URL,不暴露 WebSocket 地址、不建立 WebSocket、也不执行浏览器控制。读取、错误、空列表和端口/状态变化都有反馈,Escape/关闭后焦点回到入口。 - T-402:已规划 Windows 通知区域图标、显示主窗口、刷新已保存实例状态和显式退出协调。首版不在托盘菜单中直接操作浏览器,不改变窗口关闭语义,也不实现关闭窗口后隐藏;Windows 原生 Shell adapter、Explorer 重启恢复、图标资源与退出清理将在实施阶段完成。 - T-403:默认配置已改为实际 `chub.exe` 同级 `config.json`,不受当前工作目录影响。目标缺失时会校验并原子复制旧 AppData 配置,旧文件保持恢复副本;目标优先且不会自动合并、切回 AppData 或迁移浏览器 User Data Dir。CLI 与 GUI 共用 `OpenDefault()`;配置不可用时 CLI 返回无敏感细节的稳定错误,GUI 显示恢复提示。 -- blocker:无;下一任务为 T-402。 +- T-404:已定义代理名称与地址的同次显式保存、名称校验、列表显示和独立默认 profile 目录边界。新建实例将以实际 exe 目录生成 `user_data_dirs\\<稳定实例 ID>`,代理名称按 ProxyID 推导而不复制到实例配置;UI 不进行文件 I/O。局部表单/列表调整沿用已确认两页布局,无需新增 HTML 原型。 +- blocker:无;当前任务为 T-404,后续仍可实施 T-402。 ## 当前目录 diff --git a/docs/tasks/T-404.md b/docs/tasks/T-404.md new file mode 100644 index 0000000..6bd3f7c --- /dev/null +++ b/docs/tasks/T-404.md @@ -0,0 +1,36 @@ +--- +id: T-404 +title: 代理名称、独立默认目录与实例列表代理列 +phase: 4 +deps: [T-304, T-306, T-309, T-403] +status: DOING +created: 2026-07-27 +owner: codex +--- + +## 需求与背景 + +现有代理模型已持久化 `ProxyProfile.Name`,但设置页把它覆盖为代理地址,实例列表也无法直接确认实例使用的代理。新建表单的 User Data Dir 未预填可复制部署的独立目录。需要让用户以代理名称维护和确认实例配置,同时为每个新实例生成实际 `chub.exe` 同级 `user_data_dirs\\<稳定实例 ID>` 默认目录。 + +## 方案与边界 + +- 设置代理区新增“代理名称”输入。名称和地址采用同一次显式保存:名称必填、去首尾空白、大小写无关唯一;地址继续限制为无认证 `scheme://host:port` 并拒绝重复。选择已保存项会回填名称和地址;保存失败保留所有输入与选择。稳定 `proxyId` 不随改名或改地址变化。 +- 创建/编辑实例的代理选择器显示“名称 · 地址”;实例列表新增位于“用户数据目录”与“调试端口”之间的“代理”列,只显示名称或“无代理”。列表按 `ProxyID` 解析当前名称,不将显示名称持久化到实例,改名后立即反映;窄宽度下名称可省略但不得挤压固定操作列或改变按钮、双击、Enter 的语义。 +- 打开新建实例表单时,先分配稳定且不与已保存实例冲突的 ID,再由 platform config 从实际 `os.Executable()` 生成 `\\user_data_dirs\\`。不得使用当前工作目录,也不得把共享根目录作为多个实例的 `user-data-dir`。目录选择和手动输入仍可覆盖默认值。 +- 默认目录生成只返回路径字符串,不创建目录或检查权限;Gio UI 不做文件 I/O。既有保存/启动边界负责绝对路径、权限与占用校验;失败时保留输入并给出可恢复提示。程序目录不可写时不得静默切至 AppData 或其他路径。 +- 代理名称属于本地显示元数据:不得写入日志、事件、CLI 错误、托盘 Tooltip 或启动参数;代理认证信息继续禁止进入配置、UI 回显、日志和命令行。 + +## 验收要点 + +- 自动化:覆盖配置层代理名称的空值、空白、大小写重复与保留稳定 ID;覆盖选择回填、创建/修改代理、列表名称实时解析、无代理、长名称布局权重;覆盖默认目录由注入 executable 目录和稳定实例 ID 生成、绝不依赖当前工作目录且新实例目录不同。 +- GUI:代理设置中名称/地址均有可访问 Label;下拉项显示“名称 · 地址”,保存与删除保护沿用既有键盘和确认行为。新建实例首次打开即显示完整、可编辑的独立默认 User Data Dir;取消目录选择或保存失败不清空用户输入。列表列顺序为名称、浏览器、用户数据目录、代理、调试端口、状态、操作。 +- 布局与可访问性:验证 600px/960px 窗口、100%–200% 缩放和长中文代理名称。代理列截断不影响操作列;单击行只选择、双击/Enter 编辑、行内命令优先级保持不变;名称、地址、错误反馈均有文字而非仅颜色。 +- 回归:`go test ./...`、`go test -race ./cmd/chub ./internal/platform/config ./internal/ui`、`go vet ./...`、`build.bat` 与 `scripts\\smoke-windows.ps1` 均通过。`build.bat`/`run.bat` 若为用户未跟踪文件,不纳入本任务提交。 + +## 执行记录 + +- 状态:DOING +- 变更:已完成需求、架构、API、用户故事、交互清单、任务路线与 UI 评审场景更新。 +- UI/UX:依据 Gio 表单/列表适配约束,确认本次是已有两页工作区的局部字段和列调整,不改变导航、模态流程或已确认结构,故不新增 HTML 原型;实现保留现有持久 widget、稳定 ID、键盘与窄窗口重排契约。 +- 验证:文档链接、Git diff 检查和文档提交待完成。 +- 阻塞:无。 diff --git a/docs/ui/README.md b/docs/ui/README.md index 28240ea..6a4c863 100644 --- a/docs/ui/README.md +++ b/docs/ui/README.md @@ -17,6 +17,7 @@ 7. 切换深色主题,并在窄窗口查看导航和表单重排。 8. 点击“设置”:检查四个路径的 Label、选择/搜索按钮;搜索期间按钮显示“取消”,再次点击取消当前搜索,切换页面后状态保持。 9. 双击“运行中”或“外部已关联”实例,点击“查看标签页”:检查读取中、目标列表、只读边界文案与 Escape/关闭后回到入口。未启动或没有实际端口的实例应禁用入口。 +10. 设置代理:检查代理名称和代理地址均有 Label;选择项会回填两项,保存修改后实例列表仅显示最新代理名称。新建实例应默认填入程序目录内不同的 `user_data_dirs\\<实例 ID>` 子目录;窄窗口下代理列不能挤压操作按钮。 ## 当前原型假设 @@ -35,7 +36,7 @@ | --- | --- | | 顶级导航 | 稳定 page ID + 持久选中状态 | | 实例列表 | 虚拟化列表;实例 ID 而非行号作为身份 | -| 实例列契约 | 固定为实例名称、浏览器类型、用户数据目录、状态、启动;每行启动按钮以实例 ID 独立持有状态 | +| 实例列契约 | 固定为实例名称、浏览器类型、用户数据目录、代理、调试端口、状态、操作;代理显示名由稳定 ProxyID 推导,行内操作以实例 ID 独立持有状态 | | 启动表单 | 持久 editor/选择状态,显式提交,字段错误保留输入 | | 路径搜索 | 独立任务 ID、取消函数与结果通道;迟到结果按任务 ID 丢弃 | | 详情抽屉 | 自定义辅助面板,关闭后焦点返回实例行 |