@zhongqian97-code/ecode 0.5.21 → 0.5.22
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/dist/index.js +72 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5250,7 +5250,7 @@ function generateAdminHtml(version2) {
|
|
|
5250
5250
|
<html lang="zh">
|
|
5251
5251
|
<head>
|
|
5252
5252
|
<meta charset="UTF-8">
|
|
5253
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5253
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content">
|
|
5254
5254
|
<title>ecode web admin</title>
|
|
5255
5255
|
<style>
|
|
5256
5256
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
@@ -5567,6 +5567,13 @@ function generateAdminHtml(version2) {
|
|
|
5567
5567
|
.modal-footer { display:flex; gap:8px; justify-content:flex-end; margin-top:16px; }
|
|
5568
5568
|
#upgrade-output { display:none; background:#0d1117; border:1px solid #30363d; border-radius:4px; padding:8px; font-family:monospace; font-size:12px; color:#c9d1d9; white-space:pre-wrap; max-height:200px; overflow-y:auto; margin-top:8px; }
|
|
5569
5569
|
|
|
5570
|
+
/* \u2500\u2500 Syntax highlight \u2500\u2500 */
|
|
5571
|
+
.kw { color: #ff7b72; }
|
|
5572
|
+
.str { color: #a5d6ff; }
|
|
5573
|
+
.cmt { color: #8b949e; font-style: italic; }
|
|
5574
|
+
.num { color: #79c0ff; }
|
|
5575
|
+
.fn { color: #d2a8ff; }
|
|
5576
|
+
|
|
5570
5577
|
/* \u2500\u2500 Mobile \u2500\u2500 */
|
|
5571
5578
|
@media (max-width: 600px) {
|
|
5572
5579
|
#hamburger { display: block; }
|
|
@@ -5694,6 +5701,21 @@ function generateAdminHtml(version2) {
|
|
|
5694
5701
|
return proto + '//' + location.host + '/api/ws/sessions/' + sessionId + '?token=' + encodeURIComponent(state.token);
|
|
5695
5702
|
}
|
|
5696
5703
|
|
|
5704
|
+
// \u2500\u2500 Code highlighting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5705
|
+
function highlightCode(code) {
|
|
5706
|
+
let s = escHtml(code);
|
|
5707
|
+
// keywords
|
|
5708
|
+
s = s.replace(/\b(function|const|let|var|return|if|else|for|while|class|import|export|from|async|await|new|this|typeof|instanceof|null|undefined|true|false)\b/g, '<span class="kw">$1</span>');
|
|
5709
|
+
// strings (single, double \u2014 after HTML escaping, quotes appear as ' or ")
|
|
5710
|
+
s = s.replace(/('[^&#]*'|"[^&]*")/g, '<span class="str">$1</span>');
|
|
5711
|
+
// comments
|
|
5712
|
+
s = s.replace(/(//[^
|
|
5713
|
+
]*)/g, '<span class="cmt">$1</span>');
|
|
5714
|
+
// numbers
|
|
5715
|
+
s = s.replace(/\b(d+.?d*)\b/g, '<span class="num">$1</span>');
|
|
5716
|
+
return s;
|
|
5717
|
+
}
|
|
5718
|
+
|
|
5697
5719
|
// Basic markdown \u2192 HTML (no libs)
|
|
5698
5720
|
function renderMarkdown(text) {
|
|
5699
5721
|
// Escape HTML first
|
|
@@ -5701,9 +5723,9 @@ function generateAdminHtml(version2) {
|
|
|
5701
5723
|
.replace(/&/g, '&')
|
|
5702
5724
|
.replace(/</g, '<')
|
|
5703
5725
|
.replace(/>/g, '>');
|
|
5704
|
-
// Code blocks
|
|
5726
|
+
// Code blocks (use highlightCode for syntax coloring)
|
|
5705
5727
|
s = s.replace(/\`\`\`([\\s\\S]*?)\`\`\`/g, (_, code) =>
|
|
5706
|
-
'<pre><code>' + code.trim() + '</code></pre>');
|
|
5728
|
+
'<pre><code>' + highlightCode(code.trim()) + '</code></pre>');
|
|
5707
5729
|
// Inline code
|
|
5708
5730
|
s = s.replace(/\`([^\`]+)\`/g, '<code>$1</code>');
|
|
5709
5731
|
// Bold
|
|
@@ -5781,6 +5803,31 @@ function generateAdminHtml(version2) {
|
|
|
5781
5803
|
state.streamingMsgEl = null;
|
|
5782
5804
|
}
|
|
5783
5805
|
|
|
5806
|
+
async function loadMessages(sessionId) {
|
|
5807
|
+
try {
|
|
5808
|
+
const sep = '/api/sessions/' + sessionId + '/messages?token=' + encodeURIComponent(state.token);
|
|
5809
|
+
const res = await fetch(sep);
|
|
5810
|
+
if (!res.ok) return;
|
|
5811
|
+
const text = await res.text();
|
|
5812
|
+
const lines = text.split('\\n').filter(l => l.trim());
|
|
5813
|
+
const msgsEl = document.getElementById('messages');
|
|
5814
|
+
msgsEl.innerHTML = '';
|
|
5815
|
+
for (const line of lines) {
|
|
5816
|
+
try {
|
|
5817
|
+
const m = JSON.parse(line);
|
|
5818
|
+
if (m.content) {
|
|
5819
|
+
appendMessage(m.role === 'user' ? 'user' : 'assistant', renderMarkdown(m.content));
|
|
5820
|
+
}
|
|
5821
|
+
} catch { /* skip malformed lines */ }
|
|
5822
|
+
}
|
|
5823
|
+
if (!lines.length) {
|
|
5824
|
+
msgsEl.innerHTML = '<div class="empty-chat">\u6682\u65E0\u5386\u53F2\u6D88\u606F\uFF0C\u5F00\u59CB\u5BF9\u8BDD\u5427</div>';
|
|
5825
|
+
}
|
|
5826
|
+
} catch (e) {
|
|
5827
|
+
// silently ignore \u2014 session might have no log file yet
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
|
|
5784
5831
|
function appendMessage(role, htmlContent, opts) {
|
|
5785
5832
|
const msgsEl = document.getElementById('messages');
|
|
5786
5833
|
// Remove empty-chat placeholder
|
|
@@ -5848,7 +5895,12 @@ function generateAdminHtml(version2) {
|
|
|
5848
5895
|
finalizeStreamingMsg();
|
|
5849
5896
|
if (state.activeSessionId === sessionId && state.wsRetries < 5) {
|
|
5850
5897
|
state.wsRetries++;
|
|
5851
|
-
|
|
5898
|
+
const wsRetryDelay = Math.min(1000 * Math.pow(2, state.wsRetries), 30000);
|
|
5899
|
+
document.getElementById('ws-status').textContent =
|
|
5900
|
+
'\u91CD\u8FDE\u4E2D\u2026 (' + state.wsRetries + '/5\uFF0C' + (wsRetryDelay/1000).toFixed(0) + 's\u540E)';
|
|
5901
|
+
setTimeout(() => openWs(sessionId), wsRetryDelay);
|
|
5902
|
+
} else if (state.wsRetries >= 5) {
|
|
5903
|
+
document.getElementById('ws-status').textContent = '\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0\u9875\u9762';
|
|
5852
5904
|
}
|
|
5853
5905
|
};
|
|
5854
5906
|
}
|
|
@@ -5957,6 +6009,7 @@ function generateAdminHtml(version2) {
|
|
|
5957
6009
|
document.getElementById('chat-title').textContent =
|
|
5958
6010
|
session ? (session.title || id.slice(0, 12) + '\u2026') : id;
|
|
5959
6011
|
clearMessages();
|
|
6012
|
+
loadMessages(id);
|
|
5960
6013
|
renderSidebar();
|
|
5961
6014
|
setStatus('idle');
|
|
5962
6015
|
connectWs(id);
|
|
@@ -6113,6 +6166,20 @@ function generateAdminHtml(version2) {
|
|
|
6113
6166
|
}
|
|
6114
6167
|
});
|
|
6115
6168
|
|
|
6169
|
+
// \u2500\u2500 Mobile keyboard adaptation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
6170
|
+
document.getElementById('msg-input').addEventListener('focus', () => {
|
|
6171
|
+
setTimeout(() => {
|
|
6172
|
+
document.getElementById('msg-input').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
6173
|
+
}, 300);
|
|
6174
|
+
});
|
|
6175
|
+
|
|
6176
|
+
// \u2500\u2500 Global error boundary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
6177
|
+
window.onerror = function(msg, src, line) {
|
|
6178
|
+
const wsStatusEl = document.getElementById('ws-status');
|
|
6179
|
+
if (wsStatusEl) wsStatusEl.textContent = '\u9519\u8BEF: ' + msg;
|
|
6180
|
+
return false;
|
|
6181
|
+
};
|
|
6182
|
+
|
|
6116
6183
|
// \u2500\u2500 Init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
6117
6184
|
loadSessions();
|
|
6118
6185
|
</script>
|
|
@@ -6423,7 +6490,7 @@ async function systemRoutes(app, opts) {
|
|
|
6423
6490
|
try {
|
|
6424
6491
|
latest = execSync("npm view @zhongqian97-code/ecode version", {
|
|
6425
6492
|
encoding: "utf-8",
|
|
6426
|
-
timeout:
|
|
6493
|
+
timeout: 2e3
|
|
6427
6494
|
}).trim();
|
|
6428
6495
|
} catch {
|
|
6429
6496
|
latest = "unknown";
|