dsh-mesh-access 1.4.6 → 1.5.1

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/CHANGELOG.md CHANGED
@@ -186,3 +186,15 @@
186
186
  ## 1.4.6 — 修复所有复制按钮同时显示「已复制」
187
187
 
188
188
  - copied 状态由布尔改为记录被复制的值,各按钮只在自己的值刚复制时显示「已复制」。
189
+
190
+ ## 1.5.0 — 面板分页:快速上手 + 控制台
191
+
192
+ - 面板顶部胶囊分段切换「快速上手 / 控制台」两页,默认快速上手。
193
+ - 快速上手页:装插件 → 组网直连 → 门锁 → 公网入口 分步卡片,
194
+ 重点项着色标注(蓝=操作、绿=好处、红=必须注意),代码一律代码框。
195
+ - 新增「太懒了?」卡片:一键复制懒人文档(填空式提示词),
196
+ 粘给任何 AI 即可托管全部安装流程(含安全组/DNS 等人工步骤提醒)。
197
+
198
+ ## 1.5.1 — 删掉「第 0 步装插件」
199
+
200
+ - 能看到这个页面的用户必然已装好插件,删除冗余步骤;懒人文档同步删掉装插件一项。
package/lib/client.js CHANGED
@@ -103,6 +103,7 @@ window.__ModuleLoader__.load({
103
103
  const [authBusy, setAuthBusy] = react.useState(false)
104
104
  const [authErr, setAuthErr] = react.useState(null)
105
105
  const [authForm, setAuthForm] = react.useState({ username: '', password: '' })
106
+ const [tab, setTab] = react.useState('guide')
106
107
  const [authMsg, setAuthMsg] = react.useState('')
107
108
  const [busy, setBusy] = react.useState(false)
108
109
  const [tunnelBusy, setTunnelBusy] = react.useState(false)
@@ -232,11 +233,73 @@ window.__ModuleLoader__.load({
232
233
  const referral = (state && state.referral) || 'https://starvpn.cn/register.html?referralCode=Kurali'
233
234
  const tn = tunnel || (state && state.tunnel) || {}
234
235
 
235
- return h(
236
- 'div',
237
- { style: S.wrap },
238
- h('div', { style: S.h1 }, '组网访问'),
239
- h('div', { style: S.sub }, '用手机远程控制:手机浏览器打开就是你在电脑上用的那个 DSH——同一实例、同一份会话,不用第二个实例,不用 SSH。'),
236
+ // ===== 快速上手页 =====
237
+ const accent = '#58a6ff', good = '#3fb950', warn = '#f85149'
238
+ const Step = ({ n, title, kids }) => h('div', { style: { marginBottom: 18 } },
239
+ h('div', { style: { ...S.row, marginBottom: 6 } },
240
+ h('span', { style: { width: 22, height: 22, borderRadius: 999, background: accent, color: '#fff', fontSize: 12, fontWeight: 700, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, String(n)),
241
+ h('span', { style: { fontSize: 14, fontWeight: 600 } }, title),
242
+ ),
243
+ kids,
244
+ )
245
+ const K = ({ children }) => h('code', { style: { ...S.mono, background: 'rgba(88,166,255,.15)', color: accent, padding: '1px 6px', borderRadius: 5 } }, children)
246
+ const Mark = ({ color, children }) => h('span', { style: { color, fontWeight: 600 } }, children)
247
+ const lazyDoc = `把我手机远程接到 DSH 上。请严格按照下面的流程执行,遇到选择题先问我。
248
+
249
+ 【我的信息】(把尖括号换成真实值)
250
+ - 我的 DSH 已经在电脑上用 dsh web 跑起来了(端口 3080)
251
+ - 服务器(可选):IP <SERVER_IP>,root 密码我自己输,不要问
252
+ - 域名(可选):<MY_DOMAIN>,DNS A 记录我已指到服务器
253
+
254
+ 【你要做的事】
255
+ 1. 组网直连:如果我有星空组网/同一局域网,通过插件面板(左侧「组网访问」)在组网地址上开端口,给我带 token 的手机访问地址
256
+ 2. 公网入口(我填了服务器才做):
257
+ - 在服务器上运行 dsh-mesh-access 项目的 tools/frps-setup.sh(GitHub Release 下载 tgz 解包)
258
+ - 云安全组放行 7000 和 21081 两个端口——这一步做不了,提醒我去控制台点
259
+ - 在电脑插件面板「公网隧道」卡片填服务器信息并启动,验证公网地址可达(401/弹窗=正常)
260
+ 3. 门锁:在面板「入口登录」切到密钥模式,把「手机首次打开」链接给我
261
+ 4. 全部完成后按 docs/AI-SETUP.md 第 6 节模板回报结果;任何一步验证不过不许说成功
262
+
263
+ 参考文档(插件的 docs/ 目录里有):VPS.md(服务器步骤)、AI-SETUP.md(你的操作手册)。`
264
+
265
+ const tabBtn = (id, label) => h('div', {
266
+ style: {
267
+ padding: '6px 18px', borderRadius: 999, cursor: 'pointer', fontSize: 13,
268
+ background: tab === id ? 'rgba(88,166,255,.9)' : 'transparent',
269
+ color: tab === id ? '#fff' : 'inherit',
270
+ fontWeight: tab === id ? 600 : 400,
271
+ transition: 'all .15s ease', userSelect: 'none',
272
+ },
273
+ onClick: () => setTab(id),
274
+ }, label)
275
+
276
+ const guidePage = h('div', null,
277
+ h(Card, { title: '第 1 步 · 组网内直连(最短路径:2 次点击)' },
278
+ h(Step, { n: 1, title: '开端口' }, h('div', { style: S.hint }, '切到「控制台」页 → 「动作」卡 → ', h(Mark, {color:accent}, '在组网地址上开端口'), '。前提:手机和电脑在同一个组网(星空/局域网)。')),
279
+ h(Step, { n: 2, title: '复制地址' }, h('div', { style: S.hint }, '「访问地址」卡里点复制——那串 ', h(K, null, 'token'), ' 本身就是一层凭证。')),
280
+ h(Step, { n: 3, title: '手机打开' }, h('div', { style: S.hint }, '就是电脑上这个 DSH:', h(Mark, {color:good}, '同实例、同会话'), ',不用 SSH、不用第二个 dsh。')),
281
+ ),
282
+ h(Card, { title: '第 2 步(可选)· 加一把门锁' },
283
+ h('div', { style: S.hint }, '「控制台 → 入口登录」,滑块三选一。推荐 ', h(Mark, {color:accent}, '密钥'), ':卡片会自动生成「手机首次打开」链接,手机点一次 ', h(Mark, {color:good}, '30 天免登录、无弹窗'), ';泄露随时重置。账号密码模式 = 弹窗,24 小时仅该设备免登录。'),
284
+ ),
285
+ h(Card, { title: '第 3 步(可选)· 自备服务器做公网入口' },
286
+ h('div', { style: S.hint }, '组网中继慢(800–990ms)或要给非组网设备访问时走这条:'),
287
+ h(Step, { n: 1, title: '服务器(root)' }, h('div', { style: S.hint }, '跑 ', h(K,null,'tools/frps-setup.sh --domain 域名'), ',装好 frps + 证书 + 反代,结尾打印 IP/token/端口;', h(Mark, {color:warn}, '云安全组要自己放行 7000/21081'), ',DNS A 记录自己加。')),
288
+ h(Step, { n: 2, title: '电脑' }, h('div', { style: S.hint }, '「控制台 → 公网隧道 → 填服务器信息」,保存即启动,绿色 pill = 公网可达,延迟通常 30–60ms。')),
289
+ ),
290
+ h(Card, { title: '太懒了?把下面这段扔给 AI,它全包' },
291
+ h('div', { style: S.row, marginBottom: 8 },
292
+ h('button', { style: S.btnPrimary, onClick: () => copy(lazyDoc) }, copied === lazyDoc ? '已复制' : '复制懒人文档'),
293
+ h('span', { style: S.hint }, '粘到任何 AI 对话框(包括 DSH 自己),把尖括号换成真实值即可'),
294
+ ),
295
+ h('details', null,
296
+ h('summary', { style: { ...S.hint, cursor: 'pointer' } }, '展开预览懒人文档'),
297
+ h('pre', { style: { ...S.mono, whiteSpace: 'pre-wrap', wordBreak: 'break-all', background: 'rgba(127,127,127,.12)', borderRadius: 8, padding: 12, marginTop: 8, fontSize: 12 } }, lazyDoc),
298
+ ),
299
+ ),
300
+ )
301
+
302
+ const consolePage = h('div', null,
240
303
 
241
304
  h(
242
305
  Card, { title: '当前状态' },
@@ -477,6 +540,24 @@ window.__ModuleLoader__.load({
477
540
  ),
478
541
  ),
479
542
  )
543
+
544
+ return h(
545
+ 'div',
546
+ { style: S.wrap },
547
+ h('div', { style: S.h1 }, '组网访问'),
548
+ h('div', { style: S.sub }, '用手机远程控制:手机浏览器打开就是你在电脑上用的那个 DSH——同一实例、同一份会话,不用第二个实例,不用 SSH。'),
549
+ h('div', {
550
+ style: {
551
+ display: 'inline-flex', gap: 4, padding: 4, borderRadius: 999,
552
+ border: '1px solid rgba(127,127,127,.4)', background: 'rgba(127,127,127,.12)',
553
+ marginBottom: 16,
554
+ },
555
+ },
556
+ tabBtn('guide', '快速上手'),
557
+ tabBtn('console', '控制台'),
558
+ ),
559
+ tab === 'guide' ? guidePage : consolePage,
560
+ )
480
561
  }
481
562
 
482
563
  function apply(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mesh-access",
3
- "version": "1.4.6",
3
+ "version": "1.5.1",
4
4
  "description": "Control your DSH from your phone: opens a port on the mesh/VPN interface from inside the running server process, so a phone browser gets the same instance and the same session list — no SSH, no second dsh. Also reachable from another PC, a GUI NAS, or a TV box.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",