dsh-remote-tunnel-easy 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Raiyan007-gb
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ <div align="center">
2
+
3
+ # dsh-remote-tunnel-easy
4
+
5
+ <p align="center">
6
+ <img src="assets/logo.svg" alt="dsh-remote-tunnel-easy" width="800">
7
+ </p>
8
+
9
+ **Open your DeepSeek Harness session on your phone — by pointing the camera at it.**
10
+
11
+ Scan the QR in **Settings → Plugins** and the harness opens in your phone's
12
+ browser, *inside the session you are already working in*. Same workspace, same
13
+ chat. No typing a URL. The `dsh web` terminal prints nothing.
14
+
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
16
+ [![GitHub Stars](https://img.shields.io/github/stars/Raiyan007-gb/dsh-remote-tunnel-easy)](https://github.com/Raiyan007-gb/dsh-remote-tunnel-easy/stargazers)
17
+ [![Release](https://img.shields.io/github/v/release/Raiyan007-gb/dsh-remote-tunnel-easy)](https://github.com/Raiyan007-gb/dsh-remote-tunnel-easy/releases)
18
+ [![npm](https://img.shields.io/npm/v/dsh-remote-tunnel-easy?color=%23cb0000)](https://www.npmjs.com/package/dsh-remote-tunnel-easy)
19
+
20
+ </div>
21
+
22
+ A one-command **DeepSeek Harness web bundle** that brings QR-based remote
23
+ handoff to the Settings page. It starts a `cloudflared` quick tunnel, loops
24
+ your phone into the exact session the desktop is using, and draws the QR code
25
+ plus settings right next to your other plugins — no terminal noise, no
26
+ database, no Firebase, no app install.
27
+
28
+ - **Scan to open** — a real QR code in **Settings → Plugins**, fresh every run
29
+ - **Same session** — the phone lands inside the chat and workspace you are already in
30
+ - **Self-installing** — detects `cloudflared`, and downloads it (SHA-256 verified) when missing
31
+ - **Regenerate** — one click mints a fresh tunnel URL for the same session, without restarting
32
+ - **Editable settings** — tunnel target, `cloudflared` path, and session handoff from the page
33
+ - **Nothing stored** — the tunnel URL is random per run; nothing is saved anywhere
34
+ - **Everywhere** — Windows (x64/x86), macOS (Intel/Apple Silicon), and Linux (x64/arm64)
35
+
36
+ ## At a Glance
37
+
38
+ | Question | Answer |
39
+ |----------|--------|
40
+ | **What is it?** | A `dsh` bundle that shows a scannable QR code and access link in the Settings page, so a phone opens the harness inside the active session. |
41
+ | **Who is it for?** | Anyone running `dsh web` who wants their phone on the same session without typing tunnel URLs and tokens. |
42
+ | **What do I get?** | A loopback edge proxy, a `cloudflared` quick tunnel, same-session handoff, and a live QR + settings card in **Settings → Plugins**. |
43
+ | **What does it run on?** | Windows, macOS, and Linux — anything `dsh` runs on. |
44
+ | **Is cloud required?** | No account or signup. `cloudflared` is used, and auto-downloaded on first run when missing; the tunnel is public, and the token in the link is the gate. |
45
+
46
+ ---
47
+
48
+ ## Get Started
49
+
50
+ Run `dsh web` once so a profile exists — that is the only prerequisite.
51
+ `cloudflared` is no longer something you install by hand: on first tunnel start
52
+ the bundle probes your `PATH`, and when no `cloudflared` is found it downloads
53
+ the official pinned binary (SHA-256 verified), caches it under your user cache
54
+ directory, and reuses it from then on. Prefer your own install? Put it on
55
+ `PATH`, or set the **cloudflared path** field in the card to an absolute path —
56
+ an explicit path disables both probing and downloading.
57
+
58
+ The simplest path — install from the npm registry with the plugin name:
59
+
60
+ ```sh
61
+ dsh plugin --profile web add dsh-remote-tunnel-easy@latest --config.minimumReleaseAge=0
62
+ ```
63
+
64
+ The `--config.minimumReleaseAge=0` flag bypasses pnpm's ~24-hour release-age
65
+ gate, so a freshly published version installs immediately. Without it, a plain
66
+ `dsh plugin --profile web add dsh-remote-tunnel-easy` still works but may hold off
67
+ until the freshness window lapses.
68
+
69
+ Or, if you prefer, install straight from the GitHub repository URL:
70
+
71
+ ```sh
72
+ dsh plugin --profile web add https://github.com/Raiyan007-gb/dsh-remote-tunnel-easy
73
+ ```
74
+
75
+ For a local checkout instead, clone it and add the folder:
76
+
77
+ ```sh
78
+ git clone https://github.com/Raiyan007-gb/dsh-remote-tunnel-easy
79
+ dsh plugin --profile web add \./dsh-remote-tunnel-easy
80
+ ```
81
+
82
+ These initialize the profile if needed, link the package, and register the
83
+ bundle. No build step — the package ships plain ESM with **zero runtime
84
+ dependencies** (the QR encoder and cloudflared resolver are vendored in-tree),
85
+ so `add` and `remove` stay fast and never run install scripts.
86
+
87
+ > **Security note:** installing from a git URL asks for permission to run the
88
+ > package's install scripts. This package has none (plain ESM, no
89
+ > `postinstall`), but pin a commit — `#<sha>` on the URL — to freeze what runs.
90
+ > To skip install permissions entirely, `pnpm pack` a tarball and
91
+ > `dsh plugin --profile web add ./dsh-remote-tunnel-easy-1.1.0.tgz`.
92
+
93
+ Then **restart** `dsh web` — the QR and settings appear on **Settings →
94
+ Plugins → DSH Remote** on every start.
95
+
96
+ ---
97
+
98
+ ## What it does
99
+
100
+ On every `dsh web` start the bundle:
101
+
102
+ 1. Spawns a loopback edge proxy (127.0.0.1, ephemeral port) that forwards every
103
+ request and WebSocket upgrade to the harness, rewriting `Host` and `Origin`
104
+ to the loopback authority. This is what makes the harness's `/api`
105
+ browser-trust fence accept tunneled traffic — the fence requires
106
+ `Origin == Host`, and a phone's `Origin` is the tunnel hostname, which
107
+ `--http-host-header` rewriting alone can never satisfy. Without the proxy
108
+ the app loads but every API call 403s.
109
+ 2. Locates `cloudflared` — the configured **cloudflared path** override, else a
110
+ binary on `PATH`, else a pinned download (`2026.8.2`) SHA-256 verified and
111
+ cached under the user cache directory. It then spawns
112
+ `cloudflared tunnel --no-autoupdate --url http://127.0.0.1:<proxy-port>`
113
+ pointed at that proxy.
114
+ 3. Waits for cloudflared to print the random `https://<name>.trycloudflare.com` URL.
115
+ 4. Resolves this process's launch token via the harness connection service
116
+ (`authenticatedUrl` — the same mint the console line prints).
117
+ 5. Seeds the most recently active session id into every served index page (via
118
+ the webserver's index-injection table), gated to non-loopback origins and
119
+ once per tab — so any tunnel entry lands inside the session the desktop is
120
+ working in. The id is resolved on the Host at render time (cached, refreshed
121
+ every 15s); the phone makes no `/api` call for the seed itself.
122
+ 6. Registers a token-gated `/remote-handoff` route as a fallback entry path:
123
+ same seeding, then the normal token→cookie login (SHA-256 constant-time
124
+ compare). Prefix-matched, so `/remote-handoff` and `/remote-handoff/` both work.
125
+ 7. Registers a `remote-handoff` settings namespace and a loopback-only bridge
126
+ (`/api/dsh-remote-handoff-settings`). The card in **Settings → Plugins →
127
+ DSH Remote** reads the tunnel status (QR matrix + access link) from that
128
+ bridge and draws them in the page, alongside the editable `tunnelTarget` /
129
+ `cloudflaredPath` / `sessionHandoff` settings. The **Regenerate** button
130
+ restarts the tunnel in place for a brand-new URL on the same session, and an
131
+ empty **tunnel target** auto-fills the harness's own loopback address. The
132
+ `dsh web` terminal prints nothing.
133
+
134
+ ---
135
+
136
+ ## Requirements
137
+
138
+ - No manual `cloudflared` install — downloaded automatically when missing
139
+ (Windows x64/x86, macOS Intel/Apple Silicon, Linux x64/arm64); any other
140
+ platform needs a `cloudflared` on `PATH` or an explicit **cloudflared path**.
141
+ - Network access on first run (to reach GitHub for the binary download)
142
+ - Node — already present where `dsh` runs
143
+ - Phone on any network — the tunnel is public; the token in the URL is the only
144
+ gate, so treat the shown link like a password.
145
+
146
+ ## Removing
147
+
148
+ ```sh
149
+ dsh plugin --profile web remove dsh-remote-tunnel-easy
150
+ ```
151
+
152
+ and restart `dsh web`.
153
+
154
+ ---
155
+
156
+ ## License
157
+
158
+ MIT — use it, modify it, ship it. See [LICENSE](LICENSE).
159
+
160
+ ---
161
+
162
+ <div align="center">
163
+
164
+ *Built for the [DeepSeek Harness](https://github.com/Raiyan007-gb) — scan, open, keep working.*
165
+
166
+ </div>
@@ -0,0 +1,81 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="880" height="200" viewBox="0 0 880 200" role="img" aria-label="dsh-remote-tunnel-easy">
2
+ <defs>
3
+ <linearGradient id="wc" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#0c1229"/>
5
+ <stop offset="1" stop-color="#221a4e"/>
6
+ </linearGradient>
7
+ <linearGradient id="wa" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0" stop-color="#6b8cff"/>
9
+ <stop offset="1" stop-color="#b887ff"/>
10
+ </linearGradient>
11
+ </defs>
12
+
13
+ <rect x="0" y="0" width="880" height="200" rx="26" fill="url(#wc)"/>
14
+ <rect x="0.5" y="0.5" width="879" height="199" rx="25.5" fill="none" stroke="#ffffff" stroke-opacity="0.09" stroke-width="1"/>
15
+
16
+ <rect x="36" y="36" width="128" height="128" rx="22" fill="#ffffff"/>
17
+
18
+ <g fill="#101c33">
19
+ <rect x="48" y="48" width="35" height="35" rx="4"/>
20
+ <rect x="53" y="53" width="25" height="25" rx="3" fill="#ffffff"/>
21
+ <rect x="58" y="58" width="15" height="15" rx="2"/>
22
+ <rect x="118" y="48" width="35" height="35" rx="4"/>
23
+ <rect x="123" y="53" width="25" height="25" rx="3" fill="#ffffff"/>
24
+ <rect x="128" y="58" width="15" height="15" rx="2"/>
25
+ <rect x="48" y="118" width="35" height="35" rx="4"/>
26
+ <rect x="53" y="123" width="25" height="25" rx="3" fill="#ffffff"/>
27
+ <rect x="58" y="128" width="15" height="15" rx="2"/>
28
+ <rect x="88" y="78" width="5" height="5"/>
29
+ <rect x="98" y="78" width="5" height="5"/>
30
+ <rect x="108" y="78" width="5" height="5"/>
31
+ <rect x="78" y="88" width="5" height="5"/>
32
+ <rect x="78" y="98" width="5" height="5"/>
33
+ <rect x="78" y="108" width="5" height="5"/>
34
+ <rect x="88" y="53" width="5" height="5" fill="#101c33"/>
35
+ <rect x="103" y="58" width="5" height="5" fill="#101c33"/>
36
+ <rect x="93" y="63" width="5" height="5" fill="#101c33"/>
37
+ <rect x="108" y="68" width="5" height="5" fill="#101c33"/>
38
+ <rect x="88" y="73" width="5" height="5" fill="#101c33"/>
39
+ <rect x="108" y="53" width="5" height="5" fill="#101c33"/>
40
+ <rect x="113" y="63" width="5" height="5" fill="#101c33"/>
41
+ <rect x="98" y="73" width="5" height="5" fill="#101c33"/>
42
+ <rect x="58" y="83" width="5" height="5" fill="#101c33"/>
43
+ <rect x="68" y="88" width="5" height="5" fill="#101c33"/>
44
+ <rect x="53" y="93" width="5" height="5" fill="#101c33"/>
45
+ <rect x="63" y="98" width="5" height="5" fill="#101c33"/>
46
+ <rect x="73" y="103" width="5" height="5" fill="#101c33"/>
47
+ <rect x="58" y="108" width="5" height="5" fill="#101c33"/>
48
+ <rect x="108" y="83" width="5" height="5" fill="#101c33"/>
49
+ <rect x="93" y="88" width="5" height="5" fill="#101c33"/>
50
+ <rect x="103" y="93" width="5" height="5" fill="#101c33"/>
51
+ <rect x="88" y="98" width="5" height="5" fill="#101c33"/>
52
+ <rect x="113" y="103" width="5" height="5" fill="#101c33"/>
53
+ <rect x="98" y="108" width="5" height="5" fill="#101c33"/>
54
+ <rect x="53" y="113" width="5" height="5" fill="#101c33"/>
55
+ <rect x="128" y="83" width="5" height="5" fill="#101c33"/>
56
+ <rect x="138" y="88" width="5" height="5" fill="#101c33"/>
57
+ <rect x="123" y="93" width="5" height="5" fill="#101c33"/>
58
+ <rect x="143" y="98" width="5" height="5" fill="#101c33"/>
59
+ <rect x="133" y="103" width="5" height="5" fill="#101c33"/>
60
+ <rect x="128" y="108" width="5" height="5" fill="#101c33"/>
61
+ <rect x="148" y="113" width="5" height="5" fill="#101c33"/>
62
+ <rect x="88" y="123" width="5" height="5" fill="#101c33"/>
63
+ <rect x="103" y="128" width="5" height="5" fill="#101c33"/>
64
+ <rect x="93" y="133" width="5" height="5" fill="#101c33"/>
65
+ <rect x="108" y="138" width="5" height="5" fill="#101c33"/>
66
+ <rect x="98" y="143" width="5" height="5" fill="#101c33"/>
67
+ <rect x="128" y="123" width="5" height="5" fill="#101c33"/>
68
+ <rect x="138" y="128" width="5" height="5" fill="#101c33"/>
69
+ <rect x="123" y="133" width="5" height="5" fill="#101c33"/>
70
+ <rect x="143" y="138" width="5" height="5" fill="#101c33"/>
71
+ <rect x="88" y="148" width="5" height="5" fill="#101c33"/>
72
+ <rect x="113" y="148" width="5" height="5" fill="#101c33"/>
73
+ <rect x="133" y="143" width="5" height="5" fill="#101c33"/>
74
+ <rect x="83" y="118" width="5" height="5" fill="#101c33"/>
75
+ <rect x="118" y="118" width="5" height="5" fill="#101c33"/>
76
+ </g>
77
+
78
+ <text x="196" y="88" font-family="Segoe UI, -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif" font-size="46" font-weight="700" fill="#f6f7ff" letter-spacing="0.5">dsh-remote-tunnel-easy</text>
79
+ <text x="198" y="122" font-family="Segoe UI, -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif" font-size="17" fill="#aeb9ff">Remote access for DeepSeek Harness &#8212; scan, open, keep working.</text>
80
+ <rect x="198" y="138" width="86" height="5" rx="2.5" fill="url(#wa)"/>
81
+ </svg>
@@ -0,0 +1,12 @@
1
+ # Bundle patch for dsh-remote-tunnel-easy: starts a cloudflared quick tunnel and
2
+ # publishes its access link and QR code to the Settings → Plugins page (the
3
+ # `dsh web` terminal prints nothing), and seeds the app's persisted session
4
+ # selection so a phone scan lands in the harness's most recently active
5
+ # session. No database, no Firebase, no persisted state — the link is
6
+ # regenerated fresh each run.
7
+
8
+ - insert:
9
+ - id: dsh-remote-tunnel-easy
10
+ name: 'dsh-remote-tunnel-easy'
11
+ config:
12
+ sessionHandoff: true