@electerm/electerm-react 5.3.26 → 5.5.9

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.
Files changed (146) hide show
  1. package/README.md +246 -12
  2. package/client/common/choose-save-folder.js +21 -2
  3. package/client/common/constants.js +20 -6
  4. package/client/common/create-title.jsx +6 -0
  5. package/client/common/default-setting.js +15 -0
  6. package/client/common/init-setting-item.js +5 -0
  7. package/client/common/platform.js +24 -0
  8. package/client/components/ai/agent-tool-call-card.jsx +10 -2
  9. package/client/components/ai/agent.js +4 -1
  10. package/client/components/ai/ai-attachments.js +87 -0
  11. package/client/components/ai/ai-chat-empty.jsx +43 -0
  12. package/client/components/ai/ai-chat-entry.jsx +13 -4
  13. package/client/components/ai/ai-chat-history-item.jsx +28 -4
  14. package/client/components/ai/ai-chat-history.jsx +2 -1
  15. package/client/components/ai/ai-chat.jsx +104 -13
  16. package/client/components/ai/ai-config-props.js +4 -130
  17. package/client/components/ai/ai-config.jsx +135 -15
  18. package/client/components/ai/ai-presets.js +173 -0
  19. package/client/components/ai/ai.styl +83 -0
  20. package/client/components/bg/css-overwrite.jsx +11 -0
  21. package/client/components/bookmark-form/bookmark-schema.js +4 -0
  22. package/client/components/bookmark-form/common/fields.jsx +3 -0
  23. package/client/components/bookmark-form/config/common-fields.js +12 -0
  24. package/client/components/bookmark-form/config/local.js +3 -2
  25. package/client/components/bookmark-form/config/serial.js +3 -2
  26. package/client/components/bookmark-form/config/ssh.js +2 -1
  27. package/client/components/bookmark-form/config/telnet.js +3 -2
  28. package/client/components/common/item-filter.jsx +76 -0
  29. package/client/components/common/item-filter.styl +54 -0
  30. package/client/components/common/lazy-boundary.jsx +34 -0
  31. package/client/components/common/opacity.jsx +3 -1
  32. package/client/components/footer/cmd-history.jsx +132 -45
  33. package/client/components/footer/cmd-history.styl +42 -4
  34. package/client/components/footer/footer-entry.jsx +35 -5
  35. package/client/components/footer/footer.styl +8 -1
  36. package/client/components/footer/multi-tab-run-modal.jsx +83 -0
  37. package/client/components/footer/tab-select.jsx +34 -17
  38. package/client/components/layout/layout.jsx +23 -31
  39. package/client/components/layout/pixed.js +3 -0
  40. package/client/components/main/main.jsx +55 -28
  41. package/client/components/main/term-fullscreen.styl +9 -3
  42. package/client/components/quick-commands/qm.styl +3 -2
  43. package/client/components/quick-commands/quick-command-create-modal.jsx +60 -0
  44. package/client/components/quick-commands/quick-commands-form-elem.jsx +10 -4
  45. package/client/components/rdp/file-transfer.js +4 -4
  46. package/client/components/remote-monitor/monitor-details.jsx +458 -0
  47. package/client/components/remote-monitor/monitor-details.styl +87 -0
  48. package/client/components/remote-monitor/monitor-model.js +764 -0
  49. package/client/components/remote-monitor/remote-monitor-bar-entry.jsx +18 -0
  50. package/client/components/remote-monitor/remote-monitor-bar.jsx +344 -0
  51. package/client/components/remote-monitor/remote-monitor-bar.styl +106 -0
  52. package/client/components/remote-monitor/session-monitor.js +361 -0
  53. package/client/components/remote-monitor/use-monitor-details.js +10 -0
  54. package/client/components/remote-monitor/visibility.js +18 -0
  55. package/client/components/session/session-control.jsx +29 -2
  56. package/client/components/session/session.jsx +40 -18
  57. package/client/components/session/sessions.jsx +5 -2
  58. package/client/components/setting-panel/setting-common.jsx +25 -56
  59. package/client/components/setting-panel/setting-modal.jsx +57 -42
  60. package/client/components/setting-panel/setting-terminal.jsx +8 -2
  61. package/client/components/setting-panel/setting.styl +1 -1
  62. package/client/components/setting-panel/tab-triggers.jsx +71 -0
  63. package/client/components/sftp/file-compare-modal.jsx +6 -3
  64. package/client/components/sftp/file-item.jsx +5 -3
  65. package/client/components/sftp/owner-list.js +11 -2
  66. package/client/components/sftp/sftp-entry.jsx +4 -0
  67. package/client/components/side-panel-r/side-panel-r.jsx +2 -2
  68. package/client/components/sidebar/side-panel.jsx +1 -1
  69. package/client/components/sys-menu/menu-btn.jsx +30 -1
  70. package/client/components/tabs/index.jsx +2 -2
  71. package/client/components/tabs/tab-title.jsx +3 -2
  72. package/client/components/tabs/tab.jsx +5 -1
  73. package/client/components/terminal/attach-addon-custom.js +295 -49
  74. package/client/components/terminal/automation/index.js +64 -0
  75. package/client/components/terminal/automation/keys.js +49 -0
  76. package/client/components/terminal/automation/stream-matcher.js +82 -0
  77. package/client/components/terminal/automation/strip-ansi.js +19 -0
  78. package/client/components/terminal/automation/trigger-engine.js +233 -0
  79. package/client/components/terminal/automation/trigger-presets.js +110 -0
  80. package/client/components/terminal/command-tracker-addon.js +31 -1
  81. package/client/components/terminal/mixins/index.js +27 -0
  82. package/client/components/terminal/mixins/term-attach.js +123 -0
  83. package/client/components/terminal/mixins/term-config.jsx +84 -0
  84. package/client/components/terminal/mixins/term-content.js +126 -0
  85. package/client/components/terminal/mixins/term-context-menu.jsx +323 -0
  86. package/client/components/terminal/mixins/term-file-drop.js +149 -0
  87. package/client/components/terminal/mixins/term-init.js +122 -0
  88. package/client/components/terminal/mixins/term-log.jsx +96 -0
  89. package/client/components/terminal/mixins/term-resize.js +87 -0
  90. package/client/components/terminal/mixins/term-socket.js +433 -0
  91. package/client/components/terminal/mixins/term-suggestions.js +224 -0
  92. package/client/components/terminal/mixins/term-theme.js +190 -0
  93. package/client/components/terminal/mixins/term-touch.js +523 -0
  94. package/client/components/terminal/shell-detect.js +37 -0
  95. package/client/components/terminal/shell.js +0 -28
  96. package/client/components/terminal/shortcut-bar-defs.js +30 -4
  97. package/client/components/terminal/shortcut-bar-edit.jsx +40 -9
  98. package/client/components/terminal/shortcut-bar-entry.jsx +6 -3
  99. package/client/components/terminal/shortcut-bar.jsx +17 -10
  100. package/client/components/terminal/shortcut-bar.styl +4 -0
  101. package/client/components/terminal/ssh-reload-state.js +96 -0
  102. package/client/components/terminal/startup-queue.js +433 -0
  103. package/client/components/terminal/terminal-interactive.jsx +32 -0
  104. package/client/components/terminal/terminal-select-text.jsx +69 -0
  105. package/client/components/terminal/terminal.jsx +227 -2064
  106. package/client/components/terminal/terminal.styl +61 -0
  107. package/client/components/terminal/transfer-client-base.js +5 -29
  108. package/client/components/terminal/trzsz-client.js +1 -3
  109. package/client/components/terminal/xmodem-client.js +1 -3
  110. package/client/components/terminal/xterm-loader.js +7 -0
  111. package/client/components/terminal/zmodem-client.js +1 -3
  112. package/client/components/terminal-info/base.jsx +18 -70
  113. package/client/components/terminal-info/terminal-info-entry.jsx +13 -5
  114. package/client/components/terminal-info/terminal-info.jsx +50 -59
  115. package/client/components/terminal-info/terminal-info.styl +6 -49
  116. package/client/components/text-editor/open-text-editor.js +30 -0
  117. package/client/components/text-editor/text-editor-entry.jsx +17 -6
  118. package/client/components/text-editor/text-editor.jsx +14 -0
  119. package/client/components/triggers/trigger-editor.jsx +246 -0
  120. package/client/components/triggers/trigger-form.jsx +200 -0
  121. package/client/components/triggers/trigger-session-modal.jsx +199 -0
  122. package/client/components/triggers/trigger-setting-list.jsx +89 -0
  123. package/client/components/triggers/trigger-transport.jsx +60 -0
  124. package/client/components/triggers/triggers-field.jsx +19 -0
  125. package/client/components/widgets/widgets-list.jsx +11 -1
  126. package/client/css/mobile.styl +29 -8
  127. package/client/store/common.js +12 -1
  128. package/client/store/init-state.js +7 -0
  129. package/client/store/mcp-handler.js +158 -30
  130. package/client/store/setting.js +9 -0
  131. package/client/store/store.js +2 -0
  132. package/client/store/sync.js +2 -0
  133. package/client/store/tab.js +42 -3
  134. package/client/store/trigger.js +118 -0
  135. package/client/store/watch.js +13 -5
  136. package/client/views/index.pug +3 -0
  137. package/package.json +1 -1
  138. package/client/components/terminal-info/activity.jsx +0 -57
  139. package/client/components/terminal-info/data-cols-parser.jsx +0 -54
  140. package/client/components/terminal-info/disk.jsx +0 -45
  141. package/client/components/terminal-info/format-disks.js +0 -45
  142. package/client/components/terminal-info/network.jsx +0 -121
  143. package/client/components/terminal-info/resource.jsx +0 -99
  144. package/client/components/terminal-info/run-cmd.jsx +0 -263
  145. package/client/components/terminal-info/sys-info.jsx +0 -56
  146. package/client/components/terminal-info/up.jsx +0 -17
