Skills Plugins MCP Prompt Model 导航 博客 资讯 我的中心
工具与能力 #deepseek-harness#deepseek-harness-plugin#deepseek-harness-plugins#deepseek-harness-skills#dsh-plugin#dsh-plugins

dsh-mathmatic-symbol

Three tools for DeepSeek Harness: typeset LaTeX formulas into images, draw mathematical figures from a declarative spec, and convert a formula or SVG into an image ready to embed in a document.

jaxzhou @jaxzhou ⬇ 2 ★ 0 main

安装

dsh plugin --profile web add github:jaxzhou/dsh-mathmatic-symbol
下载安装清单

需要可复现安装时,可在仓库后追加 #commit 固定提交。

Three tools for DeepSeek Harness: typeset LaTeX formulas into images, draw mathematical figures from a declarative spec, and convert a formula or SVG into an image ready to embed in a document.

该插件未提供要点说明,请参考仓库 README。

deepseek-harnessdeepseek-harness-plugindeepseek-harness-pluginsdeepseek-harness-skillsdsh-plugindsh-plugins
  1. 安装并启动 DeepSeek Harness:npx @deepseek-ai/dsh web
  2. 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
  3. 用 dsh plugins list 确认已安装,必要时重启 Harness 生效

插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。

代码仓库github.com/jaxzhou/dsh-mathmatic-symbol
许可证MIT
主要语言main
下载量2
GitHub 星标0
最近推送2026-09-12
收录日期2026-09-19
分类工具与能力

事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。

以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。

# dsh-mathmatic-symbol

[![npm](https://img.shields.io/npm/v/@jaxzhou/dsh-mathmatic-symbol.svg)](https://www.npmjs.com/package/@jaxzhou/dsh-mathmatic-symbol)
[![license](https://img.shields.io/npm/l/@jaxzhou/dsh-mathmatic-symbol.svg)](LICENSE)

English | [中文](README.zh.md)

> The npm package name is **`@jaxzhou/dsh-mathmatic-symbol`**.

A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that
gives the agent three tools: **typeset LaTeX into an image**, **draw a
mathematical figure from a declarative spec**, and **convert a formula or SVG
into an image ready to drop into a document**. Every artifact is a
**font-free SVG** — each glyph is an outline `` — plus an optional **PNG**,
returned together with Markdown / HTML / LaTeX snippets.

```sh
dsh plugin --profile web add @jaxzhou/dsh-mathmatic-symbol
dsh --profile web
```

![Sine and cosine on the unit circle: gridded axes, a radius arrow, dashed
projections, a theta arc, and a LaTeX title](media/demo.png)

*`examples/unit-circle.json` — unit circle, $\sin\theta$/$\cos\theta$
projections, angle arc and LaTeX title. Nothing in this image depends on an
installed font.*

## Contents

- [Why images instead of text](#why-images-instead-of-text)
- [Quick start](#quick-start)
- [The three tools](#the-three-tools) · [`math_formula`](#math_formula) · [`math_figure`](#math_figure) · [`math_convert`](#math_convert)
- [Figure spec reference](#figure-spec-reference)
- [Coordinate expressions](#coordinate-expressions)
- [Output: paths, naming, layout](#output-paths-naming-layout)
- [Embedding into documents](#embedding-into-documents)
- [Inline preview](#inline-preview)
- [Configuration](#configuration) · [Disable and uninstall](#disable-and-uninstall)
- [Requirements and verification](#requirements-and-verification)
- [Privacy and authority](#privacy-and-authority)
- [Known limitations](#known-limitations)
- [Development](#development)

## Why images instead of text

A formula in a chat message is text; in a report, slide, Word file, or PDF it
usually has to be a picture. Producing that picture reliably is the whole point
of this plugin:

- **No font dependency.** MathJax runs with `fontCache: 'none'`, so every glyph
  becomes an outline path. The SVG contains no ``, ``, `id`, or
  `font-family`: it renders identically in a browser, in Word, in an
  `\includegraphics` pipeline, and on a build machine with no math fonts
  installed.
- **Deterministic rasters.** PNG output comes from `@resvg/resvg-js` with
  system font loading disabled — the same bytes on every machine.
- **Content-addressed files.** The same input always writes the same file name,
  so re-running a call overwrites instead of littering the workspace.
- **Document-shaped output.** Every call returns `embed.markdown_svg`,
  `embed.html_png`, `embed.latex_png`, and optional base64 data URIs.

The trade-off is deliberate: because text is outlined, labels are not selectable
or searchable inside the image.

## Quick start

**A formula.** `math_formula` takes bare TeX; `$…$`, `$$…$$`, `\[…\]`, `\(…\)`,
and `\begin{equation}…\end{equation}` are stripped for you.

```
math_formula({ latex: "\\int_0^\\infty e^{-x^2}\\,dx = \\frac{\\sqrt{\\pi}}{2}" })
```

→ writes `math/formula-f091edca9660.svg` and `math/formula-f091edca9660.png`, and
returns paths, sizes and snippets (the alt text is abbreviated here):

```text

svg: math/formula-f091edca9660.svg (7.4 KiB, 148x55 at 1x)
png: math/formula-f091edca9660.png (8.5 KiB, 592x220)
markdown: ![\int_0^\infty e^{-x^2}\,dx = \frac{\sqrt{\pi}}{2}](math/formula-f091edca9660.svg)
html: [图片: …]

latex: \includegraphics[width=3.92cm]{math/formula-f091edca9660.png}

```

Snippets place both formats at the 1× display size (148 px), so the 4× PNG is a
high-density asset for the same layout box rather than a 4× larger picture.

**A figure.** `math_figure` takes a JSON spec in mathematical coordinates, with
named points and LaTeX labels:

```
math_figure({ figure: { …see examples/triangle.json… }, name: "triangle" })
```

The spec behind the example above lives in
[`examples/triangle.json`](examples/triangle.json); a right triangle with a
right-angle marker, an angle label, grid and axes:

```json
{
  "width": 420, "height": 320,
  "xRange": [-1, 5], "yRange": [-1, 4],
  "axes": true, "grid": true, "aspect": "equal",
  "vars": { "a": 3, "b": "2 * a" },
  "elements": [
    { "type": "polygon", "points": [[0, 0], [4, 0], [0, "a"]], "fill": "#93c5fd", "fill_opacity": 0.25 },
    { "type": "point", "at": [0, 0], "label": "A", "label_offset": [-14, 12] },
    { "type": "point", "at": [4, 0], "label": "B", "label_offset": [14, 12] },
    { "type": "point", "at": [0, "a"], "label": "C", "label_offset": [-14, -12] },
    { "type": "segment", "from": "A", "to": "B", "label": "c", "label_offset": [0, 14] },
    { "type": "angle", "at": "B", "from": "A", "to": "C", "label": "\\beta" },
    { "type": "angle", "at": "A", "from": "B", "to": "C", "right": true }
  ]
}
```

More specs you can render as-is: [`examples/unit-circle.json`](examples/unit-circle.json),
[`examples/rose.json`](examples/rose.json) (a three-petal polar rose),
[`examples/function-plot.json`](examples/function-plot.json) (a `stretch`-aspect
function plot).

**Conversion.** `math_convert` handles what the other two do not: an existing
SVG string, or an SVG/PNG file already in the workspace.

```
math_convert({ source: { path: "diagrams/flow.svg" }, format: "png", scale: 3 })
```

Foreign SVG is sanitized first — scripts, foreign markup, event handlers,
`DOCTYPE`, external references, remote paint servers and fetching styles are
removed, and every removal is reported in `warnings`.

## Try it without a Harness

The drawing layer is an ordinary library call, so a spec can be previewed from a
source checkout:

```sh
npm install
node scripts/render-example.mjs examples/rose.json          # writes .tmp/examples/rose.{svg,png}
node scripts/render-example.mjs examples/triangle.json out --scale=2
```

## The three tools

All three share the [common parameters](#common-parameters) and return the same
structured result.

### `math_formula`

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `latex` | string, **required** | — | TeX math. Surrounding delimiters are tolerated and stripped. Max 20 000 characters. |
| `display` | boolean | `true` | Display style (limits under operators, full-size fractions) vs inline style. |
| `font_size` | number | config `fontSize` (16) | Pixels per em; 6–96. |
| `color` | string | config `color` (`#000000`) | Flat CSS color: `#111827`, `navy`, `rgb(17,24,39)`. |
| *common* | | | `format`, `scale`, `background`, `padding`, `path`, `name`, `data_uri`, `preview`. |

A TeX error never throws: MathJax's error marker is drawn into the image and the
result carries a warning.

### `math_figure`

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `figure` | object, **required** | — | The [figure spec](#figure-spec-reference). |
| *common* | | | as above (a spec-level `background`/`padding` wins over the parameter). |

### `math_convert`

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `source` | object, **required** | — | Exactly one of `{latex, display?}`, `{svg}`, or `{path}` (`.svg` or `.png`). |
| `font_size` | number | config `fontSize` (16) | Only for a `latex` source. |
| `color` | string | config `color` | Only for a `latex` source. |
| *common* | | | as above. |

A PNG source is passed through as-is (no re-encode): the result points at the
existing file and returns embed snippets for it.

### Common parameters

| Parameter | Type | Default | Notes |
| --- | --- | --- | --- |
| `format` | `svg` \| `png` \| `both` | `both` | `svg` needs no rasterizer. |
| `scale` | number | config `scale` (4) | PNG zoom; 0.25–16. Pixel size = CSS size × scale. |
| `background` | string | config `background` (`transparent`) | `transparent` or a flat color; applied to PNG and SVG alike. |
| `padding` | integer | config `padding` (8) | Transparent margin in pixels at 1×; 0–128. |
| `path` | string | `math/` + content hash | A file (`.svg`/`.png`) or a directory, workspace-relative. |
| `name` | string | content hash | Human-readable base name; sanitized to `[A-Za-z0-9._-]`. |
| `data_uri` | boolean | config `dataUri` (`false`) | Also return `data:image/…;base64,…` strings. |
| `preview` | boolean | config `preview` (`false`) | Also attach the PNG to the result when the model accepts images. |

Unknown arguments are refused with the list of supported ones; a typo is never
silently ignored.

## Figure spec reference

Top-level fields of the `figure` object:

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `width`, `height` | integer | `480`, `360` | Canvas in pixels; 40–4000. |
| `padding` | integer | the `padding` parameter (8) | Transparent margin around the drawing. |
| `background` | string | the `background` parameter | `transparent` or a flat color. |
| `xRange`, `yRange` | `[min, max]` | auto-fit from the elements | Explicit ranges win; auto-fit adds a 6 % margin. |
| `aspect` | `equal` \| `stretch` | `equal` | `equal` keeps circles circular (it widens the narrower range, like matplotlib's `adjustable="datalim"`); `stretch` fills the canvas — use it for wide function plots. |
| `vars` | object | `{}` | Named numbers; values may be expressions over earlier names, e.g. `{"a": 3, "b": "2 * a"}`. |
| `grid` | `true` \| `{step?, color?}` | off | Grid lines at a "nice" step when `step` is omitted. |
| `axes` | `true` \| `{color?, labels?}` | on for `curve`/`parametric`/`polar`, else off | Axis lines with ticks, tick labels, and `x`/`y` labels. |
| `title` | string (LaTeX) | — | Drawn top-center. |
| `elements` | array, **required** | — | At most 200 elements, evaluated in order. |

### Elements

A point is either `[x, y]` — numbers or expression strings — or a **string naming
an earlier `point` element's `label`**, which is how "the median from A" stays
readable. Points may only reference points defined before them.

| Element | Fields |
| --- | --- |
| `point` | `at`, `label` (LaTeX), `label_offset` (screen px, y down; default `[10,-10]`), `label_size` (14), `size` (3), `color`, `open` |
| `segment` | `from`, `to`, `style` (`solid`/`dashed`/`dotted`), `arrow` (`none`/`end`/`start`/`both`), `color`, `width` (1.6), `label`, `label_offset`, `label_size` |
| `vector` | `segment` with `arrow` defaulting to `end` |
| `line` | `through` (exactly two points), `extend` (`both`/`forward`/`backward`/`none`), plus the `segment` stroke/label fields |
| `ray` | `from`, `through` (one point each), `arrow` (default `end`) |
| `polyline` / `polygon` | `points`, `closed` (`false` / `true`), `fill`, `fill_opacity` (0.18), `style`, `arrow`, `label` |
| `circle` | `center` with `radius` **or** `through`; `fill`, `fill_opacity`, `style`, `color`, `width` |
| `arc` | `center`, `radius`, `start`, `end` (degrees, counter-clockwise), `arrow` |
| `angle` | `at`, `from`, `to`, `radius` (px, default 30), `right` (square marker), `label`, `label_size` |
| `curve` | `y` (expression in `x`), `domain` (default `[-5,5]`), `samples` (400) |
| `parametric` | `x`, `y` (expressions in `t`), `range` (default `[0, 2π]`), `samples` |
| `polar` | `r` (expression in `theta`), `range` (default `[0, 2π]`), `samples` |
| `text` | `at`, `text` (LaTeX), `size` (14), `color`, `anchor` (`start`/`middle`/`end`), `valign` (`baseline`/`middle`/`top`/`bottom`), `rotate` |

Notes that save a round trip:

- **Every label is LaTeX** — in math mode. Write `A_1`, `\alpha`,
  `\frac{\pi}{2}`; use `\text{…}` for upright words.
- `label_offset` is in **screen pixels**, x right and y **down**.
- `angle` and `arc` angles are **degrees** and positive angles run
  counter-clockwise in mathematical orientation; `polar`/`parametric` ranges are
  in **radians**.
- `fill` expects an opaque or alpha-hex color (`#93c5fd33`); `fill_opacity` is
  the escape hatch when you prefer to keep the color plain.
- Curves are split at the viewport edge instead of being clipped, so a pole like
  `tan(x)` breaks the line rather than drawing a fake vertical segment.
- Out-of-domain samples (`ln(x)` for `x ≤ 0`) are skipped and counted in a
  warning.

## Coordinate expressions

Every coordinate and every curve definition may be an expression. The evaluator
is a hand-written recursive-descent compiler — model-authored text is never
`eval`-ed — with a source-length cap and a 64-level nesting cap.

- Operators: `+ - * / % ^` (right-associative), parentheses, unary minus.
- Implicit multiplication: `2x`, `3sin(x)`, `2(x+1)`, `x y`.
- Constants: `pi` (or `π`), `tau`, `e`, `phi`.
- Functions: `sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh
  sqrt cbrt abs exp ln log log2 log10 floor ceil round trunc sign min max pow
  hypot mod gcd cot sec csc`.
- Backslashes are tolerated: `\sin(\pi/2)` works.
- Curve variables: `x` (cartesian), `t` (parametric), `theta`/`θ` (polar).
- Unknown variables, unknown functions, wrong arity, and over-deep nesting are
  hard errors naming the offender.

## Output: paths, naming, layout

```text
/
└── math/                             # configurable via outputDir
    ├── formula-1f0c9a2b3c4d.svg      # content hash of the formula + options
    ├── formula-1f0c9a2b3c4d.png
    ├── triangle.svg                  # when a `name` is given
    └── triangle.png
```

- Relative paths are resolved against the **calling session's working
  directory**, and a path that escapes it — including through a symlinked
  ancestor — is refused.
- Files are written atomically (temporary sibling + rename).
- The result reports both `svg_path` (workspace-relative, for documents) and
  `svg_host_path` (absolute, for other tools), plus byte counts and both CSS
  and pixel dimensions.

## Embedding into documents

| Field | Shape | Use it for |
| --- | --- | --- |
| `embed.markdown_svg` / `embed.markdown_png` | `![alt](math/…)` | GitHub, docs sites, most Markdown renderers (SVG stays crisp). |
| `embed.html_svg` / `embed.html_png` | `[图片: …]
` | HTML with explicit layout dimensions. |
| `embed.latex_svg` / `embed.latex_png` | `\includegraphics[width=…cm]{…}` | LaTeX (the SVG variant needs the `svg` package or a raster fallback). |
| `data_uri_svg` / `data_uri_png` | `data:image/…;base64,…` | Documents that cannot reference a sibling file; requires `data_uri: true`. |

Formats that were not produced are empty strings, never stale content.

## Inline preview

With `preview: true`, the PNG is also attached to the tool result as a durable
image block, so a Web session can show it inline. This happens only when the
active model declares image input **and** the deployment mounts a durable
attachment store; otherwise the call degrades to a `warnings` entry such as
`inline preview unavailable: model "…" does not declare image input`. It is
never an error, and the files are always written regardless.

## Configuration

Write it into the profile's `cordis.patch.yml` (applied after every bundle
layer):

```yaml
- id: jaxzhou-mathmatic-symbol
  config:
    outputDir: math        # asset directory, workspace-relative
    scale: 4               # default PNG zoom
    color: '#000000'       # default formula ink
    background: transparent
    padding: 8
    fontSize: 16           # pixels per em for formulas
    preview: false         # default inline preview
    dataUri: false         # default data-URI output
    # workspaceRoot: /abs/path   # host-side override, mainly for tests
```

Invalid configuration fails at mount time with the offending field named;
nothing is clamped or ignored.

## Disable and uninstall

Disable the tools without uninstalling (live profiles pick it up without a
restart):

```yaml
- id: jaxzhou-mathmatic-symbol
  disabled: true
```

```sh
dsh plugin --profile web remove @jaxzhou/dsh-mathmatic-symbol
```

## Requirements and verification

- **DeepSeek Harness `0.1.5-rc.2`** — Host-only plugin: any profile with the
  tool registry works, `headless`, `tui`, `web`, or a custom composition. No Web
  UI is required.
- **Node ≥ 22.19** (the range declared by the Harness).
- Runtime dependencies: `mathjax-full@^3.2.2` (pure JS) and
  `@resvg/resvg-js@^2.6.2` (native, only for PNG).

What was verified for `0.1.0`:

- `npm run check`: typecheck, bundle build with artifact-shape assertions, and
  57 tests, including exact-pixel geometry assertions and an end-to-end pass
  over the emitted files.
- The installed Harness's own `assertSupportedJsonSchema` and
  `validateJsonSchemaValue` accept all three output schemas and live canonical
  values.
- A real boot of a `@deepseek-ai/dsh-base` + plugin profile lists
  `math_formula`, `math_figure`, and `math_convert` in the live registry — both
  from a local checkout and from the **published npm package**.
- Not verified: a model-driven tool call with a real LLM (no API key was
  configured in the build environment). The tool layer itself is covered by the
  tests above.

## Privacy and authority

- **Writes only inside the workspace.** Output paths are resolved against the
  session's working directory and checked against symlinked ancestors.
- **No network.** Typesetting, drawing and rasterizing are local; MathJax and
  resvg are dependencies, not services.
- **No credentials, no session data.** The only service the plugin touches is
  the optional `ctx.attachments.saveImage()` used by `preview`.
- **No model-authored code is executed.** Expressions go through the compiler in
  `src/expr.ts`; LaTeX excludes the `html`/`require`/`autoload` extensions; SVG
  accepted by `math_convert` is sanitized and every removal is reported.
- **Degrades on purpose.** Without a prebuilt rasterizer binding, the call still
  returns SVG and says so in `warnings`.

## Known limitations

- **Text is outlines.** Labels are not selectable or searchable inside the
  image; that is the price of rendering without fonts.
- **`math_convert` PNG input is pass-through.** Existing PNGs are not
  re-encoded, and JPEG/WebP/GIF dimensions are not parsed; file input accepts
  only `.svg` and `.png`.
- **PNG needs the native binding.** Without a prebuilt `@resvg/resvg-js` for the
  platform, only SVG output is available.
- **`aspect: "equal"` adjusts the view.** With both ranges given, the narrower
  axis is widened so the scale stays uniform, so axes may extend slightly past
  the ranges you asked for. Use `aspect: "stretch"` for a wide function plot.
- **One figure per call.** No multi-panel/subplot syntax; draw several elements
  on one canvas or make several calls.
- **No 3-D and no implicit curves.** Planar explicit functions, parametric
  curves and polar curves only.
- **Default output directory is `math/`.** Point `path` elsewhere, or set
  `outputDir`, if you keep assets in a different tree.

## Development

Build, artifact model, dependency policy and the real-Harness verification steps
are in [CONTRIBUTING.md](CONTRIBUTING.md); repository rules are in
[AGENTS.md](AGENTS.md).

```sh
npm install
npm run check        # typecheck + build + tests
node scripts/render-example.mjs examples/rose.json
```

## License

MIT — see [LICENSE](LICENSE).

数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。