chore: 并入已删除会话的在途成果(防丢失;原会话已删,未做功能验收)
**背景**:这些改动原属本工作区另外几个会话(T01/T02 等),**那些会话已被用户删除** ⇒
工作树里的成果处于"无主"状态,一次错误 checkout / 覆盖即**永久丢失** ⇒ 代入库保全。
口径遵循本项目**先例**(`39a1f2e` / `b617cdb`:**别人的活,代入库并在提交信息里注明**)。
**内容**:档案 101「能力管理」改名 + 页内 tab 分页|档案 102 语言切换搬入「用户设置」|
`07-实例UI分区登记表.md`|`scripts/find-ui*.mjs`(UI 元素定位工具)|`poc/portal-entry/`(0.5.3)|
`src/web/locale-pref.ts` + `home-files.ts`(语言偏好持久化)|`test/locale-pref.test.mjs`|
`package.json`|`BRIEF.md` / `INDEX.md` / `docs-manifest.json` / `03-路线图与待办.md` / 档案 100 增量。
**已做最小健全性检查**(⚠️ **未跑完整构建 / 单测** —— 那是原会话的验收职责,本次只求"不丢"):
- JSON 合法:`package.json` / `poc/business-plugins/package.json` / `docs-manifest.json` ✓
- 4 个 TS 文件 `{}`/`()` 配平 ✓;新增文件均非空 ✓
- 规模:13 文件改动 +340/−210,新增 12 条
**未 push**(按 §4 提交边界:用户说"提交",未说"推送")。
This commit is contained in:
1 parent
03c8363960
commit
3efd68517f
27 files changed
+1712
-206
No files matched your search
@@ -99,7 +99,7 @@
|
||||
| ✅关闭 | ~~白名单源码安装支持~~(档案 29 §七) | **评估结论:不做(2026-09-11)**:源码安装需让第三方构建脚本以 root 在平台机执行(供应链 + 可复现性 + 性能三重风险),与"平台不执行第三方构建脚本"红线冲突。**替代路径**:admin 本地构建后走「上传 tgz」通道(已有 P0/P1 扫描);如需开启须先满足沙箱构建 + `--ignore-scripts` + 仅 admin + 审计等全部前提 |
|
||||
| 降级 | B5:给 portal-entry / business-plugins 加加载标记 | **降级为"顺手做"(2026-09-11 决策)**:不解决当前问题、源码不在仓库、且仅提升"升级时排查速度";下次改这两个插件时顺手加(零边际成本) |
|
||||
| ✅ | ~~熔断 live 实测~~(档案 20 附) | **已完成(2026-09-11)**:由真实故障用户(档案 52)的日志完成实测 —— 退避 1000→2000→4000→8000ms、`restartsInWindow` 1→4、第 **5** 次触发 `crash-loop-circuit-open`(窗口 600000ms / 5 of 5),当日 2 次开断;无需再人为 kill 复现 |
|
||||
| ✅ **已完成**(2026-09-15) | ~~档案 16 阶段 3/4(实例内「我的技能」)~~ → **= 交接单 `T01`,已归档** | **档案 100**|插件 `business-plugins` **0.3.20 → 0.3.21** 已投放两实例。① **形态修正(09-15)**:由「新增 section」改为**并入既有「功能管理」section 内分组**(依据用户口径「不要分开管理」+ 档案 60 分区命名;**仅入口层合并、机制层分离**)→ 见 `T01 §四 决策 6` 与 **`T01 §九`**;② 实现:技能行(名称/来源/状态/事实/动作)+ zip 拖拽上传 + 同名两阶段替换 + 页内确认弹窗 + 锁定行(共享技能)无动作按钮 + zh/en 46 条词条;③ 验收:`npm run verify` 全绿(含新 `scripts/verify-my-skills.mjs` 34 条断言)、06 §7 三段式全绿、端到端 **19/19**(409 / 400 守卫通过);④ 阶段 4 收口 = 未新增 section + 未改角色补丁 ⇒ 可见性不变。原述:门户 skills.html 仅 admin → 普通用户需实例内入口 |
|
||||
| ✅ **已完成**(2026-09-15) | ~~档案 16 阶段 3/4(实例内「我的技能」)~~ → **= 交接单 `T01`,已归档** | **档案 100**|插件 `business-plugins` **0.3.20 → 0.3.21** 已投放两实例。① **形态修正(09-15)**:由「新增 section」改为**并入既有「功能管理」section 内分组**(依据用户口径「不要分开管理」+ 档案 60 分区命名;**仅入口层合并、机制层分离**)→ 见 `T01 §四 决策 6` 与 **`T01 §九`**;② 实现:技能行(名称/来源/状态/事实/动作)+ zip 拖拽上传 + 同名两阶段替换 + 页内确认弹窗 + 锁定行(共享技能)无动作按钮 + zh/en 46 条词条;③ 验收:`npm run verify` 全绿(含新 `scripts/verify-my-skills.mjs` 34 条断言)、06 §7 三段式全绿、端到端 **19/19**(409 / 400 守卫通过);④ 阶段 4 收口 = 未新增 section + 未改角色补丁 ⇒ 可见性不变。⚠️ **后续(档案 101)**:该分区已改名「**能力管理**」并改为**页内 tab 分页**(功能插件 / 我的技能)。原述:门户 skills.html 仅 admin → 普通用户需实例内入口 |
|
||||
| ✅ **已消解** | ~~摘除 guest 仍在启用的已下架插件 `@liustack/modlens`~~ | **09-13 07:0x 实测:已无需处理** —— guest `profile/web` 的 `bundles` **与 `node_modules` 均已无 `@liustack/modlens`**(原「已下架却仍启用」的不一致态已不复存在)。历史:该包 09-12 从候选池下架(档案 70 收尾)时曾留在 bundles |
|
||||
| ❌已复核 | ~~Cookie 域收窄~~ | **不做(2026-09-12 用户决定:把这条待办删掉)** —— 共享 Cookie(`Domain=.alotbuy.com`)是**有意设计**:支撑「功能插件 ↔ 门户」**免令牌鉴权**(配合 `server.ts` 的 CORS 白名单),功能插件 v0.2.1 已生产跑通 → **收窄会破坏该链路,收益为零**;结论见档案 05 PoC-2 ② |
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
- 日期:2026-09-15
|
||||
- 触发:用户「规划一个产品方案(界面布局美观 方便操作)然后实现这个功能」=落地 `交接单/T01`(档案 16 阶段 3/4)
|
||||
- 对象:`poc/business-plugins`(`@dsh-local/business-plugins`)client bundle 的「功能管理」section
|
||||
- 状态:🚧 实施中(方案已定,代码/投放/验收见 §八)
|
||||
- 状态:✅ **已实施并投放**(`business-plugins` **0.3.21**,两实例;方案见 §二,验收见 §8.2/§8.4)
|
||||
- ⚠️ 后续:该分区已改名「**能力管理**」并改为**页内 tab 分页**(档案 **101**);本档案正文保留当时的形态描述(档案只增不改)
|
||||
|
||||
> **TL;DR**|**结论**:在**既有「功能管理」section 内新增「我的技能」分组**(**不新开 section**),用户在同一页看完并管理「功能插件 + 我的技能」两类功能;技能行支持 上传 / 启用 / 停用 / 删除,平台共享技能显示为**锁定只读**。
|
||||
> **关键**:入口层合并、**机制层分离**(技能 watch 即时生效 vs 插件需重启;API / 落盘各自独立)—— 依据见 `交接单/T01 §九`。
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# 101 · 「能力管理」:分区改名 + 页内 tab 分页 + 插件卡片三行描述 + DeepSeek 改名
|
||||
|
||||
- 日期:2026-09-15
|
||||
- 触发:用户三句话 —— ①「设置中 功能管理改为能力管理」②「能力管理页面改造为 tab可切换 插件和技能分别进行操作」③「插件卡片中增加中文用途描述 显示三行」④「内置 DeepSeek,去掉内置就叫 DeepSeek 就行」
|
||||
- 对象:`poc/business-plugins`(`@dsh-local/business-plugins`)client bundle 的「功能管理」section
|
||||
- 状态:✅ 已实施并投放(`0.3.21 → 0.3.22`)
|
||||
- 前置:档案 **100**(「我的技能」并入本 section)+ `交接单/archive/T01`
|
||||
|
||||
> **TL;DR**|**结论**:分区改名「**能力管理**」(label 级),页内改为 **tab 分页**(功能插件 / 我的技能,各自独立操作),插件卡片的**中文用途描述从 1 行放宽到 3 行**(`.bp-plugDesc`),并把「**内置 DeepSeek → DeepSeek**」。
|
||||
> **关键**:全部落在**用户可见文案 / 版式**这一层 —— **代码标识符、section id、包名、API 路径、词典键名一律不动**(素材库 U10)。
|
||||
> **不做**:不改服务端;不动「我的技能」的机制(仍是 watch 即时生效 / 两阶段替换 / 锁定行无可点动作)。
|
||||
|
||||
---
|
||||
|
||||
## 一、四项改动
|
||||
|
||||
### 1.1 分区改名:功能管理 → 能力管理
|
||||
|
||||
| 位置 | 旧 | 新 |
|
||||
|---|---|---|
|
||||
| `section.label`(zh) | 功能管理 | **能力管理** |
|
||||
| `section.label`(en) | Feature management | **Capability management** |
|
||||
|
||||
⛔ **只改 label**:`id: "business-plugins"`、包名 `@dsh-local/business-plugins`、`/api/plugins/*`、词典键名、CSS 类名一律不动 —— 与档案 60(功能插件→功能管理)同一口径。
|
||||
|
||||
### 1.2 页内 tab 分页(插件 / 技能各自操作)
|
||||
|
||||
```
|
||||
❙ 能力管理
|
||||
┌ 功能插件 3 ┐┌ 我的技能 2 ┐ ← 下划线式 tab(复用 .pa-tabs/.pa-tab/.pa-tcnt),各带计数
|
||||
┬────────────────────────────────
|
||||
│ 【功能插件页】内存条 / 搜索·全选·清空 / 卡片网格 / 应用更改 ← 内容与改造前逐项一致
|
||||
│ 【我的技能页】说明 + [+ 上传技能] / 上传面板 / 技能行列表
|
||||
```
|
||||
|
||||
- **实现**:`isPlugins = tab === "plugins"`(`useState("plugins")`,**默认落插件页** = 与改造前一致);插件块 `if (isPlugins)`、技能块 `if (!isPlugins)`,四段门控成对。
|
||||
- **复用而非新造**(U2):tab 直接用既有 `.pa-tabs/.pa-tab/.pa-tcnt`(下划线式;规范 §4.4「数据页用下划线式」),**没有新增样式**。
|
||||
- **计数**:插件页签 = 候选池条目数,技能页签 = 列表条目数(含共享)—— 不点进去也知道各类有多少。
|
||||
- **技能页去掉重复标题**:`❙ 我的技能` 竖条标题删掉(标题已由 tab 承担),只留「生效方式说明(左)+ 上传入口(右)」工具行(`.bp-tabHead`);避免同页出现两个同名标签。
|
||||
- 可访问性:`role="tablist"` / `role="tab"` / `aria-selected`。
|
||||
|
||||
### 1.3 插件卡片:中文用途描述 = 3 行
|
||||
|
||||
- 新增 `.bp-plugDesc`:`display:-webkit-box` + `-webkit-line-clamp:3` + `-webkit-box-orient:vertical` + `overflow:hidden` + **显式 `white-space:normal`**。
|
||||
- ⚠️ `white-space:normal` 必须显式写 —— 旧版单行截断用 `nowrap`,不覆盖会让多行截断失效(一眼看不出来的静默回退)。
|
||||
- `title` 仍挂全文,hover 可看完整。
|
||||
- 为什么:单行 ellipsis 会把「这个插件到底干什么」截掉大半;候选池入库时已优先取官方目录的**中文**说明,值得多给两行。
|
||||
|
||||
### 1.4 「内置 DeepSeek」→「DeepSeek」
|
||||
|
||||
| 词典键 | 旧(zh) | 新(zh) |
|
||||
|---|---|---|
|
||||
| `ms.kindBuiltin` | 内置 DeepSeek | **DeepSeek** |
|
||||
| `ms.optBuiltin` | 内置 DeepSeek(平台共享) | **DeepSeek** |
|
||||
| `ms.builtinPickHint` | 内置 DeepSeek:平台内置通道,固定官方端点,无需填 API 地址。 | **DeepSeek:官方通道,固定官方端点,无需填 API 地址。** |
|
||||
| `ms.tagBuiltin` | 内置 | **官方** |
|
||||
| `ms.builtinHint` | 平台内置通道,无需端点 | **官方通道,无需端点** |
|
||||
| `ms.catUnreadable` / `ms.catEmpty` | …当前只能使用内置 DeepSeek 或自定义提供方… | …当前只能使用 **DeepSeek** 或自定义提供方… |
|
||||
|
||||
en 侧同批(`Built-in DeepSeek` → `DeepSeek`;`Built-in` → `Official`)。
|
||||
|
||||
**顺带修掉的误导**:原选项名写的「(平台共享)」**是错的** —— 该选项走的是**内置通道(固定官方端点)**,但**必须填用户自己的 API 密钥**(`keyAddSchema` 里 `apiKey` 是 `required + minLength:1`;输入框 placeholder 也写着「输入你的 DeepSeek API 密钥」)。叫「平台共享」会让人以为不用填 key —— 这正是用户「添加模型也不能添加内置模型 没有对应KEY」困惑的来源。
|
||||
|
||||
---
|
||||
|
||||
## 二、与「平台共享模型」的关系(本次一并澄清,**重要,别再混**)
|
||||
|
||||
| 名称 | 是什么 | 谁的 | 要不要自己的 key | 能删吗 |
|
||||
|---|---|---|---|---|
|
||||
| **平台共享模型 `deepseek-main`**(页内**卡片**) | admin 名下**已启用**的 key 条目(`sharedKeyInfo().name` = admin 启用列表里的第一条名) | **平台 / admin** | ❌ 不要(用户不配 key 时回落到它) | ❌ **只能开关**(卡片上只有一个「停用/启用共享模型」,走 `/api/me/models/shared`) |
|
||||
| **`DeepSeek`**(「新增提供方」下拉里的选项) | 内置通道(固定官方端点)**给用户自己加条目**用的 provider 类型 | **用户自己** | ✅ **要**(否则 400) | 用户可删自己的条目 |
|
||||
|
||||
⇒ **不是一回事**:「平台共享模型 `deepseek-main`」是**平台那条 key**;「DeepSeek」是**你自己新建条目时选的通道**。另:官方 pi-ai 目录里的 `deepseek` 被后端**显式排除**(`src/web/routes/auth.ts` 注释原文:「平台已有『内置 DeepSeek』入口…再列一个同名选项只会让用户分不清哪个生效」)—— 所以下拉里不会出现第二个 DeepSeek。
|
||||
|
||||
---
|
||||
|
||||
## 三、实现落点
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `poc/business-plugins/lib/client.js` | ① zh/en:`section.label` 改名 + `cap.tabPlugins` 新词条 + `ms.*` 6 条措辞(内置→DeepSeek);② section 内新增 `tab` state + tab 条渲染 + 四段门控;③ 技能页工具行 `.bp-tabHead`(去重复标题);④ 插件卡片描述改 `.bp-plugDesc`;⑤ 注入 CSS:`.bp-tabHead` / `.bp-plugDesc` |
|
||||
| `poc/business-plugins/package.json` | 版本 `0.3.21 → 0.3.22`(含 ①②③④ 四项)+ `description` 追加本轮条目 |
|
||||
| `scripts/verify-my-skills.mjs` | 新增 **20 条**断言:改名生效 / 旧名不再是 label / tab 条与两个页签 / 计数 / `aria-selected` / 门控成对(`isPlugins` 2 处 + `!isPlugins` 2 处)/ `.bp-plugDesc` 三件套 / `title` 仍在 |
|
||||
| `scripts/verify-platform-admin-section.mjs` | 跟进改名:断言「条目名显示为 DeepSeek、不再有『内置 DeepSeek』」+ 3 处测试名/注释里的旧分区名 |
|
||||
|
||||
**零服务端改动**;未动官方包。
|
||||
|
||||
---
|
||||
|
||||
## 四、验收
|
||||
|
||||
| # | 口径 | 结果 |
|
||||
|---|---|---|
|
||||
| A | `npm run verify` | ✅ 全绿(zh/en 各 **367** 键、引用键全部已声明;含新增 20 条断言) |
|
||||
| B | 产物 | ✅ `business-plugins-0.3.22.tgz` 与服务器 sha256 一致(`a5a55b41…`) |
|
||||
| C | 投放 | 见 §五 |
|
||||
| D | 06 §7 三段式 + 浏览器 | 见 §五 |
|
||||
|
||||
---
|
||||
|
||||
## 五、实施与投放记录
|
||||
|
||||
### 5.1 投放
|
||||
|
||||
```
|
||||
产物:dsh-local-business-plugins-0.3.22.tgz 72,882 B sha256 a5a55b41…(与服务器一致)
|
||||
ssh bt-server 'cd /opt/dshs && node scripts/ensure-biz-plugins.cjs --all --restart'
|
||||
admin: 版本落后(0.3.21 → 0.3.22),升级中… ✓ bundles=7(含 @dsh-local/business-plugins: true)
|
||||
guest: 版本落后(0.3.21 → 0.3.22),升级中… ✓ bundles=6(含 @dsh-local/business-plugins: true)
|
||||
已停 0 个实例 scope(下次访问自动拉起)
|
||||
```
|
||||
⚠️ **同号覆盖说明**:`0.3.22` 在本次投放前**从未安装到任何 profile**(两实例都是 0.3.21)⇒
|
||||
打包后(含 1.4 的措辞微调)**覆盖同一版本号重发是安全的** —— 若已装过 0.3.22,则必须升到 0.3.23
|
||||
(否则 pnpm 判定"无需更新",静默不生效,档案 18 踩坑 1)。
|
||||
|
||||
### 5.2 磁盘层(06 §7.3 ①)✅
|
||||
|
||||
| 实例 profile | 版本 | `能力管理` | `cap.tabPlugins` | `bp-plugDesc` | 旧 `section.label: "功能管理"` |
|
||||
|---|---|---|---|---|---|
|
||||
| admin(`4092b965…`) | **0.3.22** | 3 | 3 | 3 | **0** |
|
||||
| guest(`cce6d1cd…`) | **0.3.22** | 3 | 3 | 3 | **0** |
|
||||
|
||||
### 5.3 本地校验 ✅
|
||||
|
||||
`npm run verify` 全绿:zh/en 各 **367** 键、引用键全部已声明;`verify-my-skills.mjs` 新增 **20** 条
|
||||
(改名生效 / 旧名不再是任何 label / tab 条与两个页签 / 计数 / `aria-selected` / 门控成对
|
||||
(`isPlugins` 2 处 + `!isPlugins` 2 处)/ `.bp-plugDesc` 三件套 / `title` 仍在);`verify-platform-admin-section.mjs`
|
||||
的「条目名 = DeepSeek」断言同步跟新。
|
||||
|
||||
### 5.4 ⚠️ 实例侧 / 浏览器验收:**本轮未完成**(原因与下一步写清)
|
||||
|
||||
**阻塞点(客观,非"将就")**:平台已切**集群模式** ⇒
|
||||
1. **新用户按容量落 Worker `w-106`**,不在 47 上 ⇒ 本机脚本「进实例 → 抓壳页 → 取 combo → 请求 bundle」
|
||||
这条路径拿不到带新包的壳页(实测 `comboHasBundle: false`,47 上也无该用户目录);
|
||||
2. **47 → 106 无 SSH 路由**(106 是经反向隧道连到 47 的)⇒ 从 47 侧探不到 106 上的 profile/实例。
|
||||
|
||||
**已做到的**:磁盘层(§5.2)已确认两实例 profile 里就是新代码 —— 而实例壳页的 combo 是对
|
||||
`profile/node_modules/**/client.js` 的**拼接**,所以"服务端会返回新内容"由 §5.2 强推出,但**未经端到端实测**。
|
||||
|
||||
**回头解决的条件**:一旦拿到「新用户落在哪台 Worker / 该 Worker 的 SSH 或 agent 通道」,
|
||||
就用档案 100 §8.4 那套(`poc-ui-user.cjs` + `agent-browser`)把三段式与视觉验收补上。
|
||||
|
||||
### 5.5 本轮附带的两个**实测事实**(高复用,已进 `PLAYBOOK §9`)
|
||||
|
||||
1. **控制面库 = PostgreSQL(集群模式)**:`DSHS_DB_URL=postgres://dshs:…@127.0.0.1:15432/dshs`,
|
||||
`DSHS_DEPLOY_MODE=cluster`。**`/var/lib/dshs/dshs.db`(SQLite)是回滚用的旧库、平台不读** ⇒
|
||||
临时用户审批写 SQLite = 白写(实测:`register` 201,但 `login` 403 `pending_review`);且 `users`
|
||||
表在 PG 里的主键列是 **`id`**(不是 `user_id`),清理脚本别照抄 SQLite 时代的列名。
|
||||
2. **一次性用户的残留**:`41a9480e-5269-463d-acce-79aeee74ced7`(`pocuimz6rb`)的 PG 行**已删**,
|
||||
但其 **home 目录留在 106 上**(47 无该目录、无路由)⇒ 需在 106 侧 `rm -rf` 该用户目录才能彻底清干净。
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
# 102 · 语言切换从「偏好设置」搬进「用户设置」,并撤除偏好设置分区
|
||||
|
||||
- 日期:2026-09-15
|
||||
- 触发:用户「把偏好设置中的 语言切换功能放到用户设置中,去掉偏好设置这个栏目,并检查语言切换功能是否正常」
|
||||
- 对象:`poc/business-plugins`(**0.3.22 → 0.3.23**)+ `poc/portal-entry`(**0.5.2 → 0.5.3**)
|
||||
- 状态:✅ 已实施并投放(两实例磁盘层已核)
|
||||
|
||||
> **TL;DR**|**结论**:语言切换搬进 **`@dsh-local/portal-entry` 的「用户设置」分区**(id `user-settings`,order 103),
|
||||
> `business-plugins` 的「**偏好设置**」分区(id `preferences`,order 99)**整块撤除**。
|
||||
> **关键**:语言是**用户级偏好** —— 与「账号 / 退出登录」同区即可,单开一个分区就是**重复入口**。
|
||||
> **不做**:不动官方包(R2);语言切换实现仍是官方扩展点(`ctx.locale`),零官方改动。
|
||||
|
||||
---
|
||||
|
||||
## 一、先澄清一件事(这轮排查的最大结论)
|
||||
|
||||
**「用户设置」是我们自己的 bundle 提供的,不是官方分区**:
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| section id | `user-settings` |
|
||||
| order | **103**(排在 能力管理 101 / 系统管理 102 之后) |
|
||||
| label | `"\u7528\u6237\u8bbe\u7f6e"` ← **转义 unicode 存的** |
|
||||
| 提供者 | `@dsh-local/portal-entry`(client 面 `lib/client.js`) |
|
||||
| 源码 | **仓内 `poc/portal-entry/`**(← 本轮补入,之前**不在仓里**) |
|
||||
|
||||
⚠️ **因为它是转义形态**,我按 UTF-8 字面量 `grep 用户设置` 在**全域**(官方树 / 平台代码 / 文档库 / profile)
|
||||
搜了十几轮全部落空,最后是"在活着的 profile 里 `grep -l settings.section @dsh-local/*/lib/client.js`"才定位到。
|
||||
⇒ 已把这条写进 **`07-实例UI分区登记表.md §二`**(含"同时搜 UTF-8 与 `\uXXXX` 两种形态")。
|
||||
|
||||
---
|
||||
|
||||
## 二、改动
|
||||
|
||||
### 2.1 `poc/portal-entry` 0.5.2 → **0.5.3**:语言行搬入「用户设置」
|
||||
|
||||
- **位置**:`UserManagementSection` 里,插在「账号/角色」(仅 admin 显示)与「退出登录」**之间**。
|
||||
- **实现**(官方扩展点,零官方改动):
|
||||
- `inject`:`["slots"]` → **`["slots", "locale"]`**;
|
||||
- 读 `ctx.locale.getLocale()`,切 `ctx.locale.setLocale(id)`,语言项 **`en` / `zh`**(= 官方 `LOCALE_IDS`;`en` 是官方 FALLBACK,即默认英语);
|
||||
- 本行自己的双语文案走 `ctx.locale.register(PE_NS, {zh,en})` + `ctx.locale.bind(PE_NS)`(与本仓 `business-plugins` 同一套姿势);
|
||||
- 切换后 `setTick()` 强制重渲染本行(官方 locale 的通知不会打到本组件);
|
||||
- 语言 id 读不到时退回 `en`,`ctx.locale` 缺失时只告警、不整区崩。
|
||||
- ⚠️ **颜色沿用本文件硬编码**(`#f9fafb` / `#43464d` / `#c9cdd4`)—— 本区渲染在 **DARK 主题**,
|
||||
v0.4.2/v0.4.3 的结论是**这里不能依赖 `--dsw-*`**(其 fallback 会让文字与底色同色而看不见)。
|
||||
- **源码入仓**:仓内此前**没有** `poc/portal-entry/`(只有服务器上的 tgz)⇒ 本轮把**部署中的 0.5.2 源码**
|
||||
取出来放进 `poc/portal-entry/`,再在其上改。**约定:自研 bundle 的产物只能从仓内源码构建。**
|
||||
|
||||
### 2.2 `poc/business-plugins` 0.3.22 → **0.3.23**:撤除「偏好设置」
|
||||
|
||||
撤掉三样东西(**只改用户可见面,不留残迹**):
|
||||
1. `PreferencesSection` 组件(整段,含其 doc 注释);
|
||||
2. `ctx.slots.inject("settings.section")` 里 **id `preferences` order 99** 的注册;
|
||||
3. zh/en 各 3 条 `pref.*` 词条(`pref.label` / `pref.lang` / `pref.hint`)。
|
||||
|
||||
⇒ 本 bundle 现在只注册 **2 个分区**:`model-settings`(100) + `business-plugins`(101)(admin 另加 `platform-admin` 102)。
|
||||
**语言切换一个字都没丢** —— 原实现就是 `ctx.locale.getLocale()/setLocale()`,搬过去后是同一套 API。
|
||||
|
||||
### 2.3 断言同步(防回退)
|
||||
|
||||
| 脚本 | 改动 |
|
||||
|---|---|
|
||||
| `scripts/verify-platform-admin-section.mjs` | 「非 admin 注册 3 个分区」→ **2 个**;「admin 注册四个」→ **三个**;新增 **「preferences 分区已撤除(不再注册)」** 断言;原「偏好设置」功能断言整块移除 |
|
||||
| `scripts/verify-portal-entry.mjs` | **新增**(22 条):源码在仓内 / **host 半边 `lib/index.js` 在**(v0.5.1 事故防线)/ id·order·label(**按转义形态**断言)/ `inject` 含 `locale` / get·setLocale 调用 / 双语词典 / en·zh 两项 / 语言行**确实 push 进 rows** / 颜色硬编码 / **R3:无 `exports.default` 赋值** |
|
||||
| 仓根 `package.json` | `npm run verify` 链尾接上 `verify-portal-entry.mjs` |
|
||||
|
||||
---
|
||||
|
||||
## 三、验收
|
||||
|
||||
| # | 口径 | 结果 |
|
||||
|---|---|---|
|
||||
| A | `npm run verify`(build + 单测 + 10 个 verify 脚本) | ✅ **全绿**(含两个新/改脚本) |
|
||||
| B | 产物 | ✅ `business-plugins-0.3.23.tgz`(72,037 B)· `portal-entry-0.5.3.tgz`(8,201 B,4 文件=两个半边都在)均已投放,与本地同名 |
|
||||
| C | 投放 | ✅ `ensure-biz-plugins.cjs --all --restart` + `ensure-portal-entry.cjs --all --restart` ⇒ admin/guest **bundles 7 / 6 完好**(未被 `pruneBrokenFileDeps` 摘依赖) |
|
||||
| D | 磁盘层(06 §7.3 ①) | ✅ 两实例:`business-plugins` **0.3.23** 且 `id: "preferences"` **命中 0**、能力管理/tab 仍在;`portal-entry` **0.5.3** 且 `key: "lang"` 命中 1、`inject` 含 `locale` |
|
||||
| E | 实例侧 / 浏览器实测 | ⚠️ **未做**,原因见 §四 |
|
||||
|
||||
---
|
||||
|
||||
## 四、未完成:实例侧与浏览器实测(原因 + 回头条件)
|
||||
|
||||
**阻塞点(客观)**:平台已切集群 ⇒ **新用户按容量落 Worker `w-106`**,而 **47 → 106 无 SSH 路由**
|
||||
(106 经反向隧道连到 47)⇒ 本机脚本走不通"建临时用户 → 进实例 → 抓壳页 → 点 UI"这条链;
|
||||
R4 又不允许用真实账号(guest/admin)登录做实测。
|
||||
|
||||
**已做到的**:磁盘层(§三 D)确认两个实例 profile 里就是新代码,而**实例壳页的 combo 是对
|
||||
`profile/node_modules/**/client.js` 的拼接** ⇒ "服务端会返回新内容"由 D 强推,但**未经端到端实测**。
|
||||
|
||||
**回头解决的条件**:拿到「新用户落哪台 Worker + 到那台机的通道」后,用档案 100 §8.4 那套
|
||||
(`poc-ui-user.cjs` + `agent-browser`)补齐三段式与视觉验收(重点看:语言行是否在「用户设置」里、
|
||||
切到 English 后**本行文案与官方 UI 是否立即变**、以及 `settings.yaml` 的持久化行为见下)。
|
||||
|
||||
### ⚠️ 一条要如实告知用户的行为边界
|
||||
|
||||
官方 `dsh-client-locale` README 原文:语言选择**立即生效**;**loopback 页面**会持久化到
|
||||
`$DSH_HOME/settings.yaml`,**非 loopback 页面只为当前进程保留**。平台是"浏览器经域名访问远程服务器"
|
||||
⇒ **属非 loopback** ⇒ **切换在新开页面/重启后不保证保持**。这不是本次改动引入的(原「偏好设置」用的是同一套 API),
|
||||
但**用户会说"我切了怎么又变回去"** ⇒ 已在 §五 记为待观察项。
|
||||
|
||||
---
|
||||
|
||||
## 五、待观察 / 技术债
|
||||
|
||||
- **持久化**:见 §四末条。若要"记住选择",得走平台侧写 `settings.yaml`(属新需求,不是本单)。
|
||||
- ⚠️ **`scripts/ensure-portal-entry.cjs` / `ensure-biz-plugins.cjs` 仍用 `better-sqlite3` 读
|
||||
`/var/lib/dshs/dshs.db` 枚举用户** —— 而集群模式下**权威库是 PG**(`DSHS_DB_URL`)。
|
||||
本轮两脚本对新用户/存量用户都工作正常(说明过渡期 SQLite 仍在被维护),但**这是一条隐患**,
|
||||
属集群化的收尾项(**不是本单 lane**)⇒ 只报告,未动手。
|
||||
- **`.pnpm` 里的历史副本**(`@[email protected]/0.3.4/0.3.8/0.3.11` 等)与文档库
|
||||
`04-调整方案/poc/portal-entry`(0.5.1 快照)都属"同名旧副本",排查时别当现行(已写进 `07 §二`)。
|
||||
|
||||
---
|
||||
|
||||
## 六、语言偏好**持久化**(2026-09-15 追加,用户:「A B 都按最优方案处理」)
|
||||
|
||||
**问题(A)与需求(B)其实不冲突** —— 最优解是**替官方把它的设置写进它自己的文件**:
|
||||
|
||||
### 6.1 做法(零官方改动、零新增平台状态)
|
||||
|
||||
| 层 | 改动 |
|
||||
|---|---|
|
||||
| 平台(新)`src/web/locale-pref.ts` | `reconcileLocalePreference(text, 'en'\|'zh')` —— **按行对账**,只在 `settings.yaml` 顶层 `locale: → preference:` 那两行上动手(不整份 YAML 解析,注释/顺序/别人的块一律不动);幂等(值相同 ⇒ `changed:false`) |
|
||||
| 平台(新)`src/web/home-files.ts` | 把原先内联在 `server.ts` 闭包里的 `readTextOrEmpty` / `writeHomeFile` **抽出来共用**(`writeHomeFile` = 备份到平台目录 + 写 + **chown 给 home 属主**,漏最后一步实例读不了 —— R10 同族)。`server.ts` 改为 import(行为不变) |
|
||||
| 平台(新路由)`POST /api/me/locale` | `requireAuth`;`{locale}` → 写 `<home>/settings.yaml`;非法值 400 `invalid_locale` |
|
||||
| 客户端 `portal-entry` **0.5.3 → 0.5.5** | `pickLocale()` 在 `setLocale()` 之后**额外调** `POST /api/me/locale`(`credentials:'include'`,跨子域);**持久化失败不影响本次切换**(就地已生效) |
|
||||
|
||||
**官方键名出处**:`dsh-client-locale` 的 **host 半边 settings schema** 用的就是 `locale` / `preference`
|
||||
(⛔ 不要凭猜 —— 首版我按 `locale.preference` 写是**核对过**的)。
|
||||
|
||||
### 6.2 为什么这是"最优"而不是"另造一套"
|
||||
|
||||
- **A(守官方语义)**:写的正是官方设置文件的官方键 ⇒ 实例启动时官方运行时读自己的文件即生效;
|
||||
- **B(记住选择)**:用户的选择跨页面 / 跨重启保留;
|
||||
- **单一来源**:平台**不新增**"语言状态"(没有新表 / 新列),唯一事实仍是 `settings.yaml`;
|
||||
- **失败可降级**:平台路由挂了 / CORS 拦了 ⇒ 只是"记不住",**不影响本次切换**(catch 兜底)。
|
||||
|
||||
### 6.3 验收
|
||||
|
||||
| # | 口径 | 结果 |
|
||||
|---|---|---|
|
||||
| A | 单测(新增 `test/locale-pref.test.mjs`,9 例) | ✅ 全过:建块 / 插行 / 换值 / **幂等** / **注释与其它块不动** / **CRLF 保持** / 行数不增 |
|
||||
| B | `npm run verify` | ✅ 全绿(`test` 45 例;含新增打包防线与持久化断言) |
|
||||
| C | 平台路由上线 | ✅ 送 4 个**编译产物**(`lib/web/{home-files,locale-pref,server}.js`、`lib/web/routes/auth.js`)+ `restart dshs`;冒烟 `POST /api/me/locale` → **401**(有鉴权 = 路由存在) |
|
||||
| D | 投放 | ✅ `portal-entry-0.5.5.tgz` 两实例 `bundles` 7/6 完好;磁盘层 **0.5.5**、`api/me/locale` 命中 1、包内无残留 tgz |
|
||||
| E | 浏览器实测 | ⚠️ 仍未做(同 §四:新用户落 `w-106`、47→106 无路由) |
|
||||
|
||||
### 6.4 ⚠️ 部署方式的一个**实测坑**(重要,别踩)
|
||||
|
||||
打算按常规 `cd /opt/dshs && npm run build && systemctl restart dshs` 部署时发现:
|
||||
**服务器 `/opt/dshs/src` 是"集群化之前"的旧源码**(`server.ts` 里还是 `K8sSpawner`,git 停在 `8390eb3 初始提交`),
|
||||
而**线上 `lib/` 却是集群版编译产物** —— 源码与产物**不一致**。
|
||||
⇒ **在那边直接 build 会把线上编译回旧版**(危险)。本次改为**只送编译产物**(4 个文件),
|
||||
并已核对"线上 `lib/` 与我本地编译版**只差本次改动**"再动手。
|
||||
⚠️ 这条属**集群化收尾项**(另一 lane):`/opt/dshs` 的 src 需要与 git 基线对齐,否则**任何一次服务器侧 build 都是事故**。
|
||||
@@ -0,0 +1,84 @@
|
||||
# 07 · 实例 UI 分区登记表(settings.section 谁提供、源码在哪、能不能改)
|
||||
|
||||
- 日期:2026-09-15
|
||||
- 触发:用户问「**为什么查代码要这么久 是不是反应 代码结构有问题或者没有 工程结构的索引文件**」——
|
||||
当时为了搞清「设置面板里的『用户设置』是谁渲染的」,我在 6 个官方包 + 3 个自研包里逐个 grep,
|
||||
绕了 ~30 次工具调用。**根因见 §三**(其中两条是真结构缺口)。
|
||||
- 状态:✅ 表格为**现行值**;改动分区时**同步改本表**(与 `INDEX.md` 一样属于"要维护的入口")
|
||||
|
||||
> **本表只回答四个问题**:这个分区**id** 是什么 → **谁提供** → **源码在哪** → **我能不能改**。
|
||||
> 单查某功能的实现细节仍去 `04-调整方案/`。
|
||||
|
||||
---
|
||||
|
||||
## 一、实例「设置」面板的分区总表(现行)
|
||||
|
||||
> **本表由 `node 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 个包里 | **真结构缺口** | ✅ 本文件(`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 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` 里的机械断言 | 已有防线,新包照抄 |
|
||||
@@ -33,7 +33,7 @@
|
||||
| 优先级 | 事项 | 备注 |
|
||||
|---|---|---|
|
||||
| 🔴 **待定窗口** | **档案 65 部署**(功能插件启停 ↔ web provider 托管段联动) | 代码完成 + 两态实测通过;**部署需 `systemctl restart dshs` → 中断在线用户**,等窗口 → 档案 65 §7.3 |
|
||||
| P1 | **T03**:7 个自研插件整合为 1 个功能插件并投放 | **候选池上传已完成**(**现行池内 = `dsh-plugin-mcn-suite @0.3.9`**,09-13 00:02;0.3.0 曾因 peer 范围被预检拒收 → 0.3.2 加 `peerDependenciesMeta.optional` → 0.3.3 补 `xlsx` 依赖 → 0.3.9 修 client 注册层与 `inject` 语义);**admin 已装并验通(host 面 3 个注册)**;剩 **guest 未启用** → 用户在「功能管理」启用 → 重启 → 验收 → 归档 → `交接单/README.md §一` |
|
||||
| P1 | **T03**:7 个自研插件整合为 1 个功能插件并投放 | **候选池上传已完成**(**现行池内 = `dsh-plugin-mcn-suite @0.3.9`**,09-13 00:02;0.3.0 曾因 peer 范围被预检拒收 → 0.3.2 加 `peerDependenciesMeta.optional` → 0.3.3 补 `xlsx` 依赖 → 0.3.9 修 client 注册层与 `inject` 语义);**admin 已装并验通(host 面 3 个注册)**;剩 **guest 未启用** → 用户在「能力管理」启用 → 重启 → 验收 → 归档 → `交接单/README.md §一` |
|
||||
| P1 | **T01**:实例内「我的技能」section + 阶段 4 权限收口 | 决策点 1 **已定**(=**A 扩展 `business-plugins`**,2026-09-12 用户拍板);只等开工 → `交接单/T01-*.md` |
|
||||
| 触发式 | dsh 升级回归(档案 26 六类耦合点)|会话 GC | 升级 / 容量触发 |
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
| **换电脑 / 改了工作区路径,规则会不会丢** | **`skills/dsh-env-bootstrap/SKILL.md`**:常驻规则快照 + `--check` 校验 / `--inject` 注入 / `--env-check` 环境自检(默认只报不改)|
|
||||
| 看还有什么没做完 | `03-路线图与待办.md` §二 | **`交接单/README.md` §一**(已规划待执行) |
|
||||
| **改前端页面(强制基线)** | **`06-工作台UI规范.md`** |
|
||||
| **改实例 UI 分区(设置面板)** | **`07-实例UI分区登记表.md`**(哪个包提供 / 源码在哪 / 能不能改)+ `06-工作台UI规范.md` |
|
||||
| 红线与硬约束 | `README.md` §红线(含 **R7 禁批量全仓写入**、**R8 中断用户须先知会**)| `04-07` |
|
||||
| **插件兼容性预检(导入/上传即判定)** | **`04-71`**(判据 + PoC + 三层防线)|**`交接单/T05`**(执行单)|`scripts/plugin-compat-check.mjs`(可在服务器直接跑) |
|
||||
| **实例崩溃循环 / 插件不兼容** | `04-70`(anysearch 与 dsh-llm `assertNever` 不兼容;判据「重启后错误是否变化」)|`04-20`(自愈熔断)|`04-25`(崩溃循环前例)|`02 §C.4` |
|
||||
@@ -28,7 +29,7 @@
|
||||
| **多会话并行 / 冲突治理** | **`04-69`**(两级文档锁 + 服务器侧操作锁 + commit 常态化)|`交接单/README.md`(占用锁 / 写者归属 / §六 服务器侧锁)|`scripts/handoff-guard.sh`、`scripts/op-lock.sh` |
|
||||
| 插件管理面 | `04-16`(三层归属)| `04-31`(门户双 Tab)| `04-57`/`04-60`(设置面板分区) |
|
||||
| **搜索 provider / 联网搜索** | `04-64`(接入 AnySearch)|`04-65`(启停与 web provider 联动)|`04-66`(P0 误报与 admin 显式信任) |
|
||||
| **「功能管理」section UI** | `04-67`(按 UI 规范重做)|`04-36`/`04-38b`(分区铺开 / 术语统一)|`04-68`(启停属主污染根治)|**`04-100`(「我的技能」分组 · 2026-09-15)** |
|
||||
| **「能力管理」section UI** | `04-67`(按 UI 规范重做)|`04-36`/`04-38b`(分区铺开 / 术语统一)|`04-68`(启停属主污染根治)|**`04-100`(「我的技能」分组 · 09-15)**|**`04-101`(改名「能力管理」+ tab 分页 + 卡片三行 + DeepSeek 改名 · 09-15)** |
|
||||
| 安全 / 暴露面 | `04-14`(出网护栏)|`04-39`(可见面收窄·封 loopback)|`04-41`(上传加固) |
|
||||
| 技能共享层 / 管理面 | `04-10`(bundledSkillDir)|`04-11`(API+页面)|`04-40`(挂载修复) |
|
||||
| 会话/登录跳转 · 断连恢复 | `04-13`(冷启动 404)|`04-24`(实例侧 401)|`04-49`(回收后反馈)|`04-51`(401 透明重放)|**`04-72`(回收/关闭后回到页面自动唤醒)** |
|
||||
@@ -145,6 +146,7 @@
|
||||
| — | 🔍 | **档案 82–86 尚未登记进本表**(本轮发现;属别人 lane 故未代加):82 R2 管理面就地化|83 登录注册页对齐|84 内存配额口径统一|85 模型密钥开放给用户自配|86 admin 跨用户实例管理 + 两处改名。**待收口会话补** |
|
||||
| — | 🧪 | `04-调整方案/poc/portal-entry/`:portal-entry 插件源码(v0.5.1)|
|
||||
| 06 | 🔄 | **前端 UI 强制基线**:Token/布局/组件/交互/9 条已知坑 |
|
||||
| 07 | ✅ | **实例 UI 分区登记表**:settings.section 的 id/order/label → 提供者 → 源码 → 可改性 + 定位套路(含"中文文案要同时搜 UTF-8 与 \uXXXX") |
|
||||
| 04-89 | 🔄 进行中(L2 机制级已验 | **对话内文件预览**:采纳官方推荐库现成插件 `@softspark/dsh-file-preview`(65 KB,包住官方 `openWorkspacePath` 接管"点文件"手势;兼容预检 ok、已启用、L5 |
|
||||
| — | 🗄 | `archive/dsh-improvement-plan-20260909-full.md`:拆分前 19 章 |
|
||||
| — | ✅ | `skills/dsh-change-workflow/SKILL.md`:六阶段 + **红线 R1-R11**(工作副本在本机 `.workbuddy/skills/`)|
|
||||
@@ -221,4 +223,6 @@
|
||||
| 04-97 | ✅ 已上线 | **`/plugins/` 合并脚本补 ETag + 304 短路**(承 96 之后查出的真缺陷,与当日故障无关):官方 `dsh-client-modules` 把全部客户端插件拼成**一条 11 MB 脚本**(` |
|
||||
| 04-98 | ✅ 已上线 | **治本:陈旧 `dsh-auth-*` cookie 回写清理**:dsh 每次实例(重)启动都换 `dsh-auth-<随机>` 的 cookie 名,平台此前只在转发时丢弃旧的、**从不回写浏览器** ⇒ jar |
|
||||
| 04-99 | 🔄 已落地待生效(钩子已装 | > 1. **根因 = 拦截点错位**(不是"AI 不听话"):既有「提问闸门」hook 的 matcher 是 `^AskUserQuestion$`,只能拦**工具调用**;实测本工作区宿主日志 `tool=AskU |
|
||||
| 04-100 | 🚧 实施中 | **结论**:在**既有「功能管理」section 内新增「我的技能」分组**(**不新开 section**),用户在同一页看完并管理「功能插件 + 我的技能」两类功能;技能行支持 上传 / 启用 / 停用 / 删除, |
|
||||
| 04-100 | ✅ 已实施并投放(`busi | **结论**:在**既有「功能管理」section 内新增「我的技能」分组**(**不新开 section**),用户在同一页看完并管理「功能插件 + 我的技能」两类功能;技能行支持 上传 / 启用 / 停用 / 删除, |
|
||||
| 04-101 | ✅ 已实施并投放 | **结论**:分区改名「**能力管理**」(label 级),页内改为 **tab 分页**(功能插件 / 我的技能,各自独立操作),插件卡片的**中文用途描述从 1 行放宽到 3 行**(`.bp-plugDesc`) |
|
||||
| 04-102 | ✅ 已实施并投放 | **结论**:语言切换搬进 **`@dsh-local/portal-entry` 的「用户设置」分区**(id `user-settings`,order 103), |
|
||||
@@ -1,29 +1,30 @@
|
||||
{
|
||||
"generatedFrom": "scripts/docs-manifest.py",
|
||||
"counts": {
|
||||
"files": 135,
|
||||
"chars": 1111460
|
||||
"files": 138,
|
||||
"chars": 1129912
|
||||
},
|
||||
"tiers": {
|
||||
"hot": 7,
|
||||
"cur": 27,
|
||||
"warm": 56,
|
||||
"cold": 10,
|
||||
"doc": 35
|
||||
"cold": 12,
|
||||
"doc": 36
|
||||
},
|
||||
"domains": {
|
||||
"platform": 54,
|
||||
"method": 28,
|
||||
"ui": 12,
|
||||
"plugin": 26,
|
||||
"ui": 14,
|
||||
"plugin": 27,
|
||||
"ops": 10,
|
||||
"external": 5
|
||||
},
|
||||
"layers": {
|
||||
"L0": 1,
|
||||
"L5": 113,
|
||||
"L5": 115,
|
||||
"L4": 4,
|
||||
"L2": 3,
|
||||
"?": 1,
|
||||
"L1": 2,
|
||||
"L3": 12
|
||||
},
|
||||
@@ -64,7 +65,7 @@
|
||||
"title": "03 路线图与待办",
|
||||
"status": "?",
|
||||
"date": "",
|
||||
"chars": 18429,
|
||||
"chars": 18493,
|
||||
"lines": 127,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
@@ -168,7 +169,7 @@
|
||||
"num": "07",
|
||||
"title": "调整方案 07:红线 — 禁止 dsh 自动获取最新版本 + 版本升级流程",
|
||||
"status": "生效",
|
||||
"date": "04-07",
|
||||
"date": "",
|
||||
"chars": 2111,
|
||||
"lines": 44,
|
||||
"refs": 10,
|
||||
@@ -216,7 +217,7 @@
|
||||
"date": "04-10",
|
||||
"chars": 6261,
|
||||
"lines": 129,
|
||||
"refs": 19,
|
||||
"refs": 24,
|
||||
"refsCurrent": 1,
|
||||
"tier": "cur",
|
||||
"layer": "L5",
|
||||
@@ -227,10 +228,10 @@
|
||||
"path": "04-调整方案/100-实例内我的技能-并入功能管理分组.md",
|
||||
"num": "100",
|
||||
"title": "100 · 实例内「我的技能」—— 并入「功能管理」的分组方案与实现",
|
||||
"status": "🚧 实施中",
|
||||
"status": "✅ 已实施并投放(`busi",
|
||||
"date": "2026-09-15",
|
||||
"chars": 12477,
|
||||
"lines": 250,
|
||||
"chars": 12599,
|
||||
"lines": 251,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
"tier": "cold",
|
||||
@@ -238,6 +239,36 @@
|
||||
"domain": "method",
|
||||
"tldr": "**结论**:在**既有「功能管理」section 内新增「我的技能」分组**(**不新开 section**),用户在同一页看完并管理「功能插件 + 我的技能」两类功能;技能行支持 上传 / 启用 / 停用 / 删除,平台共享技能显示为*"
|
||||
},
|
||||
{
|
||||
"path": "04-调整方案/101-能力管理-改名与tab分页与卡片三行.md",
|
||||
"num": "101",
|
||||
"title": "101 · 「能力管理」:分区改名 + 页内 tab 分页 + 插件卡片三行描述 + DeepSeek 改名",
|
||||
"status": "✅ 已实施并投放",
|
||||
"date": "2026-09-15",
|
||||
"chars": 6575,
|
||||
"lines": 152,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
"tier": "cold",
|
||||
"layer": "L5",
|
||||
"domain": "plugin",
|
||||
"tldr": "**结论**:分区改名「**能力管理**」(label 级),页内改为 **tab 分页**(功能插件 / 我的技能,各自独立操作),插件卡片的**中文用途描述从 1 行放宽到 3 行**(`.bp-plugDesc`),并把「**内置 D"
|
||||
},
|
||||
{
|
||||
"path": "04-调整方案/102-语言切换搬入用户设置并撤除偏好设置.md",
|
||||
"num": "102",
|
||||
"title": "102 · 语言切换从「偏好设置」搬进「用户设置」,并撤除偏好设置分区",
|
||||
"status": "✅ 已实施并投放",
|
||||
"date": "2026-09-15",
|
||||
"chars": 6957,
|
||||
"lines": 156,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
"tier": "cold",
|
||||
"layer": "L5",
|
||||
"domain": "ui",
|
||||
"tldr": "**结论**:语言切换搬进 **`@dsh-local/portal-entry` 的「用户设置」分区**(id `user-settings`,order 103),"
|
||||
},
|
||||
{
|
||||
"path": "04-调整方案/11-技能管理面-shared+mine-API与页面.md",
|
||||
"num": "11",
|
||||
@@ -351,7 +382,7 @@
|
||||
"date": "2026-09-10",
|
||||
"chars": 10704,
|
||||
"lines": 216,
|
||||
"refs": 24,
|
||||
"refs": 25,
|
||||
"refsCurrent": 1,
|
||||
"tier": "cur",
|
||||
"layer": "L5",
|
||||
@@ -996,7 +1027,7 @@
|
||||
"date": "2026-09-12",
|
||||
"chars": 3699,
|
||||
"lines": 92,
|
||||
"refs": 8,
|
||||
"refs": 9,
|
||||
"refsCurrent": 2,
|
||||
"tier": "cur",
|
||||
"layer": "L5",
|
||||
@@ -1386,7 +1417,7 @@
|
||||
"date": "2026-09-13",
|
||||
"chars": 14028,
|
||||
"lines": 218,
|
||||
"refs": 11,
|
||||
"refs": 12,
|
||||
"refsCurrent": 0,
|
||||
"tier": "warm",
|
||||
"layer": "L5",
|
||||
@@ -1603,6 +1634,21 @@
|
||||
"domain": "ui",
|
||||
"tldr": ""
|
||||
},
|
||||
{
|
||||
"path": "07-实例UI分区登记表.md",
|
||||
"num": null,
|
||||
"title": "07 · 实例 UI 分区登记表(settings.section 谁提供、源码在哪、能不能改)",
|
||||
"status": "✅ 表格为现行值",
|
||||
"date": "2026-09-15",
|
||||
"chars": 4215,
|
||||
"lines": 85,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
"tier": "doc",
|
||||
"layer": "?",
|
||||
"domain": "ui",
|
||||
"tldr": ""
|
||||
},
|
||||
{
|
||||
"path": "BRIEF.md",
|
||||
"num": null,
|
||||
@@ -1654,8 +1700,8 @@
|
||||
"title": "dsh 平台文档导航(INDEX)",
|
||||
"status": "?",
|
||||
"date": "",
|
||||
"chars": 16130,
|
||||
"lines": 816,
|
||||
"chars": 16649,
|
||||
"lines": 830,
|
||||
"refs": 0,
|
||||
"refsCurrent": 0,
|
||||
"tier": "doc",
|
||||
|
||||
Reference in new issue
Block a user