@cnbmtech/dsh-zentao-session

中文文档
0.6.9发布于 2026/11/05MITES Module零依赖近 30 天下载 2346

ZenTao (QQ) 基于会话的 DeepSeek Harness 工具和面板: 我的bug, 任务和故事横跨浏览范围, bug 确认/解析, 评论文章和评论编辑, 加上拖到聊天的 Markdown 引用. 与缺少 REST API 的遗留 ZenTao 版本一起工作

中文使用文档
文档目录14 节
  1. 能力
  2. 安装
  3. 登录与配置
  4. 侧栏入口:栏上图标 or「更多」
  5. 安全边界
  6. 排障
  7. 已知限制
  8. 更新日志
  9. 0.6.8 — 2026-11-02
  10. 0.6.6 — 2026-10-30
  11. 历史里程碑(回填,日期为 npm 发布时间)
  12. 开发与自测
  13. 发布与迭代(维护者)
  14. 许可

@cnbmtech/dsh-zentao-session

DeepSeek Harness 的禅道(ZenTao)会话式集成插件:11 个模型工具 + 一个「我的工作」面板(BUG / 任务 / 需求),可把条目一键送进对话。

走禅道的会话式接口(/my-*.json + 表单页),不依赖 REST API v1/v2 —— 因此在那些 api.php 被网关改造、官方 REST 不可用的禅道实例上照样能用。

能力

面板(左侧栏「更多」菜单 → 「禅道」;同一行右边的「侧边栏 + 眼睛」可让它常驻左侧栏,见「侧栏入口」)

  • 三个页签:我的 BUG / 我的任务 / 我的需求,每个页签自带浏览范围下拉(指派给我 / 由我创建 / 由我解决|完成 / 我评审 / 由我关闭 …,与禅道「我的地盘」的 tab 逐一对应)

  • 列表头只留刷新,条数与分页在卡片页脚(整组靠右):页脚从右往左是分页(‹ 当前页 / 总页数 › + 每页 20 / 50 / 100)与条数(共 N 条), 分页只此一处(早期条数写成「7 / 7 条」与页码「1 / 1」并排,会被读成两处分页;后来挤进头部,面板一窄就整组掉行、看着像错位,故下沉到页脚并整体贴右);刷新按当前范围 + 当前页重新取数,不会把第 2 页打回第 1 页; 筛选/搜索激活时刷新改走 query 通道强制重拉(force=1,连行集/计数缓存一起绕过),既保持筛选口径也拿到新数据(2026-10-30 修复:此前刷新会把未过滤口径覆盖回筛选视图)

  • 条数口径统一为服务端总数:无筛选时,页脚条数、页签上的数字、统计卡主卡三处都用服务端返回的总数(recTotal),不再各说各话; 统计卡的子卡(未确认 / 已确认 / 已解决 …)是全范围计数:禅道的「我的」接口不给分状态总数(pager 里只有 recTotal / pageTotal,且任何查询参数都被忽略), 所以由宿主侧把当前范围整批取回后本地按状态 / 确认度聚合(每页 200 条并发拉,最多 40 页),结果带 60 秒缓存,浏览器端只收几十字节; 子卡文案写明「全范围 …」,聚合不全时(超出页数上限或部分页失败)自动退回本页口径并标「本页 …」

  • 列表按所属产品 / 所属项目分组(2026-10-30):列表默认分组展示,组头是一行吸顶的「所属产品:<名称> (N)」(任务页签是「所属项目:<名称> (N)」), 组头本身是纯标签:置灰、不可点,不额外缩进(只留一个空格不贴边),只用来标出下面这组条目属于谁; 同组条目按列表原顺序排在一起;BUG 与需求按产品(对齐禅道 BUG/需求列表的「所属产品」维度),任务按项目(对齐任务列表的「所属项目」列), 无归属或取不到名称的条目归到末尾「未关联产品 / 未关联项目」。BUG 行 JSON 只有 product / project 两个数字 id(实测 56 个字段里没有名称), 宿主借 /product-all.json(实测 30 个产品)、/project-all.json(约 311 个项目)的 id→名称表补 productTitle / projectName (10 分钟缓存;任务行自带项目名时不发这次请求),筛选/搜索通道同样补,所以筛选后组头不会掉成「未关联」; 补名逻辑在宿主侧(Node),改了要重启宿主才生效;若宿主还是旧版(行里只有 product / project 数字 id), 面板会自动拉一次 targets 列表(与新建弹窗同一份)把 id 译成名称再分组,不会整页落到「未关联」; 列表头的「按产品分组 / 按项目分组」按钮可切回平铺列表,偏好记在 localStorage(dsh-zentao-group)。 组头括号里数是当前页该组的条数——禅道一页 20 条,同一产品跨页时每页各出一组,想一屏看全某个产品就把每页条数调到 50 / 100 或直接用筛选

  • 列表行右侧显示处理时长(2026-10-30):每行右上角一个红色「N 天」+ 其下一条细胶囊进度条, 一眼看出这条挂了多久、相对承诺天数消耗到哪了。口径三条: ① 起点取创建时间(openedDate),终点取解决 / 完成时间(BUG 用 resolvedDate、任务用 finishedDate), 没走解决就直接关闭的条目才回落到 closedDate,都为空表示仍在处理、算到今天——所以「关闭」不会把处理时间虚增成验收时间; ② 只比日期不比时刻(0 点对齐),与禅道网页的「N 天」一致,不会把 7 天 20 小时显示成 8 天; ③ 承诺天数优先取该条目的 deadline(创建 → 截止),没人填截止日期时按优先级兜底 P1=3 / P2=7 / P3=15 / P4=30 天 (实测禅道行的 deadline 大量是 0000-00-00,只认它会让进度条永远按 0 算)。 进度条宽度 = 已用 / 承诺,超期时铺满并加深字重;悬停给出「创建 … · 仍在处理/解决 … · 已用 N 天 / 承诺 M 天(来源)」,超期还写明超了几天。 没有创建时间的行不显示这个标识(宁可不显示也不编一个天数)。任务行原本不带创建/完成时间,宿主侧已一并补齐。 布局:左栏(标题 + 元数据)可收缩、右栏固定 78px 靠右;宿主侧栏只给到 ~300px 时按行自身宽度换行到标题下方(不用视口宽度判断,侧栏变窄时视口往往仍然很宽)。 七套皮肤各有一条 --dur 令牌(深色皮肤把红提亮、波普压深一档),轨道统一用半透明色——固定浅灰在选中行的浅蓝底上会整个隐形

  • 筛选/搜索是全量的,不是本页的(2026-10-29):点统计卡筛选、点工具栏状态签、输搜索词(防抖 300ms),当前页签列表走宿主 query 通道—— 宿主复用 counts 聚合时的整范围行集(同一份缓存,零额外请求)按状态/确认度/关键词过滤后本地分页, 页脚与分页器切成筛选集自己的口径(如「已解决」= 共 81 条、1 / 5 页),与统计卡子卡数字天然一致,取消筛选即回到服务端总数; 行集被 40 页上限截断时,状态筛选走排序聚类走查兜底(关闭条目的 assignedTo='closed'、未关闭是真账号,按 assignedTo/status 排序目标簇聚在两端, 每方向最多走 40 页、遇簇边界即停)——此法不适用 confirmed 维度与搜索(无对应排序列),截断场景下它们仍按「本页」口径降级

  • 切换浏览范围,列表与数字一起刷新(2026-10-29 修复):筛选/搜索激活时,列表走 query 通道、统计卡走 counts 通道, 两条通道各自按「kind:范围」取数。此前 query 的 effect 依赖里漏了 scopes,于是选中卡片后再切范围下拉会出现 「统计卡数字变了、列表还是旧范围的行」。现在依赖补齐;同时主卡数字改为优先读 counts.total(与子卡同源), 不再依赖 loadLists 的 state.*Total——筛选态下 loadLists 会跳过当前页签,那个字段本来就不会更新

  • 搜索框可一键清空(2026-10-29):有搜索词时右侧出现 ×,点击或按 Esc 清空并回到第 1 页;清空只清搜索词、不动状态筛选。

  • 写操作后的联动刷新(2026-10-30):确认/解决/加备注后,当前页签的全量计数强制重拉(此前统计卡要等切页签/换范围才更新); 翻页、改范围只重发有变化的页签,未变化的两类不再陪跑重拉;点主卡(本来就没有筛选时)是纯 no-op,不再把页码打回第 1 页; 退出登录会清掉统计卡计数与新建权限探测,换账号不残留上一账号的数字。 输入框外层由 label 改成 div——label 会把内部按钮的点击转发成输入框聚焦,清空按钮会被吞掉

  • 列表行显示真名(2026-10-29):禅道列表行 JSON 只有裸账号(实测 56 个字段无真名),宿主借 view 详情 JSON 内嵌的全量 users 表 (实测约 747 项,变化慢,缓存 10 分钟;详情接口顺手收割刷新)给行内账号附加 *Name 字段,列表指派列与详情相关人字段均显示真名; 关闭态占位账号 closed 按禅道网页写法显示「Closed」

  • HTML 实体统一还原:禅道按 htmlspecialchars 下发(& → &amp;、' → &#039;),标题/名称/产品名/模块路径/相关人真名/备注都解码, 且不限于 &amp;——命名实体(&lt; &gt; &quot; &nbsp; &mdash; &hellip; &times; &copy; …,共 80 余个)、十进制 &#39;、十六进制 &#x1F600; 都认, 只解一层(&amp;amp; 仍是 &amp;)。富文本字段(重现步骤/描述/备注 HTML)保持原样,解码交给渲染层

  • 新建:工具栏「+ 新建BUG / 新建任务 / 新建需求」——弹出禅道自己的创建表单(字段、选项、默认值、联动条件都来自创建页), 先选创建目标(BUG/需求 → 产品;任务 → 项目,下拉可搜索),提交后回读新建对象的详情页确认真的建成,并直接跳到它的详情

  • 没权限就不显示「新建」:切页签时探一次该类型有没有创建权限(禅道没权限也返回 200,只是创建页里没有表单),没有就把按钮换成一行说明(含原因与探测地址),不再点进去撞红条

  • 新建表单按禅道复刻:控件类型(下拉/多选/复选/单选组/日期/文件)、必填标记、帮助说明、隐藏域默认值都照创建页渲染; 同名单选项合并成一组(禅道「添加之后」是 3 个同名 radio —— 旧实现渲染成 3 个文本框,提交值还会后写覆盖前写); 下拉与正文里的 HTML 实体(&lt;p&gt; 等)还原成原文;整行带 class='hide'/'hidden' 的按禅道显隐(有联动条件的交给条件,其余整行隐藏); 核心内容栏是可粘图编辑器——在里面按 Ctrl+V 粘贴截图会先上传到禅道(/file-ajaxPasteImage-<uid>.html,带本次表单令牌 kuid), 再把返回的 <img src="/file-read-N.png"> 插到光标处就地预览(经本机代理,不裸取外域); 「附件」字段支持多选上传(单个 ≤ 8MB,base64 交给宿主后按 multipart/form-data 提交),超过 8MB 会在本地直接拦下; 选择器(下拉)展开是浮层:坐标按锚点实测、下方放不下就向上翻,不占行内位置,所以同一行的其它控件不会被挤走(点外部或 ESC 关闭); 同一行的控件保持一行(与创建页一致):日期范围(日程规划 预计开始 ~ 截止日期)并排等宽、不拆成两行, 第 2..N 个控件(操作系统 / 浏览器 / 严重程度 / 优先级 / 预计工时)跟在主控件后面用行内小标签补名,不另起一行被缩进一个标签列; 标题/名称独占一行(BUG标题、任务名称、需求名称铺满控件列,挤在同一行会把标题压窄、长标题看不全), 它的附加控件(严重程度 / 优先级 / 预计工时)另起一行、与控件列左对齐; 单选组与左侧字段名在同一行、垂直居中

  • 统计卡点击筛选、标题/编号搜索、列表与详情双栏、详情全屏(面板内铺满)(隐藏顶栏/页签/统计卡/搜索工具栏,详情卡贴边铺满面板,右上角刷新 + 退出;ESC 或再点退出)

  • 工具栏右侧「新建 / 角色 / 状态筛选」是一个操作组:同 32px 基线、组内 8px 间距(原来 35/30/35px 高、9-13px 间距,三个控件看着互不相干)

  • 详情里:富文本重现步骤/描述(图片走本机代理并可点击放大、左右切换)、基本信息、处理信息、关联对象、操作历史

  • BUG 可直接在面板里走禅道原生表单:确认 / 解决 / 关闭 / 激活 / 指派(提交前拉取真实表单字段,提交后回读证实)

  • 添加备注(三段式模板:问题原因/解决方案/解决时间),发错了可以直接改:zentao_bug_comment_edit 按 actionId / 内容片段 / 最近一条定位后重写(实测禅道只给条目页最新一条备注渲染编辑表单,改旧备注会报错并告知最新那条的编号)

  • 「解决」模型也能直接做:zentao_bug_resolve 走禅道自己的解决表单(解决方案 / 解决版本 / 解决日期 / 三段式备注),默认解决方案=已解决(solve)、解决版本=主干(trunk),提交后回读 status=resolved 才算成功;只发备注的 zentao_bug_comment 不会改状态

  • 「在禅道中打开」链接附带会话参数,免登录直达

  • 拖拽 / 复制为 Markdown 引用:把条目拖到聊天输入框,或点「复制」后粘贴——引用只有三行:标题行、读全文行(该调哪个工具、截图怎么拿)、免登录原地址

  • 按角色处理:选好职位(开发/测试/产品/管理)→ 点「按【开发】处理」→ 在当前项目新建对话并自动发送「身份开场白 + 条目引用 + 角色任务书」;任务书排在最后(模型读到最后的才是要它做的事),且是纯文本聊天口吻——不用 Markdown 标题/加粗,只有条目引用那两行带「- 」引导符。开发那套是四步处理流程:查沉淀(只说「用这条记录的标题自己提炼业务词」,不写死任何示例)→ 给分析 → 我确认后再改码 → 回写;末步文案按条目类型替换(BUG 先给 zentao_bug_resolve:三段式写进 comment、默认 solution=solve(已解决)/ build=trunk(主干),提交后回读确认已解决;只补备注才用 zentao_bug_comment,并提醒「发错了不用补发更正,用 zentao_bug_comment_edit 改那条」;任务/需求没有回写通道,直接说明「文案交我,我在禅道里填」)

  • 提示词不回抄详情:禅道详情页里能看到的东西(状态、优先级、正文、步骤、截图清单、信息缺口)一概不复制进对话——写进上下文只会又碎又容易失真;提示词只给 【禅道BUG #201030】标题、- 读全文:zentao_bug_view({ id: '201030' });截图按详情链接自行取回(带 zentaosid),取不到就明说,不要脑补;不要凭标题猜内容。、- 禅道原地址:https://…/bug-view-201030.html?zentaosid=… 这几行

  • 截图靠模型自己取,取不到就明说:条目里的图地址都带会话票据(?zentaosid=…,实测不带 cookie 也能取),「读全文」那行已写明截图要自行取回、取不到就明说别脑补;工具回包里的 <img src> 同样改写成绝对地址,模型直接复制就能取回来看

  • 七套皮肤随时切换:顶栏右侧的下拉选 原生(跟随宿主明暗)/ 极光 / 波普 / 棱彩 / 青海波 / 记分牌 / 碳纤红。 切换即时生效并记在 localStorage 的 dsh-zentao-theme,刷新后保持;七套皮肤共用同一套 DOM,只有配色与少量外观修饰不同, 所以分页唯一、页脚末位、浮层 portal 等结构行为在所有皮肤下完全一致。 各皮肤的浮层(选择器菜单、图片画廊)也跟随皮肤,不会掉回原生配色。

    皮肤明暗主色记忆点
    原生跟随宿主禅道蓝与宿主浑然一体
    极光暗蓝紫渐变流体光斑 + 玻璃卡
    波普浅红黄蓝三原色波点底 + 粗描边 + 硬阴影
    棱彩暗紫/天蓝/青柠马赛克彩窗虚化 + 磨砂卡
    青海波浅藍染靛 + 朱印红青海波纹样 + 明朝体标题
    记分牌暗荧光绿 + 琥珀数码管数字 + 等宽字
    碳纤红暗碳灰 + 赛车红碳纤编织纹 + 切角按钮

    实现方式是「根节点挂 zts-theme-<id>,只换 CSS 令牌 + 少量外观修饰」,新增一套皮肤只需加一条 SKINS 项和一段令牌定义。 注意两条硬约束:同一个颜色变量不能同时当「前景文字色」和「按钮底色」(例:碳纤红的 --blue 是暗底上的红字、--btn-primary 是托白字的深红); 浮层挂在 body 上,皮肤 class 必须一起带过去,否则下拉菜单会掉回原生配色。

  • 面板动效可关(2026-11-02):顶栏的动效开关默认开,关掉只是根节点摘掉 .zts-motion,DOM 结构与布局完全不变; 开着时换皮肤走 260ms 颜色交叉渐变,极光 / 棱彩的氛围光跟同一个开关,偏好记在 localStorage 的 dsh-zentao-motion。 系统的「减少动态效果」不再单独压掉面板动画——默认开是选定的默认,想静止就关顶栏这个开关

模型工具

工具用途
zentao_ping连通性与凭据自检
zentao_my_bugs / zentao_my_tasks / zentao_my_stories三类条目列表,type 指定浏览范围
zentao_bug_view / zentao_story_view / zentao_task_view单条完整详情(正文、截图地址、相关人、操作历史)
zentao_bug_confirm确认 BUG(只置「已确认」,状态仍是激活)
zentao_bug_resolve解决 BUG:提交禅道解决表单(解决方案 / 解决版本 / 解决日期 / 三段式备注),默认 solve(已解决)/ trunk(主干),提交后回读确认 status=resolved(写操作)
zentao_bug_comment追加备注(只加备注,不改状态)
zentao_bug_comment_edit修改已发出的备注(写操作;只能改最新一条,见「已知限制」)
zentao_plugin_status注册诊断(取数失败时排障用)

插件还会注册一段系统提示,告诉模型这些工具何时用、未登录该怎么办。

⚠️ 「解决」和「备注」是两条不同的写入路径:禅道里只发备注不会把 BUG 变成「已解决」。要「回复三段式并把 BUG 解决」,必须用 zentao_bug_resolve(comment 放三段式文案,resolution 默认 solve、resolvedBuild 默认 trunk),它会回读 status 证实;zentao_bug_comment 只用于补备注。

安装

前置:DeepSeek Harness 0.1.0-rc.2 ~ 0.2.x(已在 0.2.0-rc.2、0.2.1-rc.1、0.2.1-rc.2 上实机验证;0.2.1-rc.3 上已验证工具调用与槽位注册;0.2.1-rc.5 上已验证 12 个工具注册、系统提示/HTTP 路由/凭据三个槽位、面板取数与禅道真实连通,并逐项比对过 @deepseek-ai/dsh-tools 的导出面(0.2.0-rc.2 → 0.2.1-rc.5 无增删、defineTool 行为未变))、Node ^22.19 || >=24。

ℹ️ 版本声明:package.json 的 engines.dsh 写的是 >=0.1.0-rc.2 <0.3.0。DSH 0.2.1 起,第三方插件的兼容性优先按 engines.dsh 判断(未声明时才回落到旧的 peer 规则),声明不覆盖当前宿主就会被跳过并给出告警。宿主升到 0.3.x 时记得同步放宽这个区间。

方式一:DSH 桌面端插件管理器(推荐)

设置 → 插件 → 「添加插件」,输入三者之一:

  • 包名:@cnbmtech/dsh-zentao-session(npm 或公司私服)
  • Git 仓库地址:内网 Git / GitHub 地址
  • 本地目录路径:例如 D:\dsh-plugins\dsh-zentao-session

⚠️ 选「本地目录」时务必先在该目录里执行过一次 npm install。包管理器只做目录链接,不会替你安装被链接包自己的依赖;目录里没有 node_modules 时插件会因为找不到 @deepseek-ai/dsh-tools 而起不来。

宿主自带的 @deepseek-ai/* 按生态惯例只声明在 peerDependencies(本地开发用 devDependencies 装进插件自己的目录)——不写成 dependencies:那样会把钉死的版本塞进 DSH 的共享依赖树、与宿主自己的版本互相干扰(插件清单会告警)。从包名安装时这些包由 DSH 提供,无需额外处理。

方式二:CLI

# 包名
dsh plugin --profile web add @cnbmtech/dsh-zentao-session
# 本地目录(同样记得先 npm install)
dsh plugin --profile web add D:\dsh-plugins\dsh-zentao-session

安装后完全重启 DSH(客户端 bundle 只在启动时加载,关开插件不会刷新)。

ℹ️ 装到旧版本了?(pnpm 11.7 实测)

  • pnpm 默认带 minimumReleaseAge(24 小时供应链策略),但显式指定版本安装时它会自动把该版本写进 pnpm-workspace.yaml 的 minimumReleaseAgeExclude,无需手动放行。

  • 刚发布几分钟内,不带版本号(或 @latest)可能因 pnpm 的 registry 元数据缓存而拿到上一个版本。想要立刻拿到新版就把版本号写全:

    dsh plugin --profile web add '@cnbmtech/[email protected]'
    

    插件管理器里同理,填 @cnbmtech/[email protected];或者等几分钟缓存过期后重装。

  • 只有 profile 设了 minimumReleaseAgeStrict: true(策略变成"必须人工确认")时,才需要手动加 minimumReleaseAgeExclude 条目。

登录与配置

打开侧边栏「禅道」面板,填禅道地址 / 账号 / 密码,点「登录并保存」——凭据写入 DSH 凭据库 ~/.dsh/.credentials.yaml(refs:ZENTAO_BASE_URL / ZENTAO_ACCOUNT / ZENTAO_PASSWORD),之后免登录,且可随时「退出登录」清除密码。

也可以在 profile 的 cordis.patch.yml 里配置 id: zentao-session 的 config(优先级:config > 凭证库 > 环境变量):

字段默认说明
baseUrl空禅道地址(不含末尾 /);为空时读凭据 ZENTAO_BASE_URL
account / password空同上,建议放凭据库,不要写进配置文件
timeoutMs30000单次请求超时
defaultLimit20列表工具默认返回条数

未配置地址时插件不休眠:照常注册工具与路由,只在你真正取数时提示"请先在面板登录"。

侧栏入口:栏上图标 or「更多」

图标默认显示在左侧栏(低版本 DSH 没有「更多」按钮,菜单默认会让面板无门——默认上栏是向下兼容的一部分);高版本 DSH 里点「更多」→ 点那一行的 「禅道」 也能开面板。

「更多」里禅道只占一行:左边「禅道」(点开面板),右边同一行是「侧边栏」三个字 + 一颗眼睛,控制这个入口要不要常驻左侧栏—— 睁眼=图标在左侧栏上,划掉=收在「更多」里(悬停有提示;写「侧边栏」是为了说清眼睛动的是哪儿)。

  • 点这个开关当刻生效(不用重启,也不用重载插件):放出 = 立刻补注册侧栏条目,收起 = 注销那条注册(同时把宿主的入口 pin 一并置为未固定,双保险)
  • 那一行是插件自绘的,不 require 宿主的 client 包——宿主文档明确不要加载 @deepseek-ai/dsh-client-ui-primitives 一类的内部包,组件抛错会让整条槽位条目白屏
  • 那一行全部用内联样式(颜色只取宿主 --dsw-alias-* 令牌并带 fallback):菜单挂在宿主浮层里,插件样式表在这个位置实测不生效,用类名会退化成浏览器默认按钮
  • 选择记在浏览器 localStorage 的 dsh-zentao-sidebar-entry(rail = 栏上常驻,more = 收进「更多」,默认即 rail,2026-11-05 起),换浏览器 / 清缓存后回到默认;低版本 DSH 没有「更多」按钮,图标强制显示在栏上(此时开关不存在)
  • 收起后**「更多」里那行「禅道」一定还在**——宿主的「更多」本身不列面板条目(官方入口定制只把面板条目渲染给会话视图与右栏),这一行是收进去之后唯一的入口
  • 客户端插件拿不到宿主 YAML 里的 config(客户端 apply 的第二个参数在运行时是 undefined),所以这项偏好不走 cordis.patch.yml

图标用的是禅道官方 logo(官网上那颗蓝色漩涡标,60×60 透明 PNG,从 zentao.net 页头的 logo 图里裁出来;官方没提供矢量版),以 data URI 内联进 client.js,所以插件不额外带资源文件。换浏览器主题时它跟官方一致、不跟着文字变色。禅道与 ZENTAO 是禅道软件的商标,这里仅用于标识本插件连接的是禅道。

安全边界

  • 面板数据接口 /api/dsh-zentao-session/*:所有 action(含读)都要求自定义请求头 x-dsh-zentao-session: 1,且 Host 必须是回环字面量(防 DNS rebinding)
  • 截图代理 /api/dsh-zentao-session-file?path=…:只放行禅道 /file-(read|download)-数字 路径,只回位图/PDF(排除 SVG,避免同源脚本执行面),单文件 8 MB 上限;请求带 Sec-Fetch-Site 且不是 same-origin/none 的一律 403(跨站 <img> 借宿主会话探测附件的路子封掉,老内核不发该头则保持放行)
  • 表单写入:令牌 kuid 取不到就硬失败,绝不带空令牌出网;非幂等 POST 从不自动重试(避免重复备注——该版本禅道没有删除备注的入口,只能再编辑一次)
  • 贴图与附件写入同样受上一条约束:粘贴图上传(/file-ajaxPasteImage-<uid>.html)与带附件的创建提交都要求令牌,请求体上限 32MB,非幂等且不重试
  • posted: true 只代表"禅道没报错";确认/追加备注/改备注都会回读证实后才报成功
  • 仓库内不含任何禅道地址、账号或密码

排障

现象处理
面板空白 / 页签缺失客户端 bundle 没重新加载 → 完全重启 DSH(不是关开插件),再刷新页面
左侧栏找不到禅道图标默认就在左侧栏;若之前用「更多」里的开关收起过:点左侧栏的「更多」→ 点同一行的眼睛放出。低版本 DSH(没有「更多」按钮)图标强制在栏上
工具报「请在面板登录」打开侧边栏「禅道」面板登录一次
取数失败让模型调用 zentao_plugin_status,它会打出路由/RPC 注册结果与真实错误
列表比预期少禅道「我的地盘」一页只回 20 条;面板会标注"服务端共 N 条",用范围/筛选收窄,或让模型用工具的 limit
启动日志出现 skipping profile bundle "@cnbmtech/dsh-zentao-session"(面板/工具全都不在)宿主判定版本不兼容:engines.dsh 没覆盖当前 DSH 版本。升级插件到覆盖该版本的发行;确知无碍时可用 dsh plugin allow-version 或插件管理器加"精确版本豁免",再重启

已知限制

  • 创建权限按目标探测:探前 3 个产品/项目(第一个有创建页表单即视为可创建),不逐个探完;权限都在别的目标上时会误显示成"没有创建权限"

  • 新建写的是真实禅道:提交即创建(不可撤销,请在禅道里核对或删除);附件走禅道自己的 files[] 字段,扩展名/大小最终仍由禅道侧规则决定(被拒时弹窗里会显示禅道原话)

  • 创建表单的联动是服务端初始态:切换产品/项目会重新拉取该目标的表单;页面内 JS 联动(如「新建版本」勾选后展开的子字段)以禅道渲染结果为准

  • 目录/链接安装时依赖需自备(见上)

  • 列表按禅道分页(服务端一页 20 条);面板列表页脚可翻页、可改每页条数(20 / 50 / 100,页码与总页数取自服务端 pager),模型工具默认取一页再按 limit 截断

  • 分组是「当前页内」的(同一条限制的延伸):组头括号里是本页该组的条数,不是该产品/项目的全量条数;同一产品跨页时会在每页各出一个组头。要按产品整体看,用筛选/搜索,或把每页条数调到 50 / 100

  • 需求的详情接口不返回产品名(只有产品 id),面板会回落到列表行;列表能拿到就没问题

  • 表单操作只覆盖 BUG(确认/解决/关闭/激活/指派);任务与需求为只读 + 复制/拖拽/送对话

  • 需要禅道账号本身有对应权限;插件不做越权尝试

更新日志

从 0.6.6 起,每个发布版本都在这里写清「这个版本改了什么」(发版前先写,再 npm publish)。更早的版本当时没留说明,只回填了能核实的里程碑。

0.6.8 — 2026-11-02

新功能:列表按「所属产品 / 所属项目」分组、行内显示处理时长,另加面板动效开关(0.6.7 未单独发布,分组一并合入本版)。

  • 列表分组:组头吸顶一行「所属产品:<名称> (N)」(任务页签为「所属项目:<名称> (N)」),置灰不可点、一个前导不换行空格让它不贴边;BUG 与需求按所属产品、任务按所属项目,无归属的归到末尾「未关联产品 / 未关联项目」
  • 列表头「按产品分组 / 按项目分组」开关可切回平铺列表,偏好记在 localStorage(dsh-zentao-group);分组作用在当前页的行上,组头括号里是本页该组的条数
  • BUG 行补产品名:BUG 列表 JSON 只有 product / project 数字 id(实测 56 个字段没有名称),宿主借 /product-all.json、/project-all.json 的 id→名称表补 productTitle / projectName(10 分钟缓存;任务行自带名称时不发这次请求),筛选/搜索通道同样补;旧版宿主下由面板自己拉 targets 译名兜底
  • 行内处理时长:右上红色「N 天」+ 其下细进度条,天数 = 创建 → 解决/完成(没走解决直接关闭的回落到关闭时间,未结束的算到今天,只比日期);承诺天数优先取 deadline,没填按 P1=3 / P2=7 / P3=15 / P4=30 兜底;超期铺满并加深字重,悬停写明创建/结束时间、承诺天数来源与超期天数;没有创建时间的行不显示这个标识
  • 宿主侧补齐行字段:BUG 行补 assignedDate / resolvedDate / closedDate / deadline,任务行补 openedDate / assignedDate / realStarted / finishedDate / closedDate(此前任务行连创建时间都没有,无从算时长)
  • 面板动效开关(顶栏,默认开,记在 dsh-zentao-motion):关掉只是根节点摘掉 .zts-motion,DOM 结构与布局不变;开着时换皮肤走 260ms 颜色交叉渐变,极光 / 棱彩的氛围光跟同一个开关
  • 样式热更新:面板是在同一个页面里反复开关的,旧实现只在 apply() 里注入一次 <style>,插件更新后样式会冻在旧版本;现在挂载时比对内容并原地替换,关掉再打开面板即可吃到新样式
  • 行为变更:详情全屏改为面板内铺满,不再调用浏览器 Fullscreen API(ESC 仍可退出);顺手修正碳纤红分组开关按下态对比度(4.35 → 5.1)
  • 测试:新增 node test-grouping.mjs(宿主补名缓存与零额外请求、分组开关、样式热更新、旧宿主兜底),node test-client.mjs 增加处理时长用例

0.6.6 — 2026-10-30

**兼容性发布:适配 DeepSeek Harness 0.2.1-rc.5,插件代码零改动。**同时把此前一直没发到 npm 的 0.6.5 内容一并带上(0.6.4 之后安装的用户会一次拿到)。

兼容性复核(全部实测通过):

  • engines.dsh 声明 >=0.1.0-rc.2 <0.3.0 本身就覆盖新宿主,不会被启动时跳过
  • 12 个工具注册、系统提示、HTTP 前缀路由(面板取数)、凭据库三个槽位、禅道真实连通全部正常;唯一 [FAIL] 的 rpc.register-failed :: cannot get property "webServer" without inject 是长期已知项,面板走 HTTP 路由不受影响
  • 逐项比对 @deepseek-ai/dsh-tools 导出面:0.2.0-rc.2 → 0.2.1-rc.5 无增删(23 个),defineTool 行为未变;宿主本版唯一的改动只影响 PTC 嵌套调用的 presentationMeta,本插件不使用

随包内容(原 0.6.5,此前未发布):

  • 七套面板皮肤:原生(跟随宿主明暗)/ 极光 / 波普 / 棱彩 / 青海波 / 记分牌 / 碳纤红,切换即时生效并记忆在 localStorage
  • 「按角色处理」:开发 / 测试 / 产品 / 管理四套任务书,一键在项目里新建对话并发送「身份开场白 + 条目引用 + 任务书」(开发那套是四步流程,含 zentao_bug_resolve 三段式回写)
  • 详情全屏:贴边铺满,退出后列表/筛选/滚动位置复原
  • 工具栏操作组:新建 / 角色 / 状态筛选同 32px 基线、组内 8px 间距
  • 搜索与筛选口径统一:筛选态走 query 通道,页脚分页、页签计数、统计卡与主卡口径一致
  • 面板不再定时自动刷新(0.6.4 的「自动刷新」下拉已移除),改为操作后与手动刷新

本地开发:

  • devDependencies 对齐宿主:@deepseek-ai/dsh-tools 0.2.1-rc.5、@deepseek-ai/schemastery 3.18.5(只影响目录 / link: 安装的本地开发,npm 使用者用宿主自带那份)

历史里程碑(回填,日期为 npm 发布时间)

版本日期内容
0.2.02026-10-15首发:9 个工具(我的 BUG / 任务 / 需求、BUG 与需求详情、BUG 确认 / 备注、注册诊断)+ 侧栏面板(页签切换、拖拽与复制、送对话、详情全屏、图片画廊、搜索)
0.3.02026-10-15面板加「新建」表单与列表分页(页码/每页条数取自服务端 pager)
0.4.12026-10-17新增 zentao_task_view、zentao_bug_comment_edit(工具 9 → 11);新建表单支持富文本贴图与附件
0.5.12026-10-19新增 zentao_bug_resolve(工具 11 → 12):三段式备注 + 解决表单一次提交并回读状态
0.6.42026-10-26侧栏入口收进左侧栏「更多」菜单(同行开关可切回栏上)
0.6.62026-10-30适配 DSH 0.2.1-rc.5,并补发 0.6.5 的面板内容(见上)
0.6.82026-11-02列表按所属产品 / 所属项目分组、行内处理时长、面板动效开关(0.6.7 未单独发布,已合入本版)

同一阶段内的补丁版本(0.2.1–0.2.3、0.3.1–0.3.5、0.4.2、0.5.3–0.5.6)当时没留说明,只保留了包本身,不再逐条回填。

开发与自测

npm install
node test-client.mjs          # 面板全链路(最小 React hooks 模拟宿主)
node test-tools.mjs           # 11 个工具的渲染 + lossless JSON
node test-form-encoding.mjs   # 写路径铁律(多选重复键 / 302 不重发 / 缺 kuid 不出网)
node test-real-render.mjs     # 真实 React SSR 首跳
node test-real-browser.mjs    # jsdom + 真实 React 全交互链
node test-sidebar-entry.mjs   # 侧栏入口:默认上栏(低版本兼容)、开关收放当刻生效 + 低版本回退
node test-skins-and-fixes.mjs # 六套换色皮肤(+ 原生 = 七项)+ 切范围同步刷新 + 搜索清空
node test-grouping.mjs        # 列表分组:宿主补产品名/项目名(缓存/零多余请求)+ 面板按产品/项目分组与开关
node test-client.mjs          # 同一份里含「列表行处理时长」用例:8 天/15 天=53%、超期铺满、无日期不渲染

面板皮肤(全部七套)另有一套像素级验收脚本,放在仓库工作区的 ui-mocks/ 下 (SKINS=popart,ukiyo node panel-shot.mjs 可只跑指定皮肤,不传则全跑): panel-harness.html(浏览器内加载真实 client.js + 真实 React 18 + 真实禅道数据)、 panel-shot.mjs(无头 Chrome 出图 + 真实像素对比度 + 布局体检)、 panel-clip-probe.mjs(窄栏裁剪/滚动可达性定点探针)、 panel-verify-3fix.mjs(顶栏/工具栏/页签/统计卡口径的行为断言)、 verify-interactive.mjs(真浏览器:CDP 真实鼠标点搜索清空 ×、Esc 清空、切范围后 query/counts 都带新范围且主卡/子卡/页脚口径一致、皮肤切换即时生效与记忆、× 在 7 套皮肤下常规态与悬停态的对比度)、 verify-fullscreen.mjs(真浏览器 × 7 套皮肤:全屏后顶栏/页签/统计卡/工具栏必须全部消失、详情卡贴边铺满 1440×950、有退出入口、退出后四层复原;以及工具栏四控件 32px 同基线/圆角/组内 8px 间距)。

目录结构:index.js(宿主:工具 + HTTP/RPC 路由 + 系统提示)、src/client.js(宿主侧禅道客户端:登录/列表/详情/表单)、client.js(浏览器面板 bundle)、cordis.patch.yml(bundle 安装层)。

发布与迭代(维护者)

# 0. 先在 README「更新日志」最上面写这次改了什么(下面的模板),再发版
npm login                                   # 首次:需要 npm 账号,且对 @cnbmtech 组织有发布权
npm version patch                           # 0.2.0 → 0.2.1(或 minor/major)
npm publish --registry=https://registry.npmjs.org   # 本机默认 registry 是 npmmirror 镜像,发不上去
npm view @cnbmtech/dsh-zentao-session version --registry=https://registry.npmjs.org   # 确认 latest 已更新(大约 1 分钟)

更新日志模板(README.md 的「更新日志」节,新版本写在最上面):

### <版本> — <YYYY-MM-DD>

**<一句话:这个版本为什么发(兼容性 / 新功能 / 修复)>**

- <用户能感知的变化,一条一句;兼容性发布要写清核对过什么、有没有改代码>
- <已知问题 / 行为变更(比如移除了哪个开关)也要写,别只说新增>
  • 首次发布前需要在 npm 上创建组织 cnbmtech(免费组织只能发公开包),或用公司私有源: npm publish --registry https://私服地址(并让同事的插件管理器指向该源)。
  • 本机开发不必发布:profile 里以 link: 指向源码目录,改完代码重启 DSH 即生效;只有同事需要走 npm。
  • 同事升级:插件管理器里重新添加同名包(或 dsh plugin --profile web update @cnbmtech/dsh-zentao-session),再完全重启 DSH。
  • 发布物只含 10 个文件(package.json 的 files 白名单),不含 node_modules、测试脚本与任何凭据——发布前可用 npm pack --dry-run 复核。

许可

MIT

版本与发布记录

@cnbmtech/dsh-zentao-session 共发布 22 个版本,首次发布于 2026/10/15;过去 12 个月发布了 22 个版本。

版本发布日期距今
0.6.9latest2026/11/055 天前
0.6.82026/11/028 天前
0.6.62026/10/3010 天前
0.6.42026/10/2614 天前
0.5.62026/10/2020 天前
0.5.52026/10/2020 天前

关于 @cnbmtech/dsh-zentao-session 的常见问题

@cnbmtech/dsh-zentao-session 是什么?

ZenTao (QQ) 基于会话的 DeepSeek Harness 工具和面板: 我的bug, 任务和故事横跨浏览范围, bug 确认/解析, 评论文章和评论编辑, 加上拖到聊天的 Markdown 引用. 与缺少 REST API 的遗留 ZenTao 版本一起工作

如何安装 @cnbmtech/dsh-zentao-session?

在项目目录运行 npm install @cnbmtech/dsh-zentao-session,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.2.0)、@deepseek-ai/cordis(>=4.0.0)、@deepseek-ai/dsh-tools(>=0.1.0-rc.2 <0.3.0)、@deepseek-ai/schemastery(>=3.18.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cnbmtech/dsh-zentao-session 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/cnbmtech__dsh-zentao-session 是否存在。

@cnbmtech/dsh-zentao-session 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cnbmtech/dsh-zentao-session 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.19.0 || >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cnbmtech/dsh-zentao-session 可以商用吗?

@cnbmtech/dsh-zentao-session 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cnbmtech/dsh-zentao-session 的下载量有多少?

根据 npm 官方下载统计,@cnbmtech/dsh-zentao-session 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,346 次,日均约 78 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cnbmtech/dsh-zentao-session 还在维护吗?

最新版本 0.6.9 发布于 2026/11/05(5 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/10/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。