@electerm/electerm-react 1.70.2 → 1.72.6
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/client/common/cache.js +56 -0
- package/client/common/constants.js +2 -0
- package/client/common/download.jsx +5 -7
- package/client/common/setting-list.js +27 -0
- package/client/components/ai/ai-cache.jsx +36 -0
- package/client/components/ai/ai-chat-history-item.jsx +1 -1
- package/client/components/ai/ai-chat.jsx +5 -40
- package/client/components/ai/ai-config-props.js +7 -0
- package/client/components/ai/ai-config.jsx +5 -14
- package/client/components/ai/ai.styl +0 -4
- package/client/components/ai/providers.js +2 -2
- package/client/components/batch-op/batch-op-entry.jsx +1 -1
- package/client/components/batch-op/batch-op.jsx +2 -2
- package/client/components/bookmark-form/form-ssh-common.jsx +2 -3
- package/client/components/bookmark-form/form-tabs.jsx +2 -2
- package/client/components/bookmark-form/render-connection-hopping.jsx +2 -2
- package/client/components/bookmark-form/render-delayed-scripts.jsx +4 -4
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +2 -2
- package/client/components/bookmark-form/use-quick-commands.jsx +2 -2
- package/client/components/common/input-auto-focus.jsx +3 -11
- package/client/components/main/main.jsx +5 -0
- package/client/components/profile/profile-form-elem.jsx +1 -3
- package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -3
- package/client/components/quick-commands/quick-commands-list-form.jsx +2 -2
- package/client/components/session/session.jsx +50 -14
- package/client/components/session/session.styl +10 -3
- package/client/components/session/sessions.jsx +1 -1
- package/client/components/setting-panel/keywords-form.jsx +36 -38
- package/client/components/setting-panel/setting-modal.jsx +2 -2
- package/client/components/setting-panel/tab-settings.jsx +26 -0
- package/client/components/setting-sync/setting-sync-form.jsx +8 -0
- package/client/components/sftp/address-bar.jsx +9 -2
- package/client/components/sftp/address-bookmark.jsx +4 -6
- package/client/components/sftp/keyword-filter.jsx +63 -0
- package/client/components/sftp/list-table-ui.jsx +7 -9
- package/client/components/sftp/sftp-entry.jsx +45 -8
- package/client/components/sftp/sftp.styl +6 -1
- package/client/components/shortcuts/shortcut-control.jsx +20 -0
- package/client/components/shortcuts/shortcut-editor.jsx +2 -2
- package/client/components/shortcuts/shortcuts.jsx +2 -2
- package/client/components/sidebar/info-modal.jsx +2 -2
- package/client/components/sidebar/transfer-list-control.jsx +18 -20
- package/client/components/ssh-config/ssh-config-item.jsx +2 -4
- package/client/components/ssh-config/ssh-config-load-notify.jsx +2 -2
- package/client/components/sys-menu/zoom.jsx +2 -2
- package/client/components/tabs/index.jsx +1 -1
- package/client/components/tabs/tab.jsx +3 -3
- package/client/components/terminal/cmd-item.jsx +32 -0
- package/client/components/terminal/command-tracker-addon.js +3 -1
- package/client/components/terminal/term-search.jsx +5 -6
- package/client/components/terminal/terminal-command-dropdown.jsx +303 -0
- package/client/components/terminal/terminal.jsx +84 -3
- package/client/components/terminal/terminal.styl +58 -0
- package/client/components/terminal-info/terminal-info.jsx +2 -2
- package/client/components/tree-list/tree-list.jsx +1 -1
- package/client/components/web/address-bar.jsx +2 -2
- package/client/store/common.js +27 -2
- package/client/store/init-state.js +3 -3
- package/client/store/item.js +2 -1
- package/client/store/setting.js +3 -2
- package/client/store/store.js +23 -24
- package/client/store/watch.js +7 -1
- package/package.json +1 -1
|
@@ -50,7 +50,7 @@ import AIIcon from '../icons/ai-icon.jsx'
|
|
|
50
50
|
import { formatBytes } from '../../common/byte-format.js'
|
|
51
51
|
import * as fs from './fs.js'
|
|
52
52
|
import iconsMap from '../sys-menu/icons-map.jsx'
|
|
53
|
-
import { refs } from '../common/ref.js'
|
|
53
|
+
import { refs, refsStatic } from '../common/ref.js'
|
|
54
54
|
import createDefaultLogPath from '../../common/default-log-path.js'
|
|
55
55
|
|
|
56
56
|
const e = window.translate
|
|
@@ -255,7 +255,7 @@ clear\r`
|
|
|
255
255
|
|
|
256
256
|
isActiveTerminal = () => {
|
|
257
257
|
return this.props.tab.id === this.props.activeTabId &&
|
|
258
|
-
this.props.pane === paneMap.terminal
|
|
258
|
+
this.props.tab.pane === paneMap.terminal
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
clearShortcut = (e) => {
|
|
@@ -822,14 +822,56 @@ clear\r`
|
|
|
822
822
|
this.props.setCwd(cwd, this.state.id)
|
|
823
823
|
}
|
|
824
824
|
|
|
825
|
+
getCursorPosition = () => {
|
|
826
|
+
if (!this.term) return null
|
|
827
|
+
|
|
828
|
+
// Get the active buffer and cursor position
|
|
829
|
+
const buffer = this.term.buffer.active
|
|
830
|
+
const cursorRow = buffer.cursorY
|
|
831
|
+
const cursorCol = buffer.cursorX
|
|
832
|
+
|
|
833
|
+
// Get dimensions from term element
|
|
834
|
+
const termElement = this.term.element
|
|
835
|
+
if (!termElement) return null
|
|
836
|
+
|
|
837
|
+
// Get the exact position of the terminal element
|
|
838
|
+
const termRect = termElement.getBoundingClientRect()
|
|
839
|
+
|
|
840
|
+
// Calculate cell dimensions
|
|
841
|
+
const cellWidth = termRect.width / this.term.cols
|
|
842
|
+
const cellHeight = termRect.height / this.term.rows
|
|
843
|
+
|
|
844
|
+
// Calculate absolute position relative to terminal element
|
|
845
|
+
const left = Math.floor(termRect.left + (cursorCol * cellWidth))
|
|
846
|
+
const top = Math.floor(termRect.top + ((cursorRow + 1) * cellHeight))
|
|
847
|
+
|
|
848
|
+
return {
|
|
849
|
+
cellWidth,
|
|
850
|
+
cellHeight,
|
|
851
|
+
left,
|
|
852
|
+
top
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
closeSuggestions = () => {
|
|
857
|
+
refsStatic
|
|
858
|
+
.get('terminal-suggestions')
|
|
859
|
+
?.closeSuggestions()
|
|
860
|
+
}
|
|
861
|
+
|
|
825
862
|
onData = (d) => {
|
|
826
863
|
if (this.cmdAddon) {
|
|
827
864
|
this.cmdAddon.handleData(d)
|
|
828
865
|
}
|
|
866
|
+
const data = this.getCmd().trim()
|
|
829
867
|
if (!d.includes('\r')) {
|
|
830
868
|
delete this.userTypeExit
|
|
869
|
+
const cursorPos = this.getCursorPosition()
|
|
870
|
+
refsStatic
|
|
871
|
+
.get('terminal-suggestions')
|
|
872
|
+
?.openSuggestions(cursorPos, data)
|
|
831
873
|
} else {
|
|
832
|
-
|
|
874
|
+
this.closeSuggestions()
|
|
833
875
|
if (this.term.buffer.active.type !== 'alternate') {
|
|
834
876
|
this.timers.getCwd = setTimeout(this.getCwd, 200)
|
|
835
877
|
}
|
|
@@ -837,6 +879,7 @@ clear\r`
|
|
|
837
879
|
'exit',
|
|
838
880
|
'logout'
|
|
839
881
|
]
|
|
882
|
+
window.store.addCmdHistory(data)
|
|
840
883
|
if (exitCmds.includes(data)) {
|
|
841
884
|
this.userTypeExit = true
|
|
842
885
|
this.timers.userTypeExit = setTimeout(() => {
|
|
@@ -1083,6 +1126,7 @@ clear\r`
|
|
|
1083
1126
|
socket.onclose = this.oncloseSocket
|
|
1084
1127
|
socket.onerror = this.onerrorSocket
|
|
1085
1128
|
this.socket = socket
|
|
1129
|
+
this.initSocketEvents()
|
|
1086
1130
|
this.term = term
|
|
1087
1131
|
socket.onopen = () => {
|
|
1088
1132
|
this.initAttachAddon()
|
|
@@ -1106,6 +1150,43 @@ clear\r`
|
|
|
1106
1150
|
)
|
|
1107
1151
|
}
|
|
1108
1152
|
|
|
1153
|
+
initSocketEvents = () => {
|
|
1154
|
+
const originalSend = this.socket.send
|
|
1155
|
+
this.socket.send = (data) => {
|
|
1156
|
+
// Call original send first
|
|
1157
|
+
originalSend.call(this.socket, data)
|
|
1158
|
+
|
|
1159
|
+
// Broadcast to other terminals
|
|
1160
|
+
this.broadcastSocketData(data)
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
canReceiveBroadcast = (termRef) => {
|
|
1165
|
+
const tabId = termRef.props?.tab?.id
|
|
1166
|
+
const isActiveInBatch = termRef.props.currentBatchTabId === tabId
|
|
1167
|
+
return (
|
|
1168
|
+
isActiveInBatch &&
|
|
1169
|
+
termRef.socket &&
|
|
1170
|
+
termRef.props?.tab.pane === paneMap.terminal
|
|
1171
|
+
)
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
broadcastSocketData = (data) => {
|
|
1175
|
+
if (!this.isActiveTerminal() || !this.props.broadcastInput) {
|
|
1176
|
+
return
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
window.refs.forEach((termRef, refId) => {
|
|
1180
|
+
if (
|
|
1181
|
+
refId !== this.id &&
|
|
1182
|
+
refId.startsWith('term-') &&
|
|
1183
|
+
this.canReceiveBroadcast(termRef)
|
|
1184
|
+
) {
|
|
1185
|
+
termRef.socket.send(data)
|
|
1186
|
+
}
|
|
1187
|
+
})
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1109
1190
|
onResize = throttle(() => {
|
|
1110
1191
|
const cid = this.props.currentBatchTabId
|
|
1111
1192
|
const tid = this.props.tab?.id
|
|
@@ -77,3 +77,61 @@
|
|
|
77
77
|
background main-light
|
|
78
78
|
.batch-input-wrap
|
|
79
79
|
width calc(100% - 80px)
|
|
80
|
+
|
|
81
|
+
.terminal-suggestions-wrap
|
|
82
|
+
position absolute
|
|
83
|
+
z-index 100
|
|
84
|
+
color text
|
|
85
|
+
max-height 300px
|
|
86
|
+
max-width 300px
|
|
87
|
+
min-width 200px
|
|
88
|
+
box-shadow 0px 0px 3px 3px main-light
|
|
89
|
+
display flex
|
|
90
|
+
flex-direction column
|
|
91
|
+
background main
|
|
92
|
+
border-radius 4px
|
|
93
|
+
&.reverse .terminal-suggestions-list
|
|
94
|
+
border-top 1px solid main-light
|
|
95
|
+
border-bottom none
|
|
96
|
+
|
|
97
|
+
.terminal-suggestions-list
|
|
98
|
+
flex 1
|
|
99
|
+
overflow-x hidden
|
|
100
|
+
overflow-y auto
|
|
101
|
+
max-height 268px
|
|
102
|
+
max-width 300px
|
|
103
|
+
border-bottom 1px solid main-light
|
|
104
|
+
|
|
105
|
+
.terminal-suggestions-sticky
|
|
106
|
+
flex-shrink 0
|
|
107
|
+
height 32px
|
|
108
|
+
padding 0 10px
|
|
109
|
+
line-height 32px
|
|
110
|
+
|
|
111
|
+
.suggestion-item
|
|
112
|
+
display flex
|
|
113
|
+
align-items center
|
|
114
|
+
padding 5px 10px
|
|
115
|
+
cursor pointer
|
|
116
|
+
color text
|
|
117
|
+
&:hover
|
|
118
|
+
background-color main-light
|
|
119
|
+
.suggestion-delete
|
|
120
|
+
visibility visible
|
|
121
|
+
|
|
122
|
+
.suggestion-command
|
|
123
|
+
flex-grow 1
|
|
124
|
+
white-space nowrap
|
|
125
|
+
overflow hidden
|
|
126
|
+
text-overflow ellipsis
|
|
127
|
+
|
|
128
|
+
.suggestion-type
|
|
129
|
+
margin-left 5px
|
|
130
|
+
font-size 0.8em
|
|
131
|
+
opacity .8
|
|
132
|
+
&:hover
|
|
133
|
+
opacity 1
|
|
134
|
+
|
|
135
|
+
.suggestion-delete
|
|
136
|
+
margin-left 5px
|
|
137
|
+
visibility hidden
|
|
@@ -43,7 +43,7 @@ export default class TerminalInfoContent extends PureComponent {
|
|
|
43
43
|
return null
|
|
44
44
|
}
|
|
45
45
|
return (
|
|
46
|
-
|
|
46
|
+
<>
|
|
47
47
|
<TerminalInfoBase {...props} {...state} />
|
|
48
48
|
<TerminalInfoUp {...props} {...state} />
|
|
49
49
|
<TerminalInfoResource
|
|
@@ -57,7 +57,7 @@ export default class TerminalInfoContent extends PureComponent {
|
|
|
57
57
|
<TerminalInfoNetwork {...props} {...state} />
|
|
58
58
|
<TerminalInfoDisk {...props} {...state} />
|
|
59
59
|
<RunCmd {...props} setState={this.setStateRef} />
|
|
60
|
-
|
|
60
|
+
</>
|
|
61
61
|
)
|
|
62
62
|
}
|
|
63
63
|
}
|
package/client/store/common.js
CHANGED
|
@@ -10,12 +10,16 @@ import {
|
|
|
10
10
|
leftSidebarWidthKey,
|
|
11
11
|
rightSidebarWidthKey,
|
|
12
12
|
dismissDelKeyTipLsKey,
|
|
13
|
-
connectionMap
|
|
13
|
+
connectionMap,
|
|
14
|
+
settingMap,
|
|
15
|
+
settingAiId
|
|
14
16
|
} from '../common/constants'
|
|
15
17
|
import * as ls from '../common/safe-local-storage'
|
|
16
18
|
import { refs, refsStatic } from '../components/common/ref'
|
|
17
19
|
import { action } from 'manate'
|
|
18
20
|
import deepCopy from 'json-deep-copy'
|
|
21
|
+
import { aiConfigsArr } from '../components/ai/ai-config-props'
|
|
22
|
+
import settingList from '../common/setting-list'
|
|
19
23
|
|
|
20
24
|
const e = window.translate
|
|
21
25
|
const { assign } = Object
|
|
@@ -49,7 +53,12 @@ export default Store => {
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
Store.prototype.toggleAIConfig = function () {
|
|
52
|
-
|
|
56
|
+
const { store } = window
|
|
57
|
+
store.storeAssign({
|
|
58
|
+
settingTab: settingMap.setting
|
|
59
|
+
})
|
|
60
|
+
store.setSettingItem(settingList().find(d => d.id === settingAiId))
|
|
61
|
+
store.openSettingModal()
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
Store.prototype.onResize = debounce(async function () {
|
|
@@ -303,4 +312,20 @@ export default Store => {
|
|
|
303
312
|
profiles.splice(i, 1, np)
|
|
304
313
|
}
|
|
305
314
|
}
|
|
315
|
+
|
|
316
|
+
Store.prototype.aiConfigMissing = function () {
|
|
317
|
+
return aiConfigsArr.some(k => !window.store.config[k])
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
Store.prototype.addCmdHistory = action(function (cmd) {
|
|
321
|
+
const { terminalCommandHistory } = window.store
|
|
322
|
+
terminalCommandHistory.add(cmd)
|
|
323
|
+
if (terminalCommandHistory.size > 100) {
|
|
324
|
+
// Delete oldest 20 items when history exceeds 100
|
|
325
|
+
const values = Array.from(terminalCommandHistory.values())
|
|
326
|
+
for (let i = 0; i < 20 && i < values.length; i++) {
|
|
327
|
+
terminalCommandHistory.delete(values[i])
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
})
|
|
306
331
|
}
|
|
@@ -21,7 +21,8 @@ import {
|
|
|
21
21
|
resolutionsLsKey,
|
|
22
22
|
aiChatHistoryKey,
|
|
23
23
|
syncServerDataKey,
|
|
24
|
-
splitMap
|
|
24
|
+
splitMap,
|
|
25
|
+
cmdHistoryKey
|
|
25
26
|
} from '../common/constants'
|
|
26
27
|
import { buildDefaultThemes } from '../common/terminal-theme'
|
|
27
28
|
import * as ls from '../common/safe-local-storage'
|
|
@@ -72,6 +73,7 @@ export default () => {
|
|
|
72
73
|
addressBookmarksLocal: ls.getItemJSON(localAddrBookmarkLsKey, []),
|
|
73
74
|
openResolutionEdit: false,
|
|
74
75
|
resolutions: ls.getItemJSON(resolutionsLsKey, []),
|
|
76
|
+
terminalCommandHistory: new Set(ls.getItemJSON(cmdHistoryKey, [])),
|
|
75
77
|
|
|
76
78
|
// init session control
|
|
77
79
|
selectedSessions: [],
|
|
@@ -79,7 +81,6 @@ export default () => {
|
|
|
79
81
|
|
|
80
82
|
// batch input selected tab ids
|
|
81
83
|
_batchInputSelectedTabIds: new Set(),
|
|
82
|
-
showAIConfig: false,
|
|
83
84
|
aiChatHistory: ls.getItemJSON(aiChatHistoryKey, []),
|
|
84
85
|
|
|
85
86
|
// sftp
|
|
@@ -114,7 +115,6 @@ export default () => {
|
|
|
114
115
|
rightPanelWidth: parseInt(ls.getItem(rightSidebarWidthKey), 10) || 500,
|
|
115
116
|
|
|
116
117
|
// for settings related
|
|
117
|
-
_setting: '',
|
|
118
118
|
settingItem: initSettingItem([], settingMap.bookmarks),
|
|
119
119
|
settingTab: settingMap.bookmarks, // setting tab
|
|
120
120
|
bookmarkId: undefined,
|
package/client/store/item.js
CHANGED
|
@@ -6,6 +6,7 @@ import deepCopy from 'json-deep-copy'
|
|
|
6
6
|
import {
|
|
7
7
|
settingMap
|
|
8
8
|
} from '../common/constants'
|
|
9
|
+
import settingList from '../common/setting-list'
|
|
9
10
|
import getInitItem from '../common/init-setting-item'
|
|
10
11
|
|
|
11
12
|
export default Store => {
|
|
@@ -72,7 +73,7 @@ export default Store => {
|
|
|
72
73
|
|
|
73
74
|
Store.prototype.getItems = function (type) {
|
|
74
75
|
if (type === 'setting') {
|
|
75
|
-
return
|
|
76
|
+
return settingList()
|
|
76
77
|
}
|
|
77
78
|
return window.store[type]
|
|
78
79
|
}
|
package/client/store/setting.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { buildNewTheme } from '../common/terminal-theme'
|
|
16
16
|
import getInitItem from '../common/init-setting-item'
|
|
17
17
|
import newTerm from '../common/new-terminal'
|
|
18
|
+
import settingList from '../common/setting-list'
|
|
18
19
|
|
|
19
20
|
const e = window.translate
|
|
20
21
|
|
|
@@ -101,7 +102,7 @@ export default Store => {
|
|
|
101
102
|
const { store } = window
|
|
102
103
|
if (
|
|
103
104
|
store.settingTab === settingMap.setting &&
|
|
104
|
-
store.settingItem.id ===
|
|
105
|
+
store.settingItem.id === settingList()[0].id &&
|
|
105
106
|
store.showModal === modals.setting
|
|
106
107
|
) {
|
|
107
108
|
return store.hideSettingModal()
|
|
@@ -109,7 +110,7 @@ export default Store => {
|
|
|
109
110
|
store.storeAssign({
|
|
110
111
|
settingTab: settingMap.setting
|
|
111
112
|
})
|
|
112
|
-
store.setSettingItem(
|
|
113
|
+
store.setSettingItem(settingList().find(d => d.id === settingSyncId))
|
|
113
114
|
store.openSettingModal()
|
|
114
115
|
}
|
|
115
116
|
|
package/client/store/store.js
CHANGED
|
@@ -31,9 +31,6 @@ import deepCopy from 'json-deep-copy'
|
|
|
31
31
|
import getBrand from '../components/ai/get-brand'
|
|
32
32
|
import {
|
|
33
33
|
settingMap,
|
|
34
|
-
settingSyncId,
|
|
35
|
-
settingShortcutsId,
|
|
36
|
-
settingTerminalId,
|
|
37
34
|
terminalSshConfigType,
|
|
38
35
|
paneMap
|
|
39
36
|
} from '../common/constants'
|
|
@@ -44,8 +41,6 @@ import {
|
|
|
44
41
|
} from 'antd'
|
|
45
42
|
import { refs } from '../components/common/ref'
|
|
46
43
|
|
|
47
|
-
const e = window.translate
|
|
48
|
-
|
|
49
44
|
class Store {
|
|
50
45
|
constructor () {
|
|
51
46
|
Object.assign(
|
|
@@ -123,8 +118,7 @@ class Store {
|
|
|
123
118
|
return false
|
|
124
119
|
}
|
|
125
120
|
return currentTab.sshSftpSplitView ||
|
|
126
|
-
currentTab.pane === paneMap.terminal
|
|
127
|
-
currentTab.pane === paneMap.ssh
|
|
121
|
+
currentTab.pane === paneMap.terminal
|
|
128
122
|
}
|
|
129
123
|
|
|
130
124
|
get quickCommandTags () {
|
|
@@ -161,6 +155,28 @@ class Store {
|
|
|
161
155
|
]
|
|
162
156
|
}
|
|
163
157
|
|
|
158
|
+
get terminalCommandSuggestions () {
|
|
159
|
+
const { store } = window
|
|
160
|
+
const historyCommands = Array.from(store.terminalCommandHistory)
|
|
161
|
+
const batchInputCommands = store.batchInputs
|
|
162
|
+
const quickCommands = store.quickCommands.reduce(
|
|
163
|
+
(p, q) => {
|
|
164
|
+
return [
|
|
165
|
+
...p,
|
|
166
|
+
...(q.commands || []).map(c => c.command)
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
[]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// Return raw commands
|
|
173
|
+
return {
|
|
174
|
+
history: historyCommands,
|
|
175
|
+
batch: batchInputCommands,
|
|
176
|
+
quick: quickCommands
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
164
180
|
get termSearchOptions () {
|
|
165
181
|
const {
|
|
166
182
|
store
|
|
@@ -183,23 +199,6 @@ class Store {
|
|
|
183
199
|
return window.store.tabs.map(d => d.title).join('#')
|
|
184
200
|
}
|
|
185
201
|
|
|
186
|
-
get setting () {
|
|
187
|
-
return [
|
|
188
|
-
{
|
|
189
|
-
id: settingTerminalId,
|
|
190
|
-
title: e('terminal')
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
id: settingShortcutsId,
|
|
194
|
-
title: e('settingShortcuts')
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
id: settingSyncId,
|
|
198
|
-
title: e('settingSync')
|
|
199
|
-
}
|
|
200
|
-
]
|
|
201
|
-
}
|
|
202
|
-
|
|
203
202
|
get onOperation () {
|
|
204
203
|
const {
|
|
205
204
|
store
|
package/client/store/watch.js
CHANGED
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
resolutionsLsKey,
|
|
13
13
|
localAddrBookmarkLsKey,
|
|
14
14
|
syncServerDataKey,
|
|
15
|
-
aiChatHistoryKey
|
|
15
|
+
aiChatHistoryKey,
|
|
16
|
+
cmdHistoryKey
|
|
16
17
|
} from '../common/constants'
|
|
17
18
|
import * as ls from '../common/safe-local-storage'
|
|
18
19
|
import { debounce, isEmpty } from 'lodash-es'
|
|
@@ -138,6 +139,11 @@ export default store => {
|
|
|
138
139
|
return store.aiChatHistory
|
|
139
140
|
}).start()
|
|
140
141
|
|
|
142
|
+
autoRun(() => {
|
|
143
|
+
ls.setItemJSON(cmdHistoryKey, Array.from(store.terminalCommandHistory))
|
|
144
|
+
return store.terminalCommandHistory
|
|
145
|
+
}).start()
|
|
146
|
+
|
|
141
147
|
autoRun(() => {
|
|
142
148
|
store.updateBatchInputSelectedTabIds()
|
|
143
149
|
const tabs = store.getTabs()
|