npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-tool-excalidraw

v0.2.0

Published

Model-facing Excalidraw tools for DeepSeek Harness: create whiteboards, add shapes/text/arrows/lines, update or remove elements, and export SVG or JSON.

Readme

dsh-tool-excalidraw

让 DeepSeek Harness 的 agent 通过工具调用创建和编辑 Excalidraw 白板:

  • 新建 .excalidraw 白板文件(Excalidraw v2 JSON,可直接在 excalidraw.com 打开继续编辑)
  • 添加图形元素:矩形 / 椭圆 / 菱形 / 文本 / 箭头 / 直线 / 手绘笔迹
  • 按 id 更新或删除元素(移动、缩放、改文字、改颜色与手绘样式)
  • 导出为独立 SVG(roughjs 手绘渲染,浏览器可直接查看)或 JSON

渲染使用 roughjs —— 与 Excalidraw 相同的手绘渲染引擎,在纯 Node 中运行(jsdom 提供 SVG DOM),无需浏览器。

工具一览

| 工具 | 作用 | |---|---| | excalidraw_create | 新建白板文件(可带初始元素与画布尺寸) | | excalidraw_add_elements | 追加元素,返回新元素的 id | | excalidraw_update_elements | 按 id 更新元素(移动 / 缩放 / 改文字 / 改颜色 / isDeleted: true 删除) | | excalidraw_group | 按名称组合元素(同组元素在编辑器中联动,成员自动重排为连续) | | excalidraw_organize | 智能层级组织:按几何包含自动建立父子/多层组合,检测同层重叠,可选自动避让 | | excalidraw_get | 列出元素(includeFull: true 时返回完整记录) | | excalidraw_export | 导出 SVG(手绘渲染)或 JSON |

元素参数

{
  "type": "rectangle",        // rectangle | ellipse | diamond | text | arrow | line | freedraw
  "x": 10, "y": 20,           // 左上角坐标(像素)
  "width": 200, "height": 100,// 尺寸(rectangle/ellipse/diamond 必填;text 传 width 时自动换行到框内)
  "text": "Hello\nWorld",     // text 类型必填,\n 换行
  "points": [[0, 0], [120, 40]], // line/arrow/freedraw 的相对顶点
  "strokeColor": "#1971c2",   // 描边颜色
  "backgroundColor": "#a5d8ff",// 填充颜色(transparent 不填充)
  "fillStyle": "solid",       // solid | hachure | cross-hatch | zigzag | dotted
  "strokeStyle": "solid",     // solid | dashed | dotted
  "strokeWidth": 1,
  "roughness": 1,             // 手绘粗糙度 0–2
  "fontSize": 20,             // text 字号
  "group": "row-1"            // 可选:分组名,同名元素在编辑器里一起移动(如框与其内文字)
}

分组与防重叠

  • 组合:给视觉关联的元素(一个框和它的文字、标题和它的框)传同一个 group 名即可; 插件为每个名字生成确定性的组 id,之后 add 同名元素会自动并入同一组。 对已有元素用 excalidraw_group { file, groups: [{ name, elements: [ids] }] } 事后组合, 工具会自动把同组成员重排为连续(Excalidraw 要求)。
  • 智能层级组织excalidraw_organize { file, group?, resolveOverlaps?, minGap? } 从几何关系自动推断结构——
    • 层级组合group: true,默认):构建包含树,每个容器(矩形/椭圆/菱形)自动成为一组,包住 其内部文字与嵌套框;嵌套框的组再包进外层框的组(groupIds 从内到外),形成父子孙多层, 每层的同层元素各自成组。移动外层框,整棵树跟随;移动内层框,只有它和它的内容跟随。
    • 同层重叠检测:始终返回同一层元素(兄弟/顶层)之间互相覆盖的清单(overlapPairs); 父子包含不算重叠。文本元素因宽度估算偏大而超出容器也会被发现(文本的 width 现在始终取 实际估算宽度,仅用于自动换行,不再撑大包围盒)。
    • 自动避让resolveOverlaps: true):把重叠的兄弟元素沿最小重叠轴推开,留 minGap(默认 20px) 间距,移动元素时其整棵子树(内部文字/嵌套框)一起平移。
  • 防重叠:文本元素传 width(所在容器的内宽)会自动按宽度换行,不再溢出/遮挡; 宽度估算按字符分档(CJK 全宽、拉丁/数字/空格各自近似),比等宽估算更接近真实渲染。

安装

插件是一个标准 DSH 组合包(bundle),用 dsh plugin 装进你的 profile:

dsh plugin --profile web add ./excalidraw-plugin

dsh plugin 会把本目录链接进 profile、安装 roughjs / jsdom 依赖,并把插件行追加进 dsh.profile.bundles。之后重启 dsh(GUI 需刷新页面),agent 即可调用 excalidraw_* 工具。

从 GitHub 安装

插件是 TypeScript 实现,从 GitHub 安装时 pnpm 会运行 prepare 脚本构建 lib/ 产物,因此首次安装需要为构建授权(pnpm ≥10 默认拒绝运行 git 依赖的 prepare 脚本):

dsh plugin --profile web add github:<你的用户名>/dsh-tool-excalidraw
# 首次 add 会失败并打印所需包键,把它加进 profile 的 pnpm-workspace.yaml:
#   allowBuilds:
#     dsh-tool-excalidraw: true
# 然后重新 add

也可以手动接入:把构建产物(lib/)放到任何可 import 的位置,并在 profile 的 cordis.patch.ymlinsert 一行 { id: excalidraw, name: 'dsh-tool-excalidraw' }(与 deepseek-harness-zh-cn 相同的方式)。

@deepseek-ai/dsh-tools 是 optional peer:pnpm 会自动安装(registry 的 0.1.0-rc.x), 或复用 DSH host 的(Node 模块解析向上找到 ~/.dsh/profiles/node_modules),版本兼容 >=0.1.0-rc.5 <0.2.0

使用示例

  1. 创建excalidraw_create { file: "/tmp/arch.excalidraw", elements: [...] }
  2. 追加excalidraw_add_elements { file: "/tmp/arch.excalidraw", elements: [{ type: "arrow", x: 210, y: 60, points: [[0,0],[90,10]] }] }
  3. 查看excalidraw_get { file: "/tmp/arch.excalidraw" }
  4. 导出excalidraw_export { file: "/tmp/arch.excalidraw", format: "svg" } → 得到 /tmp/arch.svg

examples/ 目录有一个完整的示例白板(excalidraw-demo.excalidraw + 渲染好的 excalidraw-demo.svg / .png)。

开发

项目由 pnpm 管理,源码为 TypeScriptsrc/),构建产物输出到 lib/

pnpm install      # 安装依赖(含 typescript、@types/*;optional peer 的 dsh-tools 会自动装上)
pnpm build        # tsc 编译 src/ → lib/(js + d.ts)
pnpm test         # 构建 + 两套测试
  • test/smoke.mjs —— 数据层 + SVG 渲染冒烟测试(无需 dsh 运行时)
  • test/tools.spec.mjs —— 工具层测试(5 个工具全生命周期 + schema 校验),import 构建产物 lib/

工具层测试直接 import 构建产物(lib/),pnpm test 已包含构建步骤。 roughjs 的类型由 src/types/roughjs.d.ts 提供(其自带声明在 NodeNext 下与 CJS 包不匹配)。

限制

  • 导出格式为 SVG(浏览器可直接查看);PNG 导出可用 sharp/rsvg 等工具二次转换
  • 文本宽度按字符估算(无 DOM 测量),与 Excalidraw 的精确排版可能有细微差异
  • 不处理图片(image)与嵌入文件元素