clay-server 5.1.0-beta.1 → 5.1.0-beta.3
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/bin/cli.js +9 -91
- package/lib/builtin-mates.js +7 -7
- package/lib/daemon-project-access.js +7 -1
- package/lib/daemon-settings.js +11 -0
- package/lib/daemon.js +10 -37
- 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/linear-store.js +35 -8
- package/lib/mate-identity-file.js +39 -0
- package/lib/mate-knowledge-mcp-server.js +29 -6
- package/lib/mate-knowledge-service.js +23 -2
- package/lib/mate-knowledge-sync.js +37 -22
- package/lib/mate-ready-creation.js +2 -1
- package/lib/mate-workspace-color.js +4 -0
- package/lib/mates-identity.js +4 -4
- package/lib/mates-prompts.js +4 -3
- package/lib/mates.js +30 -11
- package/lib/os-users.js +5 -16
- package/lib/project-connection.js +36 -9
- package/lib/project-debate-proposal.js +6 -0
- package/lib/project-debate-workspace.js +43 -0
- package/lib/project-debate.js +4 -2
- package/lib/project-filesystem.js +21 -39
- package/lib/project-knowledge.js +315 -136
- package/lib/project-mate-creation-proposal.js +1 -0
- package/lib/project-mate-interaction.js +7 -6
- package/lib/project-server-settings.js +31 -0
- package/lib/project-sessions.js +92 -182
- package/lib/project-user-knowledge.js +60 -0
- package/lib/project.js +62 -21
- package/lib/public/app.js +79 -71
- 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/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/input.css +3 -1
- 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/menus.css +3 -0
- package/lib/public/css/messages.css +1 -114
- package/lib/public/css/mobile-nav.css +16 -16
- package/lib/public/css/overlays.css +15 -0
- package/lib/public/css/project-logs.css +7 -0
- package/lib/public/css/project-mate-creation.css +105 -0
- package/lib/public/css/project-settings-modal.css +56 -0
- package/lib/public/css/right-workbench.css +3 -3
- package/lib/public/css/server-settings-system.css +125 -0
- package/lib/public/css/session-folders.css +80 -21
- package/lib/public/css/session-github.css +25 -16
- package/lib/public/css/settings-ui.css +247 -22
- package/lib/public/css/shared-browser.css +7 -3
- package/lib/public/css/sidebar.css +183 -107
- package/lib/public/css/title-bar.css +156 -1
- 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 +206 -548
- package/lib/public/modules/account-island.js +232 -0
- package/lib/public/modules/admin-settings-email.js +197 -0
- package/lib/public/modules/admin-settings-invitations.js +183 -0
- package/lib/public/modules/admin-settings-projects.js +198 -0
- package/lib/public/modules/admin-settings-ui.js +100 -0
- package/lib/public/modules/admin-settings-users.js +331 -0
- package/lib/public/modules/admin.js +19 -949
- package/lib/public/modules/app-cursors.js +19 -43
- package/lib/public/modules/app-debate-ui.js +4 -3
- package/lib/public/modules/app-dm.js +0 -2
- 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 +47 -61
- package/lib/public/modules/app-notifications.js +4 -7
- package/lib/public/modules/app-projects.js +5 -38
- package/lib/public/modules/app-rate-limit.js +70 -12
- package/lib/public/modules/app-rendering.js +12 -13
- package/lib/public/modules/avatar.js +30 -9
- package/lib/public/modules/chat-render-runtime.js +16 -4
- package/lib/public/modules/command-palette.js +2 -15
- package/lib/public/modules/context-sources.js +27 -18
- 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 +88 -65
- package/lib/public/modules/header-tui-font.js +10 -20
- 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/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/linear-settings.js +3 -2
- package/lib/public/modules/markdown.js +5 -6
- 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/notification-settings.js +81 -0
- package/lib/public/modules/notifications.js +44 -28
- package/lib/public/modules/personal-settings-dialog.js +51 -0
- package/lib/public/modules/profile.js +66 -24
- 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-settings-environment.js +106 -0
- package/lib/public/modules/project-settings.js +72 -628
- 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/server-settings-controls.js +316 -0
- package/lib/public/modules/server-settings-environment.js +194 -0
- package/lib/public/modules/server-settings-navigation.js +39 -0
- package/lib/public/modules/server-settings-state.js +54 -0
- package/lib/public/modules/server-settings.js +116 -788
- package/lib/public/modules/server-storage-settings.js +84 -0
- 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-github.js +2 -1
- package/lib/public/modules/session-list-visibility.js +41 -0
- package/lib/public/modules/session-presence-ui.js +3 -0
- package/lib/public/modules/session-title-marquee.js +51 -0
- package/lib/public/modules/settings-env-values.js +34 -0
- package/lib/public/modules/settings-select.js +121 -0
- package/lib/public/modules/shared-browser.js +22 -12
- 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/stt-picker.js +14 -5
- package/lib/public/modules/terminal-prefs.js +22 -0
- package/lib/public/modules/theme.js +88 -52
- 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/user-settings-account.js +318 -0
- package/lib/public/modules/user-settings-appearance.js +55 -0
- package/lib/public/modules/user-settings-editors.js +24 -0
- package/lib/public/modules/user-settings-integrations.js +104 -0
- package/lib/public/modules/user-settings-layout.js +80 -0
- package/lib/public/modules/user-settings-preferences.js +48 -0
- package/lib/public/modules/user-settings-profile.js +53 -0
- package/lib/public/modules/user-settings-themes.js +38 -0
- package/lib/public/modules/user-settings-voice.js +75 -0
- package/lib/public/modules/user-settings.js +53 -480
- 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 +20 -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/sdk-message-processor.js +16 -4
- package/lib/sdk-quota-snapshot.js +37 -0
- package/lib/server-admin.js +11 -0
- package/lib/server-appearance-settings.js +71 -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-linear.js +14 -8
- package/lib/server-mate-instructions.js +44 -0
- package/lib/server-mates.js +14 -4
- package/lib/server-notification-settings.js +67 -0
- package/lib/server-palette.js +1 -1
- package/lib/server-settings.js +69 -1
- package/lib/server-storage.js +57 -0
- package/lib/server-user-knowledge.js +119 -0
- package/lib/server.js +31 -3
- package/lib/session-visibility.js +7 -2
- package/lib/sessions.js +35 -10
- package/lib/startup-projects.js +40 -0
- package/lib/storage-native-walk.js +85 -0
- package/lib/storage-usage.js +144 -0
- package/lib/user-knowledge-service.js +167 -0
- package/lib/users-permissions.js +7 -0
- package/lib/users-preferences.js +0 -74
- package/lib/users-project-mate-filter-preferences.js +39 -0
- package/lib/users.js +6 -4
- package/lib/workspace-query-access.js +4 -1
- package/lib/ws-schema.js +52 -4
- package/lib/yoke/acp-process-manager.js +2 -2
- package/lib/yoke/adapters/codex.js +12 -52
- package/lib/yoke/codex-app-server.js +2 -2
- package/lib/yoke/codex-model-catalog.js +52 -0
- package/lib/yoke/codex-rate-limits.js +26 -0
- package/package.json +12 -3
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
// Centered General/Model/
|
|
1
|
+
// Centered General/Model/Prompt settings dialog.
|
|
2
2
|
|
|
3
|
+
import { renderMateColorPicker, resetMateColor, mateColorSaving, applyMateColorResult } from './home-mate-color-picker.js';
|
|
4
|
+
import { resetMateProfile, hasMateProfileDraft, mateProfileSaving, applyMateProfile, renderMateProfile } from './home-mate-profile-editor.js';
|
|
5
|
+
import { showConfirm } from './app-misc.js';
|
|
6
|
+
import { resetMateInstructions, loadMateInstructions, renderMateInstructions, applyMateInstructions, hasMateInstructionDraft } from './home-mate-instructions.js';
|
|
3
7
|
import { store } from './store.js';
|
|
4
8
|
import { getWs } from './ws-ref.js';
|
|
5
9
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
10
|
+
import { confirmMateRemoval } from './mate-management.js';
|
|
11
|
+
import { renderHomeMateAvatarEditor, confirmHomeMateAvatar, failHomeMateAvatar, clearHomeMateAvatarEditor } from './home-mate-avatar-editor.js';
|
|
12
|
+
import { resetHomeMateModelPicker, clearHomeMateModelPicker, hasHomeMateModelDraft, requestHomeMateModels, renderHomeMateModelPicker, applyHomeMateModelsState, applyHomeMateModelResult } from './home-mate-model-picker.js';
|
|
8
13
|
|
|
9
14
|
var dialog = null;
|
|
10
15
|
var dialogOpener = null;
|
|
@@ -52,31 +57,7 @@ function setTransientDrawerMask(masked) {
|
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
function focusableElements(root) {
|
|
55
|
-
return root ? root.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])') : [];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function restoreModelFocusAfterRender() {
|
|
59
|
-
var active = document.activeElement;
|
|
60
|
-
var focusedModel = active && active.dataset ? active.dataset.homeMateModel : null;
|
|
61
|
-
var focusedVendor = active && active.dataset ? active.dataset.homeMateVendor : null;
|
|
62
|
-
var focusedControl = active && active.dataset ? active.dataset.homeModelFocus : null;
|
|
63
|
-
return function () {
|
|
64
|
-
if (!dialog) return;
|
|
65
|
-
var selectors = [
|
|
66
|
-
{ selector: "[data-home-mate-model]", key: "homeMateModel", value: focusedModel },
|
|
67
|
-
{ selector: "[data-home-mate-vendor]", key: "homeMateVendor", value: focusedVendor },
|
|
68
|
-
{ selector: "[data-home-model-focus]", key: "homeModelFocus", value: focusedControl },
|
|
69
|
-
];
|
|
70
|
-
for (var i = 0; i < selectors.length; i++) {
|
|
71
|
-
if (!selectors[i].value) continue;
|
|
72
|
-
var nodes = dialog.querySelectorAll(selectors[i].selector);
|
|
73
|
-
for (var j = 0; j < nodes.length; j++) {
|
|
74
|
-
if (nodes[j].dataset[selectors[i].key] !== selectors[i].value) continue;
|
|
75
|
-
nodes[j].focus({ preventScroll: true });
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
};
|
|
60
|
+
return root ? Array.from(root.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(function (el) { return el.getClientRects().length && el.tabIndex >= 0; }) : [];
|
|
80
61
|
}
|
|
81
62
|
|
|
82
63
|
function addEmpty(container, text) {
|
|
@@ -87,30 +68,30 @@ function addEmpty(container, text) {
|
|
|
87
68
|
}
|
|
88
69
|
|
|
89
70
|
function renderGeneral(body, mate) {
|
|
90
|
-
var
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
71
|
+
var description = document.createElement("p");
|
|
72
|
+
description.className = "mate-settings-help";
|
|
73
|
+
description.textContent = "Manage " + getMateName(mate) + "’s identity and appearance.";
|
|
74
|
+
body.appendChild(description);
|
|
75
|
+
renderMateProfile(body, mate, renderDialogContent, function () {
|
|
76
|
+
store.set({mateSettingsAvatarOpen: !store.get('mateSettingsAvatarOpen')});
|
|
77
|
+
renderDialogContent();
|
|
78
|
+
});
|
|
79
|
+
if (store.get('mateSettingsAvatarOpen')) {
|
|
80
|
+
var appearance = document.createElement("section");
|
|
81
|
+
appearance.className = "mate-settings-appearance";
|
|
82
|
+
renderHomeMateAvatarEditor(appearance, mate, renderDialogContent);
|
|
83
|
+
var done = document.createElement('button'); done.type = 'button'; done.className = 'mate-settings-button'; done.textContent = 'Done';
|
|
84
|
+
done.addEventListener('click',function () { store.set({mateSettingsAvatarOpen:false}); renderDialogContent(); document.getElementById('mate-profile-avatar').focus(); });
|
|
85
|
+
appearance.appendChild(done);
|
|
86
|
+
body.appendChild(appearance);
|
|
87
|
+
}
|
|
88
|
+
renderMateColorPicker(body, mate, renderDialogContent);
|
|
103
89
|
if (!mate || mate.primary) {
|
|
104
|
-
addEmpty(body, "
|
|
90
|
+
addEmpty(body, "Clay manages this Mate’s core profile.");
|
|
105
91
|
return;
|
|
106
92
|
}
|
|
107
93
|
var actions = document.createElement("div");
|
|
108
94
|
actions.className = "home-mate-settings-actions";
|
|
109
|
-
var edit = document.createElement("button");
|
|
110
|
-
edit.type = "button";
|
|
111
|
-
edit.className = "home-mate-settings-action";
|
|
112
|
-
edit.innerHTML = iconHtml("edit-2") + "<span>Edit profile</span>";
|
|
113
|
-
edit.addEventListener("click", function () { editMateProfile(edit, mate); });
|
|
114
95
|
var remove = document.createElement("button");
|
|
115
96
|
remove.type = "button";
|
|
116
97
|
remove.className = "home-mate-settings-action is-danger";
|
|
@@ -119,90 +100,46 @@ function renderGeneral(body, mate) {
|
|
|
119
100
|
removeLabel.textContent = mate.builtinKey ? "Remove Mate" : "Delete Mate";
|
|
120
101
|
remove.appendChild(removeLabel);
|
|
121
102
|
remove.addEventListener("click", function () { confirmMateRemoval(remove, mate, closeHomeMateSettings); });
|
|
122
|
-
|
|
103
|
+
var dangerCopy = document.createElement("div");
|
|
104
|
+
dangerCopy.className = "mate-settings-danger-copy";
|
|
105
|
+
dangerCopy.innerHTML = "<h4>Danger zone</h4><p>Permanently delete this Mate and its workspace data. This cannot be undone.</p>";
|
|
106
|
+
actions.appendChild(dangerCopy);
|
|
123
107
|
actions.appendChild(remove);
|
|
124
108
|
body.appendChild(actions);
|
|
125
109
|
}
|
|
126
110
|
|
|
127
|
-
function renderMemory(body) {
|
|
128
|
-
if (!memoryState) {
|
|
129
|
-
addEmpty(body, "Loading memory…");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (memoryState.summary) {
|
|
133
|
-
var summary = document.createElement("section");
|
|
134
|
-
summary.className = "home-mate-settings-summary";
|
|
135
|
-
var heading = document.createElement("h3");
|
|
136
|
-
heading.textContent = "Working summary";
|
|
137
|
-
var text = document.createElement("p");
|
|
138
|
-
text.textContent = memoryState.summary;
|
|
139
|
-
summary.appendChild(heading);
|
|
140
|
-
summary.appendChild(text);
|
|
141
|
-
body.appendChild(summary);
|
|
142
|
-
}
|
|
143
|
-
var entries = memoryState.entries || [];
|
|
144
|
-
for (var i = 0; i < entries.length; i++) {
|
|
145
|
-
var item = document.createElement("article");
|
|
146
|
-
item.className = "home-mate-settings-memory";
|
|
147
|
-
var title = document.createElement("h3");
|
|
148
|
-
title.textContent = entries[i].topic || entries[i].date || "Memory";
|
|
149
|
-
var detail = document.createElement("p");
|
|
150
|
-
detail.textContent = entries[i].my_position || entries[i].decisions || entries[i].outcome || "";
|
|
151
|
-
item.appendChild(title);
|
|
152
|
-
if (detail.textContent) item.appendChild(detail);
|
|
153
|
-
body.appendChild(item);
|
|
154
|
-
}
|
|
155
|
-
if (!memoryState.summary && !entries.length) addEmpty(body, "No memories yet.");
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function renderKnowledge(body) {
|
|
159
|
-
if (!knowledgeState) {
|
|
160
|
-
addEmpty(body, "Loading knowledge…");
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
var files = knowledgeState.files || [];
|
|
164
|
-
for (var i = 0; i < files.length; i++) {
|
|
165
|
-
var item = document.createElement("div");
|
|
166
|
-
item.className = "home-mate-settings-file";
|
|
167
|
-
item.innerHTML = iconHtml("file-text");
|
|
168
|
-
var name = document.createElement("span");
|
|
169
|
-
name.textContent = typeof files[i] === "string" ? files[i] : files[i].name || "Untitled";
|
|
170
|
-
item.appendChild(name);
|
|
171
|
-
body.appendChild(item);
|
|
172
|
-
}
|
|
173
|
-
if (!files.length) addEmpty(body, "No knowledge files yet.");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
111
|
function requestSection(section) {
|
|
177
112
|
if (section === "model" && !modelRequested) {
|
|
178
113
|
modelRequested = true;
|
|
179
|
-
|
|
180
|
-
requestHomeMateModels((mate || {}).vendor || "", renderDialogContent, false);
|
|
181
|
-
}
|
|
182
|
-
if (section === "memory") {
|
|
183
|
-
memoryState = null;
|
|
184
|
-
memoryRequestId = nextRequestId("memory");
|
|
185
|
-
send({ type: "home_mate_memory_list", mateId: dialogMateId, requestId: memoryRequestId });
|
|
186
|
-
}
|
|
187
|
-
if (section === "knowledge") {
|
|
188
|
-
knowledgeState = null;
|
|
189
|
-
knowledgeRequestId = nextRequestId("knowledge");
|
|
190
|
-
send({ type: "home_mate_knowledge_list", mateId: dialogMateId, requestId: knowledgeRequestId });
|
|
114
|
+
requestHomeMateModels((getMate(dialogMateId) || {}).vendor || "", renderDialogContent);
|
|
191
115
|
}
|
|
192
116
|
}
|
|
193
117
|
|
|
118
|
+
function savePending() {
|
|
119
|
+
var prompt = store.get('mateInstructionsDraft');
|
|
120
|
+
var model = store.get('mateModelDraft');
|
|
121
|
+
return mateColorSaving() || mateProfileSaving() || !!((prompt && prompt.status === 'saving') || (model && model.saveId));
|
|
122
|
+
}
|
|
123
|
+
|
|
194
124
|
function renderDialogContent() {
|
|
195
125
|
if (!dialog) return;
|
|
126
|
+
dialog.dataset.section = dialogSection;
|
|
196
127
|
var body = dialog.querySelector(".home-mate-settings-body");
|
|
197
128
|
if (!body) return;
|
|
129
|
+
var focus = document.activeElement;
|
|
130
|
+
var focusId = focus && focus.id;
|
|
131
|
+
var ownedFocus = focus && body.contains(focus);
|
|
132
|
+
var selection = focus && focus.tagName === 'TEXTAREA' ? [focus.selectionStart, focus.selectionEnd] : null;
|
|
133
|
+
var scroll = body.parentElement.scrollTop;
|
|
134
|
+
var expanded = body.querySelector('.mate-settings-appearance');
|
|
135
|
+
var appearanceOpen = expanded && expanded.open;
|
|
198
136
|
body.innerHTML = "";
|
|
199
137
|
var mate = getMate(dialogMateId);
|
|
200
138
|
var contentTitle = dialog.querySelector(".home-mate-settings-content-title");
|
|
201
|
-
if (contentTitle) contentTitle.textContent = dialogSection.charAt(0).toUpperCase() + dialogSection.slice(1)
|
|
139
|
+
if (contentTitle) contentTitle.textContent = dialogSection.charAt(0).toUpperCase() + dialogSection.slice(1);
|
|
202
140
|
if (dialogSection === "general") renderGeneral(body, mate);
|
|
203
141
|
else if (dialogSection === "model") renderHomeMateModelPicker(body, renderDialogContent);
|
|
204
|
-
else
|
|
205
|
-
else renderKnowledge(body);
|
|
142
|
+
else renderMateInstructions(body, renderDialogContent);
|
|
206
143
|
var nav = dialog.querySelectorAll("[data-home-mate-settings-section]");
|
|
207
144
|
for (var i = 0; i < nav.length; i++) {
|
|
208
145
|
var active = nav[i].dataset.homeMateSettingsSection === dialogSection;
|
|
@@ -211,10 +148,22 @@ function renderDialogContent() {
|
|
|
211
148
|
else nav[i].removeAttribute("aria-current");
|
|
212
149
|
}
|
|
213
150
|
refreshIcons();
|
|
151
|
+
dialog.querySelector('.home-mate-settings-close').disabled = savePending();
|
|
152
|
+
var appearance = body.querySelector('.mate-settings-appearance');
|
|
153
|
+
if (appearance && appearanceOpen) appearance.open = true;
|
|
154
|
+
body.parentElement.scrollTop = scroll;
|
|
155
|
+
var nextFocus = focusId && document.getElementById(focusId);
|
|
156
|
+
if (nextFocus && !nextFocus.disabled) {
|
|
157
|
+
nextFocus.focus({preventScroll:true});
|
|
158
|
+
if (selection) nextFocus.setSelectionRange(selection[0], selection[1]);
|
|
159
|
+
} else if (ownedFocus) {
|
|
160
|
+
var fallback = body.querySelector('#mate-prompt-input:not(:disabled), #mate-settings-model-trigger:not(:disabled)') || contentTitle;
|
|
161
|
+
if (fallback) fallback.focus({preventScroll:true});
|
|
162
|
+
}
|
|
214
163
|
}
|
|
215
164
|
|
|
216
165
|
function selectSection(section, focusContent) {
|
|
217
|
-
if (section !== "general" && section !== "model" && section !== "
|
|
166
|
+
if (section !== "general" && section !== "model" && section !== "prompt") return;
|
|
218
167
|
dialogSection = section;
|
|
219
168
|
requestSection(section);
|
|
220
169
|
renderDialogContent();
|
|
@@ -227,6 +176,7 @@ function selectSection(section, focusContent) {
|
|
|
227
176
|
function handleDialogKeydown(event) {
|
|
228
177
|
if (!dialog) return;
|
|
229
178
|
if (document.querySelector(".profile-popover") || document.querySelector("#confirm-modal:not(.hidden)")) return;
|
|
179
|
+
if (event.target.closest && event.target.closest(".worker-runtime-options")) return;
|
|
230
180
|
if (event.key === "Escape") {
|
|
231
181
|
event.preventDefault();
|
|
232
182
|
event.stopPropagation();
|
|
@@ -247,7 +197,14 @@ function handleDialogKeydown(event) {
|
|
|
247
197
|
}
|
|
248
198
|
}
|
|
249
199
|
|
|
250
|
-
export function closeHomeMateSettings() {
|
|
200
|
+
export function closeHomeMateSettings(force) {
|
|
201
|
+
if (force !== true && savePending()) return false;
|
|
202
|
+
if (force !== true && (hasMateProfileDraft() || hasMateInstructionDraft() || hasHomeMateModelDraft())) {
|
|
203
|
+
var previous = document.activeElement;
|
|
204
|
+
showConfirm("Discard unsaved Mate settings?", function () { closeHomeMateSettings(true); }, "Discard changes", false, function () { if (previous && previous.isConnected) previous.focus(); });
|
|
205
|
+
document.getElementById("confirm-cancel").focus();
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
251
208
|
var opener = dialogOpener;
|
|
252
209
|
if (dialog) dialog.remove();
|
|
253
210
|
dialog = null;
|
|
@@ -258,7 +215,12 @@ export function closeHomeMateSettings() {
|
|
|
258
215
|
memoryState = null;
|
|
259
216
|
knowledgeState = null;
|
|
260
217
|
modelRequested = false;
|
|
218
|
+
store.set({mateSettingsAvatarOpen:false});
|
|
219
|
+
resetMateProfile();
|
|
220
|
+
resetMateColor();
|
|
261
221
|
clearHomeMateModelPicker();
|
|
222
|
+
resetMateInstructions(null);
|
|
223
|
+
clearHomeMateAvatarEditor();
|
|
262
224
|
document.removeEventListener("keydown", handleDialogKeydown, true);
|
|
263
225
|
document.body.classList.remove("home-mate-settings-open");
|
|
264
226
|
setTransientDrawerMask(false);
|
|
@@ -267,11 +229,16 @@ export function closeHomeMateSettings() {
|
|
|
267
229
|
|
|
268
230
|
export function openHomeMateSettings(mateId, opener, options) {
|
|
269
231
|
var mate = getMate(mateId);
|
|
270
|
-
if (!mate) return false;
|
|
271
|
-
|
|
232
|
+
if (!mate || (dialog && savePending())) return false;
|
|
233
|
+
if (dialog && (hasMateProfileDraft() || hasMateInstructionDraft() || hasHomeMateModelDraft())) {
|
|
234
|
+
showConfirm("Discard unsaved Mate settings?", function () { closeHomeMateSettings(true); openHomeMateSettings(mateId, opener, options); }, "Discard changes", false);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
closeHomeMateSettings(true);
|
|
238
|
+
resetMateInstructions(mateId);
|
|
272
239
|
dialogMateId = mateId;
|
|
273
240
|
dialogOpener = opener || document.activeElement;
|
|
274
|
-
dialogSection = options && options.section
|
|
241
|
+
dialogSection = options && ["model", "prompt"].indexOf(options.section) !== -1 ? options.section : "general";
|
|
275
242
|
modelRequested = false;
|
|
276
243
|
resetHomeMateModelPicker(mateId, getMateName(mate), mate, options && options.sessionId);
|
|
277
244
|
var overlay = document.createElement("div");
|
|
@@ -305,7 +272,7 @@ export function openHomeMateSettings(mateId, opener, options) {
|
|
|
305
272
|
var nav = document.createElement("nav");
|
|
306
273
|
nav.className = "home-mate-settings-nav";
|
|
307
274
|
nav.setAttribute("aria-label", "Mate settings sections");
|
|
308
|
-
var sections = ["general", "model", "
|
|
275
|
+
var sections = ["general", "model", "prompt"];
|
|
309
276
|
for (var i = 0; i < sections.length; i++) {
|
|
310
277
|
(function (section) {
|
|
311
278
|
var button = document.createElement("button");
|
|
@@ -319,7 +286,7 @@ export function openHomeMateSettings(mateId, opener, options) {
|
|
|
319
286
|
var content = document.createElement("section");
|
|
320
287
|
content.className = "home-mate-settings-content";
|
|
321
288
|
var contentTitle = document.createElement("h3");
|
|
322
|
-
contentTitle.className = "home-mate-settings-content-title
|
|
289
|
+
contentTitle.className = "home-mate-settings-content-title";
|
|
323
290
|
contentTitle.tabIndex = -1;
|
|
324
291
|
contentTitle.textContent = "Mate settings content";
|
|
325
292
|
var body = document.createElement("div");
|
|
@@ -339,6 +306,7 @@ export function openHomeMateSettings(mateId, opener, options) {
|
|
|
339
306
|
document.addEventListener("keydown", handleDialogKeydown, true);
|
|
340
307
|
renderDialogContent();
|
|
341
308
|
requestSection(dialogSection);
|
|
309
|
+
loadMateInstructions(renderDialogContent);
|
|
342
310
|
refreshIcons();
|
|
343
311
|
requestAnimationFrame(function () { close.focus({ preventScroll: true }); });
|
|
344
312
|
return true;
|
|
@@ -361,23 +329,48 @@ export function handleHomeMateKnowledgeState(msg) {
|
|
|
361
329
|
export function handleHomeMateModelsState(msg) {
|
|
362
330
|
if (!dialog || !applyHomeMateModelsState(msg)) return false;
|
|
363
331
|
if (dialogSection === "model") {
|
|
364
|
-
var restoreFocus = restoreModelFocusAfterRender();
|
|
365
332
|
renderDialogContent();
|
|
366
|
-
restoreFocus();
|
|
367
333
|
}
|
|
368
334
|
return true;
|
|
369
335
|
}
|
|
370
336
|
|
|
371
337
|
export function handleHomeMateModelResult(msg) {
|
|
372
338
|
if (!dialog || !applyHomeMateModelResult(msg)) return false;
|
|
339
|
+
if (msg.ok) {
|
|
340
|
+
var mates = store.get('cachedMatesList') || [];
|
|
341
|
+
store.set({ cachedMatesList: mates.map(function (mate) {
|
|
342
|
+
return mate && mate.id === msg.mateId ? Object.assign({}, mate, { vendor: msg.vendor, model: msg.model }) : mate;
|
|
343
|
+
}) });
|
|
344
|
+
}
|
|
373
345
|
if (dialogSection === "model") {
|
|
374
|
-
var restoreFocus = restoreModelFocusAfterRender();
|
|
375
346
|
renderDialogContent();
|
|
376
|
-
restoreFocus();
|
|
377
347
|
}
|
|
378
348
|
return true;
|
|
379
349
|
}
|
|
380
350
|
|
|
381
|
-
export function syncHomeMateSettingsTarget() {
|
|
382
|
-
if (
|
|
351
|
+
export function syncHomeMateSettingsTarget(msg) {
|
|
352
|
+
if (msg) { applyMateProfile(msg); applyMateColorResult(msg); }
|
|
353
|
+
if (!dialogMateId) return;
|
|
354
|
+
var mate = getMate(dialogMateId);
|
|
355
|
+
if (!mate) closeHomeMateSettings();
|
|
356
|
+
else {
|
|
357
|
+
confirmHomeMateAvatar(mate);
|
|
358
|
+
dialog.querySelector(".home-mate-settings-header span").textContent = getMateName(mate);
|
|
359
|
+
renderDialogContent();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export function handleHomeMateAvatarError(msg) {
|
|
364
|
+
if (!dialog || !msg) return false;
|
|
365
|
+
var colorHandled = applyMateColorResult(msg);
|
|
366
|
+
var profileHandled = applyMateProfile(msg);
|
|
367
|
+
if (!colorHandled && !profileHandled && !failHomeMateAvatar(msg.mateId, msg.error)) return false;
|
|
368
|
+
renderDialogContent();
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function handleMateInstructionsResult(msg) {
|
|
373
|
+
if (!dialog || !applyMateInstructions(msg)) return false;
|
|
374
|
+
if (dialogSection === 'prompt') renderDialogContent();
|
|
375
|
+
return true;
|
|
383
376
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Reversible project-chrome suppression for the home route.
|
|
2
|
+
import { store } from './store.js';
|
|
2
3
|
|
|
3
4
|
export function showHomeShell() {
|
|
4
5
|
document.body.classList.add("home-active");
|
|
6
|
+
store.set({ homeShellVisible: true });
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
export function hideHomeShell() {
|
|
8
10
|
document.body.classList.remove("home-active");
|
|
11
|
+
store.set({ homeShellVisible: false });
|
|
9
12
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// One-shot routing for a server-selected project or the no-project Home fallback.
|
|
2
2
|
import { store } from './store.js';
|
|
3
|
-
import { rememberHomePrimarySurface } from './home-surface.js';
|
|
4
3
|
|
|
5
4
|
var initialized = false;
|
|
6
5
|
var resolved = false;
|
|
@@ -17,12 +16,7 @@ export function resolveHomeBootDestination(options) {
|
|
|
17
16
|
// Home is entered only through an explicit in-app action; reloading `/`
|
|
18
17
|
// returns to the project workspace even if Home was the last open surface.
|
|
19
18
|
if (options.currentSlug) return "project";
|
|
20
|
-
if (options.surfaceLoaded !== true) return "wait";
|
|
21
19
|
if (options.projectsLoaded !== true) return "wait";
|
|
22
|
-
if (options.surface === "home") {
|
|
23
|
-
if (options.dockLoaded !== true) return "wait";
|
|
24
|
-
return "home";
|
|
25
|
-
}
|
|
26
20
|
return "projects";
|
|
27
21
|
}
|
|
28
22
|
|
|
@@ -50,7 +44,6 @@ function settleBoot(state) {
|
|
|
50
44
|
if (destination === "wait") return;
|
|
51
45
|
resolved = true;
|
|
52
46
|
if (destination === "project") {
|
|
53
|
-
rememberHomePrimarySurface("project");
|
|
54
47
|
if (!explicitProjectPath(location.pathname)) {
|
|
55
48
|
var route = projectRoute(state.currentSlug);
|
|
56
49
|
if (route) history.replaceState(null, "", route);
|
|
@@ -61,8 +54,7 @@ function settleBoot(state) {
|
|
|
61
54
|
if (input && !input.disabled) input.focus({ preventScroll: true });
|
|
62
55
|
return;
|
|
63
56
|
}
|
|
64
|
-
|
|
65
|
-
else store.set({ homeSurfaceBootResolved: true, homeSurfaceRestoreRequested: true });
|
|
57
|
+
store.set({ homeSurfaceBootResolved: true, projectsHubRestoreRequested: true });
|
|
66
58
|
finishPendingShell();
|
|
67
59
|
}
|
|
68
60
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Singleton tooltip controller for the compact project strip.
|
|
2
|
+
// Accessible trigger labels remain on the trigger; visible tooltip metadata is
|
|
3
|
+
// explicit so names containing commas are never parsed as status copy.
|
|
4
|
+
|
|
5
|
+
var iconStripTooltip = null;
|
|
6
|
+
|
|
7
|
+
function tooltipMetadata(value) {
|
|
8
|
+
if (typeof value === "string") return { text: value };
|
|
9
|
+
return value && typeof value === "object" ? value : { text: "" };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function hideIconTooltip() {
|
|
13
|
+
if (!iconStripTooltip) return;
|
|
14
|
+
iconStripTooltip.remove();
|
|
15
|
+
iconStripTooltip = null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function showIconTooltip(el, text, options) {
|
|
19
|
+
hideIconTooltip();
|
|
20
|
+
var metadata = Object.assign({ text: text || "" }, options || {});
|
|
21
|
+
var tip = document.createElement("div");
|
|
22
|
+
tip.className = "icon-strip-tooltip";
|
|
23
|
+
tip.setAttribute("role", "tooltip");
|
|
24
|
+
tip.dataset.tooltipKind = metadata.kind || "project";
|
|
25
|
+
if (metadata.kind === "mate") {
|
|
26
|
+
tip.classList.add("icon-strip-tooltip-mate");
|
|
27
|
+
var identity = document.createElement("span");
|
|
28
|
+
identity.className = "icon-strip-tooltip-mate-identity";
|
|
29
|
+
var avatar = document.createElement("img");
|
|
30
|
+
avatar.className = "icon-strip-tooltip-mate-avatar";
|
|
31
|
+
avatar.alt = "";
|
|
32
|
+
avatar.draggable = false;
|
|
33
|
+
avatar.src = metadata.avatarUrl || "";
|
|
34
|
+
var label = document.createElement("span");
|
|
35
|
+
label.className = "icon-strip-tooltip-label";
|
|
36
|
+
label.textContent = metadata.text;
|
|
37
|
+
identity.appendChild(avatar);
|
|
38
|
+
identity.appendChild(label);
|
|
39
|
+
tip.appendChild(identity);
|
|
40
|
+
} else {
|
|
41
|
+
tip.textContent = metadata.text;
|
|
42
|
+
}
|
|
43
|
+
document.body.appendChild(tip);
|
|
44
|
+
iconStripTooltip = tip;
|
|
45
|
+
|
|
46
|
+
requestAnimationFrame(function () {
|
|
47
|
+
if (iconStripTooltip !== tip || !tip.isConnected) return;
|
|
48
|
+
var rect = el.getBoundingClientRect();
|
|
49
|
+
tip.style.top = (rect.top + rect.height / 2 - tip.offsetHeight / 2) + "px";
|
|
50
|
+
tip.classList.add("visible");
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function showIconTooltipHtml(el, html, options) {
|
|
55
|
+
hideIconTooltip();
|
|
56
|
+
options = options || {};
|
|
57
|
+
var tip = document.createElement("div");
|
|
58
|
+
tip.className = "icon-strip-tooltip" + (options.className ? " " + options.className : "");
|
|
59
|
+
tip.setAttribute("role", "tooltip");
|
|
60
|
+
tip.style.whiteSpace = "normal";
|
|
61
|
+
tip.style.maxWidth = "260px";
|
|
62
|
+
tip.innerHTML = html;
|
|
63
|
+
document.body.appendChild(tip);
|
|
64
|
+
iconStripTooltip = tip;
|
|
65
|
+
|
|
66
|
+
requestAnimationFrame(function () {
|
|
67
|
+
if (iconStripTooltip !== tip || !tip.isConnected) return;
|
|
68
|
+
var rect = el.getBoundingClientRect();
|
|
69
|
+
if (options.placement === "bottom") {
|
|
70
|
+
var left = rect.left + rect.width / 2 - tip.offsetWidth / 2;
|
|
71
|
+
left = Math.max(12, Math.min(left, window.innerWidth - tip.offsetWidth - 12));
|
|
72
|
+
tip.style.left = left + "px";
|
|
73
|
+
tip.style.top = (rect.bottom + 8) + "px";
|
|
74
|
+
} else {
|
|
75
|
+
tip.style.top = (rect.top + rect.height / 2 - tip.offsetHeight / 2) + "px";
|
|
76
|
+
}
|
|
77
|
+
tip.classList.add("visible");
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function bindIconTooltip(el, resolveMetadata) {
|
|
82
|
+
function show() {
|
|
83
|
+
var metadata = tooltipMetadata(typeof resolveMetadata === "function" ? resolveMetadata() : resolveMetadata);
|
|
84
|
+
showIconTooltip(el, metadata.text || "", metadata);
|
|
85
|
+
}
|
|
86
|
+
el.addEventListener("mouseenter", show);
|
|
87
|
+
el.addEventListener("focus", show);
|
|
88
|
+
el.addEventListener("mouseleave", hideIconTooltip);
|
|
89
|
+
el.addEventListener("blur", hideIconTooltip);
|
|
90
|
+
el.addEventListener("click", hideIconTooltip);
|
|
91
|
+
el.addEventListener("contextmenu", hideIconTooltip);
|
|
92
|
+
el.addEventListener("keydown", function (event) {
|
|
93
|
+
if (event.key === "Escape") hideIconTooltip();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function isRecordEdit(edit) {
|
|
2
|
+
return !!(edit && !edit.schema && !edit.view && !edit.settings && !edit.recover);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function buildRecordAttempt(edit, databaseId, databaseRevision, values) {
|
|
6
|
+
if (edit.attempt) return edit.attempt;
|
|
7
|
+
var creating = edit.creating === true;
|
|
8
|
+
var payload = { databaseId: databaseId, values: JSON.parse(JSON.stringify(values)), operationId: edit.operationId };
|
|
9
|
+
if (creating) payload.expectedDatabaseRevision = databaseRevision;
|
|
10
|
+
else { payload.recordId = edit.recordId; payload.expectedRevision = edit.baseVersion; }
|
|
11
|
+
return { type: creating ? 'knowledge_db_record_create' : 'knowledge_db_record_update', payload: payload, creating: creating, recordId: edit.recordId || null, submittedVersion: edit.version || 0 };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildCreateAttempt(draft, name) {
|
|
15
|
+
if (draft.attempt) return draft.attempt;
|
|
16
|
+
return { operationId: draft.operationId, name: name };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function isCurrentAttempt(edit, attempt) {
|
|
20
|
+
return !!(edit && edit.attempt && attempt && edit.attempt.payload.operationId === attempt.payload.operationId);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function applyRecordSave(edit, record, newOperationId, acknowledgedAttempt) {
|
|
24
|
+
if (!isCurrentAttempt(edit, acknowledgedAttempt)) return { edit: edit, later: false, stale: true };
|
|
25
|
+
var later = (edit.version || 0) > acknowledgedAttempt.submittedVersion;
|
|
26
|
+
if (!later) return { edit: null, later: false };
|
|
27
|
+
return { later: true, edit: Object.assign({}, edit, { creating: false, recordId: record.id, baseVersion: record.revision, saving: false, retryPending: false, attempt: null, operationId: newOperationId, error: '' }) };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function updateViewPresentation(view, values) {
|
|
31
|
+
var next = Object.assign({}, view, { name: values.name, columns: values.columns });
|
|
32
|
+
if (view.filters.length <= 1) next.filters = values.filters;
|
|
33
|
+
if (view.sorts.length <= 1) next.sorts = values.sorts;
|
|
34
|
+
return next;
|
|
35
|
+
}
|