clay-server 2.22.2 → 2.23.0-beta.1
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/build-user-env.js +57 -0
- package/lib/mates.js +202 -18
- package/lib/project.js +311 -14
- package/lib/public/app.js +185 -351
- package/lib/public/css/debate.css +263 -0
- package/lib/public/modules/debate.js +289 -0
- package/lib/public/modules/sidebar.js +3 -0
- package/lib/sdk-bridge.js +7 -5
- package/lib/server.js +24 -2
- package/lib/terminal.js +6 -9
- package/package.json +1 -1
|
@@ -898,6 +898,115 @@
|
|
|
898
898
|
cursor: not-allowed;
|
|
899
899
|
}
|
|
900
900
|
|
|
901
|
+
/* --- Quick Debate Modal (overlay-based) --- */
|
|
902
|
+
.debate-modal-overlay {
|
|
903
|
+
position: fixed;
|
|
904
|
+
inset: 0;
|
|
905
|
+
z-index: 9998;
|
|
906
|
+
display: flex;
|
|
907
|
+
align-items: center;
|
|
908
|
+
justify-content: center;
|
|
909
|
+
}
|
|
910
|
+
.debate-modal-overlay .debate-modal-backdrop {
|
|
911
|
+
position: absolute;
|
|
912
|
+
inset: 0;
|
|
913
|
+
}
|
|
914
|
+
.quick-debate-modal {
|
|
915
|
+
position: relative;
|
|
916
|
+
z-index: 9999;
|
|
917
|
+
width: 420px;
|
|
918
|
+
max-width: 90vw;
|
|
919
|
+
background: var(--bg);
|
|
920
|
+
border: 1px solid var(--border);
|
|
921
|
+
border-radius: 16px;
|
|
922
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
923
|
+
overflow: hidden;
|
|
924
|
+
animation: ctxMenuAppear 0.15s ease-out;
|
|
925
|
+
}
|
|
926
|
+
.quick-debate-modal .debate-modal-header {
|
|
927
|
+
display: flex;
|
|
928
|
+
align-items: center;
|
|
929
|
+
justify-content: space-between;
|
|
930
|
+
padding: 16px 20px;
|
|
931
|
+
border-bottom: 1px solid var(--border);
|
|
932
|
+
}
|
|
933
|
+
.quick-debate-modal .debate-modal-header h3 {
|
|
934
|
+
margin: 0;
|
|
935
|
+
font-size: 15px;
|
|
936
|
+
font-weight: 700;
|
|
937
|
+
color: var(--text);
|
|
938
|
+
}
|
|
939
|
+
.quick-debate-modal .debate-modal-close-btn {
|
|
940
|
+
background: none;
|
|
941
|
+
border: none;
|
|
942
|
+
color: var(--text-muted);
|
|
943
|
+
font-size: 20px;
|
|
944
|
+
cursor: pointer;
|
|
945
|
+
padding: 0 4px;
|
|
946
|
+
}
|
|
947
|
+
.quick-debate-modal .debate-modal-field {
|
|
948
|
+
padding: 12px 20px 0;
|
|
949
|
+
}
|
|
950
|
+
.quick-debate-modal .debate-modal-field label {
|
|
951
|
+
display: block;
|
|
952
|
+
font-size: 13px;
|
|
953
|
+
font-weight: 600;
|
|
954
|
+
color: var(--text);
|
|
955
|
+
margin-bottom: 6px;
|
|
956
|
+
}
|
|
957
|
+
.quick-debate-topic {
|
|
958
|
+
width: 100%;
|
|
959
|
+
padding: 8px 12px;
|
|
960
|
+
border: 1px solid var(--border);
|
|
961
|
+
border-radius: 8px;
|
|
962
|
+
background: var(--bg-alt);
|
|
963
|
+
color: var(--text);
|
|
964
|
+
font-size: 13px;
|
|
965
|
+
font-family: inherit;
|
|
966
|
+
outline: none;
|
|
967
|
+
transition: border-color 0.15s;
|
|
968
|
+
box-sizing: border-box;
|
|
969
|
+
}
|
|
970
|
+
.quick-debate-topic:focus {
|
|
971
|
+
border-color: var(--accent);
|
|
972
|
+
}
|
|
973
|
+
.quick-debate-panel-list {
|
|
974
|
+
max-height: 240px;
|
|
975
|
+
overflow-y: auto;
|
|
976
|
+
}
|
|
977
|
+
.quick-debate-modal .debate-modal-actions {
|
|
978
|
+
display: flex;
|
|
979
|
+
justify-content: flex-end;
|
|
980
|
+
gap: 8px;
|
|
981
|
+
padding: 12px 20px;
|
|
982
|
+
border-top: 1px solid var(--border);
|
|
983
|
+
margin-top: 12px;
|
|
984
|
+
}
|
|
985
|
+
.debate-modal-cancel-btn {
|
|
986
|
+
padding: 8px 16px;
|
|
987
|
+
border: 1px solid var(--border);
|
|
988
|
+
border-radius: 8px;
|
|
989
|
+
background: var(--bg);
|
|
990
|
+
color: var(--text-muted);
|
|
991
|
+
font-size: 13px;
|
|
992
|
+
font-weight: 600;
|
|
993
|
+
cursor: pointer;
|
|
994
|
+
font-family: inherit;
|
|
995
|
+
}
|
|
996
|
+
.debate-modal-start-btn {
|
|
997
|
+
padding: 8px 20px;
|
|
998
|
+
border: none;
|
|
999
|
+
border-radius: 8px;
|
|
1000
|
+
background: var(--accent);
|
|
1001
|
+
color: #fff;
|
|
1002
|
+
font-size: 13px;
|
|
1003
|
+
font-weight: 600;
|
|
1004
|
+
cursor: pointer;
|
|
1005
|
+
font-family: inherit;
|
|
1006
|
+
transition: opacity 0.2s;
|
|
1007
|
+
}
|
|
1008
|
+
.debate-modal-start-btn:hover { opacity: 0.9; }
|
|
1009
|
+
|
|
901
1010
|
/* --- Debate bottom bar (unified controls) --- */
|
|
902
1011
|
#debate-bottom-bar {
|
|
903
1012
|
border-top: 1px solid var(--border);
|
|
@@ -1037,3 +1146,157 @@
|
|
|
1037
1146
|
.debate-bottom-end:hover {
|
|
1038
1147
|
opacity: 0.85;
|
|
1039
1148
|
}
|
|
1149
|
+
|
|
1150
|
+
/* --- Debate Brief Card (inline proposal from DM) --- */
|
|
1151
|
+
.debate-brief-card {
|
|
1152
|
+
max-width: var(--content-width);
|
|
1153
|
+
margin: 10px auto;
|
|
1154
|
+
padding: 0 20px;
|
|
1155
|
+
}
|
|
1156
|
+
.debate-brief-card-header {
|
|
1157
|
+
display: flex;
|
|
1158
|
+
align-items: center;
|
|
1159
|
+
gap: 8px;
|
|
1160
|
+
padding: 12px 16px;
|
|
1161
|
+
background: var(--accent-bg);
|
|
1162
|
+
border: 1px solid var(--accent-20);
|
|
1163
|
+
border-radius: 12px 12px 0 0;
|
|
1164
|
+
cursor: pointer;
|
|
1165
|
+
user-select: none;
|
|
1166
|
+
}
|
|
1167
|
+
.debate-brief-card.collapsed .debate-brief-card-header { border-radius: 12px; }
|
|
1168
|
+
.debate-brief-card-icon { display: inline-flex; color: var(--accent); }
|
|
1169
|
+
.debate-brief-card-icon .lucide { width: 16px; height: 16px; }
|
|
1170
|
+
.debate-brief-card-title { font-size: 14px; font-weight: 600; color: var(--accent); flex: 1; }
|
|
1171
|
+
.debate-brief-card-chevron { display: inline-flex; color: var(--text-muted); transition: transform 0.2s; }
|
|
1172
|
+
.debate-brief-card-chevron .lucide { width: 14px; height: 14px; }
|
|
1173
|
+
.debate-brief-card.collapsed .debate-brief-card-chevron { transform: rotate(-90deg); }
|
|
1174
|
+
|
|
1175
|
+
.debate-brief-card-body {
|
|
1176
|
+
padding: 16px 18px;
|
|
1177
|
+
background: rgba(var(--overlay-rgb), 0.02);
|
|
1178
|
+
border: 1px solid var(--border);
|
|
1179
|
+
border-top: none;
|
|
1180
|
+
font-size: 14px;
|
|
1181
|
+
line-height: 1.65;
|
|
1182
|
+
}
|
|
1183
|
+
.debate-brief-card.collapsed .debate-brief-card-body { display: none; }
|
|
1184
|
+
|
|
1185
|
+
.debate-brief-topic {
|
|
1186
|
+
font-size: 16px;
|
|
1187
|
+
font-weight: 600;
|
|
1188
|
+
color: var(--text);
|
|
1189
|
+
margin-bottom: 10px;
|
|
1190
|
+
}
|
|
1191
|
+
.debate-brief-context {
|
|
1192
|
+
font-size: 13px;
|
|
1193
|
+
color: var(--text-secondary);
|
|
1194
|
+
margin-bottom: 12px;
|
|
1195
|
+
line-height: 1.5;
|
|
1196
|
+
}
|
|
1197
|
+
.debate-brief-moderator {
|
|
1198
|
+
display: flex;
|
|
1199
|
+
align-items: center;
|
|
1200
|
+
gap: 6px;
|
|
1201
|
+
font-size: 13px;
|
|
1202
|
+
color: var(--text);
|
|
1203
|
+
margin-bottom: 8px;
|
|
1204
|
+
}
|
|
1205
|
+
.debate-brief-moderator .lucide { width: 14px; height: 14px; color: var(--accent); }
|
|
1206
|
+
.debate-brief-panelists-label {
|
|
1207
|
+
display: flex;
|
|
1208
|
+
align-items: center;
|
|
1209
|
+
gap: 6px;
|
|
1210
|
+
font-size: 13px;
|
|
1211
|
+
color: var(--text);
|
|
1212
|
+
margin-bottom: 6px;
|
|
1213
|
+
}
|
|
1214
|
+
.debate-brief-panelists-label .lucide { width: 14px; height: 14px; color: var(--accent); }
|
|
1215
|
+
.debate-brief-panelists {
|
|
1216
|
+
display: flex;
|
|
1217
|
+
flex-direction: column;
|
|
1218
|
+
gap: 4px;
|
|
1219
|
+
margin-bottom: 10px;
|
|
1220
|
+
padding-left: 20px;
|
|
1221
|
+
}
|
|
1222
|
+
.debate-brief-panelist {
|
|
1223
|
+
display: flex;
|
|
1224
|
+
align-items: baseline;
|
|
1225
|
+
gap: 8px;
|
|
1226
|
+
font-size: 13px;
|
|
1227
|
+
}
|
|
1228
|
+
.debate-brief-panelist-name {
|
|
1229
|
+
font-weight: 500;
|
|
1230
|
+
color: var(--text);
|
|
1231
|
+
}
|
|
1232
|
+
.debate-brief-panelist-role {
|
|
1233
|
+
color: var(--text-secondary);
|
|
1234
|
+
font-style: italic;
|
|
1235
|
+
}
|
|
1236
|
+
.debate-brief-special {
|
|
1237
|
+
display: flex;
|
|
1238
|
+
align-items: flex-start;
|
|
1239
|
+
gap: 6px;
|
|
1240
|
+
font-size: 12px;
|
|
1241
|
+
color: var(--text-secondary);
|
|
1242
|
+
margin-top: 8px;
|
|
1243
|
+
padding: 8px 10px;
|
|
1244
|
+
background: rgba(var(--overlay-rgb), 0.04);
|
|
1245
|
+
border-radius: 6px;
|
|
1246
|
+
}
|
|
1247
|
+
.debate-brief-special .lucide { width: 14px; height: 14px; flex-shrink: 0; margin-top: 1px; }
|
|
1248
|
+
|
|
1249
|
+
/* Actions */
|
|
1250
|
+
.debate-brief-actions {
|
|
1251
|
+
display: flex;
|
|
1252
|
+
align-items: center;
|
|
1253
|
+
gap: 8px;
|
|
1254
|
+
padding: 12px 16px;
|
|
1255
|
+
background: rgba(var(--overlay-rgb), 0.02);
|
|
1256
|
+
border: 1px solid var(--border);
|
|
1257
|
+
border-top: none;
|
|
1258
|
+
border-radius: 0 0 12px 12px;
|
|
1259
|
+
}
|
|
1260
|
+
.debate-brief-card.collapsed .debate-brief-actions { display: none; }
|
|
1261
|
+
|
|
1262
|
+
.debate-brief-start-btn {
|
|
1263
|
+
display: inline-flex;
|
|
1264
|
+
align-items: center;
|
|
1265
|
+
gap: 6px;
|
|
1266
|
+
padding: 8px 16px;
|
|
1267
|
+
font-size: 13px;
|
|
1268
|
+
font-weight: 600;
|
|
1269
|
+
font-family: inherit;
|
|
1270
|
+
color: #fff;
|
|
1271
|
+
background: var(--accent, #6366f1);
|
|
1272
|
+
border: none;
|
|
1273
|
+
border-radius: 8px;
|
|
1274
|
+
cursor: pointer;
|
|
1275
|
+
transition: opacity 0.15s;
|
|
1276
|
+
}
|
|
1277
|
+
.debate-brief-start-btn:hover { opacity: 0.85; }
|
|
1278
|
+
.debate-brief-start-btn .lucide { width: 14px; height: 14px; }
|
|
1279
|
+
|
|
1280
|
+
.debate-brief-cancel-btn {
|
|
1281
|
+
padding: 8px 16px;
|
|
1282
|
+
font-size: 13px;
|
|
1283
|
+
font-family: inherit;
|
|
1284
|
+
color: var(--text-secondary);
|
|
1285
|
+
background: none;
|
|
1286
|
+
border: 1px solid var(--border);
|
|
1287
|
+
border-radius: 8px;
|
|
1288
|
+
cursor: pointer;
|
|
1289
|
+
transition: all 0.15s;
|
|
1290
|
+
}
|
|
1291
|
+
.debate-brief-cancel-btn:hover { color: var(--text); border-color: var(--text-muted); }
|
|
1292
|
+
|
|
1293
|
+
.debate-brief-resolved-label {
|
|
1294
|
+
display: inline-flex;
|
|
1295
|
+
align-items: center;
|
|
1296
|
+
gap: 6px;
|
|
1297
|
+
font-size: 13px;
|
|
1298
|
+
color: var(--accent);
|
|
1299
|
+
font-weight: 500;
|
|
1300
|
+
}
|
|
1301
|
+
.debate-brief-resolved-label .lucide { width: 14px; height: 14px; }
|
|
1302
|
+
.debate-brief-resolved-label.debate-brief-cancelled { color: var(--text-secondary); }
|
|
@@ -631,3 +631,292 @@ export function closeDebateModal() {
|
|
|
631
631
|
}
|
|
632
632
|
selectedPanelists = [];
|
|
633
633
|
}
|
|
634
|
+
|
|
635
|
+
// --- Quick Debate: start debate from DM context ---
|
|
636
|
+
var quickDebateEl = null;
|
|
637
|
+
var quickSelectedPanelists = [];
|
|
638
|
+
|
|
639
|
+
export function openQuickDebateModal(dmMessages) {
|
|
640
|
+
closeQuickDebateModal();
|
|
641
|
+
|
|
642
|
+
// Build DM context from recent messages (last 20, capped)
|
|
643
|
+
var dmContext = "";
|
|
644
|
+
if (dmMessages && dmMessages.length) {
|
|
645
|
+
var recent = dmMessages.slice(-20);
|
|
646
|
+
var parts = [];
|
|
647
|
+
for (var i = 0; i < recent.length; i++) {
|
|
648
|
+
var m = recent[i];
|
|
649
|
+
var speaker = m.isMate ? "Mate" : "User";
|
|
650
|
+
var text = m.text || "";
|
|
651
|
+
if (text.length > 500) text = text.substring(0, 500) + "...";
|
|
652
|
+
parts.push(speaker + ": " + text);
|
|
653
|
+
}
|
|
654
|
+
dmContext = parts.join("\n");
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
quickSelectedPanelists = [];
|
|
658
|
+
|
|
659
|
+
// Create modal overlay
|
|
660
|
+
quickDebateEl = document.createElement("div");
|
|
661
|
+
quickDebateEl.className = "debate-modal-overlay";
|
|
662
|
+
|
|
663
|
+
var html = '';
|
|
664
|
+
html += '<div class="debate-modal-backdrop"></div>';
|
|
665
|
+
html += '<div class="debate-modal-content quick-debate-modal">';
|
|
666
|
+
html += '<div class="debate-modal-header">';
|
|
667
|
+
html += '<h3>Quick Debate</h3>';
|
|
668
|
+
html += '<button class="debate-modal-close-btn">×</button>';
|
|
669
|
+
html += '</div>';
|
|
670
|
+
|
|
671
|
+
// Optional topic override
|
|
672
|
+
html += '<div class="debate-modal-field">';
|
|
673
|
+
html += '<label>Topic <span style="color:var(--text-tertiary);font-weight:normal">(optional, auto-detected from conversation)</span></label>';
|
|
674
|
+
html += '<input type="text" class="quick-debate-topic" placeholder="Leave blank to auto-detect..." maxlength="200" spellcheck="false">';
|
|
675
|
+
html += '</div>';
|
|
676
|
+
|
|
677
|
+
// Panelist selection
|
|
678
|
+
html += '<div class="debate-modal-field">';
|
|
679
|
+
html += '<label>Select Panelists</label>';
|
|
680
|
+
html += '<div class="quick-debate-panel-list"></div>';
|
|
681
|
+
html += '</div>';
|
|
682
|
+
|
|
683
|
+
html += '<div class="debate-modal-actions">';
|
|
684
|
+
html += '<button class="debate-modal-cancel-btn">Cancel</button>';
|
|
685
|
+
html += '<button class="debate-modal-start-btn">Start Debate</button>';
|
|
686
|
+
html += '</div>';
|
|
687
|
+
|
|
688
|
+
html += '</div>';
|
|
689
|
+
quickDebateEl.innerHTML = html;
|
|
690
|
+
document.body.appendChild(quickDebateEl);
|
|
691
|
+
|
|
692
|
+
// Populate panelist list
|
|
693
|
+
var panelList = quickDebateEl.querySelector(".quick-debate-panel-list");
|
|
694
|
+
var mates = ctx.matesList ? ctx.matesList() : [];
|
|
695
|
+
var currentMateId = ctx.currentMateId ? ctx.currentMateId() : null;
|
|
696
|
+
for (var j = 0; j < mates.length; j++) {
|
|
697
|
+
var mate = mates[j];
|
|
698
|
+
if (mate.status === "interviewing") continue;
|
|
699
|
+
if (mate.id === currentMateId) continue;
|
|
700
|
+
var item = createQuickPanelItem(mate);
|
|
701
|
+
panelList.appendChild(item);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Events
|
|
705
|
+
quickDebateEl.querySelector(".debate-modal-backdrop").onclick = closeQuickDebateModal;
|
|
706
|
+
quickDebateEl.querySelector(".debate-modal-close-btn").onclick = closeQuickDebateModal;
|
|
707
|
+
quickDebateEl.querySelector(".debate-modal-cancel-btn").onclick = closeQuickDebateModal;
|
|
708
|
+
|
|
709
|
+
quickDebateEl.querySelector(".debate-modal-start-btn").onclick = function () {
|
|
710
|
+
if (quickSelectedPanelists.length === 0) return;
|
|
711
|
+
if (!currentMateId) return;
|
|
712
|
+
|
|
713
|
+
var topicInput = quickDebateEl.querySelector(".quick-debate-topic");
|
|
714
|
+
var topic = topicInput ? topicInput.value.trim() : "";
|
|
715
|
+
|
|
716
|
+
var debatePayload = {
|
|
717
|
+
type: "debate_start",
|
|
718
|
+
quickStart: true,
|
|
719
|
+
moderatorId: currentMateId,
|
|
720
|
+
topic: topic || "(auto-detect from conversation)",
|
|
721
|
+
dmContext: dmContext,
|
|
722
|
+
panelists: quickSelectedPanelists.map(function (id) {
|
|
723
|
+
return { mateId: id, role: "", brief: "" };
|
|
724
|
+
}),
|
|
725
|
+
};
|
|
726
|
+
|
|
727
|
+
// Create new session, then send debate_start
|
|
728
|
+
if (ctx.ws) {
|
|
729
|
+
var onMessage = function (evt) {
|
|
730
|
+
try {
|
|
731
|
+
var data = JSON.parse(evt.data);
|
|
732
|
+
if (data.type === "session_switched") {
|
|
733
|
+
ctx.ws.removeEventListener("message", onMessage);
|
|
734
|
+
ctx.ws.send(JSON.stringify(debatePayload));
|
|
735
|
+
}
|
|
736
|
+
} catch (e) {}
|
|
737
|
+
};
|
|
738
|
+
ctx.ws.addEventListener("message", onMessage);
|
|
739
|
+
ctx.ws.send(JSON.stringify({ type: "new_session" }));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
closeQuickDebateModal();
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
// Focus topic input
|
|
746
|
+
var topicEl = quickDebateEl.querySelector(".quick-debate-topic");
|
|
747
|
+
if (topicEl) setTimeout(function () { topicEl.focus(); }, 50);
|
|
748
|
+
|
|
749
|
+
refreshIcons();
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
function createQuickPanelItem(mate) {
|
|
753
|
+
var item = document.createElement("div");
|
|
754
|
+
item.className = "debate-panel-item";
|
|
755
|
+
item.dataset.mateId = mate.id;
|
|
756
|
+
|
|
757
|
+
var cb = document.createElement("input");
|
|
758
|
+
cb.type = "checkbox";
|
|
759
|
+
item.appendChild(cb);
|
|
760
|
+
|
|
761
|
+
var avatarSrc = mateAvatarUrl(mate, 32);
|
|
762
|
+
var avi = document.createElement("img");
|
|
763
|
+
avi.className = "debate-panel-item-avatar";
|
|
764
|
+
avi.src = avatarSrc;
|
|
765
|
+
item.appendChild(avi);
|
|
766
|
+
|
|
767
|
+
var info = document.createElement("div");
|
|
768
|
+
info.className = "debate-panel-item-info";
|
|
769
|
+
var nameSpan = document.createElement("div");
|
|
770
|
+
nameSpan.className = "debate-panel-item-name";
|
|
771
|
+
nameSpan.textContent = (mate.profile && mate.profile.displayName) || mate.name || "Mate";
|
|
772
|
+
info.appendChild(nameSpan);
|
|
773
|
+
if (mate.bio) {
|
|
774
|
+
var bioSpan = document.createElement("div");
|
|
775
|
+
bioSpan.className = "debate-panel-item-bio";
|
|
776
|
+
bioSpan.textContent = mate.bio;
|
|
777
|
+
info.appendChild(bioSpan);
|
|
778
|
+
}
|
|
779
|
+
item.appendChild(info);
|
|
780
|
+
|
|
781
|
+
function toggle() {
|
|
782
|
+
var idx = quickSelectedPanelists.indexOf(mate.id);
|
|
783
|
+
if (idx === -1) {
|
|
784
|
+
quickSelectedPanelists.push(mate.id);
|
|
785
|
+
item.classList.add("selected");
|
|
786
|
+
cb.checked = true;
|
|
787
|
+
} else {
|
|
788
|
+
quickSelectedPanelists.splice(idx, 1);
|
|
789
|
+
item.classList.remove("selected");
|
|
790
|
+
cb.checked = false;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
item.addEventListener("click", function (e) {
|
|
795
|
+
if (e.target === cb) return;
|
|
796
|
+
toggle();
|
|
797
|
+
});
|
|
798
|
+
cb.addEventListener("change", function () {
|
|
799
|
+
var idx = quickSelectedPanelists.indexOf(mate.id);
|
|
800
|
+
if (cb.checked && idx === -1) { quickSelectedPanelists.push(mate.id); item.classList.add("selected"); }
|
|
801
|
+
else if (!cb.checked && idx !== -1) { quickSelectedPanelists.splice(idx, 1); item.classList.remove("selected"); }
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
return item;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
export function closeQuickDebateModal() {
|
|
808
|
+
if (quickDebateEl) {
|
|
809
|
+
quickDebateEl.remove();
|
|
810
|
+
quickDebateEl = null;
|
|
811
|
+
}
|
|
812
|
+
quickSelectedPanelists = [];
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// --- Debate Brief Card (inline proposal from DM) ---
|
|
816
|
+
|
|
817
|
+
export function handleDebateBriefReady(msg) {
|
|
818
|
+
renderDebateBriefCard(msg, false);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
export function renderDebateBriefReady(msg) {
|
|
822
|
+
renderDebateBriefCard(msg, true);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
function renderDebateBriefCard(msg, resolved) {
|
|
826
|
+
var el = document.createElement("div");
|
|
827
|
+
el.className = "debate-brief-card" + (resolved ? " resolved" : "");
|
|
828
|
+
|
|
829
|
+
// Header
|
|
830
|
+
var header = document.createElement("div");
|
|
831
|
+
header.className = "debate-brief-card-header";
|
|
832
|
+
header.innerHTML =
|
|
833
|
+
'<span class="debate-brief-card-icon">' + iconHtml("message-circle") + '</span>' +
|
|
834
|
+
'<span class="debate-brief-card-title">Debate Proposal</span>' +
|
|
835
|
+
'<span class="debate-brief-card-chevron">' + iconHtml("chevron-down") + '</span>';
|
|
836
|
+
|
|
837
|
+
// Body
|
|
838
|
+
var body = document.createElement("div");
|
|
839
|
+
body.className = "debate-brief-card-body";
|
|
840
|
+
|
|
841
|
+
var topicHtml = '<div class="debate-brief-topic">' + escapeHtml(msg.topic || "Untitled") + '</div>';
|
|
842
|
+
|
|
843
|
+
if (msg.context) {
|
|
844
|
+
topicHtml += '<div class="debate-brief-context">' + escapeHtml(msg.context) + '</div>';
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
topicHtml += '<div class="debate-brief-moderator">' +
|
|
848
|
+
iconHtml("mic") + ' <strong>Moderator:</strong> ' + escapeHtml(msg.moderatorName || "Unknown") +
|
|
849
|
+
'</div>';
|
|
850
|
+
|
|
851
|
+
topicHtml += '<div class="debate-brief-panelists-label">' + iconHtml("users") + ' <strong>Panelists:</strong></div>';
|
|
852
|
+
topicHtml += '<div class="debate-brief-panelists">';
|
|
853
|
+
if (msg.panelists) {
|
|
854
|
+
for (var i = 0; i < msg.panelists.length; i++) {
|
|
855
|
+
var p = msg.panelists[i];
|
|
856
|
+
topicHtml += '<div class="debate-brief-panelist">';
|
|
857
|
+
topicHtml += '<span class="debate-brief-panelist-name">' + escapeHtml(p.name || "Unknown") + '</span>';
|
|
858
|
+
if (p.role) {
|
|
859
|
+
topicHtml += '<span class="debate-brief-panelist-role">' + escapeHtml(p.role) + '</span>';
|
|
860
|
+
}
|
|
861
|
+
topicHtml += '</div>';
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
topicHtml += '</div>';
|
|
865
|
+
|
|
866
|
+
if (msg.specialRequests) {
|
|
867
|
+
topicHtml += '<div class="debate-brief-special">' +
|
|
868
|
+
iconHtml("info") + ' ' + escapeHtml(msg.specialRequests) +
|
|
869
|
+
'</div>';
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
body.innerHTML = topicHtml;
|
|
873
|
+
|
|
874
|
+
// Actions
|
|
875
|
+
var actions = document.createElement("div");
|
|
876
|
+
actions.className = "debate-brief-actions";
|
|
877
|
+
|
|
878
|
+
if (resolved) {
|
|
879
|
+
actions.innerHTML = '<span class="debate-brief-resolved-label">' + iconHtml("check") + ' Debate started</span>';
|
|
880
|
+
} else {
|
|
881
|
+
var startBtn = document.createElement("button");
|
|
882
|
+
startBtn.className = "debate-brief-start-btn";
|
|
883
|
+
startBtn.innerHTML = iconHtml("play") + " Start Debate";
|
|
884
|
+
|
|
885
|
+
var cancelBtn = document.createElement("button");
|
|
886
|
+
cancelBtn.className = "debate-brief-cancel-btn";
|
|
887
|
+
cancelBtn.textContent = "Cancel";
|
|
888
|
+
|
|
889
|
+
startBtn.addEventListener("click", function () {
|
|
890
|
+
if (ctx.sendWs) {
|
|
891
|
+
ctx.sendWs({ type: "debate_confirm_brief" });
|
|
892
|
+
}
|
|
893
|
+
el.classList.add("resolved");
|
|
894
|
+
actions.innerHTML = '<span class="debate-brief-resolved-label">' + iconHtml("check") + ' Starting debate...</span>';
|
|
895
|
+
refreshIcons();
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
cancelBtn.addEventListener("click", function () {
|
|
899
|
+
if (ctx.sendWs) {
|
|
900
|
+
ctx.sendWs({ type: "debate_stop" });
|
|
901
|
+
}
|
|
902
|
+
el.classList.add("resolved");
|
|
903
|
+
actions.innerHTML = '<span class="debate-brief-resolved-label debate-brief-cancelled">' + iconHtml("x") + ' Cancelled</span>';
|
|
904
|
+
refreshIcons();
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
actions.appendChild(startBtn);
|
|
908
|
+
actions.appendChild(cancelBtn);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// Collapse toggle
|
|
912
|
+
header.addEventListener("click", function () {
|
|
913
|
+
el.classList.toggle("collapsed");
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
el.appendChild(header);
|
|
917
|
+
el.appendChild(body);
|
|
918
|
+
el.appendChild(actions);
|
|
919
|
+
ctx.addToMessages(el);
|
|
920
|
+
refreshIcons();
|
|
921
|
+
ctx.scrollToBottom();
|
|
922
|
+
}
|
|
@@ -2436,6 +2436,9 @@ function showMateCtxMenu(anchorEl, mate) {
|
|
|
2436
2436
|
removeItem.addEventListener("click", function (e) {
|
|
2437
2437
|
e.stopPropagation();
|
|
2438
2438
|
closeUserCtxMenu();
|
|
2439
|
+
// Spawn dust particles at the mate icon position
|
|
2440
|
+
var iconRect = anchorEl.getBoundingClientRect();
|
|
2441
|
+
spawnDustParticles(iconRect.left + iconRect.width / 2, iconRect.top + iconRect.height / 2);
|
|
2439
2442
|
if (ctx.sendWs) {
|
|
2440
2443
|
ctx.sendWs({ type: "dm_remove_favorite", targetUserId: mate.id });
|
|
2441
2444
|
}
|
package/lib/sdk-bridge.js
CHANGED
|
@@ -708,11 +708,13 @@ function createSDKBridge(opts) {
|
|
|
708
708
|
try { fs.chmodSync(socketPath, 0o777); } catch (e) {}
|
|
709
709
|
|
|
710
710
|
// Spawn worker process as the target Linux user.
|
|
711
|
-
//
|
|
712
|
-
var workerEnv =
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
711
|
+
// Build a minimal, isolated env (no daemon env leakage).
|
|
712
|
+
var workerEnv = require("./build-user-env").buildUserEnv({
|
|
713
|
+
uid: userInfo.uid,
|
|
714
|
+
gid: userInfo.gid,
|
|
715
|
+
home: userInfo.home,
|
|
716
|
+
user: linuxUser,
|
|
717
|
+
shell: userInfo.shell || "/bin/bash",
|
|
716
718
|
});
|
|
717
719
|
|
|
718
720
|
console.log("[sdk-bridge] Spawning worker: uid=" + userInfo.uid + " gid=" + userInfo.gid + " cwd=" + cwd + " socket=" + socketPath);
|
package/lib/server.js
CHANGED
|
@@ -2931,9 +2931,28 @@ function createServer(opts) {
|
|
|
2931
2931
|
});
|
|
2932
2932
|
projects.set(slug, ctx);
|
|
2933
2933
|
ctx.warmup();
|
|
2934
|
+
refreshMateProjectRegistries();
|
|
2934
2935
|
return true;
|
|
2935
2936
|
}
|
|
2936
2937
|
|
|
2938
|
+
// --- Refresh project registry on all mate CLAUDE.md files ---
|
|
2939
|
+
function refreshMateProjectRegistries() {
|
|
2940
|
+
var projList = [];
|
|
2941
|
+
projects.forEach(function (ctx) {
|
|
2942
|
+
var status = ctx.getStatus();
|
|
2943
|
+
if (!status.isMate && !status.isWorktree) {
|
|
2944
|
+
projList.push({ slug: status.slug, path: status.path, title: status.title || status.project, icon: status.icon });
|
|
2945
|
+
}
|
|
2946
|
+
});
|
|
2947
|
+
projects.forEach(function (ctx) {
|
|
2948
|
+
var status = ctx.getStatus();
|
|
2949
|
+
if (status.isMate) {
|
|
2950
|
+
var claudeMdPath = path.join(status.path, "CLAUDE.md");
|
|
2951
|
+
try { mates.enforceProjectRegistry(claudeMdPath, projList); } catch (e) {}
|
|
2952
|
+
}
|
|
2953
|
+
});
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2937
2956
|
// --- DM message handler (server-level, cross-project) ---
|
|
2938
2957
|
function handleDmMessage(ws, msg) {
|
|
2939
2958
|
if (!users.isMultiUser() || !ws._clayUser) return;
|
|
@@ -3149,12 +3168,14 @@ function createServer(opts) {
|
|
|
3149
3168
|
} catch (e) {
|
|
3150
3169
|
console.error("[server] Failed to ensure built-in mates:", e.message);
|
|
3151
3170
|
}
|
|
3152
|
-
// Ensure built-in mates are in favorites (unless user explicitly removed them)
|
|
3171
|
+
// Ensure core built-in mates are in favorites (unless user explicitly removed them)
|
|
3172
|
+
// Only auto-favorite the core 3: Ally (chief of staff), Arch (architect), Buzz (marketer)
|
|
3173
|
+
var coreMateKeys = ["ally", "arch", "buzz"];
|
|
3153
3174
|
var mateList = mates.getAllMates(mateCtx5);
|
|
3154
3175
|
var currentFavs = users.getDmFavorites(userId);
|
|
3155
3176
|
var hiddenIds = users.getDmHidden(userId);
|
|
3156
3177
|
for (var bfi = 0; bfi < mateList.length; bfi++) {
|
|
3157
|
-
if (mateList[bfi].builtinKey && currentFavs.indexOf(mateList[bfi].id) === -1 && hiddenIds.indexOf(mateList[bfi].id) === -1) {
|
|
3178
|
+
if (mateList[bfi].builtinKey && coreMateKeys.indexOf(mateList[bfi].builtinKey) !== -1 && currentFavs.indexOf(mateList[bfi].id) === -1 && hiddenIds.indexOf(mateList[bfi].id) === -1) {
|
|
3158
3179
|
users.addDmFavorite(userId, mateList[bfi].id);
|
|
3159
3180
|
}
|
|
3160
3181
|
}
|
|
@@ -3314,6 +3335,7 @@ function createServer(opts) {
|
|
|
3314
3335
|
if (!ctx) return false;
|
|
3315
3336
|
ctx.destroy();
|
|
3316
3337
|
projects.delete(slug);
|
|
3338
|
+
refreshMateProjectRegistries();
|
|
3317
3339
|
return true;
|
|
3318
3340
|
}
|
|
3319
3341
|
|
package/lib/terminal.js
CHANGED
|
@@ -5,14 +5,17 @@ try {
|
|
|
5
5
|
pty = null;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
var { buildUserEnv } = require("./build-user-env");
|
|
9
|
+
|
|
8
10
|
function createTerminal(cwd, cols, rows, osUserInfo) {
|
|
9
11
|
if (!pty) return null;
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
// Determine shell: prefer target user's shell, then fallback
|
|
14
|
+
var shell = (osUserInfo && osUserInfo.shell)
|
|
12
15
|
|| (process.platform === "win32" ? process.env.COMSPEC || "cmd.exe" : "/bin/bash");
|
|
13
16
|
|
|
14
|
-
//
|
|
15
|
-
var termEnv =
|
|
17
|
+
// Build a minimal, isolated environment (no daemon env leakage)
|
|
18
|
+
var termEnv = buildUserEnv(osUserInfo);
|
|
16
19
|
var spawnOpts = {
|
|
17
20
|
name: "xterm-256color",
|
|
18
21
|
cols: cols || 80,
|
|
@@ -24,12 +27,6 @@ function createTerminal(cwd, cols, rows, osUserInfo) {
|
|
|
24
27
|
if (osUserInfo) {
|
|
25
28
|
spawnOpts.uid = osUserInfo.uid;
|
|
26
29
|
spawnOpts.gid = osUserInfo.gid;
|
|
27
|
-
// Use the target user's shell and home
|
|
28
|
-
termEnv.HOME = osUserInfo.home;
|
|
29
|
-
termEnv.USER = osUserInfo.user;
|
|
30
|
-
termEnv.LOGNAME = osUserInfo.user;
|
|
31
|
-
// Use target user's shell if available
|
|
32
|
-
if (osUserInfo.shell) shell = osUserInfo.shell;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
var args = osUserInfo ? ["-l"] : [];
|