🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

输入框定位对齐 daoyu1993-lab/dsh-plugin-composer-align

DeepSeek Harness
daoyu1993-lab32 天前有提交已提供中文文档扫描:未发现敏感能力

固定新会话输入框位置,发消息后不再跳动

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/4 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add daoyu1993-lab/dsh-plugin-composer-align
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · ui
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 固定输入框位置
  • 发消息后不跳动

把新会话输入框固定在对话输入框所在的位置,第一条消息发出后输入框不再跳动。

README

由 DeepSeek 最新模型翻译生成
dsh-plugin-composer-align 把「新会话」页的输入框钉到和发送消息后完全相同的位置 —— 同宽、同高、同一个 y,发出去、以及用量行出现时都不再位移。 修复前 / 修复后 (预览页 preview/composer-align.html 由 tools/build-composer-align-preview.mjs 在本地生成 —— 不随仓库分发,页面内联了 DSH 官方样式表,生成方式见「自检」一节的第 0 步;断言在 tools/verify-composer-align.mjs。) 一句话 官方在新会话态把「大标题 + 工作区行 + 输入卡片」整块垂直居中(justify-content:center),发出第一条消息后相位变成对话态,输入卡片落到窗口底部 —— 输入框因此会跳大约 380px;此外新会话态的写字区比对话态高 16px(52px vs 36px),卡片底距也差一条用量行的高度(26px)。 本插件只加一张样式表,把新会话态直接套进对话态的那套几何。
展开完整文档(README 剩余 1 节)
dsh-plugin-composer-align

把「新会话」页的输入框钉到和发送消息后完全相同的位置 —— 同宽、同高、同一个 y,发出去、以及用量行出现时都不再位移。

修复前 / 修复后

(预览页 preview/composer-align.html 由 tools/build-composer-align-preview.mjs 在本地生成 —— 不随仓库分发,页面内联了 DSH 官方样式表,生成方式见「自检」一节的第 0 步;断言在 tools/verify-composer-align.mjs。)

一句话

官方在新会话态把「大标题 + 工作区行 + 输入卡片」整块垂直居中(justify-content:center),发出第一条消息后相位变成对话态,输入卡片落到窗口底部 —— 输入框因此会跳大约 380px;此外新会话态的写字区比对话态高 16px(52px vs 36px),卡片底距也差一条用量行的高度(26px)。
本插件只加一张样式表,把新会话态直接套进对话态的那套几何。

实测(1600×1000 的窗口,单位 CSS px)

| | 卡片 x | 卡片 y | 尺寸 | 距身体区底边 |
| 修复前 · 新会话 | 320.5 | 494 | 952×114 | 392 |
| 修复前 · 对话(有用量行) | 320.5 | 872 | 952×98 | 30 |
| 修复后 · 新会话 | 320.5 | 872 | 952×98 | 30 |
| 修复后 · 对话(有用量行) | 320.5 | 872 | 952×98 | 30 |
| 修复后 · 对话(用量行空着) | 320.5 | 872 | 952×98 | 30 |

写字区([data-composer-input])同步:修复前新会话 948×52、对话 948×36;修复后两态都是
948×36,位置逐像素相同。真机复核见下。

它到底改了什么(6 条)

官方 @deepseek-ai/dsh-client-ui-conversation 的两态差异只有四处,插件逐条抹平:

| # | 官方行为 | 插件的做法 |
| ① | hero 态 scrollBody{justify-content:center} 把整块居中 | 改 flex-start,交给 ② 让座位吃掉整个高度 |
| ② | hero 态座位 flex:none,只占内容高 | 座位 flex:1 1 auto,撑满身体区 |
| ③ | hero 态输入栈 padding-bottom:32px、gap:8px | 去掉 32px 底距(卡片离底 32px 的来源);gap 不动(卡片是栈的最后一个孩子,改它只会白挪上方内容) |
| ④ | HeroShell 是 height:100%,在自动高父级里等于内容高 | 显式 height:auto + flex:1 1 0,让它吸掉上方余量 —— 大标题因此仍在余量里垂直居中,工作区行和卡片一起到底部 |
| ⑤ | hero 态输入行 padding-bottom:0(对话态是 4px) | 补成 4px,卡片底边与对话态对齐 |
| ⑥ | hero 态写字区 min-height:52px(对话态 36px) | 取 36px —— 这是卡片高 16px 的唯一来源 |
| ⑦ | 卡片下方那条 composer dock:对话态里是「tokens/s · 缓存命中」+ 上下文计量表(26px),新会话态官方 display:none(0px) | 把 dock 的最小高度钉在 26px 并恢复显示:有内容时本来就是 26px(对话态几何完全不变),没内容时留着空白 |

