@xcanwin/manyoyo 5.8.10 → 5.9.0
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/lib/web/frontend/app.css +196 -1
- package/lib/web/frontend/app.html +20 -0
- package/lib/web/frontend/app.js +118 -2
- package/lib/web/frontend/codemirror-entry.js +98 -0
- package/lib/web/frontend/codemirror.bundle.js +31648 -0
- package/lib/web/frontend/file-browser.js +406 -0
- package/lib/web/frontend/markdown-renderer.js +189 -28
- package/lib/web/frontend/markdown.css +9 -1
- package/lib/web/server.js +230 -1
- package/package.json +15 -1
package/lib/web/frontend/app.css
CHANGED
|
@@ -352,6 +352,20 @@ textarea:focus-visible {
|
|
|
352
352
|
white-space: pre-wrap;
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
+
.link-confirm-url {
|
|
356
|
+
margin-top: 2px;
|
|
357
|
+
padding: 12px 14px;
|
|
358
|
+
border: 1px solid rgba(146, 100, 42, 0.18);
|
|
359
|
+
border-radius: 10px;
|
|
360
|
+
background: #fff8ef;
|
|
361
|
+
color: var(--text);
|
|
362
|
+
font-family: var(--font-mono);
|
|
363
|
+
font-size: 12px;
|
|
364
|
+
line-height: 1.6;
|
|
365
|
+
word-break: break-all;
|
|
366
|
+
user-select: text;
|
|
367
|
+
}
|
|
368
|
+
|
|
355
369
|
.config-editor {
|
|
356
370
|
width: 100%;
|
|
357
371
|
min-height: 340px;
|
|
@@ -1126,6 +1140,177 @@ body.mobile-actions-open .header-actions {
|
|
|
1126
1140
|
background: #131923;
|
|
1127
1141
|
}
|
|
1128
1142
|
|
|
1143
|
+
.files-pane {
|
|
1144
|
+
min-height: 0;
|
|
1145
|
+
border: 1px solid var(--line);
|
|
1146
|
+
border-radius: 14px;
|
|
1147
|
+
overflow: hidden;
|
|
1148
|
+
background:
|
|
1149
|
+
linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(252, 246, 236, 0.88) 100%);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
.files-browser {
|
|
1153
|
+
height: 100%;
|
|
1154
|
+
min-height: 0;
|
|
1155
|
+
display: grid;
|
|
1156
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.files-toolbar {
|
|
1160
|
+
display: flex;
|
|
1161
|
+
align-items: center;
|
|
1162
|
+
gap: 8px;
|
|
1163
|
+
padding: 12px 14px;
|
|
1164
|
+
border-bottom: 1px solid var(--line);
|
|
1165
|
+
background: rgba(255, 251, 244, 0.96);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
.files-toolbar-path {
|
|
1169
|
+
flex: 1;
|
|
1170
|
+
min-width: 0;
|
|
1171
|
+
padding: 8px 10px;
|
|
1172
|
+
border: 1px solid rgba(181, 146, 99, 0.35);
|
|
1173
|
+
border-radius: 10px;
|
|
1174
|
+
background: #fffdf9;
|
|
1175
|
+
color: var(--text);
|
|
1176
|
+
font-family: var(--font-mono);
|
|
1177
|
+
font-size: 12px;
|
|
1178
|
+
line-height: 1.5;
|
|
1179
|
+
word-break: break-all;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
.files-toolbar-status {
|
|
1183
|
+
color: var(--muted);
|
|
1184
|
+
font-size: 12px;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
.files-layout {
|
|
1188
|
+
min-height: 0;
|
|
1189
|
+
display: grid;
|
|
1190
|
+
grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
.files-sidebar {
|
|
1194
|
+
min-height: 0;
|
|
1195
|
+
border-right: 1px solid var(--line);
|
|
1196
|
+
background: rgba(255, 251, 244, 0.84);
|
|
1197
|
+
overflow: auto;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.files-list {
|
|
1201
|
+
display: flex;
|
|
1202
|
+
flex-direction: column;
|
|
1203
|
+
gap: 6px;
|
|
1204
|
+
padding: 12px;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
.files-entry {
|
|
1208
|
+
width: 100%;
|
|
1209
|
+
display: flex;
|
|
1210
|
+
align-items: center;
|
|
1211
|
+
justify-content: space-between;
|
|
1212
|
+
gap: 10px;
|
|
1213
|
+
padding: 10px 12px;
|
|
1214
|
+
border: 1px solid rgba(181, 146, 99, 0.28);
|
|
1215
|
+
border-radius: 12px;
|
|
1216
|
+
background: rgba(255, 255, 255, 0.92);
|
|
1217
|
+
color: var(--text);
|
|
1218
|
+
text-align: left;
|
|
1219
|
+
cursor: pointer;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
.files-entry.is-active {
|
|
1223
|
+
border-color: rgba(120, 78, 27, 0.45);
|
|
1224
|
+
background: rgba(255, 244, 224, 0.9);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
.files-entry-name {
|
|
1228
|
+
min-width: 0;
|
|
1229
|
+
display: flex;
|
|
1230
|
+
flex-direction: column;
|
|
1231
|
+
gap: 0;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
.files-entry-title {
|
|
1235
|
+
font-size: 13px;
|
|
1236
|
+
font-weight: 600;
|
|
1237
|
+
word-break: break-word;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
.files-entry-meta {
|
|
1241
|
+
color: var(--muted);
|
|
1242
|
+
font-size: 11px;
|
|
1243
|
+
white-space: nowrap;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
.files-preview {
|
|
1247
|
+
min-height: 0;
|
|
1248
|
+
display: grid;
|
|
1249
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.files-preview-head {
|
|
1253
|
+
display: flex;
|
|
1254
|
+
flex-direction: column;
|
|
1255
|
+
gap: 6px;
|
|
1256
|
+
padding: 12px 14px;
|
|
1257
|
+
border-bottom: 1px solid var(--line);
|
|
1258
|
+
background: rgba(255, 251, 244, 0.96);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
.files-preview-title {
|
|
1262
|
+
font-family: var(--font-display);
|
|
1263
|
+
font-size: 15px;
|
|
1264
|
+
font-weight: 700;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
.files-preview-meta {
|
|
1268
|
+
color: var(--muted);
|
|
1269
|
+
font-size: 12px;
|
|
1270
|
+
word-break: break-all;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
.files-preview-body {
|
|
1274
|
+
min-height: 0;
|
|
1275
|
+
overflow: auto;
|
|
1276
|
+
padding: 14px;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
.files-empty,
|
|
1280
|
+
.files-note {
|
|
1281
|
+
padding: 18px;
|
|
1282
|
+
border: 1px dashed rgba(181, 146, 99, 0.45);
|
|
1283
|
+
border-radius: 12px;
|
|
1284
|
+
background: rgba(255, 255, 255, 0.7);
|
|
1285
|
+
color: var(--muted);
|
|
1286
|
+
line-height: 1.6;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
.files-pre {
|
|
1290
|
+
margin: 0;
|
|
1291
|
+
white-space: pre-wrap;
|
|
1292
|
+
word-break: break-word;
|
|
1293
|
+
font-family: var(--font-mono);
|
|
1294
|
+
font-size: 12px;
|
|
1295
|
+
line-height: 1.6;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
.files-editor-host {
|
|
1299
|
+
min-height: 100%;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
.files-editor-host .cm-editor {
|
|
1303
|
+
height: 100%;
|
|
1304
|
+
border: 1px solid rgba(181, 146, 99, 0.32);
|
|
1305
|
+
border-radius: 12px;
|
|
1306
|
+
overflow: hidden;
|
|
1307
|
+
background: rgba(255, 255, 255, 0.94);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
.files-editor-host .cm-scroller {
|
|
1311
|
+
font-family: var(--font-mono);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1129
1314
|
.inspector-pane {
|
|
1130
1315
|
overflow-y: auto;
|
|
1131
1316
|
padding: 0;
|
|
@@ -1925,7 +2110,7 @@ details.trace-card > .trace-card-summary {
|
|
|
1925
2110
|
|
|
1926
2111
|
.workbench-tabs {
|
|
1927
2112
|
display: grid;
|
|
1928
|
-
grid-template-columns: repeat(
|
|
2113
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
1929
2114
|
gap: 6px;
|
|
1930
2115
|
}
|
|
1931
2116
|
|
|
@@ -1939,6 +2124,16 @@ details.trace-card > .trace-card-summary {
|
|
|
1939
2124
|
align-items: flex-start;
|
|
1940
2125
|
}
|
|
1941
2126
|
|
|
2127
|
+
.files-layout {
|
|
2128
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2129
|
+
grid-template-rows: minmax(180px, 38%) minmax(0, 1fr);
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
.files-sidebar {
|
|
2133
|
+
border-right: 0;
|
|
2134
|
+
border-bottom: 1px solid var(--line);
|
|
2135
|
+
}
|
|
2136
|
+
|
|
1942
2137
|
.composer-toolbar-meta {
|
|
1943
2138
|
width: 100%;
|
|
1944
2139
|
justify-content: space-between;
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
<div class="workbench-tabs" id="workbenchTabs" aria-label="工作台视图">
|
|
69
69
|
<button type="button" id="viewActivityBtn" class="secondary is-active">活动</button>
|
|
70
70
|
<button type="button" id="viewTerminalBtn" class="secondary">终端</button>
|
|
71
|
+
<button type="button" id="viewFilesBtn" class="secondary">文件</button>
|
|
71
72
|
<button type="button" id="viewDetailBtn" class="secondary">详情</button>
|
|
72
73
|
<button type="button" id="viewConfigBtn" class="secondary">配置</button>
|
|
73
74
|
<button type="button" id="viewCheckBtn" class="secondary">检查</button>
|
|
@@ -90,6 +91,7 @@
|
|
|
90
91
|
</div>
|
|
91
92
|
<div id="terminalScreen" aria-label="终端输出区域"></div>
|
|
92
93
|
</section>
|
|
94
|
+
<section id="filesPanel" class="workspace-pane files-pane" hidden></section>
|
|
93
95
|
<section id="detailPanel" class="workspace-pane inspector-pane" hidden>
|
|
94
96
|
<div id="detailSummary" class="inspector-stack"></div>
|
|
95
97
|
</section>
|
|
@@ -275,12 +277,30 @@
|
|
|
275
277
|
</footer>
|
|
276
278
|
</section>
|
|
277
279
|
</div>
|
|
280
|
+
|
|
281
|
+
<div id="externalLinkModal" class="modal-backdrop" hidden>
|
|
282
|
+
<section class="modal" role="dialog" aria-modal="true" aria-labelledby="externalLinkTitle">
|
|
283
|
+
<header class="modal-header">
|
|
284
|
+
<h2 id="externalLinkTitle">打开外部链接</h2>
|
|
285
|
+
<button type="button" id="externalLinkCancelBtn" class="secondary">取消</button>
|
|
286
|
+
</header>
|
|
287
|
+
<div class="modal-body">
|
|
288
|
+
<div class="modal-tip">即将新标签页打开外部页面。请确认完整链接可信后再继续。</div>
|
|
289
|
+
<div id="externalLinkUrl" class="link-confirm-url"></div>
|
|
290
|
+
</div>
|
|
291
|
+
<footer class="modal-footer">
|
|
292
|
+
<button type="button" id="externalLinkOpenBtn">确认并新标签打开</button>
|
|
293
|
+
</footer>
|
|
294
|
+
</section>
|
|
295
|
+
</div>
|
|
278
296
|
</div>
|
|
279
297
|
|
|
280
298
|
<script src="/app/vendor/xterm.js"></script>
|
|
281
299
|
<script src="/app/vendor/xterm-addon-fit.js"></script>
|
|
282
300
|
<script src="/app/vendor/marked.min.js"></script>
|
|
283
301
|
<script src="/app/frontend/markdown-renderer.js"></script>
|
|
302
|
+
<script src="/app/frontend/codemirror.bundle.js"></script>
|
|
303
|
+
<script src="/app/frontend/file-browser.js"></script>
|
|
284
304
|
<script src="/app/frontend/app.js"></script>
|
|
285
305
|
</body>
|
|
286
306
|
</html>
|
package/lib/web/frontend/app.js
CHANGED
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
configModalOpen: false,
|
|
52
52
|
createModalOpen: false,
|
|
53
53
|
agentTemplateModalOpen: false,
|
|
54
|
+
externalLinkModalOpen: false,
|
|
54
55
|
configLoading: false,
|
|
55
56
|
configSaving: false,
|
|
56
57
|
configSaveMessage: '',
|
|
@@ -105,7 +106,8 @@
|
|
|
105
106
|
lastSentRows: 0,
|
|
106
107
|
ctrlMode: false,
|
|
107
108
|
altMode: false
|
|
108
|
-
}
|
|
109
|
+
},
|
|
110
|
+
externalLinkUrl: ''
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
const sidebarNode = document.querySelector('.sidebar');
|
|
@@ -116,6 +118,7 @@
|
|
|
116
118
|
const headerActions = document.getElementById('headerActions');
|
|
117
119
|
const viewActivityBtn = document.getElementById('viewActivityBtn');
|
|
118
120
|
const viewTerminalBtn = document.getElementById('viewTerminalBtn');
|
|
121
|
+
const viewFilesBtn = document.getElementById('viewFilesBtn');
|
|
119
122
|
const viewDetailBtn = document.getElementById('viewDetailBtn');
|
|
120
123
|
const viewConfigBtn = document.getElementById('viewConfigBtn');
|
|
121
124
|
const viewCheckBtn = document.getElementById('viewCheckBtn');
|
|
@@ -172,6 +175,7 @@
|
|
|
172
175
|
const activityModelChip = document.getElementById('activityModelChip');
|
|
173
176
|
const messagesNode = document.getElementById('messages');
|
|
174
177
|
const terminalPanel = document.getElementById('terminalPanel');
|
|
178
|
+
const filesPanel = document.getElementById('filesPanel');
|
|
175
179
|
const detailPanel = document.getElementById('detailPanel');
|
|
176
180
|
const configPanel = document.getElementById('configPanel');
|
|
177
181
|
const checkPanel = document.getElementById('checkPanel');
|
|
@@ -196,6 +200,10 @@
|
|
|
196
200
|
const agentTemplateCancelBtn = document.getElementById('agentTemplateCancelBtn');
|
|
197
201
|
const agentTemplateResetBtn = document.getElementById('agentTemplateResetBtn');
|
|
198
202
|
const agentTemplateSaveBtn = document.getElementById('agentTemplateSaveBtn');
|
|
203
|
+
const externalLinkModal = document.getElementById('externalLinkModal');
|
|
204
|
+
const externalLinkUrl = document.getElementById('externalLinkUrl');
|
|
205
|
+
const externalLinkCancelBtn = document.getElementById('externalLinkCancelBtn');
|
|
206
|
+
const externalLinkOpenBtn = document.getElementById('externalLinkOpenBtn');
|
|
199
207
|
const refreshBtn = document.getElementById('refreshBtn');
|
|
200
208
|
const removeBtn = document.getElementById('removeBtn');
|
|
201
209
|
const removeAllBtn = document.getElementById('removeAllBtn');
|
|
@@ -242,6 +250,7 @@
|
|
|
242
250
|
&& typeof window.ManyoyoMarkdown.render === 'function'
|
|
243
251
|
? window.ManyoyoMarkdown
|
|
244
252
|
: null;
|
|
253
|
+
let fileBrowser = null;
|
|
245
254
|
function normalizeBooleanMap(source) {
|
|
246
255
|
const result = {};
|
|
247
256
|
if (!source || typeof source !== 'object' || Array.isArray(source)) {
|
|
@@ -740,6 +749,45 @@
|
|
|
740
749
|
configStatus.textContent = text;
|
|
741
750
|
}
|
|
742
751
|
|
|
752
|
+
function openExternalLinkModalView(url) {
|
|
753
|
+
const text = String(url || '').trim();
|
|
754
|
+
if (!text) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
state.externalLinkUrl = text;
|
|
758
|
+
state.externalLinkModalOpen = true;
|
|
759
|
+
if (externalLinkUrl) {
|
|
760
|
+
externalLinkUrl.textContent = text;
|
|
761
|
+
}
|
|
762
|
+
setModalVisible(externalLinkModal, true);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function closeExternalLinkModalView() {
|
|
766
|
+
state.externalLinkModalOpen = false;
|
|
767
|
+
state.externalLinkUrl = '';
|
|
768
|
+
if (externalLinkUrl) {
|
|
769
|
+
externalLinkUrl.textContent = '';
|
|
770
|
+
}
|
|
771
|
+
setModalVisible(externalLinkModal, false);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
function confirmExternalLinkOpen() {
|
|
775
|
+
const targetUrl = String(state.externalLinkUrl || '').trim();
|
|
776
|
+
if (!targetUrl) {
|
|
777
|
+
closeExternalLinkModalView();
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (markdownRenderer && typeof markdownRenderer.openExternalLink === 'function') {
|
|
781
|
+
markdownRenderer.openExternalLink(targetUrl);
|
|
782
|
+
} else {
|
|
783
|
+
const popup = window.open(targetUrl, '_blank', 'noopener,noreferrer');
|
|
784
|
+
if (popup) {
|
|
785
|
+
popup.opener = null;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
closeExternalLinkModalView();
|
|
789
|
+
}
|
|
790
|
+
|
|
743
791
|
function showDirectoryPickerError(message) {
|
|
744
792
|
if (!directoryPickerError) return;
|
|
745
793
|
const text = String(message || '').trim();
|
|
@@ -1678,6 +1726,7 @@
|
|
|
1678
1726
|
const VIEW_LABELS = {
|
|
1679
1727
|
activity: '活动',
|
|
1680
1728
|
terminal: '终端',
|
|
1729
|
+
files: '文件',
|
|
1681
1730
|
detail: '详情',
|
|
1682
1731
|
config: '配置',
|
|
1683
1732
|
check: '检查'
|
|
@@ -1956,6 +2005,7 @@
|
|
|
1956
2005
|
|
|
1957
2006
|
const activityTab = state.activeTab === 'activity';
|
|
1958
2007
|
const terminalTab = state.activeTab === 'terminal';
|
|
2008
|
+
const filesTab = state.activeTab === 'files';
|
|
1959
2009
|
const detailTab = state.activeTab === 'detail';
|
|
1960
2010
|
const configTab = state.activeTab === 'config';
|
|
1961
2011
|
const checkTab = state.activeTab === 'check';
|
|
@@ -1966,6 +2016,7 @@
|
|
|
1966
2016
|
document.body.classList.toggle('command-mode', commandMode);
|
|
1967
2017
|
document.body.classList.toggle('agent-mode', agentMode);
|
|
1968
2018
|
document.body.classList.toggle('terminal-mode', terminalTab);
|
|
2019
|
+
document.body.classList.toggle('files-tab', filesTab);
|
|
1969
2020
|
document.body.classList.toggle('detail-tab', detailTab);
|
|
1970
2021
|
document.body.classList.toggle('config-tab', configTab);
|
|
1971
2022
|
document.body.classList.toggle('check-tab', checkTab);
|
|
@@ -1991,6 +2042,7 @@
|
|
|
1991
2042
|
}
|
|
1992
2043
|
if (viewActivityBtn) viewActivityBtn.classList.toggle('is-active', activityTab);
|
|
1993
2044
|
if (viewTerminalBtn) viewTerminalBtn.classList.toggle('is-active', terminalTab);
|
|
2045
|
+
if (viewFilesBtn) viewFilesBtn.classList.toggle('is-active', filesTab);
|
|
1994
2046
|
if (viewDetailBtn) viewDetailBtn.classList.toggle('is-active', detailTab);
|
|
1995
2047
|
if (viewConfigBtn) viewConfigBtn.classList.toggle('is-active', configTab);
|
|
1996
2048
|
if (viewCheckBtn) viewCheckBtn.classList.toggle('is-active', checkTab);
|
|
@@ -2000,6 +2052,9 @@
|
|
|
2000
2052
|
if (terminalPanel) {
|
|
2001
2053
|
terminalPanel.hidden = !terminalTab;
|
|
2002
2054
|
}
|
|
2055
|
+
if (filesPanel) {
|
|
2056
|
+
filesPanel.hidden = !filesTab;
|
|
2057
|
+
}
|
|
2003
2058
|
if (detailPanel) {
|
|
2004
2059
|
detailPanel.hidden = !detailTab;
|
|
2005
2060
|
}
|
|
@@ -2012,6 +2067,14 @@
|
|
|
2012
2067
|
if (terminalTab && state.terminal.terminalReady) {
|
|
2013
2068
|
scheduleTerminalFit(false);
|
|
2014
2069
|
}
|
|
2070
|
+
if (fileBrowser) {
|
|
2071
|
+
fileBrowser.sync({
|
|
2072
|
+
visible: filesTab,
|
|
2073
|
+
session: getActiveSession(),
|
|
2074
|
+
detail: state.sessionDetail,
|
|
2075
|
+
historyOnly: isActiveSessionHistoryOnly()
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2015
2078
|
|
|
2016
2079
|
const activeAgentRunning = isAgentRunActiveForSession(state.active);
|
|
2017
2080
|
const busy = state.loadingSessions || state.loadingMessages || state.sending;
|
|
@@ -2095,6 +2158,9 @@
|
|
|
2095
2158
|
if (agentTemplateModal) {
|
|
2096
2159
|
agentTemplateModal.hidden = !state.agentTemplateModalOpen;
|
|
2097
2160
|
}
|
|
2161
|
+
if (externalLinkModal) {
|
|
2162
|
+
externalLinkModal.hidden = !state.externalLinkModalOpen;
|
|
2163
|
+
}
|
|
2098
2164
|
if (agentTemplateSaveBtn) {
|
|
2099
2165
|
agentTemplateSaveBtn.disabled = state.agentTemplateSaving || !state.active;
|
|
2100
2166
|
}
|
|
@@ -2118,7 +2184,7 @@
|
|
|
2118
2184
|
}
|
|
2119
2185
|
document.body.classList.toggle(
|
|
2120
2186
|
'modal-open',
|
|
2121
|
-
state.configModalOpen || state.createModalOpen || state.directoryPicker.open || state.agentTemplateModalOpen
|
|
2187
|
+
state.configModalOpen || state.createModalOpen || state.directoryPicker.open || state.agentTemplateModalOpen || state.externalLinkModalOpen
|
|
2122
2188
|
);
|
|
2123
2189
|
if (!state.active) {
|
|
2124
2190
|
sendState.textContent = '未选择会话';
|
|
@@ -3901,6 +3967,12 @@
|
|
|
3901
3967
|
});
|
|
3902
3968
|
}
|
|
3903
3969
|
|
|
3970
|
+
if (viewFilesBtn) {
|
|
3971
|
+
viewFilesBtn.addEventListener('click', function () {
|
|
3972
|
+
setActiveTab('files');
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3975
|
+
|
|
3904
3976
|
if (viewDetailBtn) {
|
|
3905
3977
|
viewDetailBtn.addEventListener('click', function () {
|
|
3906
3978
|
setActiveTab('detail');
|
|
@@ -4030,6 +4102,15 @@
|
|
|
4030
4102
|
});
|
|
4031
4103
|
}
|
|
4032
4104
|
|
|
4105
|
+
if (externalLinkModal) {
|
|
4106
|
+
externalLinkModal.addEventListener('click', function (event) {
|
|
4107
|
+
if (event.target === externalLinkModal) {
|
|
4108
|
+
closeExternalLinkModalView();
|
|
4109
|
+
syncUi();
|
|
4110
|
+
}
|
|
4111
|
+
});
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4033
4114
|
window.addEventListener('keydown', function (event) {
|
|
4034
4115
|
if (event.key === 'Escape' && state.configModalOpen) {
|
|
4035
4116
|
closeConfigModal();
|
|
@@ -4046,6 +4127,10 @@
|
|
|
4046
4127
|
closeAgentTemplateModal();
|
|
4047
4128
|
syncUi();
|
|
4048
4129
|
}
|
|
4130
|
+
if (event.key === 'Escape' && state.externalLinkModalOpen) {
|
|
4131
|
+
closeExternalLinkModalView();
|
|
4132
|
+
syncUi();
|
|
4133
|
+
}
|
|
4049
4134
|
if (event.key === 'Escape' && state.mobileSidebarOpen) {
|
|
4050
4135
|
closeMobileSessionPanel();
|
|
4051
4136
|
}
|
|
@@ -4128,6 +4213,37 @@
|
|
|
4128
4213
|
}
|
|
4129
4214
|
});
|
|
4130
4215
|
|
|
4216
|
+
if (externalLinkCancelBtn) {
|
|
4217
|
+
externalLinkCancelBtn.addEventListener('click', function () {
|
|
4218
|
+
closeExternalLinkModalView();
|
|
4219
|
+
syncUi();
|
|
4220
|
+
});
|
|
4221
|
+
}
|
|
4222
|
+
|
|
4223
|
+
if (externalLinkOpenBtn) {
|
|
4224
|
+
externalLinkOpenBtn.addEventListener('click', function () {
|
|
4225
|
+
confirmExternalLinkOpen();
|
|
4226
|
+
syncUi();
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
|
|
4230
|
+
if (markdownRenderer && typeof markdownRenderer.setLinkOpenHandler === 'function') {
|
|
4231
|
+
markdownRenderer.setLinkOpenHandler(function (url) {
|
|
4232
|
+
openExternalLinkModalView(url);
|
|
4233
|
+
syncUi();
|
|
4234
|
+
});
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4237
|
+
if (window.ManyoyoFileBrowser && typeof window.ManyoyoFileBrowser.create === 'function') {
|
|
4238
|
+
fileBrowser = window.ManyoyoFileBrowser.create({
|
|
4239
|
+
root: filesPanel,
|
|
4240
|
+
api,
|
|
4241
|
+
onError: function (message) {
|
|
4242
|
+
alert(message);
|
|
4243
|
+
}
|
|
4244
|
+
});
|
|
4245
|
+
}
|
|
4246
|
+
|
|
4131
4247
|
window.addEventListener('beforeunload', function () {
|
|
4132
4248
|
disconnectTerminal('', true);
|
|
4133
4249
|
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { basicSetup } from 'codemirror';
|
|
2
|
+
import { Compartment, EditorState } from '@codemirror/state';
|
|
3
|
+
import { EditorView } from '@codemirror/view';
|
|
4
|
+
import { css } from '@codemirror/lang-css';
|
|
5
|
+
import { html } from '@codemirror/lang-html';
|
|
6
|
+
import { javascript } from '@codemirror/lang-javascript';
|
|
7
|
+
import { json } from '@codemirror/lang-json';
|
|
8
|
+
import { markdown } from '@codemirror/lang-markdown';
|
|
9
|
+
import { python } from '@codemirror/lang-python';
|
|
10
|
+
import { yaml } from '@codemirror/lang-yaml';
|
|
11
|
+
|
|
12
|
+
function resolveLanguageExtension(language) {
|
|
13
|
+
switch (String(language || '').trim()) {
|
|
14
|
+
case 'css':
|
|
15
|
+
return css();
|
|
16
|
+
case 'html':
|
|
17
|
+
return html();
|
|
18
|
+
case 'javascript':
|
|
19
|
+
return javascript({ jsx: true, typescript: true });
|
|
20
|
+
case 'json':
|
|
21
|
+
return json();
|
|
22
|
+
case 'markdown':
|
|
23
|
+
return markdown();
|
|
24
|
+
case 'python':
|
|
25
|
+
return python();
|
|
26
|
+
case 'yaml':
|
|
27
|
+
return yaml();
|
|
28
|
+
default:
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function createEditor(parent, options = {}) {
|
|
34
|
+
const target = parent;
|
|
35
|
+
const initialDoc = String(options.doc || '');
|
|
36
|
+
const initialLanguage = String(options.language || 'text').trim();
|
|
37
|
+
const initialReadOnly = options.readOnly !== false;
|
|
38
|
+
const languageCompartment = new Compartment();
|
|
39
|
+
const readOnlyCompartment = new Compartment();
|
|
40
|
+
const view = new EditorView({
|
|
41
|
+
parent: target,
|
|
42
|
+
state: EditorState.create({
|
|
43
|
+
doc: initialDoc,
|
|
44
|
+
extensions: [
|
|
45
|
+
basicSetup,
|
|
46
|
+
EditorView.lineWrapping,
|
|
47
|
+
readOnlyCompartment.of([
|
|
48
|
+
EditorState.readOnly.of(initialReadOnly),
|
|
49
|
+
EditorView.editable.of(!initialReadOnly)
|
|
50
|
+
]),
|
|
51
|
+
languageCompartment.of(resolveLanguageExtension(initialLanguage)),
|
|
52
|
+
EditorView.theme({
|
|
53
|
+
'&': {
|
|
54
|
+
height: '100%',
|
|
55
|
+
fontSize: '12px'
|
|
56
|
+
},
|
|
57
|
+
'.cm-scroller': {
|
|
58
|
+
overflow: 'auto'
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
setValue(nextValue) {
|
|
67
|
+
const text = String(nextValue == null ? '' : nextValue);
|
|
68
|
+
view.dispatch({
|
|
69
|
+
changes: {
|
|
70
|
+
from: 0,
|
|
71
|
+
to: view.state.doc.length,
|
|
72
|
+
insert: text
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
setLanguage(nextLanguage) {
|
|
77
|
+
view.dispatch({
|
|
78
|
+
effects: languageCompartment.reconfigure(resolveLanguageExtension(nextLanguage))
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
setReadOnly(readOnly) {
|
|
82
|
+
const value = readOnly !== false;
|
|
83
|
+
view.dispatch({
|
|
84
|
+
effects: readOnlyCompartment.reconfigure([
|
|
85
|
+
EditorState.readOnly.of(value),
|
|
86
|
+
EditorView.editable.of(!value)
|
|
87
|
+
])
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
destroy() {
|
|
91
|
+
view.destroy();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
window.ManyoyoCodeEditor = {
|
|
97
|
+
create: createEditor
|
|
98
|
+
};
|