READMESource: main@b36336b5
dsh-heatmap
DeepSeek Harness 页面埋点与热力图分析插件。为后续产品设计优化提供量化数据:科学采集页面交互行为,本地展示热力图与统计,预留 CLI 与外部上传接口,上传前强制用户授权。
功能一览(在原始需求上补充后的完整设计)
| # | 功能 | 说明 |
|---|---|---|
| 1 | 科学埋点设计 | 四类事件(生命周期 / 交互 / 滚动曝光 / 热力图坐标)+ 稳定元素身份 + schema 版本化,参考主流产品分析(Amplitude / Mixpanel / Heap / Clarity)的埋点原则 |
| 2 | 热力图模式 | 点击 + 鼠标悬停密度热力图,色带「蓝→青→绿→黄→红」;面板标注「本地 / 本人数据」并展示聚合统计 |
| 3 | CLI / 外部访问接口 | host 侧 analytics_export 工具(Agent 可调用)+ webServer 上的 /dsh-heatmap/* HTTP 路由,预留统一分析平台对接 |
| 4 | 上传授权弹窗 | 数据上传到外部/其他软件前弹出授权弹窗,用户「同意并上传」后才发送 |
| 5 | 隐私最小化(补充) | 只采集控件身份、坐标、时间、视口;绝不采集对话正文与输入内容(输入仅记录长度) |
| 6 | 数据本地化(补充) | 采集数据默认只存本地 localStorage;host 收集器用 NDJSON 落盘,可随时导出/清空 |
| 7 | 可配置(补充) | 采样率、事件开关、热力图开关、鼠标热力图、上传地址、授权要求、存储上限均可配置 |
埋点设计(事件分类学)
事件类型
| 类型 | 触发时机 | 采集字段 | 产品用途 |
|---|---|---|---|
session_start / session_end |
页面加载 / 卸载或隐藏 | 会话 id、时间 | 会话数、会话时长 |
page_view |
初始加载 + hash 路由变化 | path、hash | 页面/视图访问量 |
click |
任何可点击元素被点击 | 元素身份 + 视口坐标 | 按钮点击率、点击热力图 |
focus / blur |
元素获得/失去焦点 | 元素身份 | 是否 focus、交互路径 |
hover |
鼠标悬停(250ms 节流,可选) | 视口坐标 + 元素身份 | 悬停/注意力热力图 |
scroll_depth |
滚动停止后(500ms 防抖) | 滚动深度 0..1 | 内容消费深度 |
visibility |
页签可见性变化 | visible | 停留时长(活跃时段累计) |
input |
输入框输入(1s 节流) | 元素身份 + 输入长度 | 输入活跃度(不含内容) |
impression |
元素首次进入视口 ≥50%(IntersectionObserver) | 元素身份 | 曝光分析(哪些面板/控件被看到) |
元素身份(稳定指纹)
采集端按优先级生成稳定的 elementId,保证跨会话可聚合到同一控件:
data-testid > id > aria-label > role#tag > tag:文本摘要(≤40字)
同时记录 tag / role / ariaLabel / title / text 供分析侧做控件维度下钻。
数据模型(schema v1)
interface AnalyticsEvent {
v: number // schema 版本
id: string // 事件 uuid
ts: number // epoch ms
sessionId: string // 会话 uuid
type: EventType
page: { path: string; hash: string }
target?: ElementRef // 元素身份
position?: { x: number; y: number } // 热力图坐标
depth?: number // 滚动深度
visible?: boolean // 可见性
inputLength?: number // 输入长度(无内容)
}
架构
┌────────────────────────── browser 半部 ──────────────────────────┐
│ tracker.ts 全局埋点采集(document 级监听) │
│ storage.ts 本地环形缓冲 + 设置 + 授权(localStorage) │
│ HeatmapOverlay 热力图 + 统计面板 + 设置 + 上传入口(shell.overlay)│
│ ConsentModal 上传授权弹窗 │
└──────────────────────────────┬───────────────────────────────────┘
│ 授权后 fetch(POST)
┌──────────────────────────────▼────── host 半部 ──────────────────┐
│ /dsh-heatmap/ingest 批量上报(本地收集器) │
│ /dsh-heatmap/export 导出(JSON/NDJSON) │
│ /dsh-heatmap/stats 聚合统计 │
│ /dsh-heatmap/sessions 会话时间线(回放/复现) │
│ /dsh-heatmap/funnel 漏斗分析(有序步骤转化率) │
│ /dsh-heatmap/clear 清空 │
│ analytics_export 工具 stats/export/sessions/funnel/clear/upload │
│ AnalyticsStore NDJSON 落盘 + 内存环形缓冲 + 漏斗/会话聚合 │
└──────────────────────────────────────────────────────────────────┘
数据默认只在本机流动:采集→本地;上传→(授权后)host 收集器或配置的外部地址。
安装
dsh plugin --profile web add ./dsh-heatmap
# 或使用 dsh-master:dsh_master_install 工具
然后重启 dsh(dsh web 或 dsh --profile web)。重启后页面右下角会出现 🔥 按钮,打开面板即可查看统计、开启热力图。
开发
# 在插件目录内
pnpm install
pnpm run build # 构建 lib/client.js(browser 半部)
pnpm run typecheck
配置
host 配置(cordis.yml,部署级默认值)
- id: dsh-heatmap
config:
enabled: true # host 收集器与工具开关
dataDir: '' # 落盘目录;空则 $DSH_HOME/storages/dsh-heatmap
maxEvents: 20000 # 环形缓冲上限
uploadEndpoint: '' # 统一分析平台上传地址(analytics_export upload 目标)
consentRequired: true # 上传是否要求授权(文档化;实际弹窗在 browser 半部)
客户端设置(localStorage,运行时在面板中调整)
| 设置 | 默认 | 说明 |
|---|---|---|
| 热力图模式 | 关 | 开启全屏热力图覆盖层 |
| 采集埋点 | 开 | 总开关 |
| 鼠标热力图 | 关 | 是否采集悬停坐标(开启会增大数据量) |
| 上传需授权 | 开 | 上传前是否弹授权窗 |
| 上传地址 | 空 | 空 = 同源 host 收集器 /dsh-heatmap/ingest |
CLI / 外部访问接口
1. Agent 工具(analytics_export)
在会话中让 Agent 调用:
动作:stats 聚合统计(事件总数/点击/聚焦/曝光/会话数/按类型分布)
动作:export 导出最近 5000 条事件
动作:sessions 会话时间线(最近 20 个会话的有序事件序列,用于回放/复现)
动作:funnel 漏斗分析(需 steps:有序事件类型数组,如 [session_start, click, input])
动作:clear 清空收集器数据
动作:upload 上传到 config.uploadEndpoint(统一分析平台)
2. HTTP 路由
curl http://127.0.0.1:PORT/dsh-heatmap/health
curl http://127.0.0.1:PORT/dsh-heatmap/stats
curl http://127.0.0.1:PORT/dsh-heatmap/export?format=json&limit=100
curl http://127.0.0.1:PORT/dsh-heatmap/sessions?limit=20
curl -X POST http://127.0.0.1:PORT/dsh-heatmap/funnel -H 'content-type: application/json' -d '{"steps":["session_start","click","input"]}'
curl -X POST http://127.0.0.1:PORT/dsh-heatmap/ingest -H 'content-type: application/json' -d '{"v":1,"sessionId":"s","sentAt":0,"events":[...]}'
curl -X DELETE http://127.0.0.1:PORT/dsh-heatmap/clear
端口即 DSH 网页服务的端口(客户端与 host 同源)。
统一分析平台对接
预留了三条对接路径,按需选择:
- Agent 工具
upload:配置uploadEndpoint后,让 Agent 调用analytics_export(action=upload)把收集器数据批量 POST 到平台。 - HTTP 路由:
GET /dsh-heatmap/export拉取原始事件,由你的平台 SDK/脚本转发。 - 示例适配脚本:
examples/push-to-platform.mjs—— 从/export拉取、按mapEvent适配成平台形状、POST 到PLATFORM_ENDPOINT(仅需改这一个适配函数)。
DSH_BASE=http://127.0.0.1:3080 \
PLATFORM_ENDPOINT=https://analytics.example.com/ingest \
PLATFORM_API_KEY=sk-xxx \
node examples/push-to-platform.mjs
隐私与合规
- 采集默认最小化:不采集对话正文、不采集输入内容(仅长度)、不采集 PII。
- 数据默认只在用户本机(localStorage / 本地 NDJSON)。
- 上传动作前弹出授权弹窗,明示「上传什么、上传到哪里、不含对话内容」,用户确认后才发送。
- 可随时「清除本地」或在 host 侧
clear删除收集器数据。
后续演进(预留)
- 可视化会话回放:在面板内把
sessions时间线渲染成逐步重放。 - 曝光时长:为
impression记录进入/离开视口时长(当前只记首次曝光)。 - 性能埋点:
navigation/resource时序。
生成自 DSH-Master(dsh-master)脚手架并扩展。
No comments yet. Be the first to write one.