第 ⑦ 条是「一模一样」的最后一块:用量行没有显示时也留着这段间距,所以输入框在「新会话 → 发出第一条消息 → 用量行出现」整个过程中一动不动。按用户要求,空白就空着。

为什么是「一个样式表」而不是「一个组件」

新会话的这套组合属于 conversation shell,唯一被支持的替换方式是接管 conversation.composer 这条 chain 槽位 —— 代价是丢掉官方 InputBar 和它内部的所有座位(附件、指令、权限、模型、用量…)。样式表把这些都留着:最坏的失败模式是「选择器不再命中,输入框退回居中」,永远不会把输入框弄坏。纯 CSS,无构建步骤。

选择器为什么这么写

DSH 的类名都是 CSS-module 哈希(ST7X_W_composerHero、yhfFVG_hero),每次构建都变,不能用。这里只用 shell 自己声明的 data 属性:

[data-conversation-content] / [data-content-phase] 对话身体区 [data-conversation-scroll] 滚动列 [data-composer-seat] 输入区座位 [data-composer-card] 输入卡片 [data-composer-input] 写字区

输入栈(composerStack)自己没有属性,所以按角色定位:在座位里,它是唯一「包含输入卡片、但卡片不是它直接子节点」的盒子 —— 后半句同时把输入行(conversation.composer.bar,卡片正是它的直接子节点)排除掉。渲染器的槽位包装(SlotOutlet → [data-slot]、chain 兜底 → [data-chain-overlay-fallback])也按名字排除:它们都在栈的上方且是 display:contents,排除它们不改变任何布局,但不排除的话,conversation.composer.bar 的包装也会命中这个角色,「取第一个孩子」的规则就会落到输入行而不是大标题上(输入行会长高,卡片停在半空)。

第 ⑦ 条指的是卡片的最后一个兄弟节点;它和相位无关,所以在两种相位下都生效 ——这正是「用量行空着也保留间距」所需要的。

所有选择器都要求 :has()(Chrome 105+ / Safari 15.4+);若某天运行时不支持,规则整体不命中,输入框退回官方的居中,不会有更坏的后果。

安装

插件目录就是本目录。两种装法二选一,不要同时启用(会插入两行同名插件):

本地目录(本仓库 clone 下来之后)
dsh plugin --profile desktop add "link:$PWD"

或直接从 GitHub
dsh plugin --profile desktop add "github:daoyu1993-lab/dsh-plugin-composer-align"

它会把这个包加进 profile 的 dependencies 与 dsh.profile.bundles,并在 node_modules/ 下建一个指向本目录的软链接(登记的是 link: 依赖,pnpm install 不会把它清掉)。
应用运行中也能安装;装完刷新页面(⌘R)即可生效,首次安装若没有热同步就重启一次 App。

另一种装法是把插件作为一个已解析的包,由 profile 自己的补丁层装载: $DSH_HOME/profiles/desktop/cordis.patch.yml 末尾的 insert 行即装载点,dsh-hmr 会实时拾取补丁文件的改动(不需要重启)。两种别同时用。

生效时机

- 改插件源码(client.js):client 插件有热更新接收端,保存后刷新页面即可;本次实测甚至是免刷新直接生效(window.__ModuleLoader__ 的模块图在补丁行激活时会重建)。
- 改 / 增 profile 补丁行:dsh-hmr 实时拾取,不需要重启。

卸载 / 回滚

A 路线:删掉 profile 补丁里那段 insert(以及 package.json 的依赖与软链)
rm ~/.dsh/profiles/desktop/node_modules/dsh-plugin-composer-align

profile 补丁有备份:cordis.patch.yml.bak-、package.json.bak-。

自检(可复现)

cd <本仓库根目录>
NODE="$(command -v node || echo '/Applications/DeepSeek Harness.app/Contents/Resources/runtime/primary-runtime/dependencies/node/bin/node')"

0) 前置:本仓库只分发截图,不含官方产物片段(core/、preview/.css、preview/.html 都在 .gitignore 里)。断言用的夹具从本机 DSH 现场抽出来:
"$NODE" tools/asar-extract.cjs ./core \
/dsh/node_modules/@deepseek-ai/dsh-client-ui-conversation/ \
/dsh/node_modules/@deepseek-ai/dsh-client-ui-chat/ \
/dsh/node_modules/@deepseek-ai/dsh-client-ui-theme/
T=core/dsh/node_modules/@deepseek-ai
"$NODE" tools/extract-css.mjs $T/dsh-client-ui-theme/lib/client.js preview/theme.css
"$NODE" tools/extract-css.mjs $T/dsh-client-ui-theme/lib/client.js preview/palette.css --only design_platform_css_default

1) 真样式表 + 真 DOM 复刻的逐像素断言(19 项) "$NODE" tools/verify-composer-align.mjs

2) 生成 / 重画预览 "$NODE" tools/build-composer-align-preview.mjs "$NODE" tools/screenshot-preview.mjs composer-align

tools/verify-composer-align.mjs 用的不是手写几何:样式表逐字取自 @deepseek-ai/dsh-client-ui-conversation 与 @deepseek-ai/dsh-client-ui-chat 的产物,标记类名一旦改名就硬失败;插件样式表是把 client.js 放进沙箱真的跑一遍 apply(ctx) 再从它插入的 里读回来的(顺带验证模块信封、注入与卸载)。DOM 复刻带渲染器的 display:contents 槽位包装,并且同一套断言再跑一遍去掉包装的扁平 DOM,避免规则其实依赖了包装层数。

断言里带负例:修复前的两态必须不同(否则测试本身失效),对话态(用户拿来对齐的那个位置)必须一字未动,空 dock 的对话态必须与有用量时同位。

真机复核(desktop profile,1470×870 的窗口)

用系统截图对同一个窗口的前后两张图做像素定位(蓝色发送键的中心):

| | 发送键中心 |
| 对话态(有用量行) | x=2480.5, y=1629.5 |
| 新会话(修复后) | x=2480.5, y=1629.5 |
| 新会话(修复前) | x=2480.5, y=1681.5 |

修复前差 52 设备像素(26 CSS px,正好是用量行的高度),修复后完全一致。

修复后的新会话页(真实窗口截图,输入框下方那条空白就是用量行的预留位):

真机:修复后的新会话页

已知取舍

- 用量行留白:新会话页底部会有 26px 的空白(就是将来用量行的位置)。这是用户明确要的:「即使没有用量显示,也可以空着,但不要去掉这部分间距」。
- 对话态若 dock 完全为空(performanceUsage 关掉且没有上下文计量表时),输入框会比官方默认高 22px —— 但正好等于用量行出现后的位置,所以反而消除了官方自己的那一次位移。
带用量行的对话态(本 profile 的常态)几何与官方逐像素相同。
- dock 里若出现更高的内容(例如别的插件往 conversation.composer.dock 里塞面板),卡片仍会被顶高 —— 那是内容占位,不是输入框的定位,新会话页没有这类内容可对齐。
- 只改视觉层:不注册槽位、不读别的插件 DOM、不动任何官方组件。

目录

index.js 宿主半边(空实现:本插件只作用于浏览器) client.js 浏览器半边:一张样式表,ctx.effect 挂载/卸载 cordis.patch.yml bundle 装法用的 insert 行 package.json 清单(dsh.bundle.patch + dsh.client) preview/ 预览图与预览页 tools/ 断言与预览生成脚本(见「自检」) LICENSE MIT
预览分享卡片长什么样 ↓daoyu1993-lab/dsh-plugin-composer-align
分享 · DeepSeek Harness Hub
daoyu1993-lab/dsh-plugin-composer-align

固定新会话输入框位置,发消息后不再跳动

这是你的仓库?认领条目

回到顶部