@auto-ai/agent 2.1.212 → 2.1.213

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 (43) hide show
  1. package/dist/safe-a/404/index.html +1 -1
  2. package/dist/safe-a/404.html +1 -1
  3. package/dist/safe-a/index.html +2 -2
  4. package/dist/safe-a/index.txt +1 -1
  5. package/dist/safe-a/manage/about/index.html +2 -2
  6. package/dist/safe-a/manage/about/index.txt +1 -1
  7. package/dist/safe-a/manage/env/index.html +2 -2
  8. package/dist/safe-a/manage/env/index.txt +1 -1
  9. package/dist/safe-a/manage/geelib/index.html +2 -2
  10. package/dist/safe-a/manage/geelib/index.txt +1 -1
  11. package/dist/safe-a/manage/general/index.html +2 -2
  12. package/dist/safe-a/manage/general/index.txt +1 -1
  13. package/dist/safe-a/manage/git/index.html +2 -2
  14. package/dist/safe-a/manage/git/index.txt +1 -1
  15. package/dist/safe-a/manage/im/index.html +2 -2
  16. package/dist/safe-a/manage/im/index.txt +1 -1
  17. package/dist/safe-a/manage/index.html +2 -2
  18. package/dist/safe-a/manage/index.txt +1 -1
  19. package/dist/safe-a/manage/library/index.html +2 -2
  20. package/dist/safe-a/manage/library/index.txt +1 -1
  21. package/dist/safe-a/manage/mcp/index.html +2 -2
  22. package/dist/safe-a/manage/mcp/index.txt +1 -1
  23. package/dist/safe-a/manage/permissions/index.html +2 -2
  24. package/dist/safe-a/manage/permissions/index.txt +1 -1
  25. package/dist/safe-a/manage/skills/index.html +2 -2
  26. package/dist/safe-a/manage/skills/index.txt +1 -1
  27. package/dist/safe-a/manage/task/index.html +2 -2
  28. package/dist/safe-a/manage/task/index.txt +1 -1
  29. package/dist/safe-a/manage/teams/index.html +2 -2
  30. package/dist/safe-a/manage/teams/index.txt +1 -1
  31. package/dist/safe-a/manage/tools/index.html +2 -2
  32. package/dist/safe-a/manage/tools/index.txt +1 -1
  33. package/dist/ws-test/vendor/xterm-addon-fit.js +2 -0
  34. package/dist/ws-test/vendor/xterm.css +285 -0
  35. package/dist/ws-test/vendor/xterm.js +2 -0
  36. package/dist/ws-test/ws-test.css +43 -0
  37. package/dist/ws-test/ws-test.html +17 -0
  38. package/dist/ws-test/ws-test.js +244 -0
  39. package/mcps-runtime/claude-ws-channel/server/gateway.bundle.mjs +275 -45
  40. package/package.json +6 -6
  41. /package/dist/safe-a/_next/static/{AY06zpWQV0yfK_fQwZZ5t → ydg1pWMUiUWUhsV4OnPd9}/_buildManifest.js +0 -0
  42. /package/dist/safe-a/_next/static/{AY06zpWQV0yfK_fQwZZ5t → ydg1pWMUiUWUhsV4OnPd9}/_clientMiddlewareManifest.json +0 -0
  43. /package/dist/safe-a/_next/static/{AY06zpWQV0yfK_fQwZZ5t → ydg1pWMUiUWUhsV4OnPd9}/_ssgManifest.js +0 -0
@@ -3208,6 +3208,49 @@
3208
3208
  box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.18);
3209
3209
  }
3210
3210
 
3211
+ /* 命令行终端(PTY 全屏) */
3212
+ .terminal-manage-view {
3213
+ flex: 1;
3214
+ min-height: 0;
3215
+ display: flex;
3216
+ flex-direction: column;
3217
+ overflow: hidden;
3218
+ padding: 0;
3219
+ }
3220
+ .terminal-manage-view[hidden] {
3221
+ display: none !important;
3222
+ }
3223
+ .terminal-manage-layout {
3224
+ flex: 1;
3225
+ min-height: 0;
3226
+ display: flex;
3227
+ flex-direction: column;
3228
+ overflow: hidden;
3229
+ background: #1a1a1c;
3230
+ }
3231
+ .terminal-mount {
3232
+ flex: 1;
3233
+ min-height: 0;
3234
+ padding: 8px;
3235
+ overflow: hidden;
3236
+ }
3237
+ .terminal-mount .xterm {
3238
+ height: 100%;
3239
+ }
3240
+ .terminal-mount .xterm-viewport {
3241
+ overflow-y: auto;
3242
+ }
3243
+ .terminal-panel-state {
3244
+ flex-shrink: 0;
3245
+ padding: 10px 14px;
3246
+ font-size: 13px;
3247
+ color: var(--ds-muted);
3248
+ border-top: 1px solid var(--ds-border);
3249
+ }
3250
+ .terminal-panel-state.is-error {
3251
+ color: #e5534b;
3252
+ }
3253
+
3211
3254
  /* 文件浏览(纯文件系统只读) */
3212
3255
  .repo-manage-view {
3213
3256
  flex: 1;
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>Agent 会话</title>
7
7
  <link rel="stylesheet" href="/ws-test.css" />
8
+ <link rel="stylesheet" href="/vendor/xterm.css" />
8
9
  </head>
9
10
  <body>
10
11
  <div class="ws-config-hidden" aria-hidden="true">
@@ -96,6 +97,14 @@
96
97
  </svg>
97
98
  <span>文件</span>
98
99
  </button>
100
+ <button type="button" class="sidebar-nav-row" id="btnManageTerminal" data-add="terminal" title="命令行" aria-label="命令行">
101
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
102
+ <rect x="3" y="4" width="18" height="14" rx="2"/>
103
+ <path d="M7 9l3 3-3 3"/>
104
+ <path d="M12 15h5"/>
105
+ </svg>
106
+ <span>命令行</span>
107
+ </button>
99
108
  </nav>
100
109
 
101
110
  <div class="sidebar-footer">
@@ -116,6 +125,12 @@
116
125
  </header>
117
126
  <div class="main-scroll">
118
127
  <div class="main-body">
128
+ <div id="terminalManageView" class="terminal-manage-view" hidden>
129
+ <div class="terminal-manage-layout">
130
+ <div id="terminalMount" class="terminal-mount" aria-label="命令行终端"></div>
131
+ <div id="terminalState" class="terminal-panel-state" hidden></div>
132
+ </div>
133
+ </div>
119
134
  <div id="repoManageView" class="repo-manage-view" hidden>
120
135
  <div class="repo-manage-layout">
121
136
  <aside class="repo-tree-panel" aria-label="目录树">
@@ -689,6 +704,8 @@
689
704
  <div id="debugNotifyStack" class="debug-notify-stack" aria-live="polite" aria-relevant="additions"></div>
690
705
  <div id="sidebarHoverTip" class="sidebar-hover-tip" role="tooltip" hidden></div>
691
706
  <script src="https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js"></script>
707
+ <script src="/vendor/xterm.js"></script>
708
+ <script src="/vendor/xterm-addon-fit.js"></script>
692
709
  <script src="/ws-test.js"></script>
693
710
  </body>
694
711
  </html>
@@ -140,7 +140,11 @@
140
140
  const btnScheduleCreateCancel = $('btnScheduleCreateCancel')
141
141
  const btnScheduleCreateSubmit = $('btnScheduleCreateSubmit')
142
142
  const btnManageRepo = $('btnManageRepo')
143
+ const btnManageTerminal = $('btnManageTerminal')
143
144
  const repoManageView = $('repoManageView')
145
+ const terminalManageView = $('terminalManageView')
146
+ const terminalMount = $('terminalMount')
147
+ const terminalState = $('terminalState')
144
148
  const chatWorkspace = $('chatWorkspace')
145
149
  const chatComposer = $('chatComposer')
146
150
  const repoTreeList = $('repoTreeList')
@@ -2718,6 +2722,16 @@
2718
2722
  treeCache: new Map(),
2719
2723
  }
2720
2724
 
2725
+ /** 命令行主视图:PTY WebSocket 与 xterm 实例 */
2726
+ const terminalManageState = {
2727
+ viewActive: false,
2728
+ ws: null,
2729
+ term: null,
2730
+ fitAddon: null,
2731
+ resizeObserver: null,
2732
+ onDataDisposable: null,
2733
+ }
2734
+
2721
2735
  /** Agent 设置主视图是否激活(与聊天区、文件管理互斥) */
2722
2736
  const agentSettingsState = {
2723
2737
  viewActive: false,
@@ -2728,6 +2742,213 @@
2728
2742
  return repoManageState.viewActive
2729
2743
  }
