dsh-plugin-mobile-link
Verifieddsh-plugin-mobile-link Β· v0.2.0 Β· MIT
Put your PC's DeepSeek Harness in your pocket: dials a relay over WSS so the native iOS client reaches this machine even without a public IP.
Install
dsh plugin add dsh-plugin-mobile-link Confirm the layer applied with dsh --profile default --dump-config β see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Readme
dsh-plugin-mobile-link
The computer half of DSH Mobile: it dials a relay over WSS, so the native iOS client reaches this DSH instance even though the computer has no public IP.
iPhone App ββWSSβββΆ RelayοΌε
¬η½οΌεͺι΄ζδΈθ½¬εοΌββWSSβββΆ this plugin ββHTTP+WSβββΆ 127.0.0.1:<port>
The connector always talks to the local DSH as 127.0.0.1:<port>, so the host's
authority and its trust fence are unaffected: no --trusted-host, no rewritten
Host, no new listening port on this machine.
plugins/mobile-link/
βββ package.json # type: module, dsh.bundle.patch, bin: dsh-mobile-link
βββ cordis.patch.yml # bundle patch: the loader row + config reference
βββ lib/
β βββ index.js # cordis plugin: starts the agent, registers 3 routes
β βββ link.js # the DLP agent transport: identity, socket, heartbeat, reconnect
β βββ router.js # frames β local DSH mux streams, per-device `$events`
β βββ dlp.js # DLP v1 frame codec (shared with the relay)
β βββ files.js # phone β computer file transfers (`_link/file*` methods)
β βββ enroll.js # invite-code redemption, writes ~/.dsh/mobile-link/agent.json
β βββ routes.js # GET /mobile-link/status, POST /pair-code, GET /qr
β βββ qr.js # dependency-free QR SVG
β βββ cli.js # dsh-mobile-link: enroll / mint-pair-code
βββ test/ # node --test, 100+ tests (no DSH, no network)
Install
dsh plugin --profile web add dsh-plugin-mobile-link
Then restart DSH (or reload the profile). From a checkout the same command takes
a path β the leading ./ matters, because DSH anchors a relative spec against
your current directory instead of resolving it inside the profile:
dsh plugin --profile web add ./plugins/mobile-link
Use
Register this computer with a relay (once). Either redeem an invite code:
dsh-mobile-link enroll --invite <ιθ―·η > --relay wss://<δ½ ηη«ηΉ>/dsh-linkβ¦or register it on the relay host with
relay/admin.py agent-register --write-config ~/.dsh/mobile-link/agent.json.Mint a pairing code, and show it as a QR the phone camera can read:
dsh-mobile-link --mint-pair-code # prints JSON: code + relay + agentIdOr open
/mobile-link/qron the local DSH (behind DSH's own authentication).Scan it in the iOS app. After that the phone reconnects on its own β nothing else has to be run by hand.
GET /mobile-link/status reports whether the link is up, which devices are
attached, and whether this computer is registered yet.
Configuration
All optional; the defaults are what a stock deployment needs. Set them in the
plugin's config block (cordis.patch.yml), not by editing this file.
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
false stops the outbound link without uninstalling |
relayUrl |
from agent.json |
Relay base URL; a bare deployment dials <relay>/link/agent |
agentId / agentSecret |
from agent.json |
Override the enrolled identity |
stateFile |
~/.dsh/mobile-link/agent.json |
Where the identity lives |
dshUrl |
discovery | Explicit local DSH base URL |
endpointFile |
$DSH_HOME/desktop-shell/endpoint.json |
DSH endpoint handoff file |
heartbeatMs |
20000 |
DLP ping interval |
Address resolution order: this config block, then DSH_RELAY_URL (or
DSH_MOBILE_LINK_RELAY), then the enrolled identity file, then the repository
placeholder wss://relay.example.com/dsh-link β the placeholder being the
"nothing configured yet" sentinel rather than a real address.
Design notes
- No required services.
injectis empty and the routes are attached throughctx.inject([...]), so a future DSH that renames or dropswebServer/connectioncannot make the tunnel fatal on boot. - Protocol-transparent. Nothing outside
lib/is imported and no DSH business API is touched: the connector forwards frames, it does not interpret sessions. The relay has the same property. - Disable by removing the row from the profile's
cordis.patch.yml, or by settingenabled: false.
Test
cd plugins/mobile-link && npm test # zero dependencies
The wire protocol is specified in
docs/RELAY-PROTOCOL.md.
MIT.