clay-server 5.0.2-beta.1 → 5.1.0-beta.2
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/LICENSES/README.md +4 -0
- package/LICENSES/dicebear-avatars.md +16 -0
- package/lib/daemon-project-access.js +7 -1
- package/lib/daemon.js +2 -0
- package/lib/dicebear-avatar.js +62 -0
- package/lib/knowledge-db-service.js +175 -0
- package/lib/knowledge-db-validation.js +0 -0
- package/lib/knowledge-document-index.js +49 -0
- package/lib/knowledge-draft-store.js +56 -0
- package/lib/knowledge-file-store.js +199 -0
- package/lib/knowledge-markdown.js +128 -0
- package/lib/mate-knowledge-mcp-server.js +29 -6
- package/lib/mate-knowledge-service.js +23 -2
- package/lib/mate-knowledge-sync.js +36 -21
- package/lib/mate-workspace-color.js +4 -0
- package/lib/mates.js +18 -0
- package/lib/project-connection.js +36 -2
- package/lib/project-debate-proposal.js +6 -0
- package/lib/project-debate-workspace.js +43 -0
- package/lib/project-debate.js +1 -0
- package/lib/project-file-path.js +2 -3
- package/lib/project-knowledge.js +315 -136
- package/lib/project-mate-creation-proposal.js +1 -0
- package/lib/project-request-access.js +13 -1
- package/lib/project-sessions.js +39 -2
- package/lib/project-user-knowledge.js +60 -0
- package/lib/project.js +59 -18
- package/lib/public/app.js +73 -34
- package/lib/public/clay-studio-wordmark-bold.svg +20 -0
- package/lib/public/css/clay-workspace.css +105 -0
- package/lib/public/css/debates-workbench.css +47 -0
- package/lib/public/css/filebrowser.css +10 -0
- package/lib/public/css/home-debate-live.css +26 -0
- package/lib/public/css/home-hub.css +3 -1
- package/lib/public/css/home-mate-model-picker.css +15 -131
- package/lib/public/css/home-mate-settings.css +168 -16
- package/lib/public/css/icon-strip.css +249 -32
- package/lib/public/css/mate-conversation.css +176 -0
- package/lib/public/css/mate-knowledge-workbench.css +118 -0
- package/lib/public/css/mate-workspace-color.css +16 -0
- package/lib/public/css/mates.css +28 -28
- package/lib/public/css/messages.css +1 -114
- package/lib/public/css/mobile-nav.css +16 -16
- package/lib/public/css/overlays.css +8 -0
- package/lib/public/css/project-logs.css +7 -0
- package/lib/public/css/project-mate-creation.css +105 -0
- package/lib/public/css/right-workbench.css +3 -3
- package/lib/public/css/session-folders.css +80 -21
- package/lib/public/css/sidebar.css +183 -107
- package/lib/public/css/title-bar.css +151 -0
- package/lib/public/css/worker-delegation.css +47 -0
- package/lib/public/css/worker-proposal.css +72 -150
- package/lib/public/css/you.css +74 -0
- package/lib/public/index.html +33 -101
- package/lib/public/modules/account-island.js +230 -0
- package/lib/public/modules/app-cursors.js +19 -43
- package/lib/public/modules/app-debate-ui.js +4 -3
- package/lib/public/modules/app-header.js +106 -0
- package/lib/public/modules/app-message-router.js +12 -3
- package/lib/public/modules/app-messages.js +34 -9
- package/lib/public/modules/app-notifications.js +4 -7
- package/lib/public/modules/app-projects.js +5 -38
- package/lib/public/modules/app-rendering.js +12 -13
- package/lib/public/modules/avatar.js +25 -9
- package/lib/public/modules/chat-render-runtime.js +16 -4
- package/lib/public/modules/command-palette.js +2 -15
- package/lib/public/modules/cursor-sharing-preference.js +3 -3
- package/lib/public/modules/debate-controls.js +299 -0
- package/lib/public/modules/debate.js +2 -0
- package/lib/public/modules/debates-workbench.js +339 -0
- package/lib/public/modules/default-ai.js +81 -65
- package/lib/public/modules/filebrowser.js +28 -8
- package/lib/public/modules/home-debate-controls.js +18 -289
- package/lib/public/modules/home-mate-avatar-editor.js +228 -0
- package/lib/public/modules/home-mate-color-picker.js +66 -0
- package/lib/public/modules/home-mate-creation.js +1 -1
- package/lib/public/modules/home-mate-instructions.js +90 -0
- package/lib/public/modules/home-mate-model-picker.js +80 -271
- package/lib/public/modules/home-mate-profile-editor.js +72 -0
- package/lib/public/modules/home-mate-settings.js +118 -125
- package/lib/public/modules/home-shell.js +3 -0
- package/lib/public/modules/home-surface-boot.js +1 -9
- package/lib/public/modules/html-preview.js +19 -0
- package/lib/public/modules/icon-strip-tooltip.js +95 -0
- package/lib/public/modules/knowledge-db-edit-state.js +35 -0
- package/lib/public/modules/knowledge-db-workbench.js +234 -0
- package/lib/public/modules/knowledge-history-state.js +55 -0
- package/lib/public/modules/knowledge-markdown-editor.js +57 -0
- package/lib/public/modules/knowledge-preview-links.js +70 -0
- package/lib/public/modules/knowledge-workbench-shell.js +21 -0
- package/lib/public/modules/mate-knowledge-workbench-state.js +174 -0
- package/lib/public/modules/mate-knowledge-workbench.js +500 -0
- package/lib/public/modules/mate-knowledge.js +11 -3
- package/lib/public/modules/mate-management.js +54 -10
- package/lib/public/modules/mate-sidebar.js +11 -1
- package/lib/public/modules/mate-workspace-color.js +33 -0
- package/lib/public/modules/mention.js +5 -13
- package/lib/public/modules/profile.js +51 -18
- package/lib/public/modules/project-chat-identity.js +79 -0
- package/lib/public/modules/project-debate-planning-workspace.js +250 -0
- package/lib/public/modules/project-debate-workspace.js +185 -0
- package/lib/public/modules/project-header-identity.js +127 -0
- package/lib/public/modules/project-logs-render.js +9 -4
- package/lib/public/modules/project-mate-creation-workspace.js +414 -0
- package/lib/public/modules/project-mate-navigation.js +238 -0
- package/lib/public/modules/project-session-navigation.js +29 -0
- package/lib/public/modules/project-switcher.js +6 -8
- package/lib/public/modules/projects-hub-view.js +5 -6
- package/lib/public/modules/projects-hub.js +2 -6
- package/lib/public/modules/qrcode.js +27 -8
- package/lib/public/modules/search-clay-chat.js +8 -11
- package/lib/public/modules/session-activity-tooltip.js +12 -0
- package/lib/public/modules/session-create-form.js +86 -14
- package/lib/public/modules/session-create.js +50 -7
- package/lib/public/modules/session-list-visibility.js +41 -0
- package/lib/public/modules/session-presence-ui.js +4 -1
- package/lib/public/modules/session-title-marquee.js +51 -0
- package/lib/public/modules/sidebar-mates.js +3 -50
- package/lib/public/modules/sidebar-mobile.js +63 -60
- package/lib/public/modules/sidebar-projects.js +84 -97
- package/lib/public/modules/sidebar-session-folders-ui.js +2 -2
- package/lib/public/modules/sidebar-session-hierarchy.js +149 -70
- package/lib/public/modules/sidebar-sessions.js +49 -50
- package/lib/public/modules/sidebar.js +11 -13
- package/lib/public/modules/thinking-lifecycle.js +7 -6
- package/lib/public/modules/tool-palette-order.js +4 -3
- package/lib/public/modules/tool-palette.js +13 -3
- package/lib/public/modules/tools.js +22 -22
- package/lib/public/modules/worker-proposal.js +42 -8
- package/lib/public/modules/worker-runtime-picker.js +115 -0
- package/lib/public/modules/you-activity.js +121 -0
- package/lib/public/modules/you.js +251 -0
- package/lib/public/style.css +16 -8
- package/lib/public/vendor/codemirror/LICENSE +21 -0
- package/lib/public/vendor/codemirror/codemirror.css +344 -0
- package/lib/public/vendor/codemirror/codemirror.js +9884 -0
- package/lib/public/vendor/codemirror/continuelist.js +101 -0
- package/lib/public/vendor/codemirror/markdown.js +886 -0
- package/lib/public/vendor/codemirror/show-hint.css +37 -0
- package/lib/public/vendor/codemirror/show-hint.js +523 -0
- package/lib/sdk-bridge.js +15 -3
- package/lib/server-admin.js +11 -0
- package/lib/server-home-chat-events.js +1 -1
- package/lib/server-home-chat.js +25 -3
- package/lib/server-home-debate-planning.js +4 -1
- package/lib/server-home-debates.js +2 -0
- package/lib/server-home-mate-creation.js +4 -1
- package/lib/server-mate-instructions.js +44 -0
- package/lib/server-mates.js +12 -3
- package/lib/server-palette.js +1 -1
- package/lib/server-settings.js +65 -1
- package/lib/server-user-knowledge.js +119 -0
- package/lib/server.js +21 -1
- package/lib/session-visibility.js +7 -2
- package/lib/sessions.js +32 -6
- package/lib/user-knowledge-service.js +167 -0
- package/lib/users-permissions.js +7 -0
- package/lib/users-project-mate-filter-preferences.js +39 -0
- package/lib/users.js +6 -0
- package/lib/workspace-query-access.js +4 -1
- package/lib/ws-schema.js +50 -0
- package/package.json +10 -1
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { getWs } from './ws-ref.js';
|
|
4
4
|
import { showMateProfilePopover } from './profile.js';
|
|
5
|
-
import {
|
|
5
|
+
import { showToast } from './utils.js';
|
|
6
|
+
import { showConfirm, hideConfirm } from './app-misc.js';
|
|
6
7
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
7
8
|
|
|
8
9
|
var mateMenu = null;
|
|
@@ -21,15 +22,58 @@ export function editMateProfile(anchorEl, mate) {
|
|
|
21
22
|
|
|
22
23
|
export function confirmMateRemoval(anchorEl, mate, onRemoved) {
|
|
23
24
|
if (!anchorEl || !mate || mate.primary) return;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
var name = (mate.profile || {}).displayName || mate.name || "this Mate";
|
|
26
|
+
var modal = document.getElementById("confirm-modal");
|
|
27
|
+
var panel = modal.querySelector(".confirm-dialog");
|
|
28
|
+
var ok = document.getElementById("confirm-ok");
|
|
29
|
+
var cancel = document.getElementById("confirm-cancel");
|
|
30
|
+
var input;
|
|
31
|
+
function cleanup() {
|
|
32
|
+
modal.classList.remove("mate-delete-confirm");
|
|
33
|
+
panel.removeAttribute("role"); panel.removeAttribute("aria-modal");
|
|
34
|
+
panel.removeAttribute("aria-labelledby"); panel.removeAttribute("aria-describedby");
|
|
35
|
+
var field = modal.querySelector(".mate-delete-challenge"); if (field) field.remove();
|
|
36
|
+
ok.disabled = false;
|
|
37
|
+
document.removeEventListener("keydown", onKey, true);
|
|
38
|
+
if (anchorEl.isConnected) anchorEl.focus({preventScroll:true});
|
|
39
|
+
}
|
|
40
|
+
function onKey(event) {
|
|
41
|
+
if (event.key === "Escape") { event.preventDefault(); event.stopImmediatePropagation(); hideConfirm(); return; }
|
|
42
|
+
if (event.key !== "Tab") return;
|
|
43
|
+
var controls = ok.disabled ? [input,cancel] : [input,cancel,ok];
|
|
44
|
+
var index = controls.indexOf(document.activeElement);
|
|
45
|
+
event.preventDefault(); event.stopImmediatePropagation();
|
|
46
|
+
controls[(index + (event.shiftKey ? controls.length - 1 : 1)) % controls.length].focus();
|
|
47
|
+
}
|
|
48
|
+
showConfirm("", function () {
|
|
49
|
+
if (input.value !== "understand") { cleanup(); return; }
|
|
50
|
+
var ws = getWs();
|
|
51
|
+
if (!ws || ws.readyState !== 1) { cleanup(); showToast("Clay is offline. The Mate was not deleted.", "error"); return; }
|
|
52
|
+
try { ws.send(JSON.stringify({type:"mate_delete",mateId:mate.id})); }
|
|
53
|
+
catch (error) { cleanup(); showToast("Could not send the deletion request. Try again.", "error"); return; }
|
|
54
|
+
cleanup();
|
|
55
|
+
if (onRemoved) onRemoved(true);
|
|
56
|
+
}, mate.builtinKey ? "Remove permanently" : "Delete permanently", true, cleanup);
|
|
57
|
+
modal.classList.add("mate-delete-confirm");
|
|
58
|
+
panel.setAttribute("role","alertdialog"); panel.setAttribute("aria-modal","true");
|
|
59
|
+
panel.setAttribute("aria-labelledby","mate-delete-title"); panel.setAttribute("aria-describedby","mate-delete-warning");
|
|
60
|
+
var text = document.getElementById("confirm-text");
|
|
61
|
+
var title = document.createElement("h3"); title.id = "mate-delete-title"; title.textContent = "Delete " + name + "?";
|
|
62
|
+
var warning = document.createElement("p"); warning.id = "mate-delete-warning";
|
|
63
|
+
warning.textContent = "This permanently deletes the Mate and the data stored in its workspace, including its prompt and files. This cannot be undone.";
|
|
64
|
+
text.appendChild(title); text.appendChild(warning);
|
|
65
|
+
if (mate.builtinKey) {
|
|
66
|
+
var note = document.createElement("p"); note.textContent = "You can add this built-in Mate again, but its deleted data will not be restored."; text.appendChild(note);
|
|
67
|
+
}
|
|
68
|
+
var field = document.createElement("label"); field.className = "mate-delete-challenge";
|
|
69
|
+
field.textContent = 'Type understand to confirm permanent deletion.';
|
|
70
|
+
input = document.createElement("input"); input.type = "text"; input.autocomplete = "off"; input.spellcheck = false;
|
|
71
|
+
input.setAttribute("autocapitalize","none"); input.setAttribute("aria-label","Type understand to confirm permanent deletion");
|
|
72
|
+
field.appendChild(input); text.after(field);
|
|
73
|
+
ok.disabled = true;
|
|
74
|
+
input.addEventListener("input",function () { ok.disabled = input.value !== "understand"; });
|
|
75
|
+
document.addEventListener("keydown",onKey,true);
|
|
76
|
+
input.focus();
|
|
33
77
|
}
|
|
34
78
|
|
|
35
79
|
export function closeMateManagementMenu() {
|
|
@@ -394,6 +394,16 @@ export function handleMateSearchResults(msg) {
|
|
|
394
394
|
|
|
395
395
|
var expandedDebateGroups = new Set();
|
|
396
396
|
|
|
397
|
+
function appendMateSessionTitleLine(el, textSpan) {
|
|
398
|
+
var processingDot = textSpan.querySelector('.session-processing');
|
|
399
|
+
if (processingDot) processingDot.remove();
|
|
400
|
+
var titleLine = document.createElement('span');
|
|
401
|
+
titleLine.className = 'mate-session-title-line';
|
|
402
|
+
titleLine.appendChild(textSpan);
|
|
403
|
+
if (processingDot) titleLine.appendChild(processingDot);
|
|
404
|
+
el.appendChild(titleLine);
|
|
405
|
+
}
|
|
406
|
+
|
|
397
407
|
export function renderMateSessionList(sessions) {
|
|
398
408
|
if (sessions) cachedSessions = sessions;
|
|
399
409
|
if (!listEl) return;
|
|
@@ -529,7 +539,7 @@ function renderDebateGroup(children, groupKey) {
|
|
|
529
539
|
textHtml += '<span class="mate-debate-name">' + escapeHtml(debateName) + '</span>';
|
|
530
540
|
textHtml += '<span class="mate-debate-count">' + children.length + '</span>';
|
|
531
541
|
textSpan.innerHTML = textHtml;
|
|
532
|
-
el
|
|
542
|
+
appendMateSessionTitleLine(el, textSpan);
|
|
533
543
|
|
|
534
544
|
// Click row -> switch to latest session
|
|
535
545
|
el.addEventListener("click", (function (id) {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Theme-specific surfaces keep user color choices separate from text and actions.
|
|
2
|
+
export var MATE_WORKSPACE_COLORS = [
|
|
3
|
+
{ id: 'mint', label: 'Mint', pigment: '#07e5a3' },
|
|
4
|
+
{ id: 'rose', label: 'Rose', pigment: '#ec82ac' },
|
|
5
|
+
{ id: 'plum', label: 'Plum', pigment: '#b780b3' },
|
|
6
|
+
{ id: 'coral', label: 'Coral', pigment: '#ff7479' },
|
|
7
|
+
{ id: 'peach', label: 'Peach', pigment: '#ed986b' },
|
|
8
|
+
{ id: 'gold', label: 'Gold', pigment: '#e0b45b' },
|
|
9
|
+
{ id: 'sky', label: 'Sky', pigment: '#69b6d4' },
|
|
10
|
+
{ id: 'indigo', label: 'Indigo', pigment: '#8582df' },
|
|
11
|
+
{ id: 'stone', label: 'Stone', pigment: '#a5a59e' }
|
|
12
|
+
];
|
|
13
|
+
function mix(pigment, base, amount) {
|
|
14
|
+
var channels = [1, 3, 5].map(function (offset) {
|
|
15
|
+
var a = parseInt(pigment.slice(offset, offset + 2), 16);
|
|
16
|
+
var b = parseInt(base.slice(offset, offset + 2), 16);
|
|
17
|
+
return Math.round(a * amount + b * (1 - amount)).toString(16).padStart(2, '0');
|
|
18
|
+
});
|
|
19
|
+
return '#' + channels.join('');
|
|
20
|
+
}
|
|
21
|
+
export function workspaceColor(mate) {
|
|
22
|
+
var id = mate && mate.builtinKey !== 'clay' && !mate.primary ? mate.workspaceColor : 'mint';
|
|
23
|
+
var color = MATE_WORKSPACE_COLORS.find(function (item) { return item.id === id; }) || MATE_WORKSPACE_COLORS[0];
|
|
24
|
+
return Object.assign({}, color, {
|
|
25
|
+
light: mix(color.pigment, '#f2f2ef', color.id === 'mint' ? 0.03 : 0.08),
|
|
26
|
+
dark: mix(color.pigment, '#232322', color.id === 'mint' ? 0.02 : 0.10)
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function applyWorkspaceColor(mate) {
|
|
30
|
+
var color = workspaceColor(mate);
|
|
31
|
+
document.body.style.setProperty('--mate-surround-light', color.light);
|
|
32
|
+
document.body.style.setProperty('--mate-surround-dark', color.dark);
|
|
33
|
+
}
|
|
@@ -3,6 +3,7 @@ import { renderMarkdown, highlightCodeBlocks } from './markdown.js';
|
|
|
3
3
|
import { escapeHtml, copyToClipboard } from './utils.js';
|
|
4
4
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
5
5
|
import { store } from './store.js';
|
|
6
|
+
import { getProjectAssistantPlaceholder } from './project-chat-identity.js';
|
|
6
7
|
|
|
7
8
|
var ctx;
|
|
8
9
|
|
|
@@ -311,10 +312,6 @@ function color_mix_lighten(r, g, b, amount) {
|
|
|
311
312
|
.map(function (v) { return v.toString(16).padStart(2, "0"); }).join("");
|
|
312
313
|
}
|
|
313
314
|
|
|
314
|
-
// Saved textarea placeholder so we can restore it when the chip is removed.
|
|
315
|
-
// Set on first chip show, cleared on chip removal.
|
|
316
|
-
var savedInputPlaceholder = null;
|
|
317
|
-
|
|
318
315
|
function showInputMentionChip(name, color, avatarSrc) {
|
|
319
316
|
removeInputMentionChip();
|
|
320
317
|
var textColor = ensureChipContrast(color);
|
|
@@ -333,13 +330,9 @@ function showInputMentionChip(name, color, avatarSrc) {
|
|
|
333
330
|
inputRow.insertBefore(chip, textareaWrap);
|
|
334
331
|
}
|
|
335
332
|
|
|
336
|
-
// Swap the textarea placeholder so the user sees "Ask @{name}..."
|
|
337
|
-
//
|
|
338
|
-
// is queued. Save the original once so re-shows don't clobber it.
|
|
333
|
+
// Swap the textarea placeholder so the user sees "Ask @{name}..." while a
|
|
334
|
+
// mention is queued. Restoration is handled only while this prompt owns it.
|
|
339
335
|
if (ctx && ctx.inputEl) {
|
|
340
|
-
if (savedInputPlaceholder === null) {
|
|
341
|
-
savedInputPlaceholder = ctx.inputEl.placeholder || "";
|
|
342
|
-
}
|
|
343
336
|
ctx.inputEl.placeholder = "Ask @" + name + "...";
|
|
344
337
|
}
|
|
345
338
|
|
|
@@ -353,9 +346,8 @@ function showInputMentionChip(name, color, avatarSrc) {
|
|
|
353
346
|
function removeInputMentionChip() {
|
|
354
347
|
var existing = document.getElementById("input-mention-chip");
|
|
355
348
|
if (existing) existing.remove();
|
|
356
|
-
if (ctx && ctx.inputEl &&
|
|
357
|
-
ctx.inputEl.placeholder =
|
|
358
|
-
savedInputPlaceholder = null;
|
|
349
|
+
if (existing && ctx && ctx.inputEl && !ctx.inputEl.disabled && /^Ask @/.test(ctx.inputEl.placeholder || "")) {
|
|
350
|
+
ctx.inputEl.placeholder = getProjectAssistantPlaceholder(store.snap(), store.get('currentVendor'));
|
|
359
351
|
}
|
|
360
352
|
}
|
|
361
353
|
|
|
@@ -84,6 +84,44 @@ export function applyToIsland() {
|
|
|
84
84
|
ctaEl.classList.add('hidden');
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
document.dispatchEvent(new CustomEvent('clay:profile-updated'));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function updateProfileName(name) {
|
|
91
|
+
profile.name = String(name || '').trim();
|
|
92
|
+
applyToIsland();
|
|
93
|
+
debouncedSave();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function usePixelAvatar() {
|
|
97
|
+
profile.avatarCustom = '';
|
|
98
|
+
applyToIsland();
|
|
99
|
+
debouncedSave();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function regenerateProfileAvatar() {
|
|
103
|
+
profile.avatarCustom = '';
|
|
104
|
+
profile.avatarSeed = 'clay-' + Date.now();
|
|
105
|
+
applyToIsland();
|
|
106
|
+
debouncedSave();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function uploadAvatarBlob(blob) {
|
|
110
|
+
if (!blob) return Promise.reject(new Error('Missing avatar image.'));
|
|
111
|
+
return blob.arrayBuffer().then(function(ab) {
|
|
112
|
+
var buf = new Uint8Array(ab);
|
|
113
|
+
return fetch('/api/avatar', {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers: { 'Content-Type': 'application/octet-stream' },
|
|
116
|
+
body: buf,
|
|
117
|
+
});
|
|
118
|
+
}).then(function(r) { return r.json(); }).then(function(data) {
|
|
119
|
+
if (!data.ok || !data.avatar) throw new Error(data.error || 'Avatar upload failed.');
|
|
120
|
+
profile.avatarCustom = data.avatar;
|
|
121
|
+
applyToIsland();
|
|
122
|
+
debouncedSave();
|
|
123
|
+
return data;
|
|
124
|
+
});
|
|
87
125
|
}
|
|
88
126
|
|
|
89
127
|
// --- Avatar position picker ---
|
|
@@ -128,6 +166,8 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
128
166
|
|
|
129
167
|
var closeBtn = document.createElement('button');
|
|
130
168
|
closeBtn.className = 'avatar-positioner-close';
|
|
169
|
+
closeBtn.type = 'button';
|
|
170
|
+
closeBtn.setAttribute('aria-label', 'Close avatar crop editor');
|
|
131
171
|
closeBtn.innerHTML = '×';
|
|
132
172
|
container.appendChild(closeBtn);
|
|
133
173
|
|
|
@@ -239,12 +279,21 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
239
279
|
}, { passive: false });
|
|
240
280
|
|
|
241
281
|
function cleanup(revoke) {
|
|
282
|
+
document.removeEventListener('keydown', onOverlayKeydown);
|
|
242
283
|
overlay.remove();
|
|
243
284
|
if (revoke) URL.revokeObjectURL(objectUrl);
|
|
244
285
|
}
|
|
245
286
|
|
|
287
|
+
function onOverlayKeydown(event) {
|
|
288
|
+
if (event.key !== 'Escape') return;
|
|
289
|
+
event.preventDefault();
|
|
290
|
+
event.stopPropagation();
|
|
291
|
+
cleanup(true);
|
|
292
|
+
}
|
|
293
|
+
|
|
246
294
|
closeBtn.addEventListener('click', function() { cleanup(true); });
|
|
247
295
|
cancelBtn.addEventListener('click', function() { cleanup(true); });
|
|
296
|
+
document.addEventListener('keydown', onOverlayKeydown);
|
|
248
297
|
|
|
249
298
|
doneBtn.addEventListener('click', function() {
|
|
250
299
|
// Render cropped area to canvas
|
|
@@ -269,7 +318,7 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
|
|
|
269
318
|
}
|
|
270
319
|
|
|
271
320
|
// --- Popover ---
|
|
272
|
-
function
|
|
321
|
+
export function openProfileEditor() {
|
|
273
322
|
if (popoverEl) {
|
|
274
323
|
hidePopover();
|
|
275
324
|
return;
|
|
@@ -286,7 +335,7 @@ function showPopover() {
|
|
|
286
335
|
|
|
287
336
|
// Banner + close
|
|
288
337
|
html += '<div class="profile-banner">';
|
|
289
|
-
html += '<button class="profile-close-btn">×</button>';
|
|
338
|
+
html += '<button class="profile-close-btn" type="button" aria-label="Close profile editor">×</button>';
|
|
290
339
|
html += '</div>';
|
|
291
340
|
|
|
292
341
|
// Avatar row (overlapping banner)
|
|
@@ -485,22 +534,6 @@ export function initProfile(_ctx) {
|
|
|
485
534
|
var island = document.getElementById('user-island');
|
|
486
535
|
if (!island) return;
|
|
487
536
|
|
|
488
|
-
var profileArea = island.querySelector('.user-island-profile');
|
|
489
|
-
if (profileArea) {
|
|
490
|
-
profileArea.addEventListener('click', function(e) {
|
|
491
|
-
e.stopPropagation();
|
|
492
|
-
showPopover();
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
var ctaEl = island.querySelector('.user-island-cta');
|
|
497
|
-
if (ctaEl) {
|
|
498
|
-
ctaEl.addEventListener('click', function(e) {
|
|
499
|
-
e.stopPropagation();
|
|
500
|
-
showPopover();
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
|
|
504
537
|
fetchProfile().then(function(data) {
|
|
505
538
|
if (data.name !== undefined) profile.name = data.name;
|
|
506
539
|
if (data.lang) profile.lang = data.lang;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Session-bound assistant identity for ordinary project and Mate transcripts.
|
|
2
|
+
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { mateAvatarUrl } from './avatar.js';
|
|
5
|
+
import { VENDOR_AVATARS, VENDOR_NAMES } from './chat-render-runtime.js';
|
|
6
|
+
|
|
7
|
+
function mateById(state, mateId) {
|
|
8
|
+
var mates = state.cachedMatesList || [];
|
|
9
|
+
for (var i = 0; i < mates.length; i++) {
|
|
10
|
+
if (mates[i] && mates[i].id === mateId) return mates[i];
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function mateName(mate, fallback) {
|
|
16
|
+
var profile = mate && mate.profile ? mate.profile : {};
|
|
17
|
+
return profile.displayName || (mate && (mate.displayName || mate.name)) || fallback || 'Mate';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolveProjectAssistantIdentity(state, vendor) {
|
|
21
|
+
state = state || store.snap();
|
|
22
|
+
var dmTarget = state.dmMode && state.dmTargetUser && state.dmTargetUser.isMate ? state.dmTargetUser : null;
|
|
23
|
+
var mateId = dmTarget ? dmTarget.id : state.activeSessionMateId;
|
|
24
|
+
if (mateId) {
|
|
25
|
+
var mate = mateById(state, mateId) || dmTarget;
|
|
26
|
+
var fallbackName = dmTarget && dmTarget.displayName || state.activeSessionMateName || 'Mate';
|
|
27
|
+
var avatarMate = mate || { id: mateId, name: fallbackName, profile: { displayName: fallbackName } };
|
|
28
|
+
return {
|
|
29
|
+
kind: 'mate',
|
|
30
|
+
mateId: mateId,
|
|
31
|
+
name: mateName(mate, fallbackName),
|
|
32
|
+
avatarUrl: mateAvatarUrl(avatarMate, 34),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
var vendorId = vendor || state.currentVendor || 'claude';
|
|
36
|
+
return {
|
|
37
|
+
kind: 'provider',
|
|
38
|
+
mateId: '',
|
|
39
|
+
name: VENDOR_NAMES[vendorId] || VENDOR_NAMES.claude,
|
|
40
|
+
avatarUrl: VENDOR_AVATARS[vendorId] || VENDOR_AVATARS.claude,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getProjectAssistantPlaceholder(state, vendor) {
|
|
45
|
+
return 'Message ' + resolveProjectAssistantIdentity(state, vendor).name + '...';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function applyProjectAssistantIdentity(element, identity) {
|
|
49
|
+
if (!element || !identity) return element;
|
|
50
|
+
var avatar = element.querySelector('.dm-bubble-avatar');
|
|
51
|
+
var name = element.querySelector('.dm-bubble-name');
|
|
52
|
+
if (avatar) avatar.src = identity.avatarUrl;
|
|
53
|
+
if (name) name.textContent = identity.name;
|
|
54
|
+
if (identity.kind === 'mate') {
|
|
55
|
+
element.dataset.sessionMateId = identity.mateId;
|
|
56
|
+
element.dataset.sessionMateName = identity.name;
|
|
57
|
+
} else {
|
|
58
|
+
delete element.dataset.sessionMateId;
|
|
59
|
+
delete element.dataset.sessionMateName;
|
|
60
|
+
}
|
|
61
|
+
return element;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function refreshProjectAssistantIdentities(root) {
|
|
65
|
+
var target = root || document;
|
|
66
|
+
var elements = target.querySelectorAll('[data-session-mate-id]');
|
|
67
|
+
var state = store.snap();
|
|
68
|
+
for (var i = 0; i < elements.length; i++) {
|
|
69
|
+
var mateId = elements[i].dataset.sessionMateId;
|
|
70
|
+
var mate = mateById(state, mateId);
|
|
71
|
+
if (!mate) continue;
|
|
72
|
+
applyProjectAssistantIdentity(elements[i], {
|
|
73
|
+
kind: 'mate',
|
|
74
|
+
mateId: mateId,
|
|
75
|
+
name: mateName(mate, elements[i].dataset.sessionMateName || 'Mate'),
|
|
76
|
+
avatarUrl: mateAvatarUrl(mate, 34),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// Project-chat adapter for Clay's existing server-owned debate setup flow.
|
|
2
|
+
|
|
3
|
+
import { store } from './store.js';
|
|
4
|
+
import { getWs } from './ws-ref.js';
|
|
5
|
+
import { addToMessages, scrollToBottom } from './chat-render-runtime.js';
|
|
6
|
+
import { openMateWorkspace } from './project-mate-navigation.js';
|
|
7
|
+
import { createHomeDebateQuestionCard, createHomeDebateProposalCard, normalizeHomeTranscript, applyHomeDebateProposal, resolveHomeDebateProposal, failHomeDebateQuestion } from './home-debate-planning.js';
|
|
8
|
+
import { refreshIcons, iconHtml } from './icons.js';
|
|
9
|
+
|
|
10
|
+
var root = null;
|
|
11
|
+
var sequence = 0;
|
|
12
|
+
var liveReplaySessionId = null;
|
|
13
|
+
var suppressLiveSetupReplay = false;
|
|
14
|
+
|
|
15
|
+
function send(message) {
|
|
16
|
+
var ws = getWs();
|
|
17
|
+
if (!ws || ws.readyState !== 1) return false;
|
|
18
|
+
ws.send(JSON.stringify(message));
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function clayMate() {
|
|
23
|
+
var mates = store.get('cachedMatesList') || [];
|
|
24
|
+
for (var i = 0; i < mates.length; i++) if (mates[i] && mates[i].builtinKey === 'clay') return mates[i];
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function requestId() { sequence += 1; return 'project-debate-planning-' + Date.now() + '-' + sequence; }
|
|
29
|
+
function same(left, right) { return left != null && right != null && String(left) === String(right); }
|
|
30
|
+
|
|
31
|
+
function context() {
|
|
32
|
+
return { mateId: store.get('projectDebatePlanningMateId'), sessionId: store.get('projectDebatePlanningSessionId'), requestId: store.get('projectDebatePlanningRequestId') };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function messages() { return store.get('projectDebatePlanningMessages') || []; }
|
|
36
|
+
function setMessages(value) { store.set({ projectDebatePlanningMessages: value }); }
|
|
37
|
+
|
|
38
|
+
function retryPlanning() {
|
|
39
|
+
var state = store.snap();
|
|
40
|
+
store.set({ projectDebatePlanningError: '', projectDebatePlanningRetryable: false });
|
|
41
|
+
if (!state.projectDebatePlanningSessionId) {
|
|
42
|
+
store.set({ projectDebatePlanningPendingStart: true });
|
|
43
|
+
maybeStart();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
var id = requestId();
|
|
47
|
+
if (!send({ type: 'home_mate_debate_plan', mateId: state.projectDebatePlanningMateId, sessionId: state.projectDebatePlanningSessionId, topic: state.projectDebatePlanningTopic, requestId: id })) {
|
|
48
|
+
store.set({ projectDebatePlanningError: 'Reconnect to retry debate setup.', projectDebatePlanningRetryable: true });
|
|
49
|
+
render();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
store.set({ projectDebatePlanningRequestId: id, projectDebatePlanningAwaitingHistory: true });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ensureRoot() {
|
|
56
|
+
if (root && root.isConnected) return root;
|
|
57
|
+
root = document.createElement('section');
|
|
58
|
+
root.className = 'project-debate-planning-transcript home-mate-chat-transcript home-chat-bubble-layout';
|
|
59
|
+
root.setAttribute('aria-label', 'Debate setup');
|
|
60
|
+
addToMessages(root);
|
|
61
|
+
return root;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function respondToQuestion(message, action, opener, answers) {
|
|
65
|
+
if (!message || message.status === 'submitting') return;
|
|
66
|
+
if (!send(Object.assign({ type: 'home_debate_question_response', toolId: message.toolId, answers: answers || {} }, context()))) return;
|
|
67
|
+
setMessages(messages().map(function (item) { return item === message ? Object.assign({}, item, { status: 'submitting' }) : item; }));
|
|
68
|
+
render();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function respondToProposal(message, action, opener, answers, modelOverrides) {
|
|
72
|
+
if (!message || message.status === 'submitting') return;
|
|
73
|
+
if (!send(Object.assign({ type: 'home_debate_proposal_response', proposalId: message.proposal.proposalId, action: action === 'start' ? 'start' : 'cancel', modelOverrides: modelOverrides || [] }, context()))) return;
|
|
74
|
+
setMessages(messages().map(function (item) { return item === message ? Object.assign({}, item, { status: 'submitting' }) : item; }));
|
|
75
|
+
render();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function render() {
|
|
79
|
+
var container = ensureRoot();
|
|
80
|
+
container.innerHTML = '';
|
|
81
|
+
var intro = document.createElement('header');
|
|
82
|
+
intro.className = 'project-mate-creation-intro';
|
|
83
|
+
intro.innerHTML = iconHtml('messages-square') + '<span>Plan a debate with Clay</span>';
|
|
84
|
+
container.appendChild(intro);
|
|
85
|
+
var list = messages();
|
|
86
|
+
for (var i = 0; i < list.length; i++) {
|
|
87
|
+
if (list[i].role === 'question') container.appendChild(createHomeDebateQuestionCard(list[i], respondToQuestion));
|
|
88
|
+
if (list[i].role === 'proposal') container.appendChild(createHomeDebateProposalCard(list[i], respondToProposal));
|
|
89
|
+
}
|
|
90
|
+
var errorText = store.get('projectDebatePlanningError');
|
|
91
|
+
if (errorText) {
|
|
92
|
+
var error = document.createElement('section');
|
|
93
|
+
error.className = 'project-debate-planning-error';
|
|
94
|
+
error.setAttribute('role', 'alert');
|
|
95
|
+
var copy = document.createElement('p');
|
|
96
|
+
copy.textContent = errorText;
|
|
97
|
+
error.appendChild(copy);
|
|
98
|
+
if (store.get('projectDebatePlanningRetryable')) {
|
|
99
|
+
var retry = document.createElement('button');
|
|
100
|
+
retry.type = 'button';
|
|
101
|
+
retry.textContent = 'Retry debate setup';
|
|
102
|
+
retry.addEventListener('click', retryPlanning);
|
|
103
|
+
error.appendChild(retry);
|
|
104
|
+
}
|
|
105
|
+
container.appendChild(error);
|
|
106
|
+
}
|
|
107
|
+
scrollToBottom();
|
|
108
|
+
refreshIcons();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function clear() {
|
|
112
|
+
root = null;
|
|
113
|
+
store.set({ projectDebatePlanningActive: false, projectDebatePlanningMateId: null, projectDebatePlanningSessionId: null, projectDebatePlanningLocalId: null, projectDebatePlanningRequestId: null, projectDebatePlanningPendingStart: false, projectDebatePlanningAwaitingHistory: false, projectDebatePlanningAwaitingMateList: false, projectDebatePlanningHistoryReady: false, projectDebatePlanningTopic: '', projectDebatePlanningMessages: [], projectDebatePlanningError: '', projectDebatePlanningRetryable: false });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function maybeStart() {
|
|
117
|
+
var state = store.snap();
|
|
118
|
+
if (!state.projectDebatePlanningPendingStart || !state.connected || state.activeProjectSlug !== 'mate-' + state.projectDebatePlanningMateId) return;
|
|
119
|
+
var id = requestId();
|
|
120
|
+
if (!send({ type: 'home_mate_debate_plan', mateId: state.projectDebatePlanningMateId, topic: state.projectDebatePlanningTopic, requestId: id })) return;
|
|
121
|
+
store.set({ projectDebatePlanningPendingStart: false, projectDebatePlanningAwaitingHistory: true, projectDebatePlanningRequestId: id });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function startProjectDebatePlanning(topic) {
|
|
125
|
+
var clay = clayMate();
|
|
126
|
+
if (!clay) {
|
|
127
|
+
store.set({ projectDebatePlanningError: 'Clay is unavailable. Refresh and try again.', projectDebatePlanningRetryable: false });
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
root = null;
|
|
131
|
+
store.set({ projectDebatePlanningActive: true, projectDebatePlanningMateId: clay.id, projectDebatePlanningSessionId: null, projectDebatePlanningLocalId: null, projectDebatePlanningRequestId: null, projectDebatePlanningPendingStart: true, projectDebatePlanningAwaitingHistory: false, projectDebatePlanningAwaitingMateList: false, projectDebatePlanningHistoryReady: false, projectDebatePlanningTopic: typeof topic === 'string' ? topic.trim().slice(0, 1000) : '', projectDebatePlanningMessages: [], projectDebatePlanningError: '', projectDebatePlanningRetryable: false });
|
|
132
|
+
openMateWorkspace(clay.id);
|
|
133
|
+
maybeStart();
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function exact(msg, allowUnbound) {
|
|
138
|
+
var state = store.snap();
|
|
139
|
+
if (!state.projectDebatePlanningActive || !same(msg.mateId, state.projectDebatePlanningMateId) || !same(msg.requestId, state.projectDebatePlanningRequestId)) return false;
|
|
140
|
+
if (!state.projectDebatePlanningSessionId) return allowUnbound === true;
|
|
141
|
+
return same(msg.sessionId, state.projectDebatePlanningSessionId);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function openHistory(msg) {
|
|
145
|
+
if (!exact(msg, store.get('projectDebatePlanningAwaitingHistory') && !store.get('projectDebatePlanningSessionId'))) return false;
|
|
146
|
+
store.set({ projectDebatePlanningSessionId: msg.sessionId, projectDebatePlanningLocalId: typeof msg.localId === 'number' ? msg.localId : store.get('projectDebatePlanningLocalId'), projectDebatePlanningAwaitingHistory: false });
|
|
147
|
+
if (typeof msg.localId === 'number' && String(store.get('activeSessionId')) !== String(msg.localId)) {
|
|
148
|
+
send({ type: 'switch_session', id: msg.localId });
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
setMessages(normalizeHomeTranscript(msg.messages || []).filter(function (message) { return message.role === 'question' || message.role === 'proposal'; }));
|
|
152
|
+
render();
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function resume() {
|
|
157
|
+
var state = store.snap();
|
|
158
|
+
if (!state.projectDebatePlanningActive || !state.projectDebatePlanningMateId || !state.projectDebatePlanningSessionId) return;
|
|
159
|
+
var id = requestId();
|
|
160
|
+
if (!send({ type: 'home_mate_session_open', mateId: state.projectDebatePlanningMateId, sessionId: state.projectDebatePlanningSessionId, requestId: id })) return;
|
|
161
|
+
store.set({ projectDebatePlanningRequestId: id, projectDebatePlanningAwaitingHistory: true });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function activateRestored(msg, clay) {
|
|
165
|
+
root = null;
|
|
166
|
+
store.set({ projectDebatePlanningActive: true, projectDebatePlanningMateId: clay.id, projectDebatePlanningSessionId: msg.cliSessionId || 'local:' + msg.id, projectDebatePlanningLocalId: msg.id, projectDebatePlanningRequestId: requestId(), projectDebatePlanningPendingStart: false, projectDebatePlanningAwaitingHistory: false, projectDebatePlanningAwaitingMateList: false, projectDebatePlanningHistoryReady: false, projectDebatePlanningTopic: '', projectDebatePlanningMessages: [] });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function restoreAfterMateList() {
|
|
170
|
+
var state = store.snap();
|
|
171
|
+
if (!state.projectDebatePlanningAwaitingMateList) return;
|
|
172
|
+
var clay = clayMate();
|
|
173
|
+
if (!clay || state.currentSlug !== 'mate-' + clay.id || state.projectDebatePlanningLocalId == null) return;
|
|
174
|
+
var historyReady = state.projectDebatePlanningHistoryReady;
|
|
175
|
+
activateRestored({ id: state.projectDebatePlanningLocalId, cliSessionId: state.projectDebatePlanningSessionId && state.projectDebatePlanningSessionId.indexOf('local:') !== 0 ? state.projectDebatePlanningSessionId : null }, clay);
|
|
176
|
+
if (historyReady) resume();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function handleProjectDebatePlanningMessage(msg) {
|
|
180
|
+
if (msg.type === 'session_switched') {
|
|
181
|
+
if (msg.debatePlanning === true && msg.debatePhase === 'live') {
|
|
182
|
+
clear();
|
|
183
|
+
liveReplaySessionId = msg.id;
|
|
184
|
+
suppressLiveSetupReplay = true;
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
liveReplaySessionId = null;
|
|
188
|
+
suppressLiveSetupReplay = false;
|
|
189
|
+
var clay = clayMate();
|
|
190
|
+
var state = store.snap();
|
|
191
|
+
var starting = msg.debatePlanning === true && state.projectDebatePlanningActive && state.projectDebatePlanningAwaitingHistory && !state.projectDebatePlanningSessionId && state.currentSlug === 'mate-' + state.projectDebatePlanningMateId;
|
|
192
|
+
if (starting) store.set({ projectDebatePlanningSessionId: msg.cliSessionId || 'local:' + msg.id, projectDebatePlanningLocalId: msg.id, projectDebatePlanningMessages: [] });
|
|
193
|
+
else if (msg.debatePlanning === true && clay && state.currentSlug === 'mate-' + clay.id) activateRestored(msg, clay);
|
|
194
|
+
else if (msg.debatePlanning === true && !clay && /^mate-/.test(state.currentSlug || '')) store.set({ projectDebatePlanningActive: false, projectDebatePlanningAwaitingMateList: true, projectDebatePlanningHistoryReady: false, projectDebatePlanningLocalId: msg.id, projectDebatePlanningSessionId: msg.cliSessionId || 'local:' + msg.id, projectDebatePlanningMessages: [] });
|
|
195
|
+
else if (!(state.projectDebatePlanningActive && (state.projectDebatePlanningPendingStart || state.projectDebatePlanningAwaitingHistory) && state.currentSlug === 'mate-' + state.projectDebatePlanningMateId && !state.projectDebatePlanningSessionId)) clear();
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (msg.type === 'home_mate_session_identity') {
|
|
199
|
+
var identityState = store.snap();
|
|
200
|
+
if (!identityState.projectDebatePlanningActive || !same(msg.mateId, identityState.projectDebatePlanningMateId) || !same(msg.requestId, identityState.projectDebatePlanningRequestId) || !same(msg.previousSessionId, identityState.projectDebatePlanningSessionId) || !msg.sessionId) return false;
|
|
201
|
+
store.set({ projectDebatePlanningSessionId: msg.sessionId });
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
if (msg.type === 'home_debate_event' && msg.eventType === 'debate_started') {
|
|
205
|
+
suppressLiveSetupReplay = false;
|
|
206
|
+
if (store.get('projectDebatePlanningActive')) clear();
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (msg.type === 'debate_started' && suppressLiveSetupReplay && same(store.get('activeSessionId'), liveReplaySessionId)) {
|
|
210
|
+
suppressLiveSetupReplay = false;
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
if (suppressLiveSetupReplay && same(store.get('activeSessionId'), liveReplaySessionId)
|
|
214
|
+
&& ((msg.type === 'tool_executing' && msg.name === 'AskUserQuestion') || msg.type === 'ask_user_answered'
|
|
215
|
+
|| msg.type === 'debate_proposal' || msg.type === 'debate_proposal_resolved' || msg.type === 'delta'
|
|
216
|
+
|| msg.type === 'result' || msg.type === 'done' || msg.type === 'error')) return true;
|
|
217
|
+
if (msg.type === 'history_done') {
|
|
218
|
+
if (store.get('projectDebatePlanningAwaitingMateList')) store.set({ projectDebatePlanningHistoryReady: true });
|
|
219
|
+
else if (!store.get('projectDebatePlanningAwaitingHistory')) resume();
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
var raw = (msg.type === 'tool_executing' && msg.name === 'AskUserQuestion') || msg.type === 'debate_proposal' || msg.type === 'debate_proposal_resolved' || msg.type === 'ask_user_answered' || msg.type === 'delta' || msg.type === 'result' || msg.type === 'done' || msg.type === 'error' || msg.type === 'home_mate_delta' || msg.type === 'home_mate_done';
|
|
223
|
+
if (raw && store.get('projectDebatePlanningAwaitingMateList')) return same(store.get('activeSessionId'), store.get('projectDebatePlanningLocalId'));
|
|
224
|
+
if (!store.get('projectDebatePlanningActive')) return false;
|
|
225
|
+
if (msg.type === 'home_mate_history' && msg.debatePlanning === true) return openHistory(msg);
|
|
226
|
+
if (raw) return same(store.get('activeSessionId'), store.get('projectDebatePlanningLocalId'));
|
|
227
|
+
if (!exact(msg, msg.type === 'home_mate_error' && store.get('projectDebatePlanningAwaitingHistory'))) return false;
|
|
228
|
+
if (msg.type === 'home_debate_question') {
|
|
229
|
+
setMessages(messages().concat([{ role: 'question', flow: 'debate', toolId: msg.toolId, questions: msg.questions || [], status: 'pending', error: '' }])); render(); return true;
|
|
230
|
+
}
|
|
231
|
+
if (msg.type === 'home_debate_question_resolved') {
|
|
232
|
+
setMessages(messages().map(function (item) { return item.role === 'question' && item.toolId === msg.toolId ? Object.assign({}, item, { status: msg.status === 'answered' ? 'answered' : 'expired', answers: msg.answers || null, error: msg.error || '' }) : item; })); render(); return true;
|
|
233
|
+
}
|
|
234
|
+
if (msg.type === 'home_debate_proposal') { setMessages(applyHomeDebateProposal(messages(), msg)); render(); return true; }
|
|
235
|
+
if (msg.type === 'home_debate_proposal_resolved') { setMessages(resolveHomeDebateProposal(messages(), msg)); render(); return true; }
|
|
236
|
+
if (msg.type === 'home_mate_error') {
|
|
237
|
+
if (/^question_/.test(msg.code || '')) setMessages(failHomeDebateQuestion(messages(), msg));
|
|
238
|
+
else store.set({ projectDebatePlanningError: msg.text || 'Debate setup could not continue.', projectDebatePlanningRetryable: true, projectDebatePlanningAwaitingHistory: false });
|
|
239
|
+
render();
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function initProjectDebatePlanningWorkspace() {
|
|
246
|
+
store.subscribe(function (state, previous) {
|
|
247
|
+
if (state.projectDebatePlanningPendingStart !== previous.projectDebatePlanningPendingStart || state.connected !== previous.connected || state.activeProjectSlug !== previous.activeProjectSlug) maybeStart();
|
|
248
|
+
if (state.cachedMatesList !== previous.cachedMatesList) restoreAfterMateList();
|
|
249
|
+
});
|
|
250
|
+
}
|