build / build-and-scan (push) Waiting to run
文档库:目录改为编号制(01-规范/02-架构设计/03-数据库/04-调整方案/
05-交接单/06-ops/07-scripts/08-skills/09-archive),顶层散文件归入 01-规范/;
INDEX.md 与 docs-manifest.json 重刷(档案 146 篇);旧目录名引用全量对齐。
IM 线:src/im/**(SDK / hub / store / presence / ws / gateway-token)、
src/web/routes/im.ts、src/db/plugin-data/**、src/supervisor/plugin-assembly.ts
及对应 test/**。
插件线:poc/{im-agent-bridge,im-connection-gateway,im-conversation-tabs,
business-plugins-im,carbon-mcp-probe}、src/web/routes/{sessions,overlay-device}.ts、
src/net/relay/{device-grant,instance-credential}.ts。
仓库卫生:清出 40 个历史误入库 / 已改名文件(34 个交接单归档 + 6 个旧结构,
本地均有副本);dsh-server-docs/.gitignore 补 tmp/;交接单不入库(政策)。
102 lines
9.6 KiB
Markdown
102 lines
9.6 KiB
Markdown
# 143 · MCN工作台入口"点了没反应" + 用户设置里切语言"没反应"
|
||
|
||
- 日期:2026-09-20
|
||
- 触发:用户「admin账号dsh会话 点击左侧 MCN工作台入口 没有反应,找到原因修复后把MCN任务会话入口的位置改到MCN工作台 header区域(用图标即可)」+「设置选项中 用户设置里面切换 语言还是不起做用」
|
||
- 对象:`dsh-plugin-mcn-suite` **0.3.10 → 0.3.11**(客户端源 = `dsh-plugin-mcn/lib/client.js`)· `@dsh-local/portal-entry` **0.5.5 → 0.5.6**
|
||
- 状态:✅ 已落地,**真机浏览器实测通过**(admin 实例,47)
|
||
|
||
> **TL;DR**|两条都是 **dsh 0.1.5-rc.1 与插件里写死的老契约不一致**,不是用户操作问题:
|
||
> ① 对话区槽位名从 `conversation` 改成 **`main.conversation`** ⇒ 插件 `querySelector('[data-slot="conversation"]')`
|
||
> 实测**恒为 null** ⇒ 工作台面板**根本不挂载**(面板宿主 `pageHost` 一直 null,portal 不渲染)="点了没反应"。
|
||
> ② `ctx.locale.getLocale()` 由"返回 id 字符串"变成**返回快照对象** `{active,locales,revision}` ⇒
|
||
> `String(obj).split("-")[0]` 恒为 `"[object Object]"` ⇒ 受控 `<select>` 匹配不上任何 option,
|
||
> 浏览器只显示**第一项(English)** ⇒ 选「中文」时界面看着毫无变化(其实**本来就是中文**,是显示错)。
|
||
> 同时按用户要求把「MCN任务会话」入口**从左侧栏独立一行搬进工作台 header(图标按钮)**。
|
||
|
||
---
|
||
|
||
## 一、取证(先证后改,全部为实测)
|
||
|
||
| # | 结论 | 证据 |
|
||
|---|---|---|
|
||
| 1 | 线上插件客户端代码 = 本地源码(**不是**改不生效) | 实例内 `dsh-plugin-mcn-suite/lib/client.js` md5 = 本地 `dsh-plugin-mcn/lib/client.js` 拼装产物 md5(`f1a3cf7c…`) |
|
||
| 2 | 实例跑的是 **dsh 0.1.5-rc.1**(插件按 0.1.2-rc.1 写) | `/usr/local/bin/dsh --version` = `0.1.5-rc.1` |
|
||
| 3 | **槽位名已改名** | 浏览器实测 `document.querySelector('[data-slot="conversation"]')` = **null**;页面上 29 个 `data-slot` 里是 **`main.conversation`**(父 `main`、祖父 `.centerCol`,两者都是 `display:contents` 透明容器,与旧结构**同形**) |
|
||
| 4 | 语言取值形态已变 | 官方 `dsh-client-locale/lib/client.js`:`getLocale()` **`return this.snapshot`**(=`{active,locales,revision}`) |
|
||
| 5 | 语言下拉"显示错"可复现 | 用户设置里 select 的 DOM `value="en"/selectedIndex=0`,而 `document.documentElement.lang` = **`zh-CN`**(即界面本来就是中文) |
|
||
|
||
> 取证手段:`mksess.cjs`(admin 临时会话)+ `agent-browser`(`set headers` 无效 ⇒ 改用 `eval document.cookie='sid=…; domain=.ai1net.com'` 注入)+ `eval` 探针。**用完删会话**(`user_agent='poc-curl2'`)。
|
||
|
||
---
|
||
|
||
## 二、改动
|
||
|
||
### 2.1 `dsh-plugin-mcn-suite` 0.3.10 → 0.3.11
|
||
|
||
源改在 `dsh-plugin-mcn/lib/client.js`(**该包是整合包的源**,构建脚本按序拼接;整合产物 `dsh-plugin-mcn-suite/lib/client.js` 由脚本重生成,勿手改):
|
||
|
||
1. **槽位自适应**:新增 `CONVERSATION_SLOT_SELECTORS = ['[data-slot="main.conversation"]', '[data-slot="conversation"]']`
|
||
+ `findConversationSlot()`,`conversation` 的取值改为调用它(两个名字都认 ⇒ 跨 dsh 版本都能挂载)。
|
||
2. **配套 CSS** 同步:`.mcnNav_split>[data-slot='conversation']` 与 `…>div{…}` 两条规则各补 `,….mcnNav_split>[data-slot='main.conversation']…`。
|
||
3. **入口搬家**:删除侧栏独立入口组件 `AiSessionsTrigger` 与其注册(`id: mcn-sessions, order: 61`);
|
||
`McnPage` 新增 `openAiSessions()`(`setEntryParams(null); setView("ai-sessions")`)并在 **header**(面包屑右侧工具条)
|
||
增加图标按钮(新增 `V1_ICON_INNER.chat` = Lucide `messages-square`),面包屑补 `ai-sessions` → 「MCN任务会话」。
|
||
|
||
### 2.2 `@dsh-local/portal-entry` 0.5.5 → 0.5.6
|
||
|
||
`currentLocale()` 兼容两种形态(**对象取 `.active`**,并兜底 `getSnapshot().active`;字符串形态照旧)。`pickLocale` / `setLocale` 不动。
|
||
|
||
### 2.3 构建链上顺带修掉的两处**负向回归**(同轮,属"随手一构建就会把已删功能装回去")
|
||
|
||
| # | 问题 | 处置 |
|
||
|---|---|---|
|
||
| A | `build-mcn-suite.cjs` 的 `CLIENT_SOURCES` / `HOST_SYNC` **仍列着 `dsh-plugin-mcn-schedule`**,而 v0.3.10 已按用户指令摘除计划任务(`HOST_PARTS` 只剩 mcn+voxemw,线上产物 `lib/host/` 无 `schedule`)⇒ **一构建就把「计划任务」装回去** | 两处同步删掉该条目(与 `lib/index.js` 的 `HOST_PARTS` 对齐) |
|
||
| B | `dsh-plugin-mcn/lib/client.js` 里 v0.3.10 的「更多功能 → 自动任务」摘除编辑**丢了**(线上产物是注释、源文件里还是死链按钮 `openEntry("entry:mcn-schedule")`) | 源文件补回同一处编辑(改成说明注释) |
|
||
| C | `pack` 未排除 tgz ⇒ 历史散落在 suite 根的 `dsh-plugin-mcn-suite-0.3.10.tgz`(1.9 MB)会被打进新包 | `--exclude=*.tgz` + 若命中即抛错;历史 tgz 移到 `dist/` |
|
||
|
||
> A/B/C 都是为了满足**「新产物 = 线上产物 + 本次修复」**这一可核验性质:重打包后与线上 0.3.10 的 `diff` = **9 个 hunk / 51 行**,全部是本次改动。
|
||
|
||
---
|
||
|
||
## 三、验收
|
||
|
||
| # | 口径 | 结果 |
|
||
|---|---|---|
|
||
| A | 语法 / 构建 | ✅ 两个源文件 `node --check` 通过;`build-mcn-suite.cjs client` 自检全绿(load=1 / collect=5 / `exports.default`=0) |
|
||
| B | 产物核验 | ✅ `dist/dsh-plugin-mcn-suite-0.3.11.tgz`(436 条目 / 1.90 MB / md5 `0b84b3bc…`);顶层只有 `package/`,无 `.bak`/`node_modules`/`tgz`;`portal-entry-0.5.6.tgz`(4 文件,两个半边都在) |
|
||
| C | 与线上旧产物的差异面 | ✅ 仅 9 hunk / 51 行,全部为本次改动(见 §二 2.3 注) |
|
||
| D | 投放 | ✅ admin:`pnpm add` 实装 **0.3.11**(bundles=7 含本包)· `portal-entry` 实装 **0.5.6**;旧产物归档 `business-plugins/.bak/dsh-plugin-mcn-suite-0.3.10.tgz` |
|
||
| E | **浏览器实测(三段式)** | ✅ ① 点「MCN工作台」⇒ `hash=#/mcn`、`[data-mcn-split]` 与 `[data-mcn-panel]` 均出现、面板正文为「MCN 工作台 / 热点数据 / 账号列表 / AI写脚本 / 脚本诊断」;② 点 header 的「MCN任务会话」图标 ⇒ 面包屑「MCN 工作台 / MCN任务会话」、页标题与计数正常;③ 左侧栏**已无**独立「MCN任务会话」行;④ 语言:初始 `select=zh`(**修前是 en**,界面却是中文)、选 English ⇒ `lang=en` 且整站变英文、选 中文 ⇒ `lang=zh-CN` 且回中文;⑤ 持久化:`<home>/settings.yaml` 出现 `locale: preference: zh` |
|
||
| F | 平台侧校验 | ✅ `scripts/verify-portal-entry.mjs` **全绿(28 条)**(本轮把「快照对象取 `.active`」补成断言,防回退) |
|
||
| G | 收尾 | ✅ 测试会话已删(PG `sessions where user_agent='poc-curl2'` = 0);服务器 `/tmp` 暂存件已清 |
|
||
|
||
---
|
||
|
||
## 四、边界 / 未覆盖
|
||
|
||
1. ✅ **guest(实例在 w-106)已补齐(2026-09-20 09:1x–09:3x,同一会话内追加)**:106 上 `@dsh-local/portal-entry`
|
||
已从 **0.5.5 → 0.5.6**(`pnpm add` 成功、`dsh.profile.bundles` 含本包、包内 `client.js` 命中 `v = v.active`),
|
||
实例停过后由平台按需拉起;**浏览器实测**:初始态 `document.documentElement.lang` = `zh-CN` 且下拉 = `zh`(**修前恒显示 en**),
|
||
切 English ⇒ `lang=en` + 下拉 `en`(一致)⇒ 修复在 guest 同样生效。
|
||
⚠️ `dsh-plugin-mcn-suite` 在 106 上**仍未安装** —— 它本来只有 admin 装(MCN 工作台是 admin 的自研插件),不是遗漏。
|
||
手段 = 新脚本 **`scripts/install-plugin-for-user.cjs`**(见档案 144 §二:把"给某个用户装某个 tgz"收敛成**机器无关的原子动作**)。
|
||
2. `dsh` 版本契约(槽位名 / locale API)属**跨版本耦合点**:这次是"改名"型破坏,插件侧已做成双名兼容;
|
||
若 0.1.6 再改名,`CONVERSATION_SLOT_SELECTORS` 是唯一落点(一处集中维护)。
|
||
|
||
---
|
||
|
||
## 五、可复用结论(跨会话)
|
||
|
||
- 🔴 **「点了没反应」先查宿主契约**:MCN 工作台靠 `document.querySelector('[data-slot="…"]')` 找宿主 ⇒ **槽位名是外部契约**,
|
||
dsh 升级后**必须**用浏览器确认名字(本次 `conversation` → `main.conversation`)。判据:`[data-mcn-panel]` 是否出现。
|
||
- 🔴 **官方 locale 是"两形态"API**:`getLocale()` 在 0.1.5-rc.1 返回**快照对象**;凡读当前语言必须取 `.active`。
|
||
表现具有欺骗性:**下拉显示 English 但界面是中文** ⇒ 别按"界面语言对不对"判断,要看 `document.documentElement.lang` + select 的 `value`。
|
||
- 🔴 **重打包前先做"产物差异面"核验**:把新产物与**线上在跑的那份**做 `diff`,确认差异只含本次改动 ——
|
||
本次正是靠它抓到 A/B/C 三处"一构建就负向回归"(计划任务复活 / 死链菜单项 / 历史 tgz 打进包)。
|
||
- 🔧 **浏览器实测的可行姿势**:`mksess.cjs` 造 admin 会话 → `agent-browser`:`set headers` 注 Cookie **不生效**,
|
||
改用 `open https://ai1net.com/login.html` + `eval document.cookie='sid=…; domain=.ai1net.com; path=/'` → 再 `open` 实例子域。
|
||
另注:`agent-browser` 在本机**前台会被沙箱杀(SIGTERM)**,用 `run_in_background` 起一次(守护进程常驻)后,后续命令加
|
||
`> 文件 2>&1`(**不走管道**)即可前台跑。
|
||
- 🔧 **手动跑平台脚本要带运行环境**:`/etc/dshs.env` + `dshs.service.d/*.conf` 的 `Environment=`(否则 `DSH_PLATFORM_DIR` 缺省,
|
||
`artifactDir()` 会落到 `/root/.dshs/platform/artifacts`)。脚本模板见 `.workbuddy/tmp/run-with-platform-env.sh`。
|