@@ -1,99 +0,0 @@
1
- /**
2
- * cpu/swap/mem general usage
3
- */
4
-
5
- import { isEmpty } from 'lodash-es'
6
- import { Progress } from 'antd'
7
- import parseInt10 from '../../common/parse-int10'
8
-
9
- function toNumber (n = '') {
10
- let f = 1
11
- if (n.includes('G')) {
12
- f = 1024 * 1024
13
- } else if (n.includes('T')) {
14
- f = 1024 * 1024 * 1024
15
- } else if (n.includes('M')) {
16
- f = 1024
17
- }
18
- return f * parseFloat(n)
19
- }
20
-
21
- function computePercent (used, total) {
22
- const u = toNumber(used)
23
- const t = toNumber(total)
24
- return Math.floor(u * 100 / (t || (u + 1)))
25
- }
26
-
27
- export default function TerminalInfoResource (props) {
28
- const { cpu, mem, swap, isRemote, terminalInfos } = props
29
- if (
30
- !isRemote ||
31
- (!terminalInfos.includes('cpu') &&
32
- !terminalInfos.includes('mem') &&
33
- !terminalInfos.includes('swap'))
34
- ) {
35
- return null
36
- }
37
- function getColorForPercent (percent) {
38
- if (percent >= 90) return '#ff4d4f'
39
- if (percent >= 70) return '#faad14'
40
- if (percent >= 50) return '#1890ff'
41
- return '#52c41a'
42
- }
43
-
44
- function renderItem (obj) {
45
- if (isEmpty(obj)) {
46
- return <div className='pd1b' key={obj.name}>NA</div>
47
- }
48
- const {
49
- used,
50
- total,
51
- percent,
52
- name
53
- } = obj
54
- const hasPercent = Number.isFinite(percent)
55
- const p = hasPercent
56
- ? percent
57
- : computePercent(used, total) || 0
58
- const color = getColorForPercent(p)
59
- const fmt = hasPercent
60
- ? (p) => `${name}: ${p || ''}%`
61
- : (p) => `${name}: ${p || ''}%(${used || ''}/${total || ''})`
62
- return (
63
- <div className='pd1b' key={name}>
64
- <Progress
65
- style={{ width: '50%' }}
66
- percent={p}
67
- format={fmt}
68
- strokeColor={color}
69
- />
70
- </div>
71
- )
72
- }
73
- const data = []
74
- if (terminalInfos.includes('cpu')) {
75
- data.push({
76
- name: 'cpu',
77
- percent: parseInt10(cpu) || 0
78
- })
79
- }
80
- if (terminalInfos.includes('mem')) {
81
- data.push({
82
- name: 'mem',
83
- ...mem
84
- })
85
- }
86
- if (terminalInfos.includes('swap')) {
87
- data.push({
88
- name: 'swap',
89
- ...swap
90
- })
91
- }
92
- return (
93
- <div className='terminal-info-section terminal-info-resource'>
94
- {
95
- data.map(renderItem)
96
- }
97
- </div>
98
- )
99
- }
@@ -1,263 +0,0 @@
1
- /**
2
- * run command in remote terminal
3
- */
4
-
5
- import { runCmd } from '../terminal/terminal-apis'
6
- import { useEffect } from 'react'
7
- import wait from '../../common/wait'
8
- import parseInt10 from '../../common/parse-int10'
9
- import formatDisks from './format-disks'
10
-
11
- function formatActivities (str) {
12
- if (!str) {
13
- return {
14
- activities: []
15
- }
16
- }
17
- const r = str.split('\n')
18
- .map(a => a.trim())
19
- .filter(s => s)
20
- .map(st => {
21
- const arr = st.split(/ +/)
22
- return {
23
- pid: arr[0],
24
- user: arr[1],
25
- cpu: parseFloat(arr[2]),
26
- mem: parseInt10(arr[3]),
27
- cmd: arr.slice(4).join(' ')
28
- }
29
- }).filter(d => d.pid)
30
- return {
31
- activities: r
32
- }
33
- }
34
-
35
- function formatSysInfo (unameStr, prettyName) {
36
- if (!unameStr) {
37
- return {}
38
- }
39
- const parts = unameStr.trim().split(/\s+/)
40
- if (parts.length < 4) {
41
- return {}
42
- }
43
- const [sysname, hostname, kernel, arch] = parts
44
- let os = sysname
45
- const m = (prettyName || '').match(/PRETTY_NAME="?([^"\r\n]+)"?/)
46
- if (m) {
47
- os = m[1].trim()
48
- } else if (sysname === 'Darwin') {
49
- os = 'macOS'
50
- }
51
- return {
52
- sysInfo: {
53
- os,
54
- sysname,
55
- hostname,
56
- kernel,
57
- arch
58
- }
59
- }
60
- }
61
-
62
- function formatCpu (str) {
63
- if (!str) {
64
- return {
65
- cpu: ''
66
- }
67
- }
68
- return {
69
- cpu: str.split(' ')[1]
70
- }
71
- }
72
-
73
- function formatMem (str) {
74
- if (!str) {
75
- return {}
76
- }
77
- const names = ['mem', 'swap']
78
- return str
79
- .split('\n')
80
- .filter(d => d)
81
- .slice(1)
82
- .reduce((p, d, i) => {
83
- const arr = d.split(/\s+/)
84
- if (!arr[1]) {
85
- return p
86
- }
87
- p[names[i]] = {
88
- total: arr[1],
89
- used: arr[2],
90
- free: arr[3]
91
- }
92
- return p
93
- }, {})
94
- }
95
-
96
- const ipSplitReg = /\n[\d]{1,5}:\s+/
97
- const ipNameReg = /inet\s+([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})\/\d/
98
-
99
- function formatIps (ips) {
100
- if (!ips) {
101
- return {}
102
- }
103
- const arr = ips.split(ipSplitReg)
104
- return arr.reduce((p, s) => {
105
- const name = s.replace(/^[\d]{1,5}:\s+/, '').split(/:\s+/)[0]
106
- const arr1 = s.match(ipNameReg)
107
- return {
108
- ...p,
109
- [name]: {
110
- ip: arr1 ? arr1[1] : ''
111
- }
112
- }
113
- }, {})
114
- }
115
-
116
- function formatTraffic (traffic, ipObj) {
117
- if (!traffic) {
118
- return ipObj
119
- }
120
- const arr = traffic.split(ipSplitReg)
121
- return arr.reduce((p, s) => {
122
- const name = s.replace(/^[\d]{1,5}:\s+/, '').split(/:\s+/)[0]
123
- const arr1 = s.split('\n')
124
- let download = 0
125
- let upload = 0
126
- const len = arr1.length
127
- for (let i = 0; i < len; i++) {
128
- const line = arr1[i]
129
- if (line.toLowerCase().trim().startsWith('rx')) {
130
- download = Number(arr1[i + 1].trim().split(/\s+/)[0])
131
- } else if (line.trim().toLowerCase().startsWith('tx')) {
132
- upload = Number(arr1[i + 1].trim().split(/\s+/)[0])
133
- }
134
- }
135
- if (!p[name]) {
136
- p[name] = {}
137
- }
138
- Object.assign(p[name], {
139
- download, upload
140
- })
141
- return p
142
- }, ipObj)
143
- }
144
-
145
- function formatNetwork (traffic, ips) {
146
- const ipObj = formatIps(ips)
147
- return {
148
- network: formatTraffic(traffic, ipObj)
149
- }
150
- }
151
-
152
- export async function runCmds (props, cmds) {
153
- const {
154
- pid
155
- } = props
156
- const ress = []
157
- for (const cmd of cmds) {
158
- const res = await runCmd(pid, cmd)
159
- ress.push(res || '')
160
- }
161
- return ress
162
- }
163
-
164
- function InfoGetter (props) {
165
- const {
166
- // name,
167
- cmd,
168
- cmds,
169
- interval,
170
- formatter,
171
- delay
172
- } = props.options
173
- const { pid } = props
174
- const cms = cmds || [cmd]
175
- useEffect(() => {
176
- const run = async () => {
177
- await wait(delay)
178
- const ress = await runCmds(props, cms)
179
- const update = formatter(...ress)
180
- props.setState(update)
181
- }
182
- run()
183
- if (interval > 0) {
184
- const ref = setInterval(run, interval)
185
- return () => {
186
- clearInterval(ref)
187
- }
188
- }
189
- }, [pid])
190
- return null
191
- }
192
-
193
- export default (props) => {
194
- if (!props.isRemote) {
195
- return null
196
- }
197
- const cmds = [
198
- {
199
- name: 'sysinfo',
200
- cmds: [
201
- 'uname -s -n -r -m',
202
- 'grep PRETTY_NAME= /etc/os-release 2>/dev/null || echo'
203
- ],
204
- interval: 0,
205
- delay: 0,
206
- formatter: formatSysInfo
207
- },
208
- {
209
- name: 'uptime',
210
- cmd: 'uptime -p',
211
- interval: 5000,
212
- delay: 0,
213
- formatter: d => ({ uptime: d })
214
- },
215
- {
216
- name: 'activities',
217
- cmd: 'ps --no-headers -o pid,user,%cpu,size,command ax | sort -b -k3 -r',
218
- interval: 5000,
219
- delay: 800,
220
- formatter: formatActivities
221
- },
222
- {
223
- name: 'disks',
224
- cmd: 'df -hP',
225
- interval: 10000,
226
- delay: 1600,
227
- formatter: formatDisks
228
- },
229
- {
230
- name: 'cpu',
231
- cmd: '(grep \'cpu \' /proc/stat;sleep 0.1;grep \'cpu \' /proc/stat)|awk -v RS="" \'{print "CPU "($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)"%"}\'',
232
- interval: 5000,
233
- formatter: formatCpu,
234
- delay: 2400
235
- },
236
- {
237
- name: 'mem',
238
- cmd: 'free -h',
239
- interval: 5000,
240
- delay: 3200,
241
- formatter: formatMem
242
- },
243
- {
244
- name: 'network',
245
- cmds: [
246
- 'ip -s link',
247
- 'ip addr'
248
- ],
249
- delay: 4000,
250
- formatter: formatNetwork,
251
- interval: 5000
252
- }
253
- ]
254
- return cmds.map(options => {
255
- return (
256
- <InfoGetter
257
- key={'info-getter-' + options.name}
258
- {...props}
259
- options={options}
260
- />
261
- )
262
- })
263
- }
@@ -1,56 +0,0 @@
1
- /**
2
- * system info: os / hostname / kernel / arch (+ shell for local terminals)
3
- * remote info comes from uname via the session runCmd bridge,
4
- * local info from the os module + a shell version probe
5
- */
6
-
7
- import { useEffect, useState } from 'react'
8
- import { DesktopOutlined } from '@ant-design/icons'
9
- import resolveLocalInfo from './local-info-resolver'
10
-
11
- export default function TerminalInfoSys (props) {
12
- const { sysInfo, isRemote, pid } = props
13
- const [localInfo, setLocalInfo] = useState(null)
14
-
15
- useEffect(() => {
16
- if (isRemote) {
17
- return
18
- }
19
- resolveLocalInfo(pid).then(setLocalInfo)
20
- }, [isRemote, pid])
21
-
22
- const info = isRemote ? sysInfo : localInfo
23
- if (!info || !info.os) {
24
- return null
25
- }
26
- const rows = [
27
- ['os', info.os],
28
- ['hostname', info.hostname],
29
- ['kernel', info.kernel],
30
- ['arch', info.arch]
31
- ]
32
- if (info.shell) {
33
- rows.push(['shell', info.shellVersion ? `${info.shell} ${info.shellVersion}` : info.shell])
34
- }
35
- const final = rows.filter(d => d[1])
36
- if (!final.length) {
37
- return null
38
- }
39
- return (
40
- <div className='terminal-info-section terminal-info-sys'>
41
- <div className='pd1y bold'><DesktopOutlined /> System</div>
42
- <div className='terminal-info-sys-rows'>
43
- {
44
- final.map(([k, v]) => {
45
- return (
46
- <div className='terminal-info-sys-row' key={k}>
47
- <span className='terminal-info-sys-key'>{k}</span>
48
- <span className='terminal-info-sys-val' title={v}>{v}</span>
49
- </div>
50
- )
51
- })
52
- }
53
- </div>
54
- </div>
55
- )
56
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * up time info
3
- */
4
-
5
- import { ClockCircleOutlined } from '@ant-design/icons'
6
-
7
- export default function TerminalInfoUp (props) {
8
- const { uptime, isRemote, terminalInfos } = props
9
- if (!isRemote || !terminalInfos.includes('uptime')) {
10
- return null
11
- }
12
- return (
13
- <div className='terminal-info-section terminal-info-up'>
14
- <b><ClockCircleOutlined /> uptime</b>: {uptime}
15
- </div>
16
- )
17
- }