2730
2744
 
2745
+ /** 当前是否在命令行主视图 */
2746
+ function isTerminalManageViewActive() {
2747
+ return terminalManageState.viewActive
2748
+ }
2749
+
2750
+ /** 设置命令行面板底部状态文案 */
2751
+ function setTerminalPanelState(message, isError) {
2752
+ if (!terminalState) return
2753
+ const text = String(message || '').trim()
2754
+ if (!text) {
2755
+ terminalState.hidden = true
2756
+ terminalState.textContent = ''
2757
+ terminalState.classList.remove('is-error')
2758
+ return
2759
+ }
2760
+ terminalState.hidden = false
2761
+ terminalState.textContent = text
2762
+ terminalState.classList.toggle('is-error', !!isError)
2763
+ }
2764
+
2765
+ /** 构建命令行 PTY WebSocket 地址 */
2766
+ function buildTerminalWsUrl() {
2767
+ const origin = httpOriginForApi()
2768
+ const u = new URL('/ws/terminal', origin + '/')
2769
+ u.searchParams.set('agent', currentAgentParam())
2770
+ const wsOrigin = u.origin.replace(/^http:/i, 'ws:').replace(/^https:/i, 'wss:')
2771
+ return wsOrigin + u.pathname + u.search
2772
+ }
2773
+
2774
+ /** 向服务端同步终端行列数 */
2775
+ function sendTerminalResize() {
2776
+ const ws = terminalManageState.ws
2777
+ const term = terminalManageState.term
2778
+ if (!ws || ws.readyState !== WebSocket.OPEN || !term) return
2779
+ ws.send(
2780
+ JSON.stringify({
2781
+ type: 'resize',
2782
+ cols: term.cols,
2783
+ rows: term.rows,
2784
+ }),
2785
+ )
2786
+ }
2787
+
2788
+ /** 释放 xterm 与 WebSocket,避免离开视图后残留 PTY */
2789
+ function destroyTerminalSession() {
2790
+ if (terminalManageState.resizeObserver) {
2791
+ terminalManageState.resizeObserver.disconnect()
2792
+ terminalManageState.resizeObserver = null
2793
+ }
2794
+ if (terminalManageState.onDataDisposable) {
2795
+ try {
2796
+ terminalManageState.onDataDisposable.dispose()
2797
+ } catch {
2798
+ /* ignore */
2799
+ }
2800
+ terminalManageState.onDataDisposable = null
2801
+ }
2802
+ if (terminalManageState.ws) {
2803
+ try {
2804
+ terminalManageState.ws.close()
2805
+ } catch {
2806
+ /* ignore */
2807
+ }
2808
+ terminalManageState.ws = null
2809
+ }
2810
+ if (terminalManageState.term) {
2811
+ try {
2812
+ terminalManageState.term.dispose()
2813
+ } catch {
2814
+ /* ignore */
2815
+ }
2816
+ terminalManageState.term = null
2817
+ }
2818
+ terminalManageState.fitAddon = null
2819
+ if (terminalMount) terminalMount.innerHTML = ''
2820
+ }
2821
+
2822
+ /** 建立 PTY WebSocket 并挂载 xterm */
2823
+ function connectTerminalWs() {
2824
+ if (typeof Terminal === 'undefined' || typeof FitAddon === 'undefined') {
2825
+ setTerminalPanelState('终端组件未加载', true)
2826
+ return
2827
+ }
2828
+ destroyTerminalSession()
2829
+ setTerminalPanelState('连接中…', false)
2830
+
2831
+ const term = new Terminal({
2832
+ cursorBlink: true,
2833
+ fontSize: 14,
2834
+ fontFamily: 'Menlo, Monaco, "Courier New", monospace',
2835
+ theme: {
2836
+ background: '#1a1a1c',
2837
+ foreground: '#e8e8ea',
2838
+ cursor: '#0a84ff',
2839
+ selectionBackground: 'rgba(10, 132, 255, 0.28)',
2840
+ },
2841
+ })
2842
+ const fitAddon = new FitAddon()
2843
+ term.loadAddon(fitAddon)
2844
+ if (terminalMount) {
2845
+ term.open(terminalMount)
2846
+ fitAddon.fit()
2847
+ }
2848
+ terminalManageState.term = term
2849
+ terminalManageState.fitAddon = fitAddon
2850
+
2851
+ const ws = new WebSocket(buildTerminalWsUrl())
2852
+ ws.binaryType = 'arraybuffer'
2853
+ terminalManageState.ws = ws
2854
+
2855
+ ws.onopen = function () {
2856
+ setTerminalPanelState('', false)
2857
+ fitAddon.fit()
2858
+ sendTerminalResize()
2859
+ term.focus()
2860
+ }
2861
+
2862
+ ws.onmessage = function (ev) {
2863
+ if (typeof ev.data === 'string') {
2864
+ try {
2865
+ const msg = JSON.parse(ev.data)
2866
+ if (msg && msg.type === 'exit') {
2867
+ term.writeln('\r\n[shell 已退出,退出码: ' + msg.code + ']')
2868
+ setTerminalPanelState('shell 已退出', false)
2869
+ } else if (msg && msg.type === 'error') {
2870
+ setTerminalPanelState(msg.message || '终端错误', true)
2871
+ }
2872
+ } catch {
2873
+ /* ignore */
2874
+ }
2875
+ return
2876
+ }
2877
+ if (ev.data instanceof ArrayBuffer) {
2878
+ term.write(new Uint8Array(ev.data))
2879
+ }
2880
+ }
2881
+
2882
+ ws.onerror = function () {
2883
+ setTerminalPanelState('WebSocket 连接失败', true)
2884
+ }
2885
+
2886
+ ws.onclose = function () {
2887
+ if (terminalManageState.viewActive) {
2888
+ setTerminalPanelState('连接已断开', false)
2889
+ }
2890
+ }
2891
+
2892
+ terminalManageState.onDataDisposable = term.onData(function (data) {
2893
+ if (!ws || ws.readyState !== WebSocket.OPEN) return
2894
+ ws.send(new TextEncoder().encode(data))
2895
+ })
2896
+
2897
+ if (terminalMount && typeof ResizeObserver !== 'undefined') {
2898
+ const ro = new ResizeObserver(function () {
2899
+ if (!terminalManageState.fitAddon || !terminalManageState.term) return
2900
+ terminalManageState.fitAddon.fit()
2901
+ sendTerminalResize()
2902
+ })
2903
+ ro.observe(terminalMount)
2904
+ terminalManageState.resizeObserver = ro
2905
+ }
2906
+ }
2907
+
2908
+ /** 切换命令行主视图与聊天区可见性 */
2909
+ function setTerminalManageVisible(visible) {
2910
+ if (visible) {
2911
+ closeAgentSettingsView()
2912
+ closePickerManageView(false)
2913
+ closeScheduleManageView(false)
2914
+ repoManageState.viewActive = false
2915
+ if (repoManageView) repoManageView.hidden = true
2916
+ if (btnManageRepo) btnManageRepo.classList.remove('is-active')
2917
+ } else {
2918
+ destroyTerminalSession()
2919
+ }
2920
+ terminalManageState.viewActive = visible
2921
+ if (terminalManageView) terminalManageView.hidden = !visible
2922
+ if (chatWorkspace) chatWorkspace.hidden = visible
2923
+ if (chatComposer) chatComposer.hidden = visible
2924
+ if (mainHeaderEl) mainHeaderEl.hidden = false
2925
+ if (visible) {
2926
+ if (mainTitleEl) mainTitleEl.textContent = '命令行'
2927
+ if (mainSubEl) {
2928
+ mainSubEl.textContent = ''
2929
+ mainSubEl.hidden = true
2930
+ }
2931
+ } else {
2932
+ setTerminalPanelState('', false)
2933
+ if (btnManageTerminal) btnManageTerminal.classList.remove('is-active')
2934
+ updateMainHeader()
2935
+ }
2936
+ }
2937
+
2938
+ /** 关闭命令行视图,回到聊天 */
2939
+ function closeTerminalManageView() {
2940
+ if (!terminalManageState.viewActive) return
2941
+ setTerminalManageVisible(false)
2942
+ }
2943
+
2944
+ /** 打开命令行:切换主区域并连接 PTY */
2945
+ function openTerminalManageView() {
2946
+ if (!terminalManageView) return
2947
+ setTerminalManageVisible(true)
2948
+ if (btnManageTerminal) btnManageTerminal.classList.add('is-active')
2949
+ connectTerminalWs()
2950
+ }
2951
+
2731
2952
  /** 当前是否在 Agent 设置主视图 */
