Files

84 lines
6.7 KiB
Markdown
Raw Permalink Normal View History

# 07 · 实例 UI 分区登记表(settings.section 谁提供、源码在哪、能不能改)
- 日期:2026-09-15
- 触发:用户问「**为什么查代码要这么久 是不是反应 代码结构有问题或者没有 工程结构的索引文件**」——
当时为了搞清「设置面板里的『用户设置』是谁渲染的」,我在 6 个官方包 + 3 个自研包里逐个 grep,
绕了 ~30 次工具调用。**根因见 §三**(其中两条是真结构缺口)。
- 状态:✅ 表格为**现行值**;改动分区时**同步改本表**(与 `INDEX.md` 一样属于"要维护的入口")
> **本表只回答四个问题**:这个分区**id** 是什么 → **谁提供** → **源码在哪** → **我能不能改**。
> 单查某功能的实现细节仍去 `04-调整方案/`。
---
## 一、实例「设置」面板的分区总表(现行)
> **本表由 `node 07-scripts/find-ui.mjs --md` 生成**(扫的是**活着的 profile + 官方包**,不是仓里快照)。
> ⛔ **改分区 ⇒ 同一次改动里刷新本表**。下表的 label 是从代码里**解码**出来的(含 `\uXXXX` 转义形态)。
| order | id | label | 提供者 | 来源 | 源码 / 可改性 |
|---|---|---|---|---|---|
| 0 | `general` | 通用设置 | `@deepseek-ai/dsh-client-ui-settings-general` | 官方 | 官方包,⛔ **不可改**(R2);**官方语言切换就在这一页**(`settings.general.item`) |
| 10 | `models` | (官方 locale 键) | `@deepseek-ai/dsh-client-ui-settings-models` | 官方 | ⛔ 不可改;⚠️ **被角色补丁禁用**(本环境打开必报错,档案 87) |
| 15 | `plugins` | (官方 locale 键) | `@deepseek-ai/dsh-client-ui-settings-plugins` | 官方 | ⛔ 不可改;⚠️ 角色补丁禁用 |
| 20 | `agent-presets` | (内部无 label) | `@deepseek-ai/dsh-client-ui-agent-preset` | 官方 | ⛔ 不可改 |
| 100 | `model-settings` | 模型设置 | `business-plugins` | **自研** | 仓 `poc/business-plugins/lib/client.js` ✅ **可改** |
| 101 | `business-plugins` | **能力管理** | `business-plugins` | **自研** | 同上 ✅ 可改(原「功能管理」,档案 101 改名 + tab 分页) |
| 102 | `platform-admin` | 系统管理 | `business-plugins` | **自研** | 同上 ✅ 可改(**仅 admin**) |
| 103 | `user-settings` | **用户设置** | `portal-entry` | **自研** | 仓 `poc/portal-entry/lib/client.js` ✅ 可改(账号 / **界面语言** / 退出登录) |
> 附注:官方包的 label 走各自的 locale 词典(表里显示 `t("…")` 即"未在包内解析到"),
> 而**官方那 4 个我们本来也不该改**,所以不再深挖;真要读文案去该包 `README.zh.md`。
> `preferences`(偏好设置,自研)已于 2026-09-15 **撤除**(档案 102)。
## 二、定位一个 UI 分区的**最快路径**(照这个顺序,别再绕)
1. **先看"活着的实例里装了什么"**,而不是先翻官方包:
```bash
P=/var/lib/dshs/users/<uid>/home/profiles/web
ls $P/node_modules/@dsh-local/ # 自研 bundle
grep -l "settings.section" $P/node_modules/@dsh-local/*/lib/client.js # 谁注册了分区
```
⛔ 我当时的错:先去 `/usr/local/...` 官方树里找、再去 0.1.2 备份里找、又怀疑第三方插件 —— 最后才查 profile。
2. **官方包的根**(不是 profile):
`/usr/local/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/`
3. **搜中文 UI 文案必须同时搜两种形态**:
```bash
grep -rn "用户设置" . # UTF-8 字面量
grep -rn 'u7528u6237u8bbeu7f6e' . # \u 转义形态 ← portal-entry 就是这种,只搜上一条永远 0 命中
```
(可用 `python3 -c 'print(open("f").read().encode("unicode_escape").decode())'` 反推转义形态。)
4. **别被副本误导**(三处都有同名不同版本的旧拷贝):
- `dsh-server-docs/04-调整方案/poc/*` = **历史快照**(如 portal-entry 停在 0.5.1);
- profile 的 `node_modules/.pnpm/` 里堆着 `@dsh-local+business-plugins@…0.2.3/0.3.4/0.3.8/0.3.11` 等历史 tgz;
- `/opt/dsh/backups/` 下有升级前的整套官方包(如 `dsh-0.1.2-rc.1`)。
⇒ **判"现行"只认两处**:仓内 `poc/<name>/` + profile 里 `node_modules/@dsh-local/<name>/`。
---
## 三、为什么会绕这么久(诊断结论)
| # | 原因 | 性质 | 已做的处置 |
|---|---|---|---|
| 1 | 标签用 **`\uXXXX` 转义**存(`"\u7528\u6237\u8bbe\u7f6e"`),按 UTF-8 搜永远 0 命中 | **代码侧小缺陷**(可维护性) | 记入本表 §二 第 3 条;⛔ 新增文案**建议直接写中文**(官方 bundle 亦混用,但可 grep 的优先) |
| 2 | **源码没入仓**:`portal-entry` 不在 `poc/` 里,线上只有 tgz ⇒ 只能从产物反推 | **真结构缺口** | ✅ 已把 0.5.3 源码补进 `poc/portal-entry/`;**约定:产物只从仓内源码构建** |
| 3 | **没有"哪个包提供哪个 UI"的索引**,id/order/label 散在 9 个包里 | **真结构缺口** | ✅ 本文件(`01-规范/07-实例UI分区登记表.md`) |
| 4 | 集群切换后"实例侧实测"变难(新用户落 `w-106`、47→106 无 SSH 路由) | 环境复杂度 | 见 `PLAYBOOK §9.1`;新用户落点见 `03-路线图` |
---
## 四、维护约定
- **改任何分区(增/删/改名/调 order)⇒ 同一次改动里更新本表**;⛔ 不要只改代码。
- 新增自研 bundle 时,**源码必须落在仓内 `poc/<name>/`**,并在本表登记。
- 本表**不写版本号**(会漂)—— 版本去 `poc/<name>/package.json` 与 `/opt/dsh/artifacts/` 看。
## 五、长效机制(2026-09-15 建,针对 §三 的三条根因)
| 根因 | 机制 | 怎么用 |
|---|---|---|
| 找不齐「谁提供哪个 UI 分区」 | **`node 07-scripts/find-ui.mjs [关键词] [--md] [--grep]`** —— 扫活 profile + 官方包,一次给全:id / order / label(**含转义解码**)/ 提供者 / 源码路径 / **能不能改** | 改任何实例 UI 前**先跑它**(本来要 30 次 grep 的事 → 1 条命令) |
| 中文文案搜不到(`\uXXXX` 转义) | 由 `find-ui.mjs` 内建(**两种形态都搜**);`PLAYBOOK §9.2` 也记了反推转义的方法 | 手写 grep 时记得两种形态都试 |
| 自研 bundle 源码不在仓里 | **约定:`poc/<name>/` 是唯一源码位置,产物只从仓内源码构建**;`portal-entry` 已补入 | 发现某自研包不在 `poc/` ⇒ 先从部署产物取出入仓,再改 |
| 改完忘了同步断言 / 文档 | `npm run verify`(含 `verify-my-skills` / `verify-portal-entry` 的结构断言)+ **本表** | 每次改动收尾跑一次 |
| 打包把上一版 tgz 打进去(0.2.5 / 0.5.4 两次同坑) | 各包 `.npmignore` 排除 `*.tgz` + `verify-portal-entry.mjs` 里的机械断言 | 已有防线,新包照抄 |