dsh-remote 0.1.2 → 0.1.4

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.
@@ -0,0 +1,6 @@
1
+ # dsh-remote bundle patch: inserts this plugin into a profile's layer stack.
2
+ # Applied when a profile lists this bundle; rows reference the package by name so
3
+ # Node resolution finds the installed code.
4
+ - insert:
5
+ - id: dsh-remote
6
+ name: 'dsh-remote'
package/lib/client.js CHANGED
@@ -4,118 +4,135 @@
4
4
  // hosts and the exact SSH tunnel / reverse-tunnel / reverse-proxy commands,
5
5
  // with a copy button. Data comes from the host half's JSON endpoint
6
6
  // (GET /dsh-remote/info) served by the official `webServer` service.
7
- import * as React from 'react'
7
+ //
8
+ // Client entries must be classic scripts that register via
9
+ // window.__ModuleLoader__.load({ id, factory }); the factory receives a
10
+ // synchronous `require` and returns the module exports.
11
+ window.__ModuleLoader__.load({
12
+ id: 'dsh-remote',
13
+ factory: (require) => {
14
+ var module = { exports: {} }
15
+ var exports = module.exports
16
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
8
17
 
9
- export const name = 'dsh-remote'
18
+ const React = require('react')
10
19
 
11
- async function fetchInfo(target) {
12
- const q = target ? '?target=' + encodeURIComponent(target) : ''
13
- const res = await fetch('/dsh-remote/info' + q)
14
- const data = await res.json().catch(() => ({}))
15
- if (!res.ok) throw new Error((data && data.error) || 'HTTP ' + res.status)
16
- return data
17
- }
20
+ const name = 'dsh-remote'
18
21
 
19
- export function apply(ctx) {
20
- const slots = ctx.get('slots')
21
- if (slots === undefined) return
22
+ async function fetchInfo(target) {
23
+ const q = target ? '?target=' + encodeURIComponent(target) : ''
24
+ const res = await fetch('/dsh-remote/info' + q)
25
+ const data = await res.json().catch(() => ({}))
26
+ if (!res.ok) throw new Error((data && data.error) || 'HTTP ' + res.status)
27
+ return data
28
+ }
22
29
 
23
- function RemotePage() {
24
- const [info, setInfo] = React.useState(null)
25
- const [error, setError] = React.useState('')
26
- const [target, setTarget] = React.useState('')
27
- const [copied, setCopied] = React.useState(false)
30
+ function RemotePage() {
31
+ const [info, setInfo] = React.useState(null)
32
+ const [error, setError] = React.useState('')
33
+ const [target, setTarget] = React.useState('')
34
+ const [copied, setCopied] = React.useState(false)
28
35
 
29
- const refresh = (t) => {
30
- fetchInfo(t || '')
31
- .then(setInfo)
32
- .catch((err) => setError(String((err && err.message) || err)))
33
- }
36
+ const refresh = (t) => {
37
+ fetchInfo(t || '')
38
+ .then(setInfo)
39
+ .catch((err) => setError(String((err && err.message) || err)))
40
+ }
34
41
 
35
- React.useEffect(() => {
36
- refresh('')
37
- }, [])
42
+ React.useEffect(() => {
43
+ refresh('')
44
+ }, [])
38
45
 
39
- const copy = (text) => {
40
- if (navigator && navigator.clipboard) {
41
- navigator.clipboard
42
- .writeText(text)
43
- .then(() => {
44
- setCopied(true)
45
- setTimeout(() => setCopied(false), 1500)
46
- })
47
- .catch(() => {})
46
+ const copy = (text) => {
47
+ if (navigator && navigator.clipboard) {
48
+ navigator.clipboard
49
+ .writeText(text)
50
+ .then(() => {
51
+ setCopied(true)
52
+ setTimeout(() => setCopied(false), 1500)
53
+ })
54
+ .catch(() => {})
55
+ }
48
56
  }
49
- }
50
57
 
51
- const block = (title, code) =>
52
- React.createElement(
53
- 'div',
54
- { key: title, style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
55
- React.createElement('div', { style: { fontSize: '13px', fontWeight: 600 } }, title),
56
- React.createElement('code', {
57
- style: {
58
- display: 'block',
59
- padding: '8px 10px',
60
- borderRadius: '6px',
61
- border: '1px solid rgba(128,128,128,0.35)',
62
- fontSize: '12px',
63
- whiteSpace: 'pre-wrap',
64
- wordBreak: 'break-all',
65
- },
66
- }, code),
67
- React.createElement('button', { onClick: () => copy(code), style: { alignSelf: 'flex-start' } }, '复制'),
68
- )
58
+ const block = (title, code) =>
59
+ React.createElement(
60
+ 'div',
61
+ { key: title, style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
62
+ React.createElement('div', { style: { fontSize: '13px', fontWeight: 600 } }, title),
63
+ React.createElement('code', {
64
+ style: {
65
+ display: 'block',
66
+ padding: '8px 10px',
67
+ borderRadius: '6px',
68
+ border: '1px solid rgba(128,128,128,0.35)',
69
+ fontSize: '12px',
70
+ whiteSpace: 'pre-wrap',
71
+ wordBreak: 'break-all',
72
+ },
73
+ }, code),
74
+ React.createElement('button', { onClick: () => copy(code), style: { alignSelf: 'flex-start' } }, '复制'),
75
+ )
69
76
 
70
- if (error)
71
- return React.createElement('div', { style: { color: '#e06c75', padding: 16 } }, error)
72
- if (!info)
73
- return React.createElement('div', { style: { padding: 16, opacity: 0.6 } }, '加载中…')
77
+ if (error)
78
+ return React.createElement('div', { style: { color: '#e06c75', padding: 16 } }, error)
79
+ if (!info)
80
+ return React.createElement('div', { style: { padding: 16, opacity: 0.6 } }, '加载中…')
74
81
 
75
- const c = info.commands || {}
76
- const lan = Array.isArray(info.lanAddresses) ? info.lanAddresses : []
77
- const trusted = Array.isArray(info.trustedHosts) ? info.trustedHosts : []
82
+ const c = info.commands || {}
83
+ const lan = Array.isArray(info.lanAddresses) ? info.lanAddresses : []
84
+ const trusted = Array.isArray(info.trustedHosts) ? info.trustedHosts : []
78
85
 
79
- return React.createElement(
80
- 'div',
81
- { style: { padding: '16px', display: 'flex', flexDirection: 'column', gap: '14px' } },
82
- React.createElement('div', { style: { fontWeight: 600 } }, '远程访问(dsh-remote)'),
83
- React.createElement(
86
+ return React.createElement(
84
87
  'div',
85
- { style: { display: 'flex', gap: '16px', flexWrap: 'wrap', fontSize: '13px' } },
86
- React.createElement('span', null, 'Web GUI: ', React.createElement('code', null, info.url)),
87
- React.createElement('span', null, '端口: ', React.createElement('code', null, String(info.port))),
88
- lan.length
89
- ? React.createElement('span', null, '局域网: ', React.createElement('code', null, lan.join(', ')))
90
- : null,
91
- trusted.length
92
- ? React.createElement('span', null, 'trusted hosts: ', React.createElement('code', null, trusted.join(', ')))
93
- : null,
94
- ),
95
- React.createElement('div', { style: { fontSize: '12px', opacity: 0.75 } },
96
- '跨机器访问请用 SSH 隧道。harness 默认只监听 127.0.0.1,这是官方安全设计(GUI 无鉴权,--host 0.0.0.0 被刻意拒绝)。可选:输入 user@host 生成具体命令。',
97
- ),
98
- React.createElement('div', { style: { display: 'flex', gap: '8px' } },
99
- React.createElement('input', {
100
- value: target,
101
- onChange: (ev) => setTarget(ev.target.value),
102
- placeholder: 'user@remote-host(可选)',
103
- style: { flex: 1 },
104
- }),
105
- React.createElement('button', { onClick: () => refresh(target) }, '生成'),
106
- ),
107
- c.localForward ? block('本机 → 远程(ssh 本地转发,推荐)', c.localForward) : null,
108
- c.localForwardAuto ? block('autossh 保活版本', c.localForwardAuto) : null,
109
- c.reverseForward ? block('远程 → 本机(反向隧道,NAT 友好)', c.reverseForward) : null,
110
- c.trustedFlag ? block('反向代理直达(需自行加鉴权)', c.trustedFlag) : null,
111
- copied ? React.createElement('div', { style: { fontSize: '12px', opacity: 0.7 } }, '已复制 ✓') : null,
112
- )
113
- }
88
+ { style: { padding: '16px', display: 'flex', flexDirection: 'column', gap: '14px' } },
89
+ React.createElement('div', { style: { fontWeight: 600 } }, '远程访问(dsh-remote)'),
90
+ React.createElement(
91
+ 'div',
92
+ { style: { display: 'flex', gap: '16px', flexWrap: 'wrap', fontSize: '13px' } },
93
+ React.createElement('span', null, 'Web GUI: ', React.createElement('code', null, info.url)),
94
+ React.createElement('span', null, '端口: ', React.createElement('code', null, String(info.port))),
95
+ lan.length
96
+ ? React.createElement('span', null, '局域网: ', React.createElement('code', null, lan.join(', ')))
97
+ : null,
98
+ trusted.length
99
+ ? React.createElement('span', null, 'trusted hosts: ', React.createElement('code', null, trusted.join(', ')))
100
+ : null,
101
+ ),
102
+ React.createElement('div', { style: { fontSize: '12px', opacity: 0.75 } },
103
+ '跨机器访问请用 SSH 隧道。harness 默认只监听 127.0.0.1,这是官方安全设计(GUI 无鉴权,--host 0.0.0.0 被刻意拒绝)。可选:输入 user@host 生成具体命令。',
104
+ ),
105
+ React.createElement('div', { style: { display: 'flex', gap: '8px' } },
106
+ React.createElement('input', {
107
+ value: target,
108
+ onChange: (ev) => setTarget(ev.target.value),
109
+ placeholder: 'user@remote-host(可选)',
110
+ style: { flex: 1 },
111
+ }),
112
+ React.createElement('button', { onClick: () => refresh(target) }, '生成'),
113
+ ),
114
+ c.localForward ? block('本机 → 远程(ssh 本地转发,推荐)', c.localForward) : null,
115
+ c.localForwardAuto ? block('autossh 保活版本', c.localForwardAuto) : null,
116
+ c.reverseForward ? block('远程 → 本机(反向隧道,NAT 友好)', c.reverseForward) : null,
117
+ c.trustedFlag ? block('反向代理直达(需自行加鉴权)', c.trustedFlag) : null,
118
+ copied ? React.createElement('div', { style: { fontSize: '12px', opacity: 0.7 } }, '已复制 ✓') : null,
119
+ )
120
+ }
121
+
122
+ function apply(ctx) {
123
+ const slots = ctx.get('slots')
124
+ if (slots === undefined) return
125
+
126
+ slots.inject('settings.section', () =>
127
+ slots.register(
128
+ { name: 'settings.section', id: 'dsh-remote', order: 40, label: () => '远程访问' },
129
+ () => React.createElement(RemotePage, null),
130
+ ),
131
+ )
132
+ }
114
133
 
115
- slots.inject('settings.section', () =>
116
- slots.register(
117
- { name: 'settings.section', id: 'dsh-remote', order: 40, label: () => '远程访问' },
118
- () => React.createElement(RemotePage, null),
119
- ),
120
- )
121
- }
134
+ exports.name = name
135
+ exports.apply = apply
136
+ return module.exports
137
+ },
138
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-remote",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Remote-access assistant for DeepSeek Harness: /remote command and a settings page that print the exact SSH tunnel / reverse-tunnel / reverse-proxy commands for this instance (harness intentionally binds loopback only).",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -16,14 +16,22 @@
16
16
  "exports": {
17
17
  ".": "./lib/index.js",
18
18
  "./client": "./lib/client.js",
19
- "./package.json": "./package.json"
19
+ "./package.json": "./package.json",
20
+ "./cordis.patch.yml": "./cordis.patch.yml"
20
21
  },
21
22
  "files": [
22
- "lib"
23
+ "lib",
24
+ "cordis.patch.yml"
23
25
  ],
24
26
  "license": "MIT",
25
27
  "dsh": {
28
+ "bundle": {
29
+ "patch": "./cordis.patch.yml"
30
+ },
26
31
  "client": {
32
+ "inject": [
33
+ "@deepseek-ai/dsh-client-runtime"
34
+ ],
27
35
  "platform": "web"
28
36
  }
29
37
  },
@@ -31,5 +39,8 @@
31
39
  "@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
32
40
  "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
33
41
  "@deepseek-ai/cordis": "^4.0.1"
42
+ },
43
+ "dependencies": {
44
+ "@deepseek-ai/schemastery": "^3.18.1"
34
45
  }
35
46
  }