2732
2953
  function isAgentSettingsViewActive() {
2733
2954
  return agentSettingsState.viewActive
@@ -2894,6 +3115,7 @@
2894
3115
  if (visible) {
2895
3116
  closeAgentSettingsView()
2896
3117
  closePickerManageView(false)
3118
+ closeTerminalManageView()
2897
3119
  repoManageState.viewActive = false
2898
3120
  if (repoManageView) repoManageView.hidden = true
2899
3121
  if (btnManageRepo) btnManageRepo.classList.remove('is-active')
@@ -2937,6 +3159,7 @@
2937
3159
  closeAgentSettingsView()
2938
3160
  closePickerManageView(false)
2939
3161
  closeScheduleManageView(false)
3162
+ closeTerminalManageView()
2940
3163
  }
2941
3164
  repoManageState.viewActive = visible
2942
3165
  if (repoManageView) repoManageView.hidden = !visible
@@ -2968,6 +3191,7 @@
2968
3191
  if (visible) {
2969
3192
  closePickerManageView(false)
2970
3193
  closeScheduleManageView(false)
3194
+ closeTerminalManageView()
2971
3195
  repoManageState.viewActive = false
2972
3196
  if (repoManageView) repoManageView.hidden = true
2973
3197
  if (btnManageRepo) btnManageRepo.classList.remove('is-active')
@@ -3009,6 +3233,7 @@
3009
3233
  if (visible) {
3010
3234
  closeAgentSettingsView()
3011
3235
  closeScheduleManageView(false)
3236
+ closeTerminalManageView()
3012
3237
  repoManageState.viewActive = false
3013
3238
  if (repoManageView) repoManageView.hidden = true
3014
3239
  if (btnManageRepo) btnManageRepo.classList.remove('is-active')
@@ -5452,6 +5677,7 @@
5452
5677
 
5453
5678
  function switchToSession(id) {
5454
5679
  closeRepoManageView()
5680
+ closeTerminalManageView()
5455
5681
  closeAgentSettingsView()
5456
5682
  closePickerManageView()
5457
5683
  closeScheduleManageView(false)
@@ -7999,6 +8225,7 @@
7999
8225
  ev.preventDefault()
8000
8226
  ev.stopPropagation()
8001
8227
  closeRepoManageView()
8228
+ closeTerminalManageView()
8002
8229
  closeAgentSettingsView()
8003
8230
  closePickerManageView(false)
8004
8231
  const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
@@ -8013,6 +8240,7 @@
8013
8240
  ev.stopPropagation()
8014
8241
  closeScheduleManageView(false)
8015
8242
  closePickerManageView(false)
8243
+ closeTerminalManageView()
8016
8244
  const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
8017
8245
  for (let i = 0; i < items.length; i++) {
8018
8246
  items[i].classList.toggle('is-active', items[i] === btn)
@@ -8020,10 +8248,25 @@
8020
8248
  void openRepoManageView()
8021
8249
  return
8022
8250
  }
8251
+ if (k === 'terminal') {
8252
+ ev.preventDefault()
8253
+ ev.stopPropagation()
8254
+ closeScheduleManageView(false)
8255
+ closePickerManageView(false)
8256
+ closeRepoManageView()
8257
+ closeAgentSettingsView()
8258
+ const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
8259
+ for (let i = 0; i < items.length; i++) {
8260
+ items[i].classList.toggle('is-active', items[i] === btn)
8261
+ }
8262
+ openTerminalManageView()
8263
+ return
8264
+ }
8023
8265
  if (k === 'tools' || k === 'mcp' || k === 'skills' || k === 'agentTeams') {
8024
8266
  ev.preventDefault()
8025
8267
  ev.stopPropagation()
8026
8268
  closeRepoManageView()
8269
+ closeTerminalManageView()
8027
8270
  closeAgentSettingsView()
8028
8271
  closeScheduleManageView(false)
8029
8272
  const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
@@ -8410,6 +8653,7 @@
8410
8653
  function openAgentSettingsView(initialTab) {
8411
8654
  if (!agentSettingsView) return
8412
8655
  closeRepoManageView()
8656
+ closeTerminalManageView()
8413
8657
  closePickerManageView(false)
8414
8658
  closeScheduleManageView(false)
8415
8659
  if (initialTab === 'agentMd' || initialTab === 'settings') {