DSH (DeepSeek Harness) web 聚焦模式插件:?focus=<插槽路径> 让 DSH 页面只显示指定的插槽——消息流、输入区、会话列表、详情面板或任意注册插槽——其余界面隐藏,主视野留给代码。
本仓库也是 intent-flow 工作流的完整展示:
.intentflow/目录记录了每个 feature 从需求 → 设计 → 执行 → 关账的完整 AI 决策轨迹(requirement.md/design.md/later-on.md/report.md),AGENTS.md是工作流全局规范,_packages/是模块现状基线。评审工作流请直接看这些文件。
URL(?focus=) |
效果 |
|---|---|
conversation.session |
只显示消息流(隐藏输入区、会话头部、侧栏、详情) |
conversation.composer |
只显示输入区(沉底于视口底部,隐藏消息流等) |
conversation.chat.node |
消息区域全宽(与 conversation.session 视觉等价) |
conversation |
对话区整体(含输入区)全宽 |
sidebar / details |
会话列表 / 详情面板全宽 |
<任意 data-slot 路径> |
聚焦三槽内任意已注册插槽(含第三方插件注册的插槽) |
| 无参数 / 未知值 | 完全正常,插件 no-op |
聚焦模式下若 DSH 没有当前会话,插件自动恢复最近的非空白会话(否则消息流视图是空白 hero)。
DSH 的 Web UI 是插槽树(sidebar | conversation | details 三栏),渲染器为每个插槽输出 data-slot="<完整路径>" 的 wrapper。本插件不改 DSH 任何代码,纯 CSS 可见性控制:
- 读
location.search的?focus=,给<html>打上data-focus="<路径>"; - 顶层规则(静态注入):按路径首段把三栏 grid 压成单列轨道——隐藏非目标列容器后,目标列成为唯一 grid item,单轨道无自动放置歧义(规避旧版"详情列被推入 center 列"的 bug);
- 嵌套兄弟规则(注册式硬编码):目标插槽的祖先链兄弟(如聚焦
conversation.session时隐藏 composer 座位与会话头部)生成隐藏 CSS;所有规则预先注册,零时序问题; - 路径专属布局:
conversation.composer聚焦附加沉底规则(输入区固定在视口底部,active 相位生效)。
核心改进:
- 注册式硬编码规则:零时序问题,官方/第三方可扩展
- 持续监听保障:处理动态变化(切换会话、插槽重挂载)
- 快速失败策略:未注册路径直接报错,不静默降级
- 插件化扩展:第三方可通过
registerRuleAPI 注册自定义规则
架构对比:
| 维度 | 旧架构(动态枚举) | 新架构(注册式) |
|---|---|---|
| 规则来源 | 运行时枚举 DOM | 预先注册(硬编码) |
| 时序依赖 | ✗ 依赖目标渲染 | ✓ 零时序 |
| 监听策略 | ✗ 首次后 disconnect | ✓ 持续监听 |
| 失败处理 | ✗ 静默兜底 | ✓ 快速失败 |
| 扩展性 | ✗ 需改核心代码 | ✓ API 注册 |
| 稳定性 | 50%-95% | 100% |
DSH 从 ~/.dsh/profiles/node_modules 解析插件包。把本仓库链接(junction)到该位置,再经 patch 挂载:
# 1. 部署(Windows junction;修改本仓库代码即生效,无需重建)
mklink /J "$env:USERPROFILE\.dsh\profiles\node_modules\@dsh-focus\focus-plugin" "<本仓库绝对路径>"
# 2. 挂载:在 .dsh/dsh.mcp.patch.yml(或任意 --patch overlay)里 insert
# - id: focus-mode
# name: '@dsh-focus/focus-plugin'挂载行的
name必须精确等于包名(@dsh-focus/focus-plugin),写错会导致 DSH 启动失败(端口打不开)。
- 首次挂载:需重启 dsh(patch 进 boot graph);
- 修改插件代码后:无需重启——DSH 的 client-modules 按内容 hash 伺服插件,浏览器刷新即加载新代码。
npm install # tsdown + typescript + cordis 类型
npm run build # 构建 lib/client.js
npm run typecheck # 类型检查src/client/index.ts- 插件入口,注册内置规则,安装健康检查src/client/rules.ts- 规则注册系统,支持优先级覆盖和第三方扩展src/client/builtin-rules.ts- 内置规则定义(sidebar/conversation/details)src/client/core.ts- 核心逻辑:路径解析、CSS 生成、持续监听、健康检查
lib/client.js- DSH 经/plugins/<id>/client.js伺服lib/index.js- host 半(空 cordis 插件壳)
# 启用调试模式(URL 参数)
?focus=conversation.session&focus-debug=1
# 健康检查(浏览器控制台)
window.__dshFocusHealth()
# 诊断脚本(浏览器控制台)
# 粘贴 diagnostic.js 内容并运行- 基线对齐
@deepseek-ai/dsh@0.1.0-rc.6
// 在第三方插件中
import { registerRule } from '@dsh-focus/focus-plugin'
registerRule({
path: 'my-plugin.my-slot',
topSlot: 'conversation',
hiddenSelectors: [
'[data-slot="conversation.session"]',
'[data-composer-seat]',
],
layoutCss: `
html[data-focus="my-plugin.my-slot"] .my-element {
position: fixed;
bottom: 0;
}
`,
description: '我的插件聚焦规则',
source: 'my-plugin',
priority: 10, // 高优先级
})import { listRules, getRuleStats } from '@dsh-focus/focus-plugin'
// 列出所有规则
const rules = listRules()
console.log('Available paths:', rules.map(r => r.path))
// 统计信息
const stats = getRuleStats()
console.log('Total rules:', stats.total)
console.log('By source:', stats.bySource)- 优先级数字越大越优先(默认 0)
- 高优先级规则覆盖低优先级规则
- 同优先级规则覆盖并警告
| 路径 | 顶层插槽 | 说明 |
|---|---|---|
sidebar |
sidebar | 会话列表全宽显示 |
conversation |
conversation | 对话区整体全宽(含输入区和消息流) |
conversation.session |
conversation | 只显示消息流(隐藏输入区和会话头部) |
conversation.composer |
conversation | 只显示输入区,沉底于视口底部(active 相位) |
conversation.chat.node |
conversation | 消息节点区域全宽(与 session 视觉等价) |
details |
details | 详情面板全宽显示 |
MIT