dsh-table-copy: Add a hover toolbar to Markdown tables, one-click copy as Markdown or PNG

Introduction

In DeepSeek Harness Web, model outputs often appear as Markdown tables: data summaries, comparison lists, and configuration explanations. When wanting to extract and use these tables, the conventional approach is to manually select table cells and copy-paste; when tables are wide, span multiple pages, or contain many columns, it is easy to select the wrong area, resulting in a paragraph of mangled text. To directly obtain a table image that can be pasted into WeChat, Feishu, or an issue, one generally has to open a screenshot tool separately.

Below is an introduction to jiongboy/dsh-table-copy. It is a client-side plugin that places a small toolbar with two buttons in the top-right corner of every Markdown table: the left button writes the table to the clipboard as a PNG image, and the right button writes the table to the clipboard as Markdown text.

Overview

One-sentence positioning: Adds a hover toolbar to all Markdown-rendered tables in DeepSeek Harness Web, supporting copying as Markdown text or PNG image.

  • Maintainer: jiongboy
  • Category: Client-side
  • Stars: 0
  • License: MIT
  • Version: 0.1.0 (see package.json)

It addresses the “inconvenience of using Markdown tables”: no need to select, no need for screenshot tools; the toolbar appears upon hovering, and clicking yields the formatted result. The plugin adapts to light and dark themes; background, font, and borders are exported according to the current theme; the exported table in dark mode is also dark.

All capabilities are completed on the client side: no network requests, no file system access, no new backend routes, only clipboard operations.

Installation and Usage

The installation commands come from the README. The plugin has not yet been published to npm; the path is labeled # from npm (after publishing) in the README:

# from npm (after publishing)
dsh plugin --profile web add dsh-table-copy

# or straight from GitHub
dsh plugin --profile web add github:jiongboy/dsh-table-copy

After installation, reload the Web UI (Cmd/Ctrl+R), and the plugin will appear under “Plugins → Installed Plugins”. The uninstall command:

dsh plugin --profile web remove dsh-table-copy

It is worth noting that the plugin runs with the permissions of the current dsh process; before installing, you should check the source code content and the license (MIT).

Typical Usage

The operation does not involve command-line arguments; the usage flow provided in the README is:

  1. Hover the pointer over any Markdown table; a two-button toolbar will fade in at the top-right corner of the table.
  2. Left button (image): The table is written to the clipboard as PNG. If the browser refuses to write the image, the same PNG will be changed to a download.
  3. Right button (copy): The table is written to the clipboard as Markdown, formatted with header rows, | --- | separator rows, and data rows; the button flashes a checkmark and provides a toast notification of completion.

The toolbar does not take up space by default and only appears on hover. The exported PNG is captured at 2x resolution and can be directly pasted into WeChat, Feishu, documents, or issues.

Implementation and Known Limitations

The plugin is divided into two parts: the host side and the browser side.

  • The host side lib/index.js only declares the plugin’s identity and does not register routes or provide services.
  • The browser side lib/client.js is attached to a MutationObserver, finding every <table> inside the Markdown container and appending <caption class="dtc-tools"> to it.
  • The table nodes themselves are not wrapped or moved, because the DOM tree is managed by React, and extra wrappers would be discarded in subsequent stream re-renders; <caption> is a child node of the table and is re-added when the renderer rebuilds the table.
  • Both <caption> and the toolbar use position: sticky; right: 0; when a wide table scrolls horizontally, the button stays pinned to the visible right edge.
  • Markdown export reads table.rows, collapsing whitespace cell by cell and escaping |.
  • Image export clones the table, calculates inline styles for each node (a whitelist of 48 properties), wraps the clone in an foreignObject SVG, loads it as an image, draws it onto a 2x canvas, and then calls canvas.toBlob("image/png").
  • The background is taken from the background color of the first opaque ancestor, so tables in dark mode are exported as dark, not white background.

Known limitations come from the README:

  • SVG must be passed as a data: URL. blob: URLs pollute the canvas in Chromium, causing toBlob() to throw a SecurityError.
  • Images are captured according to rendered width: columns scrolled out of view horizontally are still captured because the cloned table maintains its full dimensions (width: max-content).
  • Links within the table retain color and text but are not clickable in the PNG.
  • Only Markdown-rendered tables are decorated; tables in the product interface itself (Settings page, Plugin list) are not affected.

Development and Debugging

Check methods provided in the README:

node --check lib/client.js && node --check lib/index.js   # syntax check

# confirm if the client bundle is loaded into the running instance
curl -sN --max-time 5 http://127.0.0.1:55102/plugins/events | head -c 2000

The browser side is a regular script, registered via window.__ModuleLoader__.load({ id, factory }), not ESM. The factory function returns { name, inject, apply }, using the same contract as dsh-pet and dsh-md-plus. In package.json, dsh.bundle.patch points to ./cordis.patch.yml, dsh.client.platform is web, and engines.node requires >=22.19.0.

Suitable Scenarios

Suitable for developers using the DSH Web interface who frequently need to extract table content from model outputs: directly converting configuration items, data summaries, or comparison tables into pastable images or Markdown. All processing is done on the browser side without passing through additional services, making it suitable for use cases requiring data to stay local.

Note: The plugin runs with the permissions of the current dsh process. Tables in historical outputs are visually indistinguishable from tables rendered by the plugin; be sure to read the source code and license before installing to confirm it fits your usage scenario.

Summary

dsh-table-copy does a small thing: adds a hover toolbar to Markdown tables and puts the table into the clipboard as Markdown or PNG. From an implementation perspective, it uses MutationObserver plus <caption> to bypass React’s DOM management limitations; there are no network requests on the client side, and the limitations are written in the README.

Directory Page: https://www.skillhub.cn/plugins/jiongboy/dsh-table-copy
GitHub: https://github.com/jiongboy/dsh-table-copy

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye