clay-server 2.18.0-beta.9 → 2.18.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/project.js +1445 -32
- package/lib/public/app.js +309 -125
- package/lib/public/css/debate.css +1039 -0
- package/lib/public/css/mates.css +125 -0
- package/lib/public/css/scheduler-modal.css +110 -392
- package/lib/public/css/scheduler.css +10 -3
- package/lib/public/css/sidebar.css +80 -7
- package/lib/public/index.html +53 -106
- package/lib/public/modules/debate.js +633 -0
- package/lib/public/modules/input.js +14 -5
- package/lib/public/modules/mate-sidebar.js +169 -2
- package/lib/public/modules/mention.js +6 -3
- package/lib/public/modules/scheduler.js +373 -252
- package/lib/public/modules/sidebar.js +158 -28
- package/lib/public/modules/tools.js +13 -3
- package/lib/public/modules/tooltip.js +2 -0
- package/lib/public/style.css +1 -0
- package/lib/scheduler.js +59 -1
- package/lib/sessions.js +9 -2
- package/lib/user-presence.js +92 -0
- package/package.json +1 -1
package/lib/public/app.js
CHANGED
|
@@ -7,7 +7,7 @@ import { initMateSidebar, showMateSidebar, hideMateSidebar, renderMateSessionLis
|
|
|
7
7
|
import { initMateKnowledge, requestKnowledgeList, renderKnowledgeList, handleKnowledgeContent, hideKnowledge } from './modules/mate-knowledge.js';
|
|
8
8
|
import { initRewind, setRewindMode, showRewindModal, clearPendingRewindUuid, addRewindButton } from './modules/rewind.js';
|
|
9
9
|
import { initNotifications, showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundEnabled } from './modules/notifications.js';
|
|
10
|
-
import { initInput, clearPendingImages, handleInputSync, autoResize, builtinCommands, sendMessage } from './modules/input.js';
|
|
10
|
+
import { initInput, clearPendingImages, handleInputSync, autoResize, builtinCommands, sendMessage, hasSendableContent } from './modules/input.js';
|
|
11
11
|
import { initQrCode, triggerShare } from './modules/qrcode.js';
|
|
12
12
|
import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
|
|
13
13
|
import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
|
|
@@ -29,7 +29,7 @@ import { initMateWizard, openMateWizard, closeMateWizard, handleMateCreated } fr
|
|
|
29
29
|
import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } from './modules/command-palette.js';
|
|
30
30
|
import { initLongPress } from './modules/longpress.js';
|
|
31
31
|
import { initMention, handleMentionStart, handleMentionStream, handleMentionDone, handleMentionError, handleMentionActivity, renderMentionUser, renderMentionResponse } from './modules/mention.js';
|
|
32
|
-
import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity, handleDebateStream, handleDebateTurnDone, handleDebateCommentQueued, handleDebateCommentInjected, handleDebateEnded, handleDebateError, renderDebateStarted, renderDebateTurnDone, renderDebateEnded, renderDebateCommentInjected, openDebateModal, closeDebateModal } from './modules/debate.js';
|
|
32
|
+
import { initDebate, handleDebateStarted, handleDebateResumed, handleDebateTurn, handleDebateActivity, handleDebateStream, handleDebateTurnDone, handleDebateCommentQueued, handleDebateCommentInjected, handleDebateEnded, handleDebateError, renderDebateStarted, renderDebateTurnDone, renderDebateEnded, renderDebateCommentInjected, renderDebateUserResume, openDebateModal, closeDebateModal } from './modules/debate.js';
|
|
33
33
|
|
|
34
34
|
// --- Base path for multi-project routing ---
|
|
35
35
|
var slugMatch = location.pathname.match(/^\/p\/([a-z0-9_-]+)/);
|
|
@@ -568,6 +568,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
568
568
|
}
|
|
569
569
|
|
|
570
570
|
function enterDmMode(key, targetUser, messages) {
|
|
571
|
+
console.log("[DEBUG enterDmMode] key=" + key, "isMate=" + (targetUser && targetUser.isMate), "messages=" + (messages ? messages.length : 0));
|
|
571
572
|
// Clean up previous DM/mate state before entering new one
|
|
572
573
|
if (dmMode) {
|
|
573
574
|
disconnectMateWs();
|
|
@@ -603,9 +604,9 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
603
604
|
dmKey = key;
|
|
604
605
|
dmTargetUser = targetUser;
|
|
605
606
|
|
|
606
|
-
//
|
|
607
|
-
if (targetUser && targetUser.isMate) {
|
|
608
|
-
try {
|
|
607
|
+
// Notify server of active mate DM (server-side presence tracking)
|
|
608
|
+
if (targetUser && targetUser.isMate && ws && ws.readyState === 1) {
|
|
609
|
+
try { ws.send(JSON.stringify({ type: "set_mate_dm", mateId: targetUser.id })); } catch(e) {}
|
|
609
610
|
}
|
|
610
611
|
|
|
611
612
|
// Clear unread for this user
|
|
@@ -747,7 +748,10 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
747
748
|
dmKey = null;
|
|
748
749
|
dmTargetUser = null;
|
|
749
750
|
setCurrentDmUser(null);
|
|
750
|
-
|
|
751
|
+
// Notify server that mate DM is closed
|
|
752
|
+
if (ws && ws.readyState === 1) {
|
|
753
|
+
try { ws.send(JSON.stringify({ type: "set_mate_dm", mateId: null })); } catch(e) {}
|
|
754
|
+
}
|
|
751
755
|
|
|
752
756
|
var mainCol = document.getElementById("main-column");
|
|
753
757
|
if (mainCol) mainCol.classList.remove("dm-mode");
|
|
@@ -979,6 +983,9 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
979
983
|
}, 100);
|
|
980
984
|
}
|
|
981
985
|
// Feed everything into the main message handler (renders text, tools, etc.)
|
|
986
|
+
if (msg.type === "session_switched" || msg.type === "history_meta") {
|
|
987
|
+
console.log("[DEBUG mateWs]", msg.type, msg.type === "session_switched" ? "id=" + msg.id + " cli=" + (msg.cliSessionId || "").substring(0, 8) : "from=" + msg.from + " total=" + msg.total);
|
|
988
|
+
}
|
|
982
989
|
processMessage(msg);
|
|
983
990
|
}
|
|
984
991
|
|
|
@@ -1076,13 +1083,16 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
1076
1083
|
delete backgroundMateWs[slug];
|
|
1077
1084
|
}
|
|
1078
1085
|
|
|
1086
|
+
// Block main WS messages immediately (before mate WS connects)
|
|
1087
|
+
// so project history doesn't leak into the DM chat
|
|
1088
|
+
savedMainWs = ws;
|
|
1089
|
+
savedActiveSessionId = activeSessionId;
|
|
1090
|
+
|
|
1079
1091
|
var protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
|
1080
1092
|
mateWs = new WebSocket(protocol + "//" + location.host + "/p/" + slug + "/ws");
|
|
1081
1093
|
|
|
1082
1094
|
mateWs.onopen = function () {
|
|
1083
1095
|
// Swap main ws to mateWs so all UI (input, model selector, etc.) routes through mate project
|
|
1084
|
-
savedMainWs = ws;
|
|
1085
|
-
savedActiveSessionId = activeSessionId;
|
|
1086
1096
|
ws = mateWs;
|
|
1087
1097
|
connected = true;
|
|
1088
1098
|
// Wrap send to blink IO on outgoing traffic
|
|
@@ -1099,6 +1109,10 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
1099
1109
|
if (ws === mateWs) {
|
|
1100
1110
|
ws = savedMainWs;
|
|
1101
1111
|
savedMainWs = null;
|
|
1112
|
+
} else if (savedMainWs && !ws) {
|
|
1113
|
+
// Mate WS failed before swap completed; restore main WS
|
|
1114
|
+
ws = savedMainWs;
|
|
1115
|
+
savedMainWs = null;
|
|
1102
1116
|
}
|
|
1103
1117
|
mateWs = null;
|
|
1104
1118
|
delete backgroundMateWs[slug];
|
|
@@ -1136,6 +1150,11 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
1136
1150
|
savedActiveSessionId = null;
|
|
1137
1151
|
}
|
|
1138
1152
|
mateProjectSlug = null;
|
|
1153
|
+
// Hide debate sticky when leaving mate DM
|
|
1154
|
+
showDebateSticky("hide", null);
|
|
1155
|
+
// Hide debate info float
|
|
1156
|
+
var debateFloat = document.getElementById("debate-info-float");
|
|
1157
|
+
if (debateFloat) { debateFloat.classList.add("hidden"); debateFloat.innerHTML = ""; }
|
|
1139
1158
|
// If main WS was disconnected while in mate DM, reconnect now
|
|
1140
1159
|
if (ws && ws.readyState !== 1) {
|
|
1141
1160
|
connect();
|
|
@@ -1602,6 +1621,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
1602
1621
|
var loopAvailable = false;
|
|
1603
1622
|
var loopIteration = 0;
|
|
1604
1623
|
var loopMaxIterations = 0;
|
|
1624
|
+
var loopBannerName = null;
|
|
1605
1625
|
var ralphPhase = "idle"; // idle | wizard | crafting | approval | executing | done
|
|
1606
1626
|
var ralphCraftingSessionId = null;
|
|
1607
1627
|
var ralphCraftingSource = null; // "ralph" or null (task)
|
|
@@ -2118,7 +2138,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
2118
2138
|
} else if (status === "processing") {
|
|
2119
2139
|
if (dot) { dot.classList.add("connected"); dot.classList.add("processing"); }
|
|
2120
2140
|
processing = true;
|
|
2121
|
-
setSendBtnMode(
|
|
2141
|
+
setSendBtnMode(hasSendableContent() ? "send" : "stop");
|
|
2122
2142
|
} else {
|
|
2123
2143
|
connected = false;
|
|
2124
2144
|
sendBtn.disabled = true;
|
|
@@ -2171,7 +2191,11 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
2171
2191
|
'<span class="mate-thinking-dots"><span></span><span></span><span></span></span>' +
|
|
2172
2192
|
'</div>' +
|
|
2173
2193
|
'</div>';
|
|
2174
|
-
|
|
2194
|
+
if (activityEl && activityEl.parentNode) {
|
|
2195
|
+
activityEl.parentNode.insertBefore(matePreThinkingEl, activityEl);
|
|
2196
|
+
} else {
|
|
2197
|
+
addToMessages(matePreThinkingEl);
|
|
2198
|
+
}
|
|
2175
2199
|
scrollToBottom();
|
|
2176
2200
|
}
|
|
2177
2201
|
function removeMatePreThinking() {
|
|
@@ -2896,6 +2920,13 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
2896
2920
|
isMateDm: function () { return dmMode && dmTargetUser && dmTargetUser.isMate; },
|
|
2897
2921
|
getMateName: function () { return dmTargetUser ? (dmTargetUser.displayName || "Mate") : "Mate"; },
|
|
2898
2922
|
getMateAvatarUrl: function () { return document.body.dataset.mateAvatarUrl || ""; },
|
|
2923
|
+
getMateById: function (id) {
|
|
2924
|
+
if (!id || !cachedMatesList) return null;
|
|
2925
|
+
for (var i = 0; i < cachedMatesList.length; i++) {
|
|
2926
|
+
if (cachedMatesList[i].id === id) return cachedMatesList[i];
|
|
2927
|
+
}
|
|
2928
|
+
return null;
|
|
2929
|
+
},
|
|
2899
2930
|
});
|
|
2900
2931
|
|
|
2901
2932
|
// isPlanFile, toolSummary, toolActivityText, shortPath -> modules/tools.js
|
|
@@ -3692,30 +3723,8 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
3692
3723
|
ws.send(JSON.stringify({ type: "mate_list" }));
|
|
3693
3724
|
} catch(e) {}
|
|
3694
3725
|
|
|
3695
|
-
//
|
|
3696
|
-
|
|
3697
|
-
var savedSessionId = localStorage.getItem("clay_active_session_" + basePath);
|
|
3698
|
-
if (savedSessionId) {
|
|
3699
|
-
ws.send(JSON.stringify({ type: "switch_session", id: parseInt(savedSessionId, 10) }));
|
|
3700
|
-
}
|
|
3701
|
-
} catch(e) {}
|
|
3702
|
-
|
|
3703
|
-
// Restore mate DM after hard refresh or server restart
|
|
3704
|
-
try {
|
|
3705
|
-
var savedMateDm = localStorage.getItem("clay_active_mate_dm");
|
|
3706
|
-
if (savedMateDm) {
|
|
3707
|
-
// If dmMode is stale (server restarted while in mate DM), clean up first
|
|
3708
|
-
if (dmMode) {
|
|
3709
|
-
dmMode = false;
|
|
3710
|
-
savedMainWs = null;
|
|
3711
|
-
mateWs = null;
|
|
3712
|
-
document.body.classList.remove("mate-dm-active");
|
|
3713
|
-
}
|
|
3714
|
-
pendingMateDmRestore = true;
|
|
3715
|
-
messagesEl.innerHTML = ""; // prevent regular history flash
|
|
3716
|
-
openDm(savedMateDm);
|
|
3717
|
-
}
|
|
3718
|
-
} catch(e) {}
|
|
3726
|
+
// Session restore is now server-driven (user-presence.json).
|
|
3727
|
+
// Mate DM restore is also server-driven via "restore_mate_dm" message.
|
|
3719
3728
|
};
|
|
3720
3729
|
|
|
3721
3730
|
ws.onclose = function (e) {
|
|
@@ -3780,11 +3789,18 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
3780
3789
|
}
|
|
3781
3790
|
|
|
3782
3791
|
function processMessage(msg) {
|
|
3792
|
+
// DEBUG: trace session/history loading
|
|
3793
|
+
if (msg.type === "session_switched" || msg.type === "history_meta" || msg.type === "history_done" || msg.type === "mention_user" || msg.type === "mention_response") {
|
|
3794
|
+
console.log("[DEBUG msg]", msg.type, msg.type === "session_switched" ? "id=" + msg.id + " cli=" + (msg.cliSessionId || "").substring(0, 8) : "", msg.type === "history_meta" ? "from=" + msg.from + " total=" + msg.total : "", msg.type === "mention_user" ? "mate=" + msg.mateName : "", "dmMode=" + dmMode, "pending=" + pendingMateDmRestore, "ws===mateWs?" + (ws === mateWs));
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3783
3797
|
// Suppress regular project messages while restoring mate DM
|
|
3784
3798
|
if (pendingMateDmRestore) {
|
|
3785
3799
|
if (msg.type === "dm_history" || msg.type === "dm_list" || msg.type === "mate_list" || msg.type === "mate_created" || msg.type === "info") {
|
|
3786
3800
|
// Let these through
|
|
3801
|
+
console.log("[DEBUG] pendingRestore: letting through", msg.type);
|
|
3787
3802
|
} else {
|
|
3803
|
+
console.log("[DEBUG] pendingRestore: BLOCKING", msg.type);
|
|
3788
3804
|
return; // skip regular session messages
|
|
3789
3805
|
}
|
|
3790
3806
|
}
|
|
@@ -3841,6 +3857,21 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
3841
3857
|
}
|
|
3842
3858
|
break;
|
|
3843
3859
|
|
|
3860
|
+
case "restore_mate_dm":
|
|
3861
|
+
if (msg.mateId) {
|
|
3862
|
+
// Server-driven mate DM restore on reconnect
|
|
3863
|
+
if (dmMode) {
|
|
3864
|
+
dmMode = false;
|
|
3865
|
+
savedMainWs = null;
|
|
3866
|
+
mateWs = null;
|
|
3867
|
+
document.body.classList.remove("mate-dm-active");
|
|
3868
|
+
}
|
|
3869
|
+
pendingMateDmRestore = true;
|
|
3870
|
+
messagesEl.innerHTML = "";
|
|
3871
|
+
openDm(msg.mateId);
|
|
3872
|
+
}
|
|
3873
|
+
break;
|
|
3874
|
+
|
|
3844
3875
|
case "info":
|
|
3845
3876
|
if (msg.text && !msg.project && !msg.cwd) {
|
|
3846
3877
|
addSystemMessage(msg.text, false);
|
|
@@ -4081,8 +4112,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4081
4112
|
}
|
|
4082
4113
|
activeSessionId = msg.id;
|
|
4083
4114
|
cliSessionId = msg.cliSessionId || null;
|
|
4084
|
-
//
|
|
4085
|
-
try { localStorage.setItem("clay_active_session_" + basePath, String(msg.id)); } catch(e) {}
|
|
4115
|
+
// Session presence is now tracked server-side (user-presence.json)
|
|
4086
4116
|
clearRemoteCursors();
|
|
4087
4117
|
resetClientState();
|
|
4088
4118
|
updateRalphBars();
|
|
@@ -4246,7 +4276,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4246
4276
|
break;
|
|
4247
4277
|
|
|
4248
4278
|
case "permission_request":
|
|
4249
|
-
renderPermissionRequest(msg.requestId, msg.toolName, msg.toolInput, msg.decisionReason);
|
|
4279
|
+
renderPermissionRequest(msg.requestId, msg.toolName, msg.toolInput, msg.decisionReason, msg.mateId);
|
|
4250
4280
|
startUrgentBlink();
|
|
4251
4281
|
break;
|
|
4252
4282
|
|
|
@@ -4261,7 +4291,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4261
4291
|
break;
|
|
4262
4292
|
|
|
4263
4293
|
case "permission_request_pending":
|
|
4264
|
-
renderPermissionRequest(msg.requestId, msg.toolName, msg.toolInput, msg.decisionReason);
|
|
4294
|
+
renderPermissionRequest(msg.requestId, msg.toolName, msg.toolInput, msg.decisionReason, msg.mateId);
|
|
4265
4295
|
startUrgentBlink();
|
|
4266
4296
|
break;
|
|
4267
4297
|
|
|
@@ -4702,12 +4732,13 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4702
4732
|
break;
|
|
4703
4733
|
|
|
4704
4734
|
case "mention_user":
|
|
4705
|
-
//
|
|
4735
|
+
// Finalize current assistant block so mention renders in correct DOM position
|
|
4736
|
+
finalizeAssistantBlock();
|
|
4706
4737
|
renderMentionUser(msg);
|
|
4707
4738
|
break;
|
|
4708
4739
|
|
|
4709
4740
|
case "mention_response":
|
|
4710
|
-
|
|
4741
|
+
finalizeAssistantBlock();
|
|
4711
4742
|
renderMentionResponse(msg);
|
|
4712
4743
|
break;
|
|
4713
4744
|
|
|
@@ -4718,7 +4749,11 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4718
4749
|
|
|
4719
4750
|
case "debate_started":
|
|
4720
4751
|
showDebateSticky("live", msg);
|
|
4721
|
-
|
|
4752
|
+
if (replayingHistory) {
|
|
4753
|
+
renderDebateStarted(msg);
|
|
4754
|
+
} else {
|
|
4755
|
+
handleDebateStarted(msg);
|
|
4756
|
+
}
|
|
4722
4757
|
break;
|
|
4723
4758
|
|
|
4724
4759
|
case "debate_turn":
|
|
@@ -4735,7 +4770,12 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4735
4770
|
break;
|
|
4736
4771
|
|
|
4737
4772
|
case "debate_turn_done":
|
|
4738
|
-
|
|
4773
|
+
if (msg.round) updateDebateRound(msg.round);
|
|
4774
|
+
if (replayingHistory) {
|
|
4775
|
+
renderDebateTurnDone(msg);
|
|
4776
|
+
} else {
|
|
4777
|
+
handleDebateTurnDone(msg);
|
|
4778
|
+
}
|
|
4739
4779
|
break;
|
|
4740
4780
|
|
|
4741
4781
|
case "debate_comment_queued":
|
|
@@ -4743,12 +4783,33 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4743
4783
|
break;
|
|
4744
4784
|
|
|
4745
4785
|
case "debate_comment_injected":
|
|
4746
|
-
|
|
4786
|
+
if (replayingHistory) {
|
|
4787
|
+
renderDebateCommentInjected(msg);
|
|
4788
|
+
} else {
|
|
4789
|
+
handleDebateCommentInjected(msg);
|
|
4790
|
+
}
|
|
4791
|
+
break;
|
|
4792
|
+
|
|
4793
|
+
case "debate_conclude_confirm":
|
|
4794
|
+
showDebateConcludeConfirm(msg);
|
|
4795
|
+
break;
|
|
4796
|
+
|
|
4797
|
+
case "debate_user_resume":
|
|
4798
|
+
renderDebateUserResume(msg);
|
|
4799
|
+
break;
|
|
4800
|
+
|
|
4801
|
+
case "debate_resumed":
|
|
4802
|
+
handleDebateResumed(msg);
|
|
4803
|
+
showDebateSticky("live", msg);
|
|
4747
4804
|
break;
|
|
4748
4805
|
|
|
4749
4806
|
case "debate_ended":
|
|
4750
4807
|
showDebateSticky("ended", msg);
|
|
4751
|
-
|
|
4808
|
+
if (replayingHistory) {
|
|
4809
|
+
renderDebateEnded(msg);
|
|
4810
|
+
} else {
|
|
4811
|
+
handleDebateEnded(msg);
|
|
4812
|
+
}
|
|
4752
4813
|
break;
|
|
4753
4814
|
|
|
4754
4815
|
case "debate_error":
|
|
@@ -4786,6 +4847,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4786
4847
|
loopActive = msg.active;
|
|
4787
4848
|
loopIteration = msg.iteration || 0;
|
|
4788
4849
|
loopMaxIterations = msg.maxIterations || 20;
|
|
4850
|
+
loopBannerName = msg.name || null;
|
|
4789
4851
|
updateLoopButton();
|
|
4790
4852
|
if (loopActive) {
|
|
4791
4853
|
showLoopBanner(true);
|
|
@@ -4793,7 +4855,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4793
4855
|
updateLoopBanner(loopIteration, loopMaxIterations, "running");
|
|
4794
4856
|
}
|
|
4795
4857
|
inputEl.disabled = true;
|
|
4796
|
-
inputEl.placeholder = "
|
|
4858
|
+
inputEl.placeholder = (loopBannerName || "Loop") + " is running...";
|
|
4797
4859
|
}
|
|
4798
4860
|
break;
|
|
4799
4861
|
|
|
@@ -4802,11 +4864,12 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4802
4864
|
ralphPhase = "executing";
|
|
4803
4865
|
loopIteration = 0;
|
|
4804
4866
|
loopMaxIterations = msg.maxIterations;
|
|
4867
|
+
loopBannerName = msg.name || null;
|
|
4805
4868
|
showLoopBanner(true);
|
|
4806
4869
|
updateLoopButton();
|
|
4807
|
-
addSystemMessage("
|
|
4870
|
+
addSystemMessage((loopBannerName || "Loop") + " started (max " + msg.maxIterations + " iterations)", false);
|
|
4808
4871
|
inputEl.disabled = true;
|
|
4809
|
-
inputEl.placeholder = "
|
|
4872
|
+
inputEl.placeholder = (loopBannerName || "Loop") + " is running...";
|
|
4810
4873
|
break;
|
|
4811
4874
|
|
|
4812
4875
|
case "loop_iteration":
|
|
@@ -4814,16 +4877,16 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4814
4877
|
loopMaxIterations = msg.maxIterations;
|
|
4815
4878
|
updateLoopBanner(msg.iteration, msg.maxIterations, "running");
|
|
4816
4879
|
updateLoopButton();
|
|
4817
|
-
addSystemMessage("
|
|
4880
|
+
addSystemMessage((loopBannerName || "Loop") + " iteration #" + msg.iteration + " started", false);
|
|
4818
4881
|
inputEl.disabled = true;
|
|
4819
|
-
inputEl.placeholder = "
|
|
4882
|
+
inputEl.placeholder = (loopBannerName || "Loop") + " is running...";
|
|
4820
4883
|
break;
|
|
4821
4884
|
|
|
4822
4885
|
case "loop_judging":
|
|
4823
4886
|
updateLoopBanner(loopIteration, loopMaxIterations, "judging");
|
|
4824
4887
|
addSystemMessage("Judging iteration #" + msg.iteration + "...", false);
|
|
4825
4888
|
inputEl.disabled = true;
|
|
4826
|
-
inputEl.placeholder = "
|
|
4889
|
+
inputEl.placeholder = (loopBannerName || "Loop") + " is judging...";
|
|
4827
4890
|
break;
|
|
4828
4891
|
|
|
4829
4892
|
case "loop_verdict":
|
|
@@ -4837,21 +4900,23 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
4837
4900
|
case "loop_finished":
|
|
4838
4901
|
loopActive = false;
|
|
4839
4902
|
ralphPhase = "done";
|
|
4903
|
+
loopBannerName = null;
|
|
4840
4904
|
showLoopBanner(false);
|
|
4841
4905
|
updateLoopButton();
|
|
4842
4906
|
enableMainInput();
|
|
4907
|
+
var loopLabel = loopBannerName || "Loop";
|
|
4843
4908
|
var finishMsg = msg.reason === "pass"
|
|
4844
|
-
? "
|
|
4909
|
+
? loopLabel + " completed successfully after " + msg.iterations + " iteration(s)."
|
|
4845
4910
|
: msg.reason === "max_iterations"
|
|
4846
|
-
? "
|
|
4911
|
+
? loopLabel + " reached maximum iterations (" + msg.iterations + ")."
|
|
4847
4912
|
: msg.reason === "stopped"
|
|
4848
|
-
? "
|
|
4849
|
-
: "
|
|
4913
|
+
? loopLabel + " stopped."
|
|
4914
|
+
: loopLabel + " ended with error.";
|
|
4850
4915
|
addSystemMessage(finishMsg, false);
|
|
4851
4916
|
break;
|
|
4852
4917
|
|
|
4853
4918
|
case "loop_error":
|
|
4854
|
-
addSystemMessage("
|
|
4919
|
+
addSystemMessage((loopBannerName || "Loop") + " error: " + msg.text, true);
|
|
4855
4920
|
break;
|
|
4856
4921
|
|
|
4857
4922
|
// --- Ralph Wizard / Crafting ---
|
|
@@ -5086,6 +5151,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
5086
5151
|
scrollToBottom: scrollToBottom,
|
|
5087
5152
|
addUserMessage: addUserMessage,
|
|
5088
5153
|
addCopyHandler: addCopyHandler,
|
|
5154
|
+
addToMessages: addToMessages,
|
|
5089
5155
|
});
|
|
5090
5156
|
|
|
5091
5157
|
// --- Debate module ---
|
|
@@ -5515,7 +5581,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
5515
5581
|
modal.querySelector(".loop-status-dialog-stop").addEventListener("click", function(e) {
|
|
5516
5582
|
e.stopPropagation();
|
|
5517
5583
|
closeModal();
|
|
5518
|
-
showConfirm("Stop the running
|
|
5584
|
+
showConfirm("Stop the running " + (loopBannerName || "loop") + "?", function() {
|
|
5519
5585
|
if (ws && ws.readyState === 1) {
|
|
5520
5586
|
ws.send(JSON.stringify({ type: "loop_stop" }));
|
|
5521
5587
|
}
|
|
@@ -5534,11 +5600,12 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
5534
5600
|
return;
|
|
5535
5601
|
}
|
|
5536
5602
|
|
|
5603
|
+
var bannerLabel = loopBannerName || "Loop";
|
|
5537
5604
|
stickyEl.innerHTML =
|
|
5538
5605
|
'<div class="ralph-sticky-inner">' +
|
|
5539
5606
|
'<div class="ralph-sticky-header">' +
|
|
5540
5607
|
'<span class="ralph-sticky-icon">' + iconHtml("repeat") + '</span>' +
|
|
5541
|
-
'<span class="ralph-sticky-label">
|
|
5608
|
+
'<span class="ralph-sticky-label">' + escapeHtml(bannerLabel) + '</span>' +
|
|
5542
5609
|
'<span class="ralph-sticky-status" id="loop-status">Starting\u2026</span>' +
|
|
5543
5610
|
'<button class="ralph-sticky-action ralph-sticky-stop" title="Stop loop">' + iconHtml("square") + '</button>' +
|
|
5544
5611
|
'</div>' +
|
|
@@ -5559,10 +5626,16 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
5559
5626
|
function updateLoopBanner(iteration, maxIterations, phase) {
|
|
5560
5627
|
var statusEl = document.getElementById("loop-status");
|
|
5561
5628
|
if (!statusEl) return;
|
|
5562
|
-
var text
|
|
5563
|
-
if (phase === "
|
|
5564
|
-
|
|
5565
|
-
else
|
|
5629
|
+
var text;
|
|
5630
|
+
if (phase === "stopping") {
|
|
5631
|
+
text = "Stopping\u2026";
|
|
5632
|
+
} else if (maxIterations <= 1) {
|
|
5633
|
+
text = phase === "judging" ? "judging\u2026" : "running";
|
|
5634
|
+
} else {
|
|
5635
|
+
text = "#" + iteration + "/" + maxIterations;
|
|
5636
|
+
if (phase === "judging") text += " judging\u2026";
|
|
5637
|
+
else text += " running";
|
|
5638
|
+
}
|
|
5566
5639
|
statusEl.textContent = text;
|
|
5567
5640
|
}
|
|
5568
5641
|
|
|
@@ -6293,111 +6366,222 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
6293
6366
|
var debateStickyState = null;
|
|
6294
6367
|
var debateHandRaiseOpen = false;
|
|
6295
6368
|
|
|
6369
|
+
function showDebateConcludeConfirm(msg) {
|
|
6370
|
+
showDebateBottomBar("conclude", msg);
|
|
6371
|
+
scrollToBottom();
|
|
6372
|
+
}
|
|
6373
|
+
|
|
6374
|
+
// Legacy handler kept for compatibility
|
|
6296
6375
|
function showDebateSticky(phase, msg) {
|
|
6297
6376
|
if (phase === "ended" || phase === "hide") {
|
|
6298
6377
|
debateStickyState = null;
|
|
6299
6378
|
} else {
|
|
6300
6379
|
debateStickyState = { phase: phase, msg: msg };
|
|
6301
6380
|
}
|
|
6381
|
+
|
|
6382
|
+
// Hide the old sticky element (no longer used for content)
|
|
6302
6383
|
var stickyEl = document.getElementById("debate-sticky");
|
|
6303
|
-
if (
|
|
6384
|
+
if (stickyEl) { stickyEl.classList.add("hidden"); stickyEl.innerHTML = ""; }
|
|
6385
|
+
|
|
6386
|
+
// Remove existing header badges
|
|
6387
|
+
var oldBadges = document.querySelectorAll(".debate-header-badge");
|
|
6388
|
+
for (var i = 0; i < oldBadges.length; i++) oldBadges[i].remove();
|
|
6304
6389
|
|
|
6305
6390
|
if (phase === "ended" || phase === "hide") {
|
|
6306
|
-
stickyEl.classList.add("hidden");
|
|
6307
|
-
stickyEl.innerHTML = "";
|
|
6308
6391
|
debateHandRaiseOpen = false;
|
|
6392
|
+
removeDebateBottomBar();
|
|
6309
6393
|
return;
|
|
6310
6394
|
}
|
|
6311
6395
|
|
|
6312
|
-
|
|
6313
|
-
var
|
|
6396
|
+
// Add badges next to header title
|
|
6397
|
+
var headerTitle = document.getElementById("header-title");
|
|
6398
|
+
if (!headerTitle) return;
|
|
6314
6399
|
|
|
6315
6400
|
if (phase === "preparing") {
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6401
|
+
var badge = document.createElement("span");
|
|
6402
|
+
badge.className = "debate-header-badge preparing";
|
|
6403
|
+
badge.textContent = "Setting up\u2026";
|
|
6404
|
+
headerTitle.after(badge);
|
|
6405
|
+
} else if (phase === "live") {
|
|
6406
|
+
var liveBadge = document.createElement("span");
|
|
6407
|
+
liveBadge.className = "debate-header-badge live";
|
|
6408
|
+
liveBadge.textContent = "Live";
|
|
6409
|
+
headerTitle.after(liveBadge);
|
|
6410
|
+
|
|
6411
|
+
var roundBadge = document.createElement("span");
|
|
6412
|
+
roundBadge.className = "debate-header-badge round";
|
|
6413
|
+
roundBadge.id = "debate-header-round";
|
|
6414
|
+
roundBadge.textContent = "R" + ((msg && msg.round) || 1);
|
|
6415
|
+
liveBadge.after(roundBadge);
|
|
6416
|
+
|
|
6417
|
+
debateHandRaiseOpen = false;
|
|
6418
|
+
showDebateBottomBar("live");
|
|
6419
|
+
}
|
|
6420
|
+
}
|
|
6421
|
+
|
|
6422
|
+
// --- Debate bottom bar (replaces input-area during debate) ---
|
|
6423
|
+
function showDebateBottomBar(mode, msg) {
|
|
6424
|
+
removeDebateBottomBar();
|
|
6425
|
+
|
|
6426
|
+
var inputArea = document.getElementById("input-area");
|
|
6427
|
+
if (!inputArea || !inputArea.parentNode) return;
|
|
6428
|
+
|
|
6429
|
+
var bar = document.createElement("div");
|
|
6430
|
+
bar.id = "debate-bottom-bar";
|
|
6431
|
+
bar.className = "debate-bottom-bar";
|
|
6432
|
+
|
|
6433
|
+
if (mode === "live") {
|
|
6434
|
+
bar.innerHTML =
|
|
6435
|
+
'<div class="debate-bottom-inner">' +
|
|
6436
|
+
'<button class="debate-bottom-hand" id="debate-bottom-hand">' + iconHtml("hand") + ' Raise hand</button>' +
|
|
6437
|
+
'<button class="debate-bottom-stop" id="debate-bottom-stop">' + iconHtml("square") + ' Stop</button>' +
|
|
6324
6438
|
'</div>';
|
|
6325
|
-
|
|
6326
|
-
|
|
6439
|
+
|
|
6440
|
+
inputArea.parentNode.insertBefore(bar, inputArea);
|
|
6441
|
+
inputArea.style.display = "none";
|
|
6327
6442
|
refreshIcons();
|
|
6328
6443
|
|
|
6329
|
-
|
|
6330
|
-
|
|
6444
|
+
document.getElementById("debate-bottom-hand").addEventListener("click", function () {
|
|
6445
|
+
toggleDebateHandRaise();
|
|
6446
|
+
});
|
|
6447
|
+
document.getElementById("debate-bottom-stop").addEventListener("click", function () {
|
|
6331
6448
|
if (ws && ws.readyState === 1) {
|
|
6332
6449
|
ws.send(JSON.stringify({ type: "debate_stop" }));
|
|
6333
6450
|
}
|
|
6334
|
-
stickyEl.classList.add("hidden");
|
|
6335
|
-
stickyEl.innerHTML = "";
|
|
6336
6451
|
});
|
|
6337
|
-
} else if (
|
|
6338
|
-
|
|
6339
|
-
'<div class="debate-
|
|
6340
|
-
'<div class="debate-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
'<
|
|
6344
|
-
'<
|
|
6345
|
-
'<button class="debate-sticky-action debate-sticky-hand" title="Raise hand">' + iconHtml("hand") + '</button>' +
|
|
6346
|
-
'<button class="debate-sticky-action debate-sticky-stop" title="Stop debate">' + iconHtml("square") + '</button>' +
|
|
6347
|
-
'</div>' +
|
|
6348
|
-
'<div class="debate-sticky-hand-input hidden" id="debate-sticky-hand-input">' +
|
|
6349
|
-
'<textarea id="debate-sticky-comment" rows="1" placeholder="Your comment\u2026"></textarea>' +
|
|
6350
|
-
'<button class="debate-sticky-send" id="debate-sticky-send">Send</button>' +
|
|
6351
|
-
'<button class="debate-sticky-send-cancel" id="debate-sticky-send-cancel">Cancel</button>' +
|
|
6452
|
+
} else if (mode === "conclude") {
|
|
6453
|
+
bar.innerHTML =
|
|
6454
|
+
'<div class="debate-bottom-inner debate-bottom-conclude">' +
|
|
6455
|
+
'<div class="debate-bottom-conclude-label">' + iconHtml("check-circle") + ' The moderator is ready to conclude. End the debate?</div>' +
|
|
6456
|
+
'<textarea class="debate-bottom-conclude-input" id="debate-bottom-conclude-input" rows="3" placeholder="Or add a direction to continue..."></textarea>' +
|
|
6457
|
+
'<div class="debate-bottom-conclude-actions">' +
|
|
6458
|
+
'<button class="debate-bottom-continue" id="debate-bottom-continue">Continue</button>' +
|
|
6459
|
+
'<button class="debate-bottom-end" id="debate-bottom-end">End Debate</button>' +
|
|
6352
6460
|
'</div>' +
|
|
6353
6461
|
'</div>';
|
|
6354
|
-
|
|
6355
|
-
|
|
6462
|
+
|
|
6463
|
+
inputArea.parentNode.insertBefore(bar, inputArea);
|
|
6464
|
+
inputArea.style.display = "none";
|
|
6356
6465
|
refreshIcons();
|
|
6357
|
-
debateHandRaiseOpen = false;
|
|
6358
6466
|
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6467
|
+
var textArea = document.getElementById("debate-bottom-conclude-input");
|
|
6468
|
+
document.getElementById("debate-bottom-end").addEventListener("click", function () {
|
|
6469
|
+
if (ws && ws.readyState === 1) {
|
|
6470
|
+
ws.send(JSON.stringify({ type: "debate_conclude_response", action: "end" }));
|
|
6471
|
+
}
|
|
6472
|
+
removeDebateBottomBar();
|
|
6362
6473
|
});
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
e.stopPropagation();
|
|
6474
|
+
document.getElementById("debate-bottom-continue").addEventListener("click", function () {
|
|
6475
|
+
var text = textArea ? textArea.value.trim() : "";
|
|
6366
6476
|
if (ws && ws.readyState === 1) {
|
|
6367
|
-
ws.send(JSON.stringify({ type: "
|
|
6477
|
+
ws.send(JSON.stringify({ type: "debate_conclude_response", action: "continue", text: text }));
|
|
6368
6478
|
}
|
|
6479
|
+
removeDebateBottomBar();
|
|
6480
|
+
showDebateBottomBar("live");
|
|
6369
6481
|
});
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
if (e.key === "Escape") { toggleDebateHandRaise(false); }
|
|
6482
|
+
if (textArea) {
|
|
6483
|
+
textArea.focus();
|
|
6484
|
+
textArea.addEventListener("keydown", function (e) {
|
|
6485
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
6486
|
+
e.preventDefault();
|
|
6487
|
+
document.getElementById("debate-bottom-continue").click();
|
|
6488
|
+
}
|
|
6489
|
+
});
|
|
6490
|
+
textArea.addEventListener("input", function () {
|
|
6491
|
+
debateAutoResize(textArea, 12);
|
|
6381
6492
|
});
|
|
6382
6493
|
}
|
|
6383
6494
|
}
|
|
6384
6495
|
}
|
|
6385
6496
|
|
|
6497
|
+
function debateAutoResize(textarea, maxRows) {
|
|
6498
|
+
textarea.style.height = "auto";
|
|
6499
|
+
var lineHeight = parseInt(getComputedStyle(textarea).lineHeight) || 20;
|
|
6500
|
+
var maxHeight = lineHeight * maxRows;
|
|
6501
|
+
var newHeight = Math.min(textarea.scrollHeight, maxHeight);
|
|
6502
|
+
textarea.style.height = newHeight + "px";
|
|
6503
|
+
textarea.style.overflowY = textarea.scrollHeight > maxHeight ? "auto" : "hidden";
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6506
|
+
function removeDebateBottomBar() {
|
|
6507
|
+
var existing = document.getElementById("debate-bottom-bar");
|
|
6508
|
+
if (existing) existing.remove();
|
|
6509
|
+
// Also remove hand raise bar if open
|
|
6510
|
+
var handBar = document.getElementById("debate-hand-raise-bar");
|
|
6511
|
+
if (handBar) handBar.remove();
|
|
6512
|
+
debateHandRaiseOpen = false;
|
|
6513
|
+
// Restore input area
|
|
6514
|
+
var inputArea = document.getElementById("input-area");
|
|
6515
|
+
if (inputArea) inputArea.style.display = "";
|
|
6516
|
+
}
|
|
6517
|
+
|
|
6386
6518
|
function toggleDebateHandRaise(forceState) {
|
|
6387
|
-
var inputWrap = document.getElementById("debate-sticky-hand-input");
|
|
6388
|
-
var commentInput = document.getElementById("debate-sticky-comment");
|
|
6389
|
-
if (!inputWrap) return;
|
|
6390
6519
|
var show = typeof forceState === "boolean" ? forceState : !debateHandRaiseOpen;
|
|
6391
6520
|
debateHandRaiseOpen = show;
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6521
|
+
|
|
6522
|
+
var existing = document.getElementById("debate-hand-raise-bar");
|
|
6523
|
+
if (!show) {
|
|
6524
|
+
if (existing) existing.remove();
|
|
6525
|
+
return;
|
|
6526
|
+
}
|
|
6527
|
+
if (existing) {
|
|
6528
|
+
var inp = existing.querySelector(".debate-hand-input");
|
|
6529
|
+
if (inp) { inp.value = ""; inp.focus(); }
|
|
6530
|
+
return;
|
|
6531
|
+
}
|
|
6532
|
+
|
|
6533
|
+
// Create hand raise bar above input area
|
|
6534
|
+
var bar = document.createElement("div");
|
|
6535
|
+
bar.id = "debate-hand-raise-bar";
|
|
6536
|
+
bar.className = "debate-hand-raise-bar";
|
|
6537
|
+
bar.innerHTML =
|
|
6538
|
+
'<div class="debate-hand-raise-inner">' +
|
|
6539
|
+
'<span class="debate-hand-raise-label">' + iconHtml("hand") + ' Your comment:</span>' +
|
|
6540
|
+
'<textarea class="debate-hand-input" rows="1" placeholder="Type your comment..."></textarea>' +
|
|
6541
|
+
'<button class="debate-hand-send">Send</button>' +
|
|
6542
|
+
'<button class="debate-hand-cancel">Cancel</button>' +
|
|
6543
|
+
'</div>';
|
|
6544
|
+
|
|
6545
|
+
var inputArea = document.getElementById("input-area");
|
|
6546
|
+
if (inputArea && inputArea.parentNode) {
|
|
6547
|
+
inputArea.parentNode.insertBefore(bar, inputArea);
|
|
6548
|
+
}
|
|
6549
|
+
refreshIcons();
|
|
6550
|
+
|
|
6551
|
+
var textarea = bar.querySelector(".debate-hand-input");
|
|
6552
|
+
var sendBtn = bar.querySelector(".debate-hand-send");
|
|
6553
|
+
var cancelBtn = bar.querySelector(".debate-hand-cancel");
|
|
6554
|
+
|
|
6555
|
+
if (textarea) {
|
|
6556
|
+
textarea.focus();
|
|
6557
|
+
textarea.addEventListener("input", function () {
|
|
6558
|
+
debateAutoResize(textarea, 12);
|
|
6559
|
+
});
|
|
6560
|
+
}
|
|
6561
|
+
|
|
6562
|
+
sendBtn.addEventListener("click", function () {
|
|
6563
|
+
var text = textarea ? textarea.value.trim() : "";
|
|
6564
|
+
if (!text) return;
|
|
6565
|
+
if (ws && ws.readyState === 1) {
|
|
6566
|
+
ws.send(JSON.stringify({ type: "debate_comment", text: text }));
|
|
6567
|
+
}
|
|
6568
|
+
toggleDebateHandRaise(false);
|
|
6569
|
+
});
|
|
6570
|
+
|
|
6571
|
+
cancelBtn.addEventListener("click", function () {
|
|
6572
|
+
toggleDebateHandRaise(false);
|
|
6573
|
+
});
|
|
6574
|
+
|
|
6575
|
+
if (textarea) {
|
|
6576
|
+
textarea.addEventListener("keydown", function (e) {
|
|
6577
|
+
if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendBtn.click(); }
|
|
6578
|
+
if (e.key === "Escape") { toggleDebateHandRaise(false); }
|
|
6579
|
+
});
|
|
6397
6580
|
}
|
|
6398
6581
|
}
|
|
6399
6582
|
|
|
6400
6583
|
function sendDebateStickyComment() {
|
|
6584
|
+
// Legacy fallback (kept for compatibility)
|
|
6401
6585
|
var commentInput = document.getElementById("debate-sticky-comment");
|
|
6402
6586
|
if (!commentInput) return;
|
|
6403
6587
|
var text = commentInput.value.trim();
|
|
@@ -6409,7 +6593,7 @@ import { initDebate, handleDebateStarted, handleDebateTurn, handleDebateActivity
|
|
|
6409
6593
|
}
|
|
6410
6594
|
|
|
6411
6595
|
function updateDebateRound(round) {
|
|
6412
|
-
var roundEl = document.getElementById("debate-
|
|
6596
|
+
var roundEl = document.getElementById("debate-header-round");
|
|
6413
6597
|
if (roundEl) roundEl.textContent = "R" + round;
|
|
6414
6598
|
}
|
|
6415
6599
|
|