DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Endless-zby /

Endless-zby/dsh-lan-share

Verified

LAN text and file sharing for DeepSeek Harness — discover peers, send text/files, accept-or-ask policy

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@39be6f93

dsh-lan-share

Share text and files between DeepSeek Harness devices on the same local network — from a 局域网服务 tab in the right sidebar, or by asking the agent.

简体中文说明见 README.zh.md.

What it does

  • Discovers devices that also run this plugin: UDP multicast plus broadcast, with a hand-added IP path for networks that filter both.
  • Rename devices — your own name (what the whole LAN sees) or a local alias for someone else's machine.
  • Sends text or a file to one chosen device.
  • Receives text and files, with the file placed in a directory you choose (the DSH working directory, or a path you set).
  • Asks or accepts automatically: an "全部默认接收" master switch, a fallback policy for unknown devices, and a per-device override on top. A size ceiling and an extension filter decide which files may skip the question.
  • Notifies on arrival: unread count on the tab, a page-wide prompt for a file that needs a decision, and a receive history with the local path.
  • Shows progress for every send and receive: bytes, rate, ETA, cancel.
  • Resumes an interrupted transfer from the byte the receiver actually kept.
  • Visibility switch: hide this device from the LAN entirely, or require a shared code before another device may connect.
  • Seven model tools (lan_share_devices, lan_share_send_text, lan_share_send_file, lan_share_inbox, lan_share_respond, lan_share_rename_device, lan_share_settings) so the agent can do all of the above in a conversation.

Install

dsh plugin --profile web add dsh-lan-share

DSH Desktop uses the web profile; restart the app afterwards, because the host half only loads at boot.

If dsh is not on PATH, use the binary shipped with the desktop app:

$app = "<INSTALL_DIR>\DSH Desktop\resources\app"
node "$app\node_modules\@deepseek-ai\dsh\lib\bin.js" plugin --profile web add dsh-lan-share

Verify

  1. profiles\web\package.json lists dsh-lan-share in dependencies and in dsh.profile.bundles.
  2. profiles\web\node_modules\dsh-lan-share\lib\ contains index.js and client.js.
  3. After a restart, a conversation's right sidebar "add tab" guide offers 局域网服务, and a 局域网服务 button appears in the conversation header.

Install on another machine

A LAN plugin is installed once per machine — it is not "install on one, the whole network has it". Two routes:

1. Ship the tarball (no registry, no toolchain on the target)

On the development machine:

npm run check      # make sure the artifacts are current and the gates pass
npm pack           # writes dsh-lan-share-<version>.tgz

Copy the .tgz to the target (USB, scp, or send it with this very plugin), then on the target machine:

# The dsh bundled with the desktop app; DSH Desktop uses the `web` profile
$app = "<INSTALL_DIR>\DSH Desktop\resources\app"
& "$app\node_modules\node\bin\node.exe" "$app\node_modules\@deepseek-ai\dsh\lib\bin.js" `
    plugin --profile web add "C:\path\to\dsh-lan-share-0.1.0.tgz"

Then quit and restart that machine's harness (tray → Quit for the desktop app, Ctrl+C and re-run for dsh web).

lib/ is built into the tarball, so the target needs no Node toolchain, no npm install, and no network. There is no src/ and no devDependency inside it.

2. Publish to npm

npm publish --access public

Every machine is then one command, with nothing to copy:

dsh plugin --profile web add dsh-lan-share

Verifying on the target

# 1) the manifest
Select-String dsh-lan-share "$env:APPDATA\dsh-desktop\harness\profiles\web\package.json"

# 2) the built halves shipped with it
Test-Path "$env:APPDATA\dsh-desktop\harness\profiles\web\node_modules\dsh-lan-share\lib\client.js"

# 3) the LAN plane (no login needed; the port is in the startup log or the panel header)
curl.exe -s "http://127.0.0.1:48901/lan-share/v1/info"

# 4) the panel plane: 401 without a cookie, 200 with one
curl.exe -s -o NUL -w '%{http_code}' "http://127.0.0.1:43129/lan-share/api/state"

That 401/200 pair is the cheapest proof the trust gate is really working, and it is worth re-running on every deployment.

Two timings that look like failures

  • The panel routes register a beat after the listening port. Probing /lan-share/api/state the instant the port opens answers 404; a second later it answers 401. Do not read that as "the plugin did not install".
  • The browser boot graph is scanned once, at harness start. After installing — or after rebuilding lib/client.js — that harness must be restarted, because the page keeps the old graph. The host half hot-mounts; the browser half does not.

Use

Open the tab from the sidebar's add-tab guide, or ask the agent to send something.

  1. Same network, nothing else to do. On a normal home or office LAN the two devices find each other within a few seconds. If they do not, use 手动添加设备 with the other machine's IP — many guest Wi-Fi networks and managed switches drop multicast.
  2. First time on a trusted network: leave 共享口令 empty, or set the same code on both machines. With a code set, a device that does not know it cannot connect at all.
  3. Send: pick the device, then 发文字 or 发文件. The file box takes a local absolute path — a browser cannot read a real path from a file picker, so the path is what the panel can actually send.
  4. Receive: with the default policy the panel asks before any byte moves. Turn on 全部默认接收 to skip the question, and use a device's own policy selector when one machine should stay manual.

Where received files go

The 设置 tab chooses between 当前工作区目录 (the DSH process working directory, or a path you set) and a 指定目录. The resolved absolute path is shown at the top of the panel, so there is never a guess about where a file landed. Partially received transfers live in <save dir>/.dsh-lan-share-incoming and are removed once the file is complete.

Ports and firewall

Port Protocol Purpose
48900 UDP Beacons: multicast to 239.255.77.88, plus broadcast to 255.255.255.255
48901 TCP Transfer plane, bound to 0.0.0.0

Both are configurable in the composition patch row:

- insert:
    - id: lan-share
      name: 'dsh-lan-share'
      config:
        discoveryPort: 48900
        transferPort: 48901
        multicastGroup: '239.255.77.88'
        checksumMaxBytes: 268435456
        maxConcurrentInbound: 4
        registerTools: true

If the port is taken (a second instance on the same machine), the plugin binds a free port instead, says so in the panel, and hand-added devices still work.

The transfer plane is not the DSH web server. The web server is loopback-only and gated by a browser cookie; this plugin runs its own listener on 0.0.0.0 so a peer on the LAN can reach it, and gates every route with the bearer token from the handshake. The panel, in contrast, uses same-origin routes on the DSH web server and is gated by the host's own trust fence.

Security model

  • Beacons are unauthenticated advertisements. They can only make a device appear; they never authorise anything.
  • Every data request carries a token proving the sender completed a handshake. With 共享口令 set, that requires knowing the code, and changing the code invalidates every token already issued.
  • The sender's name comes from the receiver's own device table, never from the request body — one device cannot label its messages as another's.
  • File names are sanitized to a single path segment, and the resolved path is re-checked against the save directory before every write.
  • Executables are refused by default (exe, bat, cmd, com, scr, msi, ps1, vbs, js, jar), whatever the policy says.
  • A file is only renamed into the save directory after its declared size — and its digest, when one was offered — has been verified.

An open LAN (no share code) means any device running this plugin on the same segment can send you files. That is the convenient default for a home network; set a code on an untrusted one.

Development

npm install
npm test                  # tsc + tests/*.ts
npm run build             # host half → lib/, browser half → lib/client.js
npm run typecheck
npm run check             # tests + build + the two publish gates

Tests have no framework: each file under tests/ is a plain Node script that prints N/M checks passed. They cover four layers — pure rules, two real nodes over loopback sockets, UDP discovery, the assembled service twice over, and the panel routes' trust gate. See AGENTS.md for the platform contracts worth knowing before changing anything.

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 39be6f9345b4

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout