dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh 的个人收件箱:输入框的 /inbox 或侧栏面板把链接、图片、文本与账密收进本地仓库,先按本地规则、再由有每日上限的模型分类,可在面板里筛选、搜索与编辑;对话里让助手按需检索取回,账密正文加密落盘,可选 WebDAV 或 S3 远端同步记录与附件字节。目前只在 Windows 实测。

A local inbox plugin for DeepSeek Harness (dsh): file whatever you copy into one vault, get it back when you need it — including by asking your assistant in conversation.
English | 中文
The things you copy in a day — a link to read later, a screenshot, a config snippet, an account and password — end up scattered across clipboard history, bookmarks and temp files. dsh-inbox keeps them in one local vault: paste to file, automatic classification, browse and search from the sidebar — and instead of digging through it yourself, ask your assistant "what was that article about caching I saved last month?".
Everything lands on your machine, and the model only sees a record when you ask it to look.
| Feature | What it does |
|---|---|
| Three ways in | /inbox <text or link> in the composer (attach images to carry them along), paste / drop / pick a file in the panel, or ask the assistant to keep something |
| Automatic classification | Links by platform and media type (60-odd sites: Bilibili, YouTube, WeChat, 掘金, Zhihu…), text by credential shape, images get a 疑似证件 tag at card proportions; the rest goes to the model, with a daily cap |
| Panel | Filter by watch-later / category / tag, search title, text, link and note, two list densities; the detail pane edits name, category, note and tags, flags watch-later, deletes and restores — and it follows dsh's theme and language |
| Every record has a name | A link takes the page's own headline (no model tokens), a photo or file its file name, and the name you type always wins. A page that will not be read — an anti-bot page, a dead link — leaves the address as the name rather than a guess |
| Who judged the category | A coloured badge: 规则判定 (local rules) / 模型判定 (the capped model pass) / 手动判定 (yours — nothing overwrites it later) |
| Ask in conversation | Ask for 收件箱 / 仓库 / inbox and the assistant searches by words, category, tag, watch-later flag or kind (ten at a time plus a count, thumbnails inline) and opens one by id (text up to 1000 characters, link, note, tags, attachments). 「打开 ↗」 under an answer jumps to that record in the 仓库 tab. Hand it something to keep and it files that too — no name, and no credential while the vault is locked |
| Looking at a picture | Image bytes stay out of the conversation; ask the assistant to look at one and that single image is sent — explicitly, per call |
| Credentials are safe | The body is encrypted at rest, with a key derived from your master password — neither is ever written down. The list shows only the name you gave it, and plain text never reaches a conversation or a model |
| Two-way sync | Point it at a WebDAV folder or an S3 bucket: changes push a few seconds later, 「同步」 runs a full push-then-pull merged per record by id + timestamp, and emptying the recycle bin deletes the cloud copies too. Two machines see each other when they share one 「目录」 |
| Conversation cards | Tool results render as dsh-inbox cards — links clickable, image markers drawn as thumbnails on your machine |
| Gateway quirks | Some object-storage gateways bind each AccessKey to an "application" and identify clients by a header — so the plugin keeps one client identity per protocol |

① File something from the conversation
/inbox in the composer, followed by text or a link, with images attached right there — this never reaches the model, it only goes into the vault. That is the way to file credentials and throwaway links.
Or just say so — "keep this in my inbox", with the link or the paragraph right there — and the assistant files it for you. That path does put the content in front of the model on the way through, so /inbox stays the way to file credentials.
② Ask for it later
No command, just talk:
which of my saved images is the mini-program code?
show me that article about caching I saved last week
list the links in my inbox I haven't read yet
Two questions in the same conversation, on a real machine:


Needs Node ≥ 22 and a working dsh (the installer brings pnpm along when your machine does not have it). Windows only so far — macOS and Linux are unverified.
Web (command line)
# install (`dsh web` is `dsh --profile web`, so this is the profile you already start)
npx @chance722/dsh-inbox init --profile web --install-pnpm
# never run dsh on this machine? create the profile in the same command
npx @chance722/dsh-inbox init --profile web --create-profile --install-pnpm
# update (within 24h of a release, swap @latest for the exact version, e.g. @0.2.15)
dsh plugin --profile web add @chance722/dsh-inbox@latest
Desktop app (DeepSeek Harness)
Open Plugins in the sidebar → install → enter @chance722/dsh-inbox@latest (within 24h of a release, @0.2.15) → restart when it asks.
That field also takes a GitHub URL (https://github.com/Chance722/dsh-inbox): the built plugin ships in the repository, so it installs the same way with nothing extra to do. Reinstalling is how you upgrade; the package name is still the smoother path day to day.
The same from the desktop's own CLI:
"<desktop install dir>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add @chance722/dsh-inbox@latest
Restart afterwards. Inbox is in the left rail, and a new session's assistant can look things up ("what links in my inbox haven't I read yet?").
To keep your daily dsh untouched, give the plugin its own profile and port: npx @chance722/dsh-inbox init --create-profile, then dsh --profile inbox --no-open --port 3102.
Other flags: --profile <name>, --install-pnpm, --no-default, --help.
git clone <this repo> dsh-inbox ; cd dsh-inbox
pnpm install ; pnpm build
node lib/cli.js init --package <absolute path to this repo>
# 1. remove the package from the profile you installed it into
# (also drops it from dsh.profile.bundles)
# desktop app: uninstall it in the Plugins panel — same thing
dsh plugin --profile <that profile> remove @chance722/dsh-inbox
# 2. delete what init created (**dsh 0.1.x only**; from 0.2 init skips this)
rm -r ~/.dsh/.agent-presets/inbox # the preset copy
# default preset: delete agent-presets.default in ~/.dsh/settings.yaml (falls back to the
# deployment default) or set it to standard; every init left a settings.yaml.bak-* backup
# 3. and the profile itself, if you made one just for this
rm -r ~/.dsh/profiles/<that profile>
Uninstalling does not delete your vault. To remove the records too: rm -r ~/.dsh/storages/dsh_inbox.
Everything under %DSH_HOME% (C:\Users\<you>\.dsh on Windows):
| What | Where |
|---|---|
| Records: text, links, category, note, tags, watch-later… | storages\dsh_inbox\items\*.json, one file each |
| Attachment index (mime / size / original name) | storages\dsh_inbox\attachments\*.json |
| The bytes of images, videos and files | attachments\ — dsh's own content-addressed store, never auto-deleted |
| Remote password / S3 AccessKey Secret | dsh's credential store, .credentials.yaml |
| Remote settings (URL, bucket, client identity…) | dsh's own settings |
With a remote configured and /inbox as the directory:
| Remote path | What it is |
|---|---|
inbox/<whatever you drop> | The drop folder: any device drops files here and this one ingests them |
inbox/sync/items/<record id>.json | One record, machine-readable — the source of truth for sync |
inbox/sync/items/<record id>.txt | The same record, readable (text, note, which attachments it points at) |
inbox/sync/attachments/<attachment id>.<ext> | Attachment bytes (images, video, PDFs open as themselves) |
inbox/sync/attachments/<attachment id>.meta.json | The attachment's metadata (original name, dimensions, size, digest) |
A 0-byte key ending in / | A folder marker the cloud drive made itself, not us |
id + timestamp, the newer write wins, no conflict copies; needed attachment bytes come down with the record./ and inbox are the same). Records a machine left under an older directory come back if you tick Merge other sync directories too in the settings.[attachment:id] marker — that one image is sent only when you explicitly ask the assistant to look at it.sync/master.json, holds the non-secret derivation parameters (salt, work factors, a check value) so the same master password opens synced credentials on any machine — on a second machine, enter the password you set on the first.web-fetch-http.userAgent shipped in this package's cordis.patch.yml. That identity is the whole profile's, the model's own web tools included; your own cordis.patch.yml overrides it. Details: docs/help/link-title-fetch.md.pnpm install
pnpm build # lib/index.js (host) + lib/client.js (panel) + lib/cli.js (init) + lib/types
pnpm typecheck
pnpm test # vitest
Client-side changes need pnpm build (dsh's client-hmr reloads the page); host-side changes need a restart. Details in docs/help/dev-setup.md, milestones in the development bus.
To switch the profile you actually run between the published package and this checkout (default profile web; set DSH_PROFILE for another):
pnpm dev:status # which one is in use right now
pnpm dev:npm # point it at the published version
pnpm dev:local # point it back here (builds first, then links)
MIT