dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DeepSeek Harness 插件 — 手机(微信桥)入站附件的受控清单与按需取用:让 agent 知道本会话收到了哪些附件,并把选中的一份搬进工作区。仅提示差异,不作出定性结论。
English · 简体中文 · Español · Português · हिन्दी
The session's inbound phone (WeChat bridge) attachment inbox: list the attachments this conversation actually received, and adopt one into the workspace on demand.
*Workflow overview: install → open panel → act. The examples below use the real command surface.*
dsh plugin --profile <name> add dsh-phone-inbox
dsh plugin --profile <name> remove dsh-phone-inboxThe plugin has no runtime dependencies (dependencies is empty). Its only peers are the host packages it is built against; see the peerDependencies block in package.json.
dsh-wechat saves inbound phone media to ~/.dsh-wechat/tempfile/ — outside the session workspace — and writes the absolute path into a plain text block. Two consequences follow, and neither is visible to the user:
dsh-data-quality rejects any path that escapes the session workspace (path-escape), so "I sent you a CSV, profile it" fails even though the file is right there.${Date.now()}-${rand4hex}-${name.replace(/[^\w.-]/g, "_")}, so 材料.csv lands on disk as __.csv. The user cannot recognize their own file.dsh-phone-inbox adds no new channel and copies nothing by default. It makes the session's own inbound list addressable, and it restores the name the bridge mangled — from the [收到文件: ] marker the bridge already writes.
Tool · Question it answers inbox_list · "Where is the file I just sent you from my phone?" inbox_adopt · "Put it somewhere my workspace-confined tools can read it."
Both tools are registered by the function plugin, so they appear in the model's tool list as soon as the bundle row is mounted.
# 1. Mount the plugin (a bundle row in the target profile)
dsh plugin --profile <name> add dsh-phone-inboxThen, in a session that received a phone attachment:
inbox_list # the paths this session received
inbox_adopt { "path": "<the path from inbox_list>" }inbox_adopt returns relativePath (for example phone-inbox/材料.csv). Pass that to a workspace-confined tool such as data_profile; pass the original host path only to consumers that accept any absolute path.
Engine · Range Node.js · ^22.19.0 \ · \ · >=24.0.0 DSH · >=0.2.1-alpha.1
The host peer range is the ecosystem's canonical six-clause OR range (see dsh-plugin-kit/data/peer-range.json). The host evaluates peerDependencies at preflight and silently disables a plugin row whose range does not admit the running version, so a wrong range looks like "the plugin mounted and does nothing". The host also adjudicates engines.dsh independently; a mismatch there can disable the row even when the peer range admits the version.
These are the plugin's real entry points; install once, then call one.
Command
~~~sh inbox_adopt ~~~
Input
~~~json { "path": "/tmp/dsh-test-phone-inbox-acceptance-5AoMHy/.dsh-wechat/tempfile/1792414010975-0a67121b-__.csv" } ~~~
Output
~~~text { "relativePath": "phone-inbox/材料.csv", "copyMethod": "node-fs" } ~~~
*Observed from plugins/dsh-phone-inbox/scripts/acceptance.mjs:134-147*
Input
~~~text {"path":"/tmp/dsh-phone-inbox-example/workspace/local.csv"} ~~~
Output
~~~text phone-inbox could not adopt that attachment. reason: not-in-inbox /tmp/dsh-phone-inbox-example/workspace/local.csv is not inside the inbox directory /tmp/dsh-phone-inbox-example/inbox; this plugin only adopts files the bridge saved there ~~~
*Observed from plugins/dsh-phone-inbox/src/provider-base.ts:443-449; plugins/dsh-phone-inbox/src/render.ts:108-115; plugins/dsh-phone-inbox/tests/integration.test.ts:359-368*
inbox_adoptEvery field is optional; the table lists the default. See cordis.patch.yml for the same values with inline comments.
Key · Default · Meaning enabled · true · Master switch; false mounts no service and no tools. inboxDir · "" → ~/.dsh-wechat/tempfile · Directory the bridge drops inbound media into. Empty derives the bridge's own default; set it when the bridge's storageDir was moved. maxItems · 5 · Cap on entries inbox_list returns. The MVP contract is "the session's most recent few". provider · session · Which registered provider answers: session (this conversation's own messages) or tempdir (session plus a scan of inboxDir). allowTempdirScan · false · Enables the directory scan at all. Off because inboxDir is global. tempdirScanMaxItems · 5 · Cap on entries a scan may contribute. tempdirScanMaxAgeMs · 3600000 · Age ceiling for a scanned file; 0 disables the filter. markers · see below · Marker wording per media kind, as RegExp sources. defaultSubdir · phone-inbox · Workspace subdirectory inbox_adopt writes into. restoreOriginalName · true · Use the sender's recovered original name as the adopted file name. writeChannel · auto · auto (fs service for text, node:fs otherwise) · fs (host fs service only) · node (bytes directly). registerAttachment · false · Also register adopted bytes as a durable host attachment. Attachment objects are never garbage-collected.
The markers default wording, per media kind — each value is a RegExp source whose first capture group is the path:
image.path — ` 文件已保存到:\s*(\S+) file.path — ` (?:文件已保存到|文件路径):\s*(\S+) file.name — ` [收到文件:\s*([^]\r\n]+)] video.path — ` 文件已保存到:\s*(\S+) Marker wording is a soft contract with the bridge: it writes the path into prose, and the prose can change between bridge releases without notice. The patterns are configuration precisely so a wording change is a config edit rather than a plugin release.
inbox_list({
limit?: number, // default: config.maxItems
includeTempdir?: boolean, // only honoured when allowTempdirScan is true
})Returns { ok: true, source, inboxDir, items[], attachments, deriveMessages, emptyReason?, emptyDetail?, tempdirScan, unresolvedAttachmentBlocks }, or { ok: false, reason, detail }.
inbox_adopt({
path: string, // required: exactly what inbox_list reported
name?: string, // default: the recovered original name
subdir?: string, // default: config.defaultSubdir
channel?: 'auto' | 'fs' | 'node',
overwrite?: boolean, // default false: a duplicate gets a -1 suffix
register?: boolean, // default: config.registerAttachment
})Returns { ok: true, item } with hostPath, workspacePath, relativePath, bytes, sha256, copyMethod, nameRestored, sourceLeafName, and attachmentId/attachmentHostPath when registered; or { ok: false, reason, detail }.
The plugin also appends one system-prompt section (phone-inbox, order 320) so the model knows the capability exists, and subscribes to session/event for user/message observation. Neither is required for correctness: the history read is authoritative on every call.
inboxDir and the calling session's own messages. Nothing else.path.resolve + a separator-aware containment check), and only when inbox_adopt is called.inboxDir, a subdir that escapes the workspace, and a name that could traverse. The path argument comes from the model and is never trusted.allowTempdirScan is explicitly enabled; when it does, every entry it contributes is stamped source: "tempdir".-1, -2, … suffix unless overwrite: true.writeText/editText), so this plugin enforces its own containment on both ends of the copy.fs write channel goes through ctx.fs.writeText with the session-scoped sandbox policy, so a confining backend fences it exactly as it fences the write tool. node bypasses that fence by construction; it exists because ctx.fs has no byte-write API. The returned copyMethod always says which one ran.auto prefers the fs service for text and falls back to node:fs; the fallback reason is recorded and the channel is reported, never implied.source.0o700/0o600 handling). This plugin does not assume otherwise.(\S+) because that is what stops it from swallowing the sentence the bridge writes after the path; the bridge's own temp names never contain a space.image.png, video.mp4) tells them apart.image. / video.mp4 and the wording carries no original name. The plugin reports the on-disk name and says so rather than inventing one.tempfile/, but nothing guarantees it stays.pnpm install
pnpm run typecheck && pnpm test && pnpm run build \
&& pnpm run verify:self-contained && pnpm run verify:artifacts \
&& pnpm run check:readmes && pnpm run check:lockfile
pnpm run acceptance # end-to-end: probe -> list -> adopt -> dsh-data-qualityprepublishOnly re-runs the gate, so a release cannot ship an unbuilt or drifted tree.
dsh · dsh-plugin · deepseek-harness · cordis · wechat · inbox · attachment · phone
PerryLink.
This project is part of the DeepSeek Harness plugin family from PerryLink. The roster stays collapsed below so every README keeps a short first screen; expand it to see every row and its status.
Expand all plugins
Plugin · Status dsh-aqua-input-check · dsh-archive-check · dsh-auto-review · dsh-autotier · dsh-bid-ca-precheck · dsh-bid-qual-check · dsh-cert-mcp · dsh-checkpoint-rewind · dsh-click · dsh-composer-history · dsh-contract-stance · dsh-customs-doc-check · dsh-data-quality · dsh-demurrage-ledger · dsh-doublecheck · dsh-drill-script-check · dsh-eia-guide-check · dsh-emergency-plan · dsh-essay-rubric-check · dsh-evidence-check · dsh-export-ctl-check · dsh-fast · dsh-fmea-table-check · dsh-forecast-penalty · dsh-fund-research · dsh-github · dsh-gongwen-flow-check · dsh-gongwen-word-check · dsh-guard-plan-qc · dsh-hazchem-check · dsh-hazplan-check · dsh-hidden-risk-map · dsh-hs-classify · dsh-icd-rule-check · dsh-industry-research · dsh-lawcite-adapter · dsh-laya · dsh-lc-doc-check · dsh-learning-gap-check · dsh-library · dsh-local-ai · dsh-lsp-actions · dsh-mask · dsh-mcp-panel · dsh-medrec-qc · dsh-memento · dsh-nsfc-form-check · dsh-nurse-record-check · dsh-observe · dsh-origin-rvc-check · dsh-ota-review-check · dsh-output-styles · dsh-paper-doc-adapter · dsh-permission-rules · dsh-permit-report-check · dsh-pipeline-check · dsh-pleading-draft · dsh-plugin-doctor · dsh-plugin-guide · dsh-plugin-kit · dsh-plugin-upgrade · dsh-policy-brief-draft · dsh-power-loss-split · dsh-power-ticket-check · dsh-ppap-check · dsh-protest-deadline · dsh-railway-window · dsh-repair-order-qc · dsh-research-report · dsh-review-reply-check · dsh-rulefile-check · dsh-safety-brief-check · dsh-score · dsh-session-sync · dsh-site-log-check · dsh-skill-pack-security · dsh-soe-decision-check · dsh-soilwater-check · dsh-sop-sync-check · dsh-spc-gbt-adapter · dsh-talk · dsh-tender-extract · dsh-tender-matrix · dsh-test-drive · dsh-ticktick · dsh-translate · dsh-warranty-calc · dsh-budget · 🧊 FROZEN — see the repo README dsh-claude-move · 🧊 FROZEN — see the repo README dsh-defend · 🧊 FROZEN — see the repo README dsh-draw · 🧊 FROZEN — see the repo README dsh-reach · 🧊 FROZEN — see the repo README dsh-background-agents · 🚫 RETIRED — see the repo README dsh-session-pin · 🚫 RETIRED — see the repo README dsh-team-rooms · 🚫 RETIRED — see the repo README
Apache-2.0. Every file in this repository is covered by it.