clay-server 2.26.0-beta.9 → 2.26.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/browser-mcp-server.js +4 -4
- package/lib/debate-mcp-server.js +94 -0
- package/lib/mates.js +12 -24
- package/lib/project-debate.js +304 -166
- package/lib/project-mate-interaction.js +10 -5
- package/lib/project.js +108 -39
- package/lib/public/app.js +317 -85
- package/lib/public/css/debate.css +230 -2
- package/lib/public/css/filebrowser.css +41 -4
- package/lib/public/css/icon-strip.css +10 -10
- package/lib/public/css/input.css +33 -0
- package/lib/public/css/mates.css +17 -38
- package/lib/public/css/messages.css +17 -0
- package/lib/public/css/mobile-nav.css +3 -1
- package/lib/public/css/rewind.css +17 -4
- package/lib/public/index.html +23 -15
- package/lib/public/modules/context-sources.js +21 -6
- package/lib/public/modules/debate.js +298 -97
- package/lib/public/modules/input.js +15 -0
- package/lib/public/modules/mate-knowledge.js +11 -11
- package/lib/public/modules/mate-memory.js +5 -5
- package/lib/public/modules/mate-sidebar.js +13 -9
- package/lib/public/modules/sidebar.js +105 -26
- package/lib/public/modules/terminal.js +62 -6
- package/lib/public/modules/tools.js +2 -2
- package/lib/sdk-bridge.js +123 -22
- package/lib/sessions.js +2 -2
- package/package.json +1 -1
|
@@ -223,12 +223,27 @@ function renderPicker() {
|
|
|
223
223
|
var tabSection = document.getElementById("context-picker-tabs");
|
|
224
224
|
tabSection.innerHTML = "";
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
226
|
+
var tabLabel = document.createElement("div");
|
|
227
|
+
tabLabel.className = "context-picker-section-label";
|
|
228
|
+
tabLabel.textContent = "Browser Tabs";
|
|
229
|
+
tabSection.appendChild(tabLabel);
|
|
230
|
+
|
|
231
|
+
if (browserTabList.length === 0) {
|
|
232
|
+
// Extension not connected: show notice with setup button
|
|
233
|
+
var notice = document.createElement("div");
|
|
234
|
+
notice.className = "context-picker-ext-notice";
|
|
235
|
+
notice.innerHTML =
|
|
236
|
+
'<span class="context-picker-ext-notice-text">Chrome extension required to access browser tabs.</span>' +
|
|
237
|
+
'<button class="context-picker-ext-btn" type="button"><i data-lucide="puzzle"></i> Setup Extension</button>';
|
|
238
|
+
var setupBtn = notice.querySelector(".context-picker-ext-btn");
|
|
239
|
+
setupBtn.addEventListener("click", function (e) {
|
|
240
|
+
e.stopPropagation();
|
|
241
|
+
closePicker();
|
|
242
|
+
var extPill = document.getElementById("ext-pill");
|
|
243
|
+
if (extPill) extPill.click();
|
|
244
|
+
});
|
|
245
|
+
tabSection.appendChild(notice);
|
|
246
|
+
} else {
|
|
232
247
|
for (var j = 0; j < browserTabList.length; j++) {
|
|
233
248
|
var tab = browserTabList[j];
|
|
234
249
|
var tabSourceId = "tab:" + tab.id;
|
|
@@ -360,8 +360,9 @@ export function handleDebateEnded(msg) {
|
|
|
360
360
|
currentTurnEl = null;
|
|
361
361
|
currentTurnMateId = null;
|
|
362
362
|
|
|
363
|
-
// Hide float info panel
|
|
363
|
+
// Hide float info panel and PDF button
|
|
364
364
|
hideDebateInfoFloat();
|
|
365
|
+
showPdfBtn(false);
|
|
365
366
|
|
|
366
367
|
// Ensure debate bottom bar is removed
|
|
367
368
|
var bottomBar = document.getElementById("debate-bottom-bar");
|
|
@@ -369,10 +370,23 @@ export function handleDebateEnded(msg) {
|
|
|
369
370
|
var handBar = document.getElementById("debate-hand-raise-bar");
|
|
370
371
|
if (handBar) handBar.remove();
|
|
371
372
|
|
|
373
|
+
// Render status line in messages area
|
|
372
374
|
if (ctx.messagesEl) {
|
|
373
|
-
|
|
375
|
+
var existing = ctx.messagesEl.querySelector(".debate-ended-status-line");
|
|
376
|
+
if (existing) existing.remove();
|
|
377
|
+
var statusLine = document.createElement("div");
|
|
378
|
+
statusLine.className = "debate-ended-status-line";
|
|
379
|
+
var reasonText = msg.reason === "natural" ? "Debate concluded" :
|
|
380
|
+
msg.reason === "user_stopped" ? "Debate stopped by user" :
|
|
381
|
+
"Debate ended due to error";
|
|
382
|
+
statusLine.innerHTML = iconHtml("check-circle") + " " + escapeHtml(reasonText) + " (" + (msg.rounds || 0) + " rounds)";
|
|
383
|
+
ctx.messagesEl.appendChild(statusLine);
|
|
384
|
+
refreshIcons();
|
|
374
385
|
}
|
|
375
386
|
|
|
387
|
+
// Show ended mode: native input area with banner
|
|
388
|
+
if (ctx.showDebateEndedMode) ctx.showDebateEndedMode(msg);
|
|
389
|
+
|
|
376
390
|
if (ctx.scrollToBottom) ctx.scrollToBottom();
|
|
377
391
|
}
|
|
378
392
|
|
|
@@ -445,7 +459,7 @@ function renderEndedBanner(entry) {
|
|
|
445
459
|
refreshIcons();
|
|
446
460
|
}
|
|
447
461
|
|
|
448
|
-
function exportDebateAsPdf() {
|
|
462
|
+
export function exportDebateAsPdf() {
|
|
449
463
|
var popup = window.open("", "_blank", "width=900,height=700");
|
|
450
464
|
if (!popup) {
|
|
451
465
|
return Promise.resolve();
|
|
@@ -656,6 +670,7 @@ export function renderDebateEnded(entry) {
|
|
|
656
670
|
debateActive = false;
|
|
657
671
|
debatePhase = "ended";
|
|
658
672
|
hideDebateInfoFloat();
|
|
673
|
+
showPdfBtn(false);
|
|
659
674
|
|
|
660
675
|
// Ensure debate bars are removed during history replay
|
|
661
676
|
var bottomBar = document.getElementById("debate-bottom-bar");
|
|
@@ -663,7 +678,20 @@ export function renderDebateEnded(entry) {
|
|
|
663
678
|
var handBar = document.getElementById("debate-hand-raise-bar");
|
|
664
679
|
if (handBar) handBar.remove();
|
|
665
680
|
|
|
666
|
-
|
|
681
|
+
// Render status line
|
|
682
|
+
var existing = ctx.messagesEl.querySelector(".debate-ended-status-line");
|
|
683
|
+
if (existing) existing.remove();
|
|
684
|
+
var statusLine = document.createElement("div");
|
|
685
|
+
statusLine.className = "debate-ended-status-line";
|
|
686
|
+
var reasonText = entry.reason === "natural" ? "Debate concluded" :
|
|
687
|
+
entry.reason === "user_stopped" ? "Debate stopped by user" :
|
|
688
|
+
"Debate ended due to error";
|
|
689
|
+
statusLine.innerHTML = iconHtml("check-circle") + " " + escapeHtml(reasonText) + " (" + (entry.rounds || 0) + " rounds)";
|
|
690
|
+
ctx.messagesEl.appendChild(statusLine);
|
|
691
|
+
refreshIcons();
|
|
692
|
+
|
|
693
|
+
// During history replay, don't activate ended mode banner.
|
|
694
|
+
// The debate is already over; status line in messages is sufficient.
|
|
667
695
|
}
|
|
668
696
|
|
|
669
697
|
export function renderDebateCommentInjected(entry) {
|
|
@@ -690,9 +718,73 @@ export function isDebateActive() {
|
|
|
690
718
|
return debateActive;
|
|
691
719
|
}
|
|
692
720
|
|
|
693
|
-
// --- Debate modal ---
|
|
721
|
+
// --- Debate modal (wizard) ---
|
|
694
722
|
var modalEl = null;
|
|
695
723
|
var selectedPanelists = [];
|
|
724
|
+
var wizardStep = 0;
|
|
725
|
+
|
|
726
|
+
function goToStep(step) {
|
|
727
|
+
wizardStep = step;
|
|
728
|
+
if (!modalEl) return;
|
|
729
|
+
var pages = modalEl.querySelectorAll(".debate-wizard-page");
|
|
730
|
+
var dots = modalEl.querySelectorAll(".debate-step-dot");
|
|
731
|
+
for (var i = 0; i < pages.length; i++) {
|
|
732
|
+
if (i === step) {
|
|
733
|
+
pages[i].classList.add("active");
|
|
734
|
+
if (dots[i]) dots[i].classList.add("active");
|
|
735
|
+
} else {
|
|
736
|
+
pages[i].classList.remove("active");
|
|
737
|
+
if (dots[i]) dots[i].classList.remove("active");
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
var backBtn = document.getElementById("debate-modal-back");
|
|
741
|
+
var nextBtn = document.getElementById("debate-modal-next");
|
|
742
|
+
var quickBtn = document.getElementById("debate-modal-quick");
|
|
743
|
+
var startBtn = document.getElementById("debate-modal-start");
|
|
744
|
+
var cancelBtn = document.getElementById("debate-modal-cancel");
|
|
745
|
+
if (step === 0) {
|
|
746
|
+
// Cancel + (Quick / Setup Panel) - buttons hidden until topic entered
|
|
747
|
+
if (backBtn) backBtn.classList.add("hidden");
|
|
748
|
+
if (cancelBtn) cancelBtn.classList.remove("hidden");
|
|
749
|
+
if (quickBtn) quickBtn.classList.add("hidden");
|
|
750
|
+
if (nextBtn) nextBtn.classList.add("hidden");
|
|
751
|
+
if (startBtn) startBtn.classList.add("hidden");
|
|
752
|
+
} else {
|
|
753
|
+
// Back + (Quick / Setup Detail)
|
|
754
|
+
if (backBtn) backBtn.classList.remove("hidden");
|
|
755
|
+
if (cancelBtn) cancelBtn.classList.add("hidden");
|
|
756
|
+
if (quickBtn) quickBtn.classList.add("hidden");
|
|
757
|
+
if (nextBtn) nextBtn.classList.add("hidden");
|
|
758
|
+
if (startBtn) startBtn.classList.add("hidden");
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function updateStepButtons() {
|
|
763
|
+
var topicInput = document.getElementById("debate-topic-input");
|
|
764
|
+
var topic = topicInput ? topicInput.value.trim() : "";
|
|
765
|
+
var quickBtn = document.getElementById("debate-modal-quick");
|
|
766
|
+
var nextBtn = document.getElementById("debate-modal-next");
|
|
767
|
+
var startBtn = document.getElementById("debate-modal-start");
|
|
768
|
+
if (wizardStep === 0) {
|
|
769
|
+
// Show buttons only when topic is filled
|
|
770
|
+
if (topic) {
|
|
771
|
+
if (quickBtn) quickBtn.classList.remove("hidden");
|
|
772
|
+
if (nextBtn) nextBtn.classList.remove("hidden");
|
|
773
|
+
} else {
|
|
774
|
+
if (quickBtn) quickBtn.classList.add("hidden");
|
|
775
|
+
if (nextBtn) nextBtn.classList.add("hidden");
|
|
776
|
+
}
|
|
777
|
+
} else if (wizardStep === 1) {
|
|
778
|
+
// Show buttons only when at least 1 panelist selected
|
|
779
|
+
if (selectedPanelists.length > 0) {
|
|
780
|
+
if (quickBtn) quickBtn.classList.remove("hidden");
|
|
781
|
+
if (startBtn) startBtn.classList.remove("hidden");
|
|
782
|
+
} else {
|
|
783
|
+
if (quickBtn) quickBtn.classList.add("hidden");
|
|
784
|
+
if (startBtn) startBtn.classList.add("hidden");
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
696
788
|
|
|
697
789
|
export function openDebateModal(opts) {
|
|
698
790
|
opts = opts || {};
|
|
@@ -700,36 +792,13 @@ export function openDebateModal(opts) {
|
|
|
700
792
|
if (!modalEl) return;
|
|
701
793
|
|
|
702
794
|
modalEl.classList.remove("hidden");
|
|
795
|
+
goToStep(0);
|
|
703
796
|
|
|
704
797
|
var topicInput = document.getElementById("debate-topic-input");
|
|
705
798
|
if (topicInput) {
|
|
706
799
|
topicInput.value = "";
|
|
707
800
|
topicInput.focus();
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
// Show/hide skip-setup toggle (only when dmContext is available)
|
|
711
|
-
var skipSetupRow = document.getElementById("debate-skip-setup-row");
|
|
712
|
-
var skipSetupToggle = document.getElementById("debate-skip-setup-toggle");
|
|
713
|
-
if (skipSetupRow) {
|
|
714
|
-
if (opts.dmContext) {
|
|
715
|
-
skipSetupRow.classList.remove("hidden");
|
|
716
|
-
} else {
|
|
717
|
-
skipSetupRow.classList.add("hidden");
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
if (skipSetupToggle) {
|
|
721
|
-
skipSetupToggle.checked = false;
|
|
722
|
-
skipSetupToggle.onchange = function () {
|
|
723
|
-
var topicLabel = modalEl.querySelector('.debate-field-label[for="debate-topic-input"]');
|
|
724
|
-
var reqSpan = topicLabel ? topicLabel.querySelector(".debate-field-req") : null;
|
|
725
|
-
if (skipSetupToggle.checked) {
|
|
726
|
-
if (topicInput) topicInput.placeholder = "Leave blank to auto-detect from conversation...";
|
|
727
|
-
if (reqSpan) reqSpan.style.display = "none";
|
|
728
|
-
} else {
|
|
729
|
-
if (topicInput) topicInput.placeholder = "e.g. Should AI development be regulated?";
|
|
730
|
-
if (reqSpan) reqSpan.style.display = "";
|
|
731
|
-
}
|
|
732
|
-
};
|
|
801
|
+
topicInput.oninput = function () { updateStepButtons(); };
|
|
733
802
|
}
|
|
734
803
|
|
|
735
804
|
// Build DM context string for quick start
|
|
@@ -763,87 +832,103 @@ export function openDebateModal(opts) {
|
|
|
763
832
|
}
|
|
764
833
|
}
|
|
765
834
|
|
|
766
|
-
// Close
|
|
835
|
+
// Close / Cancel / Backdrop
|
|
767
836
|
var closeBtn = document.getElementById("debate-modal-close");
|
|
768
|
-
if (closeBtn)
|
|
769
|
-
closeBtn.onclick = closeDebateModal;
|
|
770
|
-
}
|
|
837
|
+
if (closeBtn) closeBtn.onclick = closeDebateModal;
|
|
771
838
|
var cancelBtn = document.getElementById("debate-modal-cancel");
|
|
772
|
-
if (cancelBtn)
|
|
773
|
-
cancelBtn.onclick = closeDebateModal;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// Backdrop click to close
|
|
839
|
+
if (cancelBtn) cancelBtn.onclick = closeDebateModal;
|
|
777
840
|
var backdrop = modalEl.querySelector(".debate-modal-backdrop");
|
|
778
|
-
if (backdrop)
|
|
779
|
-
|
|
841
|
+
if (backdrop) backdrop.onclick = closeDebateModal;
|
|
842
|
+
|
|
843
|
+
// Back button
|
|
844
|
+
var backBtn = document.getElementById("debate-modal-back");
|
|
845
|
+
if (backBtn) {
|
|
846
|
+
backBtn.onclick = function () {
|
|
847
|
+
if (wizardStep > 0) goToStep(wizardStep - 1);
|
|
848
|
+
updateStepButtons();
|
|
849
|
+
};
|
|
780
850
|
}
|
|
781
851
|
|
|
782
|
-
//
|
|
783
|
-
var
|
|
784
|
-
if (
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
topicInput.focus();
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
if (selectedPanelists.length === 0) return;
|
|
852
|
+
// Choose Panel (step 0 -> 1)
|
|
853
|
+
var nextBtn = document.getElementById("debate-modal-next");
|
|
854
|
+
if (nextBtn) {
|
|
855
|
+
nextBtn.onclick = function () {
|
|
856
|
+
goToStep(1);
|
|
857
|
+
updateStepButtons();
|
|
858
|
+
};
|
|
859
|
+
}
|
|
794
860
|
|
|
795
|
-
|
|
796
|
-
|
|
861
|
+
// Helper: build payload and send
|
|
862
|
+
function fireDebate(quick) {
|
|
863
|
+
var topic = topicInput ? topicInput.value.trim() : "";
|
|
864
|
+
var currentMateId = ctx.currentMateId ? ctx.currentMateId() : null;
|
|
865
|
+
if (!currentMateId || !topic) return;
|
|
797
866
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}),
|
|
805
|
-
};
|
|
867
|
+
var debatePayload = {
|
|
868
|
+
type: "debate_start",
|
|
869
|
+
moderatorId: currentMateId,
|
|
870
|
+
topic: topic,
|
|
871
|
+
quickStart: !!quick,
|
|
872
|
+
};
|
|
806
873
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
874
|
+
if (quick && wizardStep === 0) {
|
|
875
|
+
// Step 0 quick: delegate panelist selection to moderator
|
|
876
|
+
debatePayload.panelists = [];
|
|
877
|
+
debatePayload.delegatePanelists = true;
|
|
878
|
+
debatePayload.dmContext = dmContextStr;
|
|
879
|
+
} else {
|
|
880
|
+
// Step 1: user picked panelists
|
|
881
|
+
if (selectedPanelists.length === 0) return;
|
|
882
|
+
debatePayload.panelists = selectedPanelists.map(function (id) {
|
|
883
|
+
return { mateId: id, role: "", brief: "" };
|
|
884
|
+
});
|
|
885
|
+
if (quick) {
|
|
810
886
|
debatePayload.dmContext = dmContextStr;
|
|
811
887
|
}
|
|
888
|
+
}
|
|
812
889
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
ctx.ws.send(JSON.stringify({ type: "new_session" }));
|
|
827
|
-
}
|
|
828
|
-
closeDebateModal();
|
|
890
|
+
function sendDebate() {
|
|
891
|
+
if (ctx.ws) {
|
|
892
|
+
var onMessage = function (evt) {
|
|
893
|
+
try {
|
|
894
|
+
var data = JSON.parse(evt.data);
|
|
895
|
+
if (data.type === "session_switched") {
|
|
896
|
+
ctx.ws.removeEventListener("message", onMessage);
|
|
897
|
+
ctx.ws.send(JSON.stringify(debatePayload));
|
|
898
|
+
}
|
|
899
|
+
} catch (e) {}
|
|
900
|
+
};
|
|
901
|
+
ctx.ws.addEventListener("message", onMessage);
|
|
902
|
+
ctx.ws.send(JSON.stringify({ type: "new_session" }));
|
|
829
903
|
}
|
|
904
|
+
closeDebateModal();
|
|
905
|
+
}
|
|
830
906
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
907
|
+
if (quick) {
|
|
908
|
+
sendDebate();
|
|
909
|
+
} else {
|
|
910
|
+
if (ctx.requireSkills) {
|
|
911
|
+
ctx.requireSkills({
|
|
912
|
+
title: "Skill Installation Required",
|
|
913
|
+
reason: "The Debate Setup skill is required to design this debate.",
|
|
914
|
+
skills: [{ name: "clay-debate-setup", url: "https://github.com/chadbyte/clay-debate-setup", scope: "global" }]
|
|
915
|
+
}, sendDebate);
|
|
834
916
|
} else {
|
|
835
|
-
|
|
836
|
-
if (ctx.requireSkills) {
|
|
837
|
-
ctx.requireSkills({
|
|
838
|
-
title: "Skill Installation Required",
|
|
839
|
-
reason: "The Debate Setup skill is required to start a debate.",
|
|
840
|
-
skills: [{ name: "clay-debate-setup", url: "https://github.com/chadbyte/clay-debate-setup", scope: "global" }]
|
|
841
|
-
}, sendDebate);
|
|
842
|
-
} else {
|
|
843
|
-
sendDebate();
|
|
844
|
-
}
|
|
917
|
+
sendDebate();
|
|
845
918
|
}
|
|
846
|
-
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// Quick Start button (both steps)
|
|
923
|
+
var quickBtn = document.getElementById("debate-modal-quick");
|
|
924
|
+
if (quickBtn) {
|
|
925
|
+
quickBtn.onclick = function () { fireDebate(true); };
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// Design Debate button (step 1, full setup with skill)
|
|
929
|
+
var startBtn = document.getElementById("debate-modal-start");
|
|
930
|
+
if (startBtn) {
|
|
931
|
+
startBtn.onclick = function () { fireDebate(false); };
|
|
847
932
|
}
|
|
848
933
|
|
|
849
934
|
refreshIcons();
|
|
@@ -895,10 +980,11 @@ function createPanelItem(mate) {
|
|
|
895
980
|
item.classList.remove("selected");
|
|
896
981
|
cb.checked = false;
|
|
897
982
|
}
|
|
983
|
+
updateStepButtons();
|
|
898
984
|
}
|
|
899
985
|
|
|
900
986
|
item.addEventListener("click", function (e) {
|
|
901
|
-
if (e.target === cb) return;
|
|
987
|
+
if (e.target === cb) return;
|
|
902
988
|
toggle();
|
|
903
989
|
});
|
|
904
990
|
cb.addEventListener("change", function () {
|
|
@@ -910,6 +996,7 @@ function createPanelItem(mate) {
|
|
|
910
996
|
selectedPanelists.splice(idx, 1);
|
|
911
997
|
item.classList.remove("selected");
|
|
912
998
|
}
|
|
999
|
+
updateStepButtons();
|
|
913
1000
|
});
|
|
914
1001
|
|
|
915
1002
|
return item;
|
|
@@ -1214,3 +1301,117 @@ function renderDebateBriefCard(msg, resolved) {
|
|
|
1214
1301
|
refreshIcons();
|
|
1215
1302
|
ctx.scrollToBottom();
|
|
1216
1303
|
}
|
|
1304
|
+
|
|
1305
|
+
// --- MCP-based debate proposal card ---
|
|
1306
|
+
// Renders an inline card from the propose_debate MCP tool input.
|
|
1307
|
+
// The card reuses the same visual structure as renderDebateBriefCard
|
|
1308
|
+
// but sends debate_proposal_response instead of debate_confirm_brief.
|
|
1309
|
+
|
|
1310
|
+
export function renderMcpDebateProposal(toolId, input) {
|
|
1311
|
+
var panelists = [];
|
|
1312
|
+
try {
|
|
1313
|
+
panelists = typeof input.panelists === "string" ? JSON.parse(input.panelists) : (input.panelists || []);
|
|
1314
|
+
} catch (e) {
|
|
1315
|
+
panelists = [];
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
var el = document.createElement("div");
|
|
1319
|
+
el.className = "debate-brief-card";
|
|
1320
|
+
|
|
1321
|
+
// Header
|
|
1322
|
+
var header = document.createElement("div");
|
|
1323
|
+
header.className = "debate-brief-card-header";
|
|
1324
|
+
header.innerHTML =
|
|
1325
|
+
'<span class="debate-brief-card-icon">' + iconHtml("message-circle") + '</span>' +
|
|
1326
|
+
'<span class="debate-brief-card-title">Debate Proposal</span>' +
|
|
1327
|
+
'<span class="debate-brief-card-chevron">' + iconHtml("chevron-down") + '</span>';
|
|
1328
|
+
|
|
1329
|
+
// Body
|
|
1330
|
+
var body = document.createElement("div");
|
|
1331
|
+
body.className = "debate-brief-card-body";
|
|
1332
|
+
|
|
1333
|
+
var topicHtml = '<div class="debate-brief-topic">' + escapeHtml(input.topic || "Untitled") + '</div>';
|
|
1334
|
+
|
|
1335
|
+
if (input.context) {
|
|
1336
|
+
topicHtml += '<div class="debate-brief-context">' + escapeHtml(input.context) + '</div>';
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// Resolve mate names from matesList
|
|
1340
|
+
var mates = ctx.matesList ? ctx.matesList() : [];
|
|
1341
|
+
var mateMap = {};
|
|
1342
|
+
for (var mi = 0; mi < mates.length; mi++) {
|
|
1343
|
+
mateMap[mates[mi].id] = mates[mi];
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
topicHtml += '<div class="debate-brief-panelists-label">' + iconHtml("users") + ' <strong>Panelists:</strong></div>';
|
|
1347
|
+
topicHtml += '<div class="debate-brief-panelists">';
|
|
1348
|
+
for (var i = 0; i < panelists.length; i++) {
|
|
1349
|
+
var p = panelists[i];
|
|
1350
|
+
var mate = mateMap[p.mateId];
|
|
1351
|
+
var mateName = mate ? (mate.displayName || mate.name || p.mateId) : p.mateId;
|
|
1352
|
+
var avatarSrc = mate ? mateAvatarUrl(mate, 24) : "";
|
|
1353
|
+
topicHtml += '<div class="debate-brief-panelist" style="display:flex;align-items:center;gap:8px;">';
|
|
1354
|
+
if (avatarSrc) {
|
|
1355
|
+
topicHtml += '<img src="' + escapeHtml(avatarSrc) + '" width="24" height="24" style="border-radius:50%;flex-shrink:0;">';
|
|
1356
|
+
}
|
|
1357
|
+
topicHtml += '<span class="debate-brief-panelist-name">' + escapeHtml(mateName) + '</span>';
|
|
1358
|
+
if (p.role) {
|
|
1359
|
+
topicHtml += '<span class="debate-brief-panelist-role">' + escapeHtml(p.role) + '</span>';
|
|
1360
|
+
}
|
|
1361
|
+
topicHtml += '</div>';
|
|
1362
|
+
}
|
|
1363
|
+
topicHtml += '</div>';
|
|
1364
|
+
|
|
1365
|
+
if (input.specialRequests) {
|
|
1366
|
+
topicHtml += '<div class="debate-brief-special">' +
|
|
1367
|
+
iconHtml("info") + ' ' + escapeHtml(input.specialRequests) +
|
|
1368
|
+
'</div>';
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
body.innerHTML = topicHtml;
|
|
1372
|
+
|
|
1373
|
+
// Actions
|
|
1374
|
+
var actions = document.createElement("div");
|
|
1375
|
+
actions.className = "debate-brief-actions";
|
|
1376
|
+
|
|
1377
|
+
var startBtn = document.createElement("button");
|
|
1378
|
+
startBtn.className = "debate-brief-start-btn";
|
|
1379
|
+
startBtn.innerHTML = iconHtml("play") + " Start Debate";
|
|
1380
|
+
|
|
1381
|
+
var cancelBtn = document.createElement("button");
|
|
1382
|
+
cancelBtn.className = "debate-brief-cancel-btn";
|
|
1383
|
+
cancelBtn.textContent = "Cancel";
|
|
1384
|
+
|
|
1385
|
+
startBtn.addEventListener("click", function () {
|
|
1386
|
+
if (ctx.sendWs) {
|
|
1387
|
+
ctx.sendWs({ type: "debate_proposal_response", proposalId: input.proposalId, action: "start" });
|
|
1388
|
+
}
|
|
1389
|
+
el.classList.add("resolved");
|
|
1390
|
+
actions.innerHTML = '<span class="debate-brief-resolved-label">' + iconHtml("check") + ' Starting debate...</span>';
|
|
1391
|
+
refreshIcons();
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
cancelBtn.addEventListener("click", function () {
|
|
1395
|
+
if (ctx.sendWs) {
|
|
1396
|
+
ctx.sendWs({ type: "debate_proposal_response", proposalId: input.proposalId, action: "cancel" });
|
|
1397
|
+
}
|
|
1398
|
+
el.classList.add("resolved");
|
|
1399
|
+
actions.innerHTML = '<span class="debate-brief-resolved-label debate-brief-cancelled">' + iconHtml("x") + ' Cancelled</span>';
|
|
1400
|
+
refreshIcons();
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
actions.appendChild(startBtn);
|
|
1404
|
+
actions.appendChild(cancelBtn);
|
|
1405
|
+
|
|
1406
|
+
// Collapse toggle
|
|
1407
|
+
header.addEventListener("click", function () {
|
|
1408
|
+
el.classList.toggle("collapsed");
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1411
|
+
el.appendChild(header);
|
|
1412
|
+
el.appendChild(body);
|
|
1413
|
+
el.appendChild(actions);
|
|
1414
|
+
ctx.addToMessages(el);
|
|
1415
|
+
refreshIcons();
|
|
1416
|
+
ctx.scrollToBottom();
|
|
1417
|
+
}
|
|
@@ -71,6 +71,21 @@ export var builtinCommands = [
|
|
|
71
71
|
|
|
72
72
|
// --- Send ---
|
|
73
73
|
export function sendMessage() {
|
|
74
|
+
// Debate ended mode intercept: route to resume handler
|
|
75
|
+
if (ctx.isDebateEndedMode && ctx.isDebateEndedMode() && ctx.handleDebateEndedSend) {
|
|
76
|
+
ctx.handleDebateEndedSend();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Debate conclude mode intercept: route to conclude handler
|
|
80
|
+
if (ctx.isDebateConcludeMode && ctx.isDebateConcludeMode() && ctx.handleDebateConcludeSend) {
|
|
81
|
+
ctx.handleDebateConcludeSend();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Debate floor mode intercept: route to floor response handler
|
|
85
|
+
if (ctx.isDebateFloorMode && ctx.isDebateFloorMode() && ctx.handleDebateFloorSend) {
|
|
86
|
+
ctx.handleDebateFloorSend();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
74
89
|
// DM mode intercept: if in DM mode, route to DM handler instead
|
|
75
90
|
if (ctx.isDmMode && ctx.isDmMode() && ctx.handleDmSend) {
|
|
76
91
|
ctx.handleDmSend();
|
|
@@ -3,7 +3,7 @@ import { hideNotes } from './sticky-notes.js';
|
|
|
3
3
|
import { hideMemory } from './mate-memory.js';
|
|
4
4
|
import { renderMarkdown, highlightCodeBlocks } from './markdown.js';
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var getWs = null;
|
|
7
7
|
var filesEl = null;
|
|
8
8
|
var sidebarBtn = null;
|
|
9
9
|
var countBadge = null;
|
|
@@ -46,8 +46,8 @@ var dirty = false;
|
|
|
46
46
|
var mode = "none"; // "none" | "viewer" | "editor"
|
|
47
47
|
var pendingEditMode = false;
|
|
48
48
|
|
|
49
|
-
export function initMateKnowledge(
|
|
50
|
-
|
|
49
|
+
export function initMateKnowledge(wsGetter) {
|
|
50
|
+
getWs = wsGetter;
|
|
51
51
|
filesEl = document.getElementById("mate-knowledge-files");
|
|
52
52
|
sidebarBtn = document.getElementById("mate-knowledge-btn");
|
|
53
53
|
countBadge = document.getElementById("mate-knowledge-count");
|
|
@@ -123,7 +123,7 @@ export function initMateKnowledge(mateWsGetter) {
|
|
|
123
123
|
if (editorDeleteBtn) {
|
|
124
124
|
editorDeleteBtn.addEventListener("click", function () {
|
|
125
125
|
if (editingFile) {
|
|
126
|
-
var ws =
|
|
126
|
+
var ws = getWs ? getWs() : null;
|
|
127
127
|
if (ws && ws.readyState === 1) {
|
|
128
128
|
ws.send(JSON.stringify({ type: "knowledge_delete", name: editingFile }));
|
|
129
129
|
}
|
|
@@ -317,7 +317,7 @@ export function isKnowledgeVisible() {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
export function requestKnowledgeList() {
|
|
320
|
-
var ws =
|
|
320
|
+
var ws = getWs ? getWs() : null;
|
|
321
321
|
if (ws && ws.readyState === 1) {
|
|
322
322
|
ws.send(JSON.stringify({ type: "knowledge_list" }));
|
|
323
323
|
}
|
|
@@ -457,7 +457,7 @@ function renderFileItem(file) {
|
|
|
457
457
|
|
|
458
458
|
item.addEventListener("click", (function (f) {
|
|
459
459
|
return function () {
|
|
460
|
-
var ws =
|
|
460
|
+
var ws = getWs ? getWs() : null;
|
|
461
461
|
if (ws && ws.readyState === 1) {
|
|
462
462
|
var msg = { type: "knowledge_read", name: f.name };
|
|
463
463
|
if (f.common) {
|
|
@@ -554,7 +554,7 @@ function saveKnowledge() {
|
|
|
554
554
|
setTimeout(function () { editorNameEl.style.outline = ""; }, 1500);
|
|
555
555
|
return;
|
|
556
556
|
}
|
|
557
|
-
var ws =
|
|
557
|
+
var ws = getWs ? getWs() : null;
|
|
558
558
|
if (ws && ws.readyState === 1) {
|
|
559
559
|
ws.send(JSON.stringify({ type: "knowledge_save", name: name, content: content }));
|
|
560
560
|
}
|
|
@@ -720,7 +720,7 @@ function showFileMenu(file, anchorBtn) {
|
|
|
720
720
|
// Request file content, then open editor directly
|
|
721
721
|
editingCommon = false;
|
|
722
722
|
editingFile = file.name;
|
|
723
|
-
var ws =
|
|
723
|
+
var ws = getWs ? getWs() : null;
|
|
724
724
|
if (ws && ws.readyState === 1) {
|
|
725
725
|
ws.send(JSON.stringify({ type: "knowledge_read", name: file.name }));
|
|
726
726
|
// Override handleKnowledgeContent to go straight to editor
|
|
@@ -736,7 +736,7 @@ function showFileMenu(file, anchorBtn) {
|
|
|
736
736
|
promoteItem.innerHTML = iconHtml("share-2") + "<span>Share to all mates</span>";
|
|
737
737
|
promoteItem.addEventListener("click", function (e) {
|
|
738
738
|
e.stopPropagation();
|
|
739
|
-
var ws =
|
|
739
|
+
var ws = getWs ? getWs() : null;
|
|
740
740
|
if (ws && ws.readyState === 1) {
|
|
741
741
|
ws.send(JSON.stringify({ type: "knowledge_promote", name: file.name }));
|
|
742
742
|
}
|
|
@@ -749,7 +749,7 @@ function showFileMenu(file, anchorBtn) {
|
|
|
749
749
|
depromoteItem.innerHTML = iconHtml("x-circle") + "<span>Unshare</span>";
|
|
750
750
|
depromoteItem.addEventListener("click", function (e) {
|
|
751
751
|
e.stopPropagation();
|
|
752
|
-
var ws =
|
|
752
|
+
var ws = getWs ? getWs() : null;
|
|
753
753
|
if (ws && ws.readyState === 1) {
|
|
754
754
|
ws.send(JSON.stringify({ type: "knowledge_depromote", name: file.name }));
|
|
755
755
|
}
|
|
@@ -770,7 +770,7 @@ function showFileMenu(file, anchorBtn) {
|
|
|
770
770
|
deleteItem.innerHTML = iconHtml("trash-2") + "<span>Delete</span>";
|
|
771
771
|
deleteItem.addEventListener("click", function (e) {
|
|
772
772
|
e.stopPropagation();
|
|
773
|
-
var ws =
|
|
773
|
+
var ws = getWs ? getWs() : null;
|
|
774
774
|
if (ws && ws.readyState === 1) {
|
|
775
775
|
ws.send(JSON.stringify({ type: "knowledge_delete", name: file.name }));
|
|
776
776
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
2
2
|
import { escapeHtml } from './utils.js';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var getWs = null;
|
|
5
5
|
var visible = false;
|
|
6
6
|
var cachedEntries = [];
|
|
7
7
|
var cachedSummary = "";
|
|
@@ -24,8 +24,8 @@ var confirmOverlay = null;
|
|
|
24
24
|
|
|
25
25
|
var _onShow = null;
|
|
26
26
|
|
|
27
|
-
export function initMateMemory(
|
|
28
|
-
|
|
27
|
+
export function initMateMemory(wsGetter, opts) {
|
|
28
|
+
getWs = wsGetter;
|
|
29
29
|
if (opts && opts.onShow) _onShow = opts.onShow;
|
|
30
30
|
|
|
31
31
|
sidebarBtn = document.getElementById("mate-memory-btn");
|
|
@@ -99,7 +99,7 @@ export function isMemoryVisible() {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function requestMemoryList() {
|
|
102
|
-
var ws =
|
|
102
|
+
var ws = getWs ? getWs() : null;
|
|
103
103
|
if (ws && ws.readyState === 1) {
|
|
104
104
|
ws.send(JSON.stringify({ type: "memory_list" }));
|
|
105
105
|
}
|
|
@@ -325,7 +325,7 @@ function confirmDelete(index) {
|
|
|
325
325
|
deleteBtn.className = "mate-memory-confirm-delete";
|
|
326
326
|
deleteBtn.textContent = "Delete";
|
|
327
327
|
deleteBtn.addEventListener("click", function () {
|
|
328
|
-
var ws =
|
|
328
|
+
var ws = getWs ? getWs() : null;
|
|
329
329
|
if (ws && ws.readyState === 1) {
|
|
330
330
|
ws.send(JSON.stringify({ type: "memory_delete", index: index }));
|
|
331
331
|
}
|