clay-server 2.17.0 → 2.18.0-beta.10
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/daemon.js +2 -2
- package/lib/mates.js +85 -6
- package/lib/project.js +409 -4
- package/lib/public/app.js +307 -18
- package/lib/public/css/base.css +1 -0
- package/lib/public/css/input.css +5 -0
- package/lib/public/css/mates.css +5 -6
- package/lib/public/css/mention.css +226 -0
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/index.html +1 -0
- package/lib/public/modules/input.js +41 -0
- package/lib/public/modules/mention.js +652 -0
- package/lib/public/modules/notifications.js +9 -3
- package/lib/public/modules/scheduler.js +47 -14
- package/lib/public/style.css +1 -0
- package/lib/sdk-bridge.js +191 -0
- package/lib/sessions.js +13 -0
- package/package.json +1 -1
package/lib/public/app.js
CHANGED
|
@@ -28,6 +28,8 @@ import { initTooltips, registerTooltip } from './modules/tooltip.js';
|
|
|
28
28
|
import { initMateWizard, openMateWizard, closeMateWizard, handleMateCreated } from './modules/mate-wizard.js';
|
|
29
29
|
import { initCommandPalette, handlePaletteSessionSwitch, setPaletteVersion } from './modules/command-palette.js';
|
|
30
30
|
import { initLongPress } from './modules/longpress.js';
|
|
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';
|
|
31
33
|
|
|
32
34
|
// --- Base path for multi-project routing ---
|
|
33
35
|
var slugMatch = location.pathname.match(/^\/p\/([a-z0-9_-]+)/);
|
|
@@ -61,6 +63,7 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
61
63
|
|
|
62
64
|
// --- DM Mode ---
|
|
63
65
|
var dmMode = false;
|
|
66
|
+
var pendingMateDmRestore = false; // suppress regular history while restoring mate DM
|
|
64
67
|
var dmKey = null;
|
|
65
68
|
var dmTargetUser = null;
|
|
66
69
|
var dmUnread = {}; // { otherUserId: count }
|
|
@@ -693,9 +696,9 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
693
696
|
}
|
|
694
697
|
}
|
|
695
698
|
|
|
696
|
-
// Hide user-island
|
|
699
|
+
// Hide user-island in human DM, keep visible in Mate DM
|
|
697
700
|
var userIsland = document.getElementById("user-island");
|
|
698
|
-
if (userIsland) userIsland.classList.add("dm-hidden");
|
|
701
|
+
if (userIsland && !isMate) userIsland.classList.add("dm-hidden");
|
|
699
702
|
|
|
700
703
|
// Render DM messages
|
|
701
704
|
messagesEl.innerHTML = "";
|
|
@@ -740,6 +743,7 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
740
743
|
function exitDmMode() {
|
|
741
744
|
if (!dmMode) return;
|
|
742
745
|
dmMode = false;
|
|
746
|
+
pendingMateDmRestore = false;
|
|
743
747
|
dmKey = null;
|
|
744
748
|
dmTargetUser = null;
|
|
745
749
|
setCurrentDmUser(null);
|
|
@@ -904,6 +908,13 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
904
908
|
var mateSessionDot = document.querySelector(".mate-session-item.active .session-processing");
|
|
905
909
|
if (mateSessionDot) mateSessionDot.style.display = "none";
|
|
906
910
|
}
|
|
911
|
+
// Handle skill_installed in mate DM context (for skill install modal)
|
|
912
|
+
if (msg.type === "skill_installed") {
|
|
913
|
+
handleSkillInstalled(msg);
|
|
914
|
+
if (msg.success) knownInstalledSkills[msg.skill] = true;
|
|
915
|
+
handleSkillInstallWs(msg);
|
|
916
|
+
}
|
|
917
|
+
|
|
907
918
|
// Intercept session_list for mate sidebar
|
|
908
919
|
if (msg.type === "init" && msg.sessions) {
|
|
909
920
|
renderMateSessionList(msg.sessions);
|
|
@@ -2121,18 +2132,9 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
2121
2132
|
if (!activityEl) {
|
|
2122
2133
|
activityEl = document.createElement("div");
|
|
2123
2134
|
activityEl.className = "activity-inline";
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
var mateAvUrl = document.body.dataset.mateAvatarUrl || "";
|
|
2128
|
-
activityEl.innerHTML =
|
|
2129
|
-
'<img class="mate-activity-avatar" src="' + mateAvUrl + '" alt="">' +
|
|
2130
|
-
'<span class="activity-text"></span>';
|
|
2131
|
-
} else {
|
|
2132
|
-
activityEl.innerHTML =
|
|
2133
|
-
'<span class="activity-icon">' + iconHtml("sparkles") + '</span>' +
|
|
2134
|
-
'<span class="activity-text"></span>';
|
|
2135
|
-
}
|
|
2135
|
+
activityEl.innerHTML =
|
|
2136
|
+
'<span class="activity-icon">' + iconHtml("sparkles") + '</span>' +
|
|
2137
|
+
'<span class="activity-text"></span>';
|
|
2136
2138
|
addToMessages(activityEl);
|
|
2137
2139
|
refreshIcons();
|
|
2138
2140
|
}
|
|
@@ -3690,10 +3692,27 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
3690
3692
|
ws.send(JSON.stringify({ type: "mate_list" }));
|
|
3691
3693
|
} catch(e) {}
|
|
3692
3694
|
|
|
3693
|
-
// Restore
|
|
3695
|
+
// Restore the last active session for this project (overrides server global)
|
|
3696
|
+
try {
|
|
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
|
|
3694
3704
|
try {
|
|
3695
3705
|
var savedMateDm = localStorage.getItem("clay_active_mate_dm");
|
|
3696
|
-
if (savedMateDm
|
|
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
|
|
3697
3716
|
openDm(savedMateDm);
|
|
3698
3717
|
}
|
|
3699
3718
|
} catch(e) {}
|
|
@@ -3733,8 +3752,18 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
3733
3752
|
};
|
|
3734
3753
|
|
|
3735
3754
|
ws.onmessage = function (event) {
|
|
3736
|
-
// If this WS is stashed while in mate DM,
|
|
3737
|
-
if (savedMainWs === this)
|
|
3755
|
+
// If this WS is stashed while in mate DM, only allow skill_installed through
|
|
3756
|
+
if (savedMainWs === this) {
|
|
3757
|
+
try {
|
|
3758
|
+
var stashedMsg = JSON.parse(event.data);
|
|
3759
|
+
if (stashedMsg.type === "skill_installed") {
|
|
3760
|
+
handleSkillInstalled(stashedMsg);
|
|
3761
|
+
if (stashedMsg.success) knownInstalledSkills[stashedMsg.skill] = true;
|
|
3762
|
+
handleSkillInstallWs(stashedMsg);
|
|
3763
|
+
}
|
|
3764
|
+
} catch (e) {}
|
|
3765
|
+
return;
|
|
3766
|
+
}
|
|
3738
3767
|
|
|
3739
3768
|
// Backup: if we're receiving messages, we're connected
|
|
3740
3769
|
if (!connected) {
|
|
@@ -3751,6 +3780,15 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
3751
3780
|
}
|
|
3752
3781
|
|
|
3753
3782
|
function processMessage(msg) {
|
|
3783
|
+
// Suppress regular project messages while restoring mate DM
|
|
3784
|
+
if (pendingMateDmRestore) {
|
|
3785
|
+
if (msg.type === "dm_history" || msg.type === "dm_list" || msg.type === "mate_list" || msg.type === "mate_created" || msg.type === "info") {
|
|
3786
|
+
// Let these through
|
|
3787
|
+
} else {
|
|
3788
|
+
return; // skip regular session messages
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3754
3792
|
switch (msg.type) {
|
|
3755
3793
|
case "history_meta":
|
|
3756
3794
|
historyFrom = msg.from;
|
|
@@ -4043,6 +4081,8 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
4043
4081
|
}
|
|
4044
4082
|
activeSessionId = msg.id;
|
|
4045
4083
|
cliSessionId = msg.cliSessionId || null;
|
|
4084
|
+
// Persist active session per project so reconnect restores it
|
|
4085
|
+
try { localStorage.setItem("clay_active_session_" + basePath, String(msg.id)); } catch(e) {}
|
|
4046
4086
|
clearRemoteCursors();
|
|
4047
4087
|
resetClientState();
|
|
4048
4088
|
updateRalphBars();
|
|
@@ -4515,6 +4555,7 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
4515
4555
|
|
|
4516
4556
|
// --- DM ---
|
|
4517
4557
|
case "dm_history":
|
|
4558
|
+
pendingMateDmRestore = false; // DM data arrived, resume normal processing
|
|
4518
4559
|
// Attach projectSlug to targetUser for mate DMs
|
|
4519
4560
|
if (msg.projectSlug && msg.targetUser) {
|
|
4520
4561
|
msg.targetUser.projectSlug = msg.projectSlug;
|
|
@@ -4638,6 +4679,83 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
4638
4679
|
showToast(msg.error || "Mate operation failed", "error");
|
|
4639
4680
|
break;
|
|
4640
4681
|
|
|
4682
|
+
// --- @Mention ---
|
|
4683
|
+
case "mention_start":
|
|
4684
|
+
handleMentionStart(msg);
|
|
4685
|
+
break;
|
|
4686
|
+
|
|
4687
|
+
case "mention_activity":
|
|
4688
|
+
handleMentionActivity(msg);
|
|
4689
|
+
break;
|
|
4690
|
+
|
|
4691
|
+
case "mention_stream":
|
|
4692
|
+
handleMentionStream(msg);
|
|
4693
|
+
break;
|
|
4694
|
+
|
|
4695
|
+
case "mention_done":
|
|
4696
|
+
handleMentionDone(msg);
|
|
4697
|
+
break;
|
|
4698
|
+
|
|
4699
|
+
case "mention_error":
|
|
4700
|
+
handleMentionError(msg);
|
|
4701
|
+
if (msg.error) showToast("@Mention: " + msg.error, "error");
|
|
4702
|
+
break;
|
|
4703
|
+
|
|
4704
|
+
case "mention_user":
|
|
4705
|
+
// History replay: render mention user message from another client
|
|
4706
|
+
renderMentionUser(msg);
|
|
4707
|
+
break;
|
|
4708
|
+
|
|
4709
|
+
case "mention_response":
|
|
4710
|
+
// History replay: render mention response from another client
|
|
4711
|
+
renderMentionResponse(msg);
|
|
4712
|
+
break;
|
|
4713
|
+
|
|
4714
|
+
// --- Debate ---
|
|
4715
|
+
case "debate_preparing":
|
|
4716
|
+
showDebateSticky("preparing", msg);
|
|
4717
|
+
break;
|
|
4718
|
+
|
|
4719
|
+
case "debate_started":
|
|
4720
|
+
showDebateSticky("live", msg);
|
|
4721
|
+
handleDebateStarted(msg);
|
|
4722
|
+
break;
|
|
4723
|
+
|
|
4724
|
+
case "debate_turn":
|
|
4725
|
+
handleDebateTurn(msg);
|
|
4726
|
+
if (msg.round) updateDebateRound(msg.round);
|
|
4727
|
+
break;
|
|
4728
|
+
|
|
4729
|
+
case "debate_activity":
|
|
4730
|
+
handleDebateActivity(msg);
|
|
4731
|
+
break;
|
|
4732
|
+
|
|
4733
|
+
case "debate_stream":
|
|
4734
|
+
handleDebateStream(msg);
|
|
4735
|
+
break;
|
|
4736
|
+
|
|
4737
|
+
case "debate_turn_done":
|
|
4738
|
+
handleDebateTurnDone(msg);
|
|
4739
|
+
break;
|
|
4740
|
+
|
|
4741
|
+
case "debate_comment_queued":
|
|
4742
|
+
handleDebateCommentQueued(msg);
|
|
4743
|
+
break;
|
|
4744
|
+
|
|
4745
|
+
case "debate_comment_injected":
|
|
4746
|
+
handleDebateCommentInjected(msg);
|
|
4747
|
+
break;
|
|
4748
|
+
|
|
4749
|
+
case "debate_ended":
|
|
4750
|
+
showDebateSticky("ended", msg);
|
|
4751
|
+
handleDebateEnded(msg);
|
|
4752
|
+
break;
|
|
4753
|
+
|
|
4754
|
+
case "debate_error":
|
|
4755
|
+
handleDebateError(msg);
|
|
4756
|
+
if (msg.error) showToast("Debate: " + msg.error, "error");
|
|
4757
|
+
break;
|
|
4758
|
+
|
|
4641
4759
|
case "daemon_config":
|
|
4642
4760
|
updateDaemonConfig(msg.config);
|
|
4643
4761
|
break;
|
|
@@ -4958,6 +5076,28 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
4958
5076
|
showMatePreThinking: function () { showMatePreThinking(); },
|
|
4959
5077
|
});
|
|
4960
5078
|
|
|
5079
|
+
// --- @Mention module ---
|
|
5080
|
+
initMention({
|
|
5081
|
+
get ws() { return ws; },
|
|
5082
|
+
get connected() { return connected; },
|
|
5083
|
+
inputEl: inputEl,
|
|
5084
|
+
messagesEl: messagesEl,
|
|
5085
|
+
matesList: function () { return cachedMatesList || []; },
|
|
5086
|
+
scrollToBottom: scrollToBottom,
|
|
5087
|
+
addUserMessage: addUserMessage,
|
|
5088
|
+
addCopyHandler: addCopyHandler,
|
|
5089
|
+
});
|
|
5090
|
+
|
|
5091
|
+
// --- Debate module ---
|
|
5092
|
+
initDebate({
|
|
5093
|
+
get ws() { return ws; },
|
|
5094
|
+
messagesEl: messagesEl,
|
|
5095
|
+
scrollToBottom: scrollToBottom,
|
|
5096
|
+
addCopyHandler: addCopyHandler,
|
|
5097
|
+
matesList: function () { return cachedMatesList || []; },
|
|
5098
|
+
currentMateId: function () { return (dmTargetUser && dmTargetUser.isMate) ? dmTargetUser.id : null; },
|
|
5099
|
+
});
|
|
5100
|
+
|
|
4961
5101
|
// --- STT module (voice input via Web Speech API) ---
|
|
4962
5102
|
initSTT({
|
|
4963
5103
|
inputEl: inputEl,
|
|
@@ -5449,6 +5589,13 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
5449
5589
|
updateLoopBanner(loopIteration, loopMaxIterations, "running");
|
|
5450
5590
|
}
|
|
5451
5591
|
}
|
|
5592
|
+
|
|
5593
|
+
// Restore debate sticky on session switch
|
|
5594
|
+
if (debateStickyState && debateStickyState.phase) {
|
|
5595
|
+
showDebateSticky(debateStickyState.phase, debateStickyState.msg);
|
|
5596
|
+
} else {
|
|
5597
|
+
showDebateSticky("hide", null);
|
|
5598
|
+
}
|
|
5452
5599
|
}
|
|
5453
5600
|
|
|
5454
5601
|
// --- Skill install dialog (generic) ---
|
|
@@ -5677,6 +5824,24 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
5677
5824
|
}, cb);
|
|
5678
5825
|
}
|
|
5679
5826
|
|
|
5827
|
+
function requireClayDebateSetup(cb) {
|
|
5828
|
+
requireSkills({
|
|
5829
|
+
title: "Skill Installation Required",
|
|
5830
|
+
reason: "The Debate Setup skill is required to start a debate.",
|
|
5831
|
+
skills: [{ name: "clay-debate-setup", url: "https://github.com/chadbyte/clay-debate-setup", scope: "global" }]
|
|
5832
|
+
}, cb);
|
|
5833
|
+
}
|
|
5834
|
+
|
|
5835
|
+
// Debate button in mate sidebar
|
|
5836
|
+
var debateBtn = document.getElementById("mate-debate-btn");
|
|
5837
|
+
if (debateBtn) {
|
|
5838
|
+
debateBtn.addEventListener("click", function () {
|
|
5839
|
+
requireClayDebateSetup(function () {
|
|
5840
|
+
openDebateModal();
|
|
5841
|
+
});
|
|
5842
|
+
});
|
|
5843
|
+
}
|
|
5844
|
+
|
|
5680
5845
|
// --- Ralph Wizard ---
|
|
5681
5846
|
|
|
5682
5847
|
var wizardMode = "draft"; // "draft" or "own"
|
|
@@ -6124,6 +6289,130 @@ import { initLongPress } from './modules/longpress.js';
|
|
|
6124
6289
|
}
|
|
6125
6290
|
}
|
|
6126
6291
|
|
|
6292
|
+
// --- Debate Sticky Banner ---
|
|
6293
|
+
var debateStickyState = null;
|
|
6294
|
+
var debateHandRaiseOpen = false;
|
|
6295
|
+
|
|
6296
|
+
function showDebateSticky(phase, msg) {
|
|
6297
|
+
if (phase === "ended" || phase === "hide") {
|
|
6298
|
+
debateStickyState = null;
|
|
6299
|
+
} else {
|
|
6300
|
+
debateStickyState = { phase: phase, msg: msg };
|
|
6301
|
+
}
|
|
6302
|
+
var stickyEl = document.getElementById("debate-sticky");
|
|
6303
|
+
if (!stickyEl) return;
|
|
6304
|
+
|
|
6305
|
+
if (phase === "ended" || phase === "hide") {
|
|
6306
|
+
stickyEl.classList.add("hidden");
|
|
6307
|
+
stickyEl.innerHTML = "";
|
|
6308
|
+
debateHandRaiseOpen = false;
|
|
6309
|
+
return;
|
|
6310
|
+
}
|
|
6311
|
+
|
|
6312
|
+
var topic = (msg && msg.topic) || "Debate";
|
|
6313
|
+
var truncTopic = topic.length > 30 ? topic.slice(0, 30) + "\u2026" : topic;
|
|
6314
|
+
|
|
6315
|
+
if (phase === "preparing") {
|
|
6316
|
+
stickyEl.innerHTML =
|
|
6317
|
+
'<div class="debate-sticky-inner">' +
|
|
6318
|
+
'<div class="debate-sticky-header">' +
|
|
6319
|
+
'<span class="debate-sticky-icon">' + iconHtml("mic") + '</span>' +
|
|
6320
|
+
'<span class="debate-sticky-label">' + escapeHtml(truncTopic) + '</span>' +
|
|
6321
|
+
'<span class="debate-sticky-status" id="debate-sticky-status">Setting up\u2026</span>' +
|
|
6322
|
+
'<button class="debate-sticky-action debate-sticky-cancel" title="Cancel debate">' + iconHtml("x") + '</button>' +
|
|
6323
|
+
'</div>' +
|
|
6324
|
+
'</div>';
|
|
6325
|
+
stickyEl.classList.remove("hidden");
|
|
6326
|
+
stickyEl.className = "debate-sticky preparing";
|
|
6327
|
+
refreshIcons();
|
|
6328
|
+
|
|
6329
|
+
stickyEl.querySelector(".debate-sticky-cancel").addEventListener("click", function (e) {
|
|
6330
|
+
e.stopPropagation();
|
|
6331
|
+
if (ws && ws.readyState === 1) {
|
|
6332
|
+
ws.send(JSON.stringify({ type: "debate_stop" }));
|
|
6333
|
+
}
|
|
6334
|
+
stickyEl.classList.add("hidden");
|
|
6335
|
+
stickyEl.innerHTML = "";
|
|
6336
|
+
});
|
|
6337
|
+
} else if (phase === "live") {
|
|
6338
|
+
stickyEl.innerHTML =
|
|
6339
|
+
'<div class="debate-sticky-inner">' +
|
|
6340
|
+
'<div class="debate-sticky-header">' +
|
|
6341
|
+
'<span class="debate-sticky-icon">' + iconHtml("mic") + '</span>' +
|
|
6342
|
+
'<span class="debate-sticky-label">' + escapeHtml(truncTopic) + '</span>' +
|
|
6343
|
+
'<span class="debate-sticky-status" id="debate-sticky-status">Live</span>' +
|
|
6344
|
+
'<span class="debate-sticky-round" id="debate-sticky-round">R1</span>' +
|
|
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>' +
|
|
6352
|
+
'</div>' +
|
|
6353
|
+
'</div>';
|
|
6354
|
+
stickyEl.classList.remove("hidden");
|
|
6355
|
+
stickyEl.className = "debate-sticky live";
|
|
6356
|
+
refreshIcons();
|
|
6357
|
+
debateHandRaiseOpen = false;
|
|
6358
|
+
|
|
6359
|
+
stickyEl.querySelector(".debate-sticky-hand").addEventListener("click", function (e) {
|
|
6360
|
+
e.stopPropagation();
|
|
6361
|
+
toggleDebateHandRaise();
|
|
6362
|
+
});
|
|
6363
|
+
|
|
6364
|
+
stickyEl.querySelector(".debate-sticky-stop").addEventListener("click", function (e) {
|
|
6365
|
+
e.stopPropagation();
|
|
6366
|
+
if (ws && ws.readyState === 1) {
|
|
6367
|
+
ws.send(JSON.stringify({ type: "debate_stop" }));
|
|
6368
|
+
}
|
|
6369
|
+
});
|
|
6370
|
+
|
|
6371
|
+
var sendBtn = document.getElementById("debate-sticky-send");
|
|
6372
|
+
var cancelBtn = document.getElementById("debate-sticky-send-cancel");
|
|
6373
|
+
var commentInput = document.getElementById("debate-sticky-comment");
|
|
6374
|
+
|
|
6375
|
+
if (sendBtn) sendBtn.addEventListener("click", function () { sendDebateStickyComment(); });
|
|
6376
|
+
if (cancelBtn) cancelBtn.addEventListener("click", function () { toggleDebateHandRaise(false); });
|
|
6377
|
+
if (commentInput) {
|
|
6378
|
+
commentInput.addEventListener("keydown", function (e) {
|
|
6379
|
+
if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendDebateStickyComment(); }
|
|
6380
|
+
if (e.key === "Escape") { toggleDebateHandRaise(false); }
|
|
6381
|
+
});
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
6385
|
+
|
|
6386
|
+
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
|
+
var show = typeof forceState === "boolean" ? forceState : !debateHandRaiseOpen;
|
|
6391
|
+
debateHandRaiseOpen = show;
|
|
6392
|
+
if (show) {
|
|
6393
|
+
inputWrap.classList.remove("hidden");
|
|
6394
|
+
if (commentInput) { commentInput.value = ""; commentInput.focus(); }
|
|
6395
|
+
} else {
|
|
6396
|
+
inputWrap.classList.add("hidden");
|
|
6397
|
+
}
|
|
6398
|
+
}
|
|
6399
|
+
|
|
6400
|
+
function sendDebateStickyComment() {
|
|
6401
|
+
var commentInput = document.getElementById("debate-sticky-comment");
|
|
6402
|
+
if (!commentInput) return;
|
|
6403
|
+
var text = commentInput.value.trim();
|
|
6404
|
+
if (!text) return;
|
|
6405
|
+
if (ws && ws.readyState === 1) {
|
|
6406
|
+
ws.send(JSON.stringify({ type: "debate_comment", text: text }));
|
|
6407
|
+
}
|
|
6408
|
+
toggleDebateHandRaise(false);
|
|
6409
|
+
}
|
|
6410
|
+
|
|
6411
|
+
function updateDebateRound(round) {
|
|
6412
|
+
var roundEl = document.getElementById("debate-sticky-round");
|
|
6413
|
+
if (roundEl) roundEl.textContent = "R" + round;
|
|
6414
|
+
}
|
|
6415
|
+
|
|
6127
6416
|
// --- Ralph Preview Modal ---
|
|
6128
6417
|
function openRalphPreviewModal() {
|
|
6129
6418
|
var modal = document.getElementById("ralph-preview-modal");
|
package/lib/public/css/base.css
CHANGED
package/lib/public/css/input.css
CHANGED
|
@@ -629,6 +629,11 @@
|
|
|
629
629
|
#input-area {
|
|
630
630
|
padding-bottom: calc(var(--safe-bottom) + 56px + 8px);
|
|
631
631
|
}
|
|
632
|
+
|
|
633
|
+
/* When keyboard is open, tab bar is hidden behind keyboard — remove the offset */
|
|
634
|
+
body.keyboard-open #input-area {
|
|
635
|
+
padding-bottom: 8px;
|
|
636
|
+
}
|
|
632
637
|
}
|
|
633
638
|
|
|
634
639
|
/* ==========================================================================
|
package/lib/public/css/mates.css
CHANGED
|
@@ -1958,10 +1958,7 @@ body.mate-dm-active .mate-permission.resolved .permission-decision-label {
|
|
|
1958
1958
|
color: var(--text-dimmer);
|
|
1959
1959
|
}
|
|
1960
1960
|
|
|
1961
|
-
/* --- Mate Activity: avatar + text
|
|
1962
|
-
body.mate-dm-active .activity-inline {
|
|
1963
|
-
display: none;
|
|
1964
|
-
}
|
|
1961
|
+
/* --- Mate Activity: avatar + text --- */
|
|
1965
1962
|
|
|
1966
1963
|
/* --- Mate AskUserQuestion: avatar + content layout (matches msg-assistant) --- */
|
|
1967
1964
|
body.mate-dm-active .mate-ask-user {
|
|
@@ -2005,8 +2002,10 @@ body.mate-dm-active .ask-user-container:not(.mate-ask-user),
|
|
|
2005
2002
|
body.mate-dm-active .subagent-log,
|
|
2006
2003
|
body.mate-dm-active .conflict-msg,
|
|
2007
2004
|
body.mate-dm-active .context-overflow-msg,
|
|
2008
|
-
body.mate-dm-active .sys-msg
|
|
2009
|
-
|
|
2005
|
+
body.mate-dm-active .sys-msg {
|
|
2006
|
+
display: none;
|
|
2007
|
+
}
|
|
2008
|
+
body.mate-dm-active .activity-inline:not(.mention-activity-bar) {
|
|
2010
2009
|
padding-left: 60px;
|
|
2011
2010
|
margin-left: 0;
|
|
2012
2011
|
margin-right: 0;
|