/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
写了一个插件,Host启动没有报错,设置窗口里却找不到入口。把入口修好以后,按钮能点了,数据又一直是0。升级一次,原来的页面还在,读取数据的方法却开始抛异常。
这些问题表面上都叫“插件不好用”,实际断在不同位置。如果每次都从重新安装开始,往往会把原来的错误盖住,或者在没有问题的层上反复修改。
这篇沿着一个设置页插件,从包声明、Host加载、客户端执行、页面注册,一直看到业务调用、升级和停用。我们要解决的不是“记住几个接口名”,而是弄清楚:一个功能需要经过哪些步骤,每一步成功后能证明什么,失败时下一步该查哪里。
前半部分给出三个完整文件,页面只有一个计数按钮。这个小例子有意不读会话、不写配置,也不请求模型,方便先确认加载链路。后半部分用同一个设置页接入Host的合成数据路由,再分析增加业务功能以后会遇到的边界;投影读取、授权和构建批准采用各自已验证的固定版本对照,不把它们说成这个计数插件已经实现的功能。
本文以@deepseek-ai/dsh@0.2.1-rc.2及对应版本的客户端模块为主。历史接口变化另列具体版本。需要区别包的发布版本、实际加载的文件和浏览器当前执行的代码,这三者不能只看其中一个。

1. “插件加载了”,到底加载了什么
先假设你已经把插件文件放好,启动Harness后也没有报错。此时能不能直接说插件正常?不能,因为这个功能至少经过下面几层。


