DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Plugin Message Board — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
P

dsh-plugin-message-board

Plugin Message Board

DeepSeek Harness 的共享留言板:彼此留言,可将留言范围限定为整个实例、某个项目或单个会话。留言支持 Markdown 渲染。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:Chicago01/dsh-plugin-message-board#b2356e4d4f3b3a9af25a86e9eefa150ef2feda9c
README兼容性版本
The message board panelDark theme

兼容性与来源证明

Plugin Message Board 以 dsh-plugin-message-board 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/2

版本

0.2.0stable
2026/10/2
0.1.0stable
2026/10/1

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/2
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Ab Publishdsh-ab-publish浏览器自动化发布工具,可登录任意网站并发布内容,整合为一个可发布的插件包Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "树外 wechat_scrape 工具:获取微信公众号文章,过滤推广区块,并将每篇文章保存为 Markdown 文件,供此机器的 dsh 配置文件维护者使用。" kind: "package-reference" ---Im@xmanrui/dsh-im将微信、飞书、企微、钉钉、QQ、Telegram、WhatsApp、Slack、Discord 和 Matrix 接入 DSH。

README

dsh-plugin-message-board

A shared message board for DeepSeek Harness.

When more than one person uses the same DSH instance — a laptop your teammate connects to, a shared box behind a tunnel — the conversation history is the only place to leave something behind, and it is a bad place for it: it is per-session, it is linear, and writing in it makes the agent act. This plugin adds a quiet side channel instead. Leave a note, and the other person sees it the next time they open the board.

Notes are scoped three ways:

ScopeBoardUse it for
Globalone per instance"deploy is frozen until Thursday", "the VM is rebooting"
Projectone per workspace directory"the build is green again", "don't touch the lockfile"
Sessionone per session"here are the open questions in this session"

Every note is attributed and carries a per-reader watermark, so you can tell whether the other person has actually seen it.

The message board panel

English | 中文

Features

  • Three scopes — global, per project, per session, with a single rail that lists every board, so one can be started before anyone has written in it.
  • Mutual visibility with read receipts — each reader has their own watermark; your own notes show ✓ read by … once the other person opens the board, and theirs are highlighted until you do.
  • Markdown notes — headings, lists, quotes, rules, fenced and inline code, bold, italic, strikethrough and links, rendered as React elements so a note can never inject markup.
  • One click from a session — a board button in the session header opens that session's board directly.
  • The agent can read and write the board too — two tools, so a note left for the agent is something it can actually act on.
  • Zero dependencies, no build step — plain JavaScript, node: builtins only, React from the browser module table. Copy the directory and it runs.
  • Reuses DSH's own browser session — the HTTP API is admitted by the same trust and cookie policy that guards /api, so there is no second credential to manage.
  • Theme-aware and localized — theme tokens only, so light and dark both read correctly; UI text is registered through the Client locale service (中文 / English).

Dark theme

Writing notes

A note body is Markdown:

SyntaxRenders as
# Heading … ###### Headinga heading, demoted two levels so a note can never outrank the page
**bold**, *italic*, ~~struck~~emphasis
`code`, ```lang … ```inline code and a fenced block
- item, 1. itemunordered and ordered lists
> quoteda blockquote
---a horizontal rule
[text](https://…), bare https://…a link
a single newlinea line break, the way a message box works

A few deliberate limits:

  • Links are scheme-checked. Only http:, https: and mailto: become anchors; javascript: and data: are shown as the literal text that was typed.
  • Raw HTML is not rendered. <b>x</b> stays visible as <b>x</b>, because notes are rendered to React elements rather than to an HTML string.
  • Underscore emphasis is off. _like this_ is left alone so snake_case names survive untouched. Use *asterisks*.
  • Line structure is preserved by the server. Note bodies keep \n and \t; every other control character is replaced with a space. Labels, which are single-line, are flattened.

Install

A bundle install has two effects: the package becomes resolvable from the profile, and its patch layer is applied.

Into the profile you are running

Ask the agent in that session to install it, pointing at the checkout:

plugin_manager install_bundle → /absolute/path/to/dsh-plugin-message-board

Into any profile, from a shell

git clone https://github.com/Chicago01/dsh-plugin-message-board.git
dsh plugin --profile <profile> add /absolute/path/to/dsh-plugin-message-board

dsh plugin add installs the package and, because the manifest declares dsh.bundle.patch, records the bundle in the profile's dsh.profile.bundles in one step.

Then restart the host

The Host half is a Node module. A change to index.js only takes effect after the DSH host process restarts — neither a page refresh nor a remove_bundle/install_bundle cycle re-imports an already-loaded module generation. The Client half (client.js) is fetched as a browser artifact, so it does refresh with the page.

Configuration

Override the row's config from your own patch layer. A matching id replaces the whole config, so restate every field you still want.

- id: message-board
  name: 'dsh-plugin-message-board'
  config:
    identityHeader: x-gateway-user
    allowDelete: true
KeyDefaultMeaning
routePath/dsh-message-boardPrefix route on ctx.webServer. Stored without a trailing slash — a prefix route matches p and p/<anything>, so a trailing slash would match nothing. / is refused.
dataFile$DSH_HOME/message-board/board.jsonBoard database. Created on first write, written atomically.
identityHeader""Optional request header carrying the authenticated user name. See below.
allowDeletetrueAuthors may delete their own notes.
agentToolstrueRegister message_board_read / message_board_post.
agentAuthorDSH AgentAuthor name the tools write under.
maxMessagesPerBoard2000Oldest notes are dropped past this count.

Identity on a shared instance

DSH itself has one operator, so the plugin cannot know which human is typing. It takes the name from a small field in the panel header, remembered per browser in localStorage.

If you put your own authenticating proxy in front of DSH — an HTTP basic-auth gateway, Cloudflare Access with a header, an SSO sidecar — point identityHeader at the header it sets and the name becomes authoritative:

- id: message-board
  name: 'dsh-plugin-message-board'
  config:
    identityHeader: x-gateway-user

The header wins over anything the browser claims, so the panel shows who the proxy authenticated rather than who the browser claims to be.

Agent tools

Both are registered on every session.

ToolWhat it does
message_board_readRead a board's notes. scope is global, project, or session; session defaults to the calling session.
message_board_postLeave a note. Same scopes; label records a human-facing board title.

A note left on a session board is something the agent working in that session can pick up:

> post a note on this session's board saying the flaky test is the rerun loop

… message_board_post { scope: "session", text: "The flaky test is the rerun loop." }

HTTP API

The Client half talks to the Host half over a prefix route. Every response is JSON, and every failure uses the same envelope.

MethodPathBody / query
GETapi/boards?author= → every board with counts and read watermarks
GETapi/messages?board= → one board's notes, newest first
POSTapi/post{ board, text, author?, label? }
POSTapi/read{ board, author? } → advance that reader's watermark
POSTapi/delete{ id, author? } → author only

Requests are admitted by ctx.connection.requestRejection(...), the same Host/Origin/trust check and signed browser-session cookie that guards DSH's own /api. An untrusted Host gets 403, a missing or stale session gets 401.

How it works

ctx.webServer  ──prefix route──▶  index.js   (Host half)
                                     │  board.json, atomic writes
                                     ├─ ctx.connection.requestRejection  → trust + cookie
                                     └─ ctx.tools.register               → agent tools

slots ──▶ client.js  (Client half: sidebar.panellist, main, session header)
             └─ fetch('/dsh-message-board/api/…', credentials: same-origin)
  • The Host half owns the store and the HTTP API. It registers the mount point into the page through ctx.webServer.tapIndex, so a custom routePath needs no matching edit in client.js.
  • The Client half renders three slot contributions and never imports a Harness Client package: React comes from the browser module table, and the only thing shared with the host is the --dsw-alias-* theme tokens.
  • Text drawn on a --dsw-alias-brand-primary fill uses --dsw-alias-bg-base as its foreground. The two are inverse surfaces in both shipped themes, so the pairing stays legible when the theme flips.
  • Writes are serialized through an in-process queue and persisted with write-temp-then-rename, so a crash cannot leave a half-written board.

Data format

{
  "version": 1,
  "boards": {
    "global": {
      "scope": "global", "target": "", "label": "",
      "createdAt": "2026-10-01T13:30:44.847Z",
      "readAt": { "Alice": "2026-10-01T14:09:44.847Z" }
    },
    "session:session-8f21c0": {
      "scope": "session", "target": "session-8f21c0",
      "label": "Refactor the auth gate",
      "createdAt": "2026-10-01T13:54:44.847Z",
      "readAt": {}
    }
  },
  "messages": [
    {
      "id": "mb_demo_1", "board": "global", "scope": "global", "target": "",
      "author": "Alice", "text": "…", "createdAt": "2026-10-01T13:30:44.847Z"
    }
  ]
}

A board key is global, project:<path>, or session:<session id>. "Unread" is derived, not stored: a note is unread for a reader when its createdAt is newer than that reader's watermark.

Security

  • The board is not a secret channel. Its API is reachable by anyone who can reach the DSH web UI with a valid browser session — which is everyone who can use the agent, and the agent can already run commands. Do not put credentials in a note.
  • The API is only as strong as the deployment around it. On a loopback-only DSH, that is your machine. Behind a tunnel, it is whatever guards the tunnel. If you expose DSH directly to a network, the board is exposed with it.
  • routePath must stay reserved. Do not point another plugin at the same prefix; the webserver throws on a duplicate route, which fails the load.

Development

The Host half has a contract test suite that needs no DSH at all. It stands in for the two services the plugin uses and copies their real rules from the DSH source — route matching (prefix p matches p and p/<anything>) and the Host/Origin trust fence:

node --test test/host.test.mjs

To exercise the Client half, install the bundle into any profile and restart the host. client.js reloads with the page; index.js does not.

Compatibility

Built and verified against DSH 0.2.0-rc.2. The plugin relies on ctx.webServer.register (prefix routes), ctx.connection.requestRejection, ctx.tools.register, the sidebar.panellist / main / conversation.session.header.utilities slots, and the --dsw-alias-* theme tokens.

License

MIT — see LICENSE.