Skip to content

Commit e50a2ed

Browse files
committed
chore: commit archived task docs and tasks_index updates
1 parent 60a8918 commit e50a2ed

23 files changed

Lines changed: 800 additions & 0 deletions

docs/archive/tasks/_pre/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Task 清单(待你批复后再实现)
2+
3+
| ID | 标题 | 复杂度 | Spec | Plan | 依赖/备注 |
4+
| --- | ------------------------------------ | ------ | ------------------------------------------- | ------------------------------------------- | ------------------------------------------------ |
5+
| T1 | 关闭输入框拼写红波浪线 | S | [spec](./T1_disable_spellcheck_spec.md) | [plan](./T1_disable_spellcheck_plan.md) | 独立 |
6+
| T2 | 密钥框小眼睛统一 | S–M | [spec](./T2_secret_eye_toggle_spec.md) | [plan](./T2_secret_eye_toggle_plan.md) | 与 T3/T4 同批 |
7+
| T3 | **已存密钥明文回填 + 等长掩码** | **L** | [spec](./T3_secret_mask_length_spec.md) | [plan](./T3_secret_mask_length_plan.md) | **改安全模型**:IPC `getSecrets`;更新 blueprint |
8+
| T4 | 眼睛睁/闭(基于真密钥) | S | [spec](./T4_secret_reveal_honesty_spec.md) | [plan](./T4_secret_reveal_honesty_plan.md) | 依赖 T3 |
9+
| T5 | 界面脱敏(隐藏备注,无序号) | M | [spec](./T5_ui_desensitize_remarks_spec.md) | [plan](./T5_ui_desensitize_remarks_plan.md) | 独立 |
10+
| T6 | 多账号半行间距 | S | [spec](./T6_account_row_spacing_spec.md) | [plan](./T6_account_row_spacing_plan.md) | 独立 |
11+
| T7 | 厂商统一百分比(刷新下、标签映射上) | M | [spec](./T7_provider_force_percent_spec.md) | [plan](./T7_provider_force_percent_plan.md) | SettingsForm 位置已定 |
12+
| T8 | 取消用量面板编辑按钮 | S | [spec](./T8_remove_main_panel_edit_spec.md) | [plan](./T8_remove_main_panel_edit_plan.md) | 独立 |
13+
14+
## 已拍板
15+
16+
|| 决定 |
17+
| --- | ----------------------------------------------------------------------- |
18+
| T3 | **前端必须能回看已存密钥**;打开编辑时 vault→IPC→表单明文;闭眼等长掩码 |
19+
| T4 | 标准睁/闭眼睛;不再「无法回显」 |
20+
| T5 | 脱敏后不要序号 |
21+
| T7 | 开关在「跟随全局自动刷新间隔」下、「数据标签映射」上 |
22+
23+
## 建议实现顺序
24+
25+
1. T1、T6、T8
26+
2. **T3**(IPC + 回填 + 文档改安全模型)→ T2 → T4
27+
3. T5、T7
28+
29+
## 待确认开写
30+
31+
回复 `T1-T8 OK`(或改某条)后开始实现。
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# T1 Plan: 关闭输入框拼写红波浪线
2+
3+
## 复杂度
4+
5+
**S**
6+
7+
## 方案
8+
9+
**推荐**:在 CSS/全局无法可靠关 Chromium spellcheck 时,对所有相关 `<input>`/`<textarea>``spellCheck={false}`
10+
11+
可选增强(同批):抽 `AdInput` 薄封装统一属性;若改动面嫌大,直接各文件加属性即可。
12+
13+
## 改动文件
14+
15+
1. `src/renderer/components/SettingsForm.tsx` — 所有 text/password/number/url input
16+
2. `src/renderer/components/AddAccountDialog.tsx` — input + textarea
17+
3. `src/renderer/components/CpaConnectorSettings.tsx`
18+
4. `src/renderer/components/LabelMapDialog.tsx`
19+
5. `src/renderer/components/RenameAccountDialog.tsx`
20+
6. `src/renderer/views/SettingsView.tsx` — 内联 secret/input
21+
7. `src/renderer/components/GrokLoginSection.tsx` — 若有可编辑文本框
22+
23+
## 测试
24+
25+
- 单元:关键组件 render 后 `expect(input).toHaveAttribute("spellcheck", "false")`(HTML 小写)。
26+
- 或新增轻量 util 测试不必;优先在 `settings_form` / `add_account_dialog` / `cpa_connector_settings` 各加 1 断言。
27+
28+
## Commit
29+
30+
```
31+
fix(ui): disable spellcheck on technical text inputs
32+
```
33+
34+
## 验证
35+
36+
`pnpm test` 相关 renderer unit;手工:endpoint 输入域名无红线。
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# T1 Spec: 关闭输入框拼写/语法红波浪线
2+
3+
## 问题
4+
5+
多数字符串输入框(域名、endpoint、密钥、备注、标签)未禁用浏览器 spellcheck,Chromium 对英文域名/技术串画红色拼写波浪线。
6+
7+
## 现状(代码)
8+
9+
`src/renderer``<input>` / `<textarea>` 均未设置 `spellCheck={false}`。涉及:
10+
11+
| 组件 | 字段类型 |
12+
| -------------------------- | ----------------------------------------------------- |
13+
| `SettingsForm.tsx` | 备注、secret、string/integer、endpoint (`type="url"`) |
14+
| `AddAccountDialog.tsx` | 备注、API key、endpoint、cookie textarea |
15+
| `CpaConnectorSettings.tsx` | 备注、endpoint、管理密钥 |
16+
| `LabelMapDialog.tsx` | 显示名称 |
17+
| `RenameAccountDialog.tsx` | 备注 |
18+
| `SettingsView.tsx` | 内联密钥等 |
19+
| `GrokLoginSection.tsx` | 若有文本输入一并纳入 |
20+
21+
## 期望
22+
23+
- 所有用户可编辑的 `input[type=text|url|password|number|email|search]``textarea``spellCheck={false}`
24+
- 可选:`autoCorrect="off"` / `autoCapitalize="off"`(Chromium 部分生效,无害)。
25+
- checkbox / select / button 不涉及。
26+
27+
## 验收
28+
29+
1. 设置 → 编辑任意账号 → 接口地址输入 `api.example.com`:无红波浪线。
30+
2. 数据标签映射输入框、备注名、密钥框:无红波浪线。
31+
3. 新增账号弹窗:同上。
32+
33+
## 非目标
34+
35+
- 不改 Electron `webPreferences` 全局 spellchecker(优先组件级属性,改动面小、可测)。
36+
- 不做中文语法检查相关功能。
37+
38+
## 风险
39+
40+
- 若未来有「写日记」类自然语言字段,需白名单开启 spellcheck;当前产品无此字段。
41+
42+
## 手工验证
43+
44+
打包产物:各设置表单输入域名/随机英文串,确认无红色下划线。
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# T2 Plan: 密钥框小眼睛统一
2+
3+
## 复杂度
4+
5+
**S–M**
6+
7+
## 方案
8+
9+
抽取共享组件(推荐):
10+
11+
```tsx
12+
// src/renderer/components/SecretInput.tsx
13+
// props: name, id, value|defaultValue, onChange?, className, aria-label, mono?, disabled?
14+
// 内部:show 状态 + input type + .ad-eye 按钮
15+
```
16+
17+
迁移:
18+
19+
1. `SettingsForm` secret 分支 → `SecretInput`(补上眼睛,当前最大缺口)
20+
2. `AddAccountDialog` key 行
21+
3. `CpaConnectorSettings` 管理密钥
22+
4. `SettingsView` 内联密钥
23+
24+
样式复用 `.ad-key` / `.ad-secret-row` / `.ad-eye`
25+
26+
## 与 T4 接口
27+
28+
`SecretInput` 预留 `revealable?: boolean`(默认 true):
29+
30+
- `false` 时眼睛 disabled + title「已保存密钥无法回显」(T4 启用)。
31+
32+
## 测试
33+
34+
- `SecretInput` 单元:点击切换 type password/text。
35+
- `settings_form`:secret 参数渲染出眼睛按钮。
36+
- 现有 CPA/AddAccount 测试不回归。
37+
38+
## Commit
39+
40+
```
41+
feat(ui): unify secret field eye toggle via SecretInput
42+
```
43+
44+
## 验证
45+
46+
设置 → DeepSeek/GLM 等编辑 → API Key 行有眼睛;新增账号弹窗仍正常。
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# T2 Spec: 密钥框小眼睛按钮统一
2+
3+
## 问题
4+
5+
密钥输入框有的有眼睛(显示/隐藏),有的没有,体验不一致。
6+
7+
## 现状盘点
8+
9+
| 位置 | 有眼睛 | 实现 |
10+
| -------------------------------------------- | ------ | ------------------------------- |
11+
| `AddAccountDialog.tsx` API key || `show_key` + `.ad-eye` |
12+
| `CpaConnectorSettings.tsx` `cpa_mgmt_key` || `showKey` + `.ad-eye` |
13+
| `SettingsView.tsx` 内联密钥(约 L577) || `showKey` + `.ad-eye` |
14+
| `SettingsForm.tsx` `param.type === "secret"` | **** |`type="password"`,无 toggle |
15+
| `GrokLoginSection.tsx` | N/A | OAuth device-code,无密码框 |
16+
17+
样式:`globals.css` `.ad-eye` / `.ad-key` / `.ad-secret-row` 已存在。
18+
19+
## 期望
20+
21+
1. 所有 **secret/password** 输入统一提供眼睛按钮(与 AddAccountDialog 视觉一致)。
22+
2. 行为:本地有可切换明文时,toggle `type` password ↔ text。
23+
3. 与 T3/T4 协调:若字段为 vault 占位、无法回显真实密钥,眼睛策略由 T4 定义(禁用/隐藏/tooltip);T2 负责「有密钥编辑能力的框」控件齐全。
24+
25+
## 验收
26+
27+
1. 直连账号编辑(`SettingsForm`)任意 secret 参数:有眼睛按钮。
28+
2. 新增账号、CPA 管理密钥:与现有一致且样式统一。
29+
3. 非 secret 字段:无眼睛。
30+
31+
## 非目标
32+
33+
- 不从 vault 拉回明文(见 T3/T4)。
34+
- 不改 Grok OAuth 流程。
35+
36+
## 风险
37+
38+
- SettingsForm 用 `defaultValue` + 非受控;加眼睛需本地 `showSecrets` map(按 param.name)。
39+
- 多 secret 字段时每行独立 toggle。
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# T3 Plan: 已存密钥明文回填 + 等长掩码
2+
3+
## 复杂度
4+
5+
**L**(改安全边界 + IPC + 多表单)
6+
7+
## 方案
8+
9+
### 1. 新 IPC(推荐按 instance 按需拉取)
10+
11+
```ts
12+
// config:getSecrets
13+
// request: { instanceId: string }
14+
// response: { secrets: Record<string, string> } // 仅该实例 vault 中存在的 secret 参数
15+
```
16+
17+
- 白名单:仅 `secretParamKeys` 允许的 param 名。
18+
- 主进程:`secretsStore.get` / vault `get(keyFor(instanceId, name))`
19+
- preload 白名单暴露 `config.getSecrets`
20+
- **不要**`config.get` 里默认塞全量明文(减少常驻暴露)。
21+
22+
可选:`config:getSecret({ instanceId, name })` 单条;批量更省 IPC。
23+
24+
### 2. 表单回填
25+
26+
| 组件 | 改动 |
27+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
28+
| `SettingsForm` | mount/展开时 `getSecrets(instanceId)`,secret 字段 `defaultValue`/`value` = 明文;删 `SECRET_PLACEHOLDER` 假长度逻辑 |
29+
| `CpaConnectorSettings` | 打开时拉 `cpa_mgmt_key` 明文,替换 `***` |
30+
| `SettingsView` 内联密钥 | 同上 |
31+
| `AddAccountDialog` | 新建无 vault,不变 |
32+
33+
与 T2 `SecretInput`:始终可睁/闭真文;T4 简化为普通 password UX。
34+
35+
### 3. 保存逻辑
36+
37+
- 提交时:value 非空则写入(可与旧值比较,相同则 skip)。
38+
- 删除「占位符不提交」分支,改为「空串 = 不更新 / 或明确清除」——**默认空串不更新 vault**(避免误清空)。
39+
40+
### 4. 文档
41+
42+
实现 commit 内更新 blueprint:secret-vault / domain / ipc / prd / architecture。
43+
44+
### 5. 测试
45+
46+
- unit/integration:mock vault → getSecrets 返回明文
47+
- SettingsForm:has 配置时 input value 为真密钥
48+
- 日志测试:getSecrets 路径不 log 明文
49+
50+
## 文件清单(预计)
51+
52+
- `src/shared/types/ipc.ts` — channel + API 类型
53+
- `src/preload/index.ts`
54+
- `src/main/ipc/config-ipc.ts` — handler
55+
- `src/renderer/hooks/use-config.ts` — 可选 `loadSecrets`
56+
- `SettingsForm.tsx` / `CpaConnectorSettings.tsx` / `SettingsView.tsx`
57+
- `tests/...`
58+
- blueprint 若干 md
59+
60+
## Commit(可拆)
61+
62+
```
63+
feat(secrets): allow settings UI to load vault plaintext for edit
64+
fix(ui): show real secret length under password mask
65+
docs(security): update secret exposure model for settings reveal
66+
```
67+
68+
## 依赖
69+
70+
- T2(SecretInput 眼睛)可并行或先做。
71+
- T4 改为轻量确认项(见更新后 T4)。
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# T3 Spec: 掩码长度 + 已存密钥可回看(产品已改)
2+
3+
## 产品决策(已拍板,推翻旧不变量)
4+
5+
**前端必须能看到已保存的密钥。**
6+
打开编辑表单时,从主进程 vault 解密后经 IPC 把明文交给渲染进程填入输入框;眼睛睁/闭对**真密钥**生效;隐藏时掩码长度 = 真实字符数。
7+
8+
旧规则「渲染进程永远只拿 hasSecret」在本功能上作废,实现时同步改:
9+
10+
- `docs/omni_powers/op_blueprint/specs/secret-vault.md` 最小暴露规则
11+
- `domain.md` §9
12+
- `prd.md` / `architecture.md` / `ipc.md` 中「secret 永不经 IPC 明文」表述
13+
14+
## 问题
15+
16+
1. 隐藏后星号数量应等于密钥长度(3 字符 → 3 掩码)。
17+
2. 旧实现用固定占位,且无法回看 → 与新产品要求冲突。
18+
19+
## 期望行为
20+
21+
| 场景 | 行为 |
22+
| -------------------------- | -------------------------------------------------------------------- |
23+
| 打开已配置 secret 的编辑页 | IPC 取明文 → input value = 真密钥;默认 `type=password`(闭眼) |
24+
| 闭眼 | 浏览器 password 掩码,长度 = value.length |
25+
| 睁眼 | 可见完整明文 |
26+
| 未配置 | 空输入框 |
27+
| 保存 | 与现网一致:有改动则 `saveSecrets`;无改动可跳过写 vault(可选优化) |
28+
| 关闭表单 | 不强制清内存(Electron 进程内);不写日志明文 |
29+
30+
## 安全边界(诚实记录)
31+
32+
- **仍防**:仅拷贝 `secrets.vault``vault.key` 读不出。
33+
- **新增暴露**:设置窗打开期间,明文在渲染进程内存;截图/开发者工具/恶意预加载可触及。用户已接受该代价。
34+
- **日志**:scrubber 仍必须脱敏,明文禁止进 log。
35+
- **范围**:仅设置/编辑表单按需拉取,**用量面板/托盘不拉密钥**
36+
37+
## 验收
38+
39+
1. 保存 API Key `abc` → 关对话框 → 再打开编辑 → 闭眼 3 点,睁眼 `abc`
40+
2. CPA 管理密钥、SESSION_COOKIE 等同。
41+
3. 新账号未保存:行为与现网一致。
42+
4. `pnpm test` 覆盖 getSecrets IPC + 表单回填。
43+
44+
## 非目标
45+
46+
- 用量面板用量卡显示密钥。
47+
- 导出文件加密(导出已是明文,见现 secret-vault)。
48+
- 主口令二次确认(可后续增强,本 task 不做)。
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# T4 Plan: 眼睛控件(依赖 T3 明文回填)
2+
3+
## 复杂度
4+
5+
**S**(T3 完成后)
6+
7+
## 实现
8+
9+
1. 随 T2 统一 `SecretInput`(睁/闭)。
10+
2.`configured` 不可回显分支。
11+
3. 加载中:secret 字段可 skeleton / disabled,避免先闪占位再变明文。
12+
13+
## 测试
14+
15+
- 回填后 click eye → type=text 且 value 为 vault 明文。
16+
17+
## Commit
18+
19+
可并入 T2/T3:
20+
21+
```
22+
feat(ui): secret eye toggle works on vault-loaded plaintext
23+
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# T4 Spec: 密钥眼睛(在可回看前提下)
2+
3+
## 产品前提(已拍板)
4+
5+
保存后再打开,前端经 IPC 拿到 vault **明文**(见 T3)。因此「按眼睛看不到原密码」的根因被移除。
6+
7+
## 期望
8+
9+
1. 图标两态:`eye` 睁 = 显示明文,`eye_off` 闭 = `type=password`
10+
2. 打开编辑时 value 已是真密钥 → 睁眼必见原文。
11+
3. 闭眼掩码长度 = 字符数(浏览器 password 或等长,与 T3 一致)。
12+
4. 所有 secret 框具备眼睛(T2)。
13+
14+
## 验收
15+
16+
1. 已存密钥打开 → 闭眼等长掩码 → 睁眼完整明文。
17+
2. 新输入同理。
18+
19+
## 非目标
20+
21+
- 不再做「无法回显」提示(旧 T4 方案废弃)。
22+
- 不在用量面板展示密钥。
23+
24+
## 依赖
25+
26+
T3 IPC 回填完成前,本 task 无法单独验收「已存回看」。

0 commit comments

Comments
 (0)