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.
Files changed (162) hide show
  1. package/LICENSES/README.md +4 -0
  2. package/LICENSES/dicebear-avatars.md +16 -0
  3. package/lib/daemon-project-access.js +7 -1
  4. package/lib/daemon.js +2 -0
  5. package/lib/dicebear-avatar.js +62 -0
  6. package/lib/knowledge-db-service.js +175 -0
  7. package/lib/knowledge-db-validation.js +0 -0
  8. package/lib/knowledge-document-index.js +49 -0
  9. package/lib/knowledge-draft-store.js +56 -0
  10. package/lib/knowledge-file-store.js +199 -0
  11. package/lib/knowledge-markdown.js +128 -0
  12. package/lib/mate-knowledge-mcp-server.js +29 -6
  13. package/lib/mate-knowledge-service.js +23 -2
  14. package/lib/mate-knowledge-sync.js +36 -21
  15. package/lib/mate-workspace-color.js +4 -0
  16. package/lib/mates.js +18 -0
  17. package/lib/project-connection.js +36 -2
  18. package/lib/project-debate-proposal.js +6 -0
  19. package/lib/project-debate-workspace.js +43 -0
  20. package/lib/project-debate.js +1 -0
  21. package/lib/project-file-path.js +2 -3
  22. package/lib/project-knowledge.js +315 -136
  23. package/lib/project-mate-creation-proposal.js +1 -0
  24. package/lib/project-request-access.js +13 -1
  25. package/lib/project-sessions.js +39 -2
  26. package/lib/project-user-knowledge.js +60 -0
  27. package/lib/project.js +59 -18
  28. package/lib/public/app.js +73 -34
  29. package/lib/public/clay-studio-wordmark-bold.svg +20 -0
  30. package/lib/public/css/clay-workspace.css +105 -0
  31. package/lib/public/css/debates-workbench.css +47 -0
  32. package/lib/public/css/filebrowser.css +10 -0
  33. package/lib/public/css/home-debate-live.css +26 -0
  34. package/lib/public/css/home-hub.css +3 -1
  35. package/lib/public/css/home-mate-model-picker.css +15 -131
  36. package/lib/public/css/home-mate-settings.css +168 -16
  37. package/lib/public/css/icon-strip.css +249 -32
  38. package/lib/public/css/mate-conversation.css +176 -0
  39. package/lib/public/css/mate-knowledge-workbench.css +118 -0
  40. package/lib/public/css/mate-workspace-color.css +16 -0
  41. package/lib/public/css/mates.css +28 -28
  42. package/lib/public/css/messages.css +1 -114
  43. package/lib/public/css/mobile-nav.css +16 -16
  44. package/lib/public/css/overlays.css +8 -0
  45. package/lib/public/css/project-logs.css +7 -0
  46. package/lib/public/css/project-mate-creation.css +105 -0
  47. package/lib/public/css/right-workbench.css +3 -3
  48. package/lib/public/css/session-folders.css +80 -21
  49. package/lib/public/css/sidebar.css +183 -107
  50. package/lib/public/css/title-bar.css +151 -0
  51. package/lib/public/css/worker-delegation.css +47 -0
  52. package/lib/public/css/worker-proposal.css +72 -150
  53. package/lib/public/css/you.css +74 -0
  54. package/lib/public/index.html +33 -101
  55. package/lib/public/modules/account-island.js +230 -0
  56. package/lib/public/modules/app-cursors.js +19 -43
  57. package/lib/public/modules/app-debate-ui.js +4 -3
  58. package/lib/public/modules/app-header.js +106 -0
  59. package/lib/public/modules/app-message-router.js +12 -3
  60. package/lib/public/modules/app-messages.js +34 -9
  61. package/lib/public/modules/app-notifications.js +4 -7
  62. package/lib/public/modules/app-projects.js +5 -38
  63. package/lib/public/modules/app-rendering.js +12 -13
  64. package/lib/public/modules/avatar.js +25 -9
  65. package/lib/public/modules/chat-render-runtime.js +16 -4
  66. package/lib/public/modules/command-palette.js +2 -15
  67. package/lib/public/modules/cursor-sharing-preference.js +3 -3
  68. package/lib/public/modules/debate-controls.js +299 -0
  69. package/lib/public/modules/debate.js +2 -0
  70. package/lib/public/modules/debates-workbench.js +339 -0
  71. package/lib/public/modules/default-ai.js +81 -65
  72. package/lib/public/modules/filebrowser.js +28 -8
  73. package/lib/public/modules/home-debate-controls.js +18 -289
  74. package/lib/public/modules/home-mate-avatar-editor.js +228 -0
  75. package/lib/public/modules/home-mate-color-picker.js +66 -0
  76. package/lib/public/modules/home-mate-creation.js +1 -1
  77. package/lib/public/modules/home-mate-instructions.js +90 -0
  78. package/lib/public/modules/home-mate-model-picker.js +80 -271
  79. package/lib/public/modules/home-mate-profile-editor.js +72 -0
  80. package/lib/public/modules/home-mate-settings.js +118 -125
  81. package/lib/public/modules/home-shell.js +3 -0
  82. package/lib/public/modules/home-surface-boot.js +1 -9
  83. package/lib/public/modules/html-preview.js +19 -0
  84. package/lib/public/modules/icon-strip-tooltip.js +95 -0
  85. package/lib/public/modules/knowledge-db-edit-state.js +35 -0
  86. package/lib/public/modules/knowledge-db-workbench.js +234 -0
  87. package/lib/public/modules/knowledge-history-state.js +55 -0
  88. package/lib/public/modules/knowledge-markdown-editor.js +57 -0
  89. package/lib/public/modules/knowledge-preview-links.js +70 -0
  90. package/lib/public/modules/knowledge-workbench-shell.js +21 -0
  91. package/lib/public/modules/mate-knowledge-workbench-state.js +174 -0
  92. package/lib/public/modules/mate-knowledge-workbench.js +500 -0
  93. package/lib/public/modules/mate-knowledge.js +11 -3
  94. package/lib/public/modules/mate-management.js +54 -10
  95. package/lib/public/modules/mate-sidebar.js +11 -1
  96. package/lib/public/modules/mate-workspace-color.js +33 -0
  97. package/lib/public/modules/mention.js +5 -13
  98. package/lib/public/modules/profile.js +51 -18
  99. package/lib/public/modules/project-chat-identity.js +79 -0
  100. package/lib/public/modules/project-debate-planning-workspace.js +250 -0
  101. package/lib/public/modules/project-debate-workspace.js +185 -0
  102. package/lib/public/modules/project-header-identity.js +127 -0
  103. package/lib/public/modules/project-logs-render.js +9 -4
  104. package/lib/public/modules/project-mate-creation-workspace.js +414 -0
  105. package/lib/public/modules/project-mate-navigation.js +238 -0
  106. package/lib/public/modules/project-session-navigation.js +29 -0
  107. package/lib/public/modules/project-switcher.js +6 -8
  108. package/lib/public/modules/projects-hub-view.js +5 -6
  109. package/lib/public/modules/projects-hub.js +2 -6
  110. package/lib/public/modules/qrcode.js +27 -8
  111. package/lib/public/modules/search-clay-chat.js +8 -11
  112. package/lib/public/modules/session-activity-tooltip.js +12 -0
  113. package/lib/public/modules/session-create-form.js +86 -14
  114. package/lib/public/modules/session-create.js +50 -7
  115. package/lib/public/modules/session-list-visibility.js +41 -0
  116. package/lib/public/modules/session-presence-ui.js +4 -1
  117. package/lib/public/modules/session-title-marquee.js +51 -0
  118. package/lib/public/modules/sidebar-mates.js +3 -50
  119. package/lib/public/modules/sidebar-mobile.js +63 -60
  120. package/lib/public/modules/sidebar-projects.js +84 -97
  121. package/lib/public/modules/sidebar-session-folders-ui.js +2 -2
  122. package/lib/public/modules/sidebar-session-hierarchy.js +149 -70
  123. package/lib/public/modules/sidebar-sessions.js +49 -50
  124. package/lib/public/modules/sidebar.js +11 -13
  125. package/lib/public/modules/thinking-lifecycle.js +7 -6
  126. package/lib/public/modules/tool-palette-order.js +4 -3
  127. package/lib/public/modules/tool-palette.js +13 -3
  128. package/lib/public/modules/tools.js +22 -22
  129. package/lib/public/modules/worker-proposal.js +42 -8
  130. package/lib/public/modules/worker-runtime-picker.js +115 -0
  131. package/lib/public/modules/you-activity.js +121 -0
  132. package/lib/public/modules/you.js +251 -0
  133. package/lib/public/style.css +16 -8
  134. package/lib/public/vendor/codemirror/LICENSE +21 -0
  135. package/lib/public/vendor/codemirror/codemirror.css +344 -0
  136. package/lib/public/vendor/codemirror/codemirror.js +9884 -0
  137. package/lib/public/vendor/codemirror/continuelist.js +101 -0
  138. package/lib/public/vendor/codemirror/markdown.js +886 -0
  139. package/lib/public/vendor/codemirror/show-hint.css +37 -0
  140. package/lib/public/vendor/codemirror/show-hint.js +523 -0
  141. package/lib/sdk-bridge.js +15 -3
  142. package/lib/server-admin.js +11 -0
  143. package/lib/server-home-chat-events.js +1 -1
  144. package/lib/server-home-chat.js +25 -3
  145. package/lib/server-home-debate-planning.js +4 -1
  146. package/lib/server-home-debates.js +2 -0
  147. package/lib/server-home-mate-creation.js +4 -1
  148. package/lib/server-mate-instructions.js +44 -0
  149. package/lib/server-mates.js +12 -3
  150. package/lib/server-palette.js +1 -1
  151. package/lib/server-settings.js +65 -1
  152. package/lib/server-user-knowledge.js +119 -0
  153. package/lib/server.js +21 -1
  154. package/lib/session-visibility.js +7 -2
  155. package/lib/sessions.js +32 -6
  156. package/lib/user-knowledge-service.js +167 -0
  157. package/lib/users-permissions.js +7 -0
  158. package/lib/users-project-mate-filter-preferences.js +39 -0
  159. package/lib/users.js +6 -0
  160. package/lib/workspace-query-access.js +4 -1
  161. package/lib/ws-schema.js +50 -0
  162. package/package.json +10 -1
@@ -0,0 +1,37 @@
1
+ .CodeMirror-hints {
2
+ position: absolute;
3
+ z-index: 10;
4
+ overflow: hidden;
5
+ list-style: none;
6
+
7
+ margin: 0;
8
+ padding: 2px;
9
+
10
+ -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
11
+ -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
12
+ box-shadow: 2px 3px 5px rgba(0,0,0,.2);
13
+ border-radius: 3px;
14
+ border: 1px solid silver;
15
+
16
+ background: white;
17
+ font-size: 90%;
18
+ font-family: monospace;
19
+
20
+ max-height: 20em;
21
+ overflow-y: auto;
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ .CodeMirror-hint {
26
+ margin: 0;
27
+ padding: 0 4px;
28
+ border-radius: 2px;
29
+ white-space: pre;
30
+ color: black;
31
+ cursor: pointer;
32
+ }
33
+
34
+ li.CodeMirror-hint-active {
35
+ background: #08f;
36
+ color: white;
37
+ }
@@ -0,0 +1,523 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ // declare global: DOMRect
5
+
6
+ (function(mod) {
7
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
8
+ mod(require("../../lib/codemirror"));
9
+ else if (typeof define == "function" && define.amd) // AMD
10
+ define(["../../lib/codemirror"], mod);
11
+ else // Plain browser env
12
+ mod(CodeMirror);
13
+ })(function(CodeMirror) {
14
+ "use strict";
15
+
16
+ var HINT_ELEMENT_CLASS = "CodeMirror-hint";
17
+ var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
18
+
19
+ // This is the old interface, kept around for now to stay
20
+ // backwards-compatible.
21
+ CodeMirror.showHint = function(cm, getHints, options) {
22
+ if (!getHints) return cm.showHint(options);
23
+ if (options && options.async) getHints.async = true;
24
+ var newOpts = {hint: getHints};
25
+ if (options) for (var prop in options) newOpts[prop] = options[prop];
26
+ return cm.showHint(newOpts);
27
+ };
28
+
29
+ CodeMirror.defineExtension("showHint", function(options) {
30
+ options = parseOptions(this, this.getCursor("start"), options);
31
+ var selections = this.listSelections()
32
+ if (selections.length > 1) return;
33
+ // By default, don't allow completion when something is selected.
34
+ // A hint function can have a `supportsSelection` property to
35
+ // indicate that it can handle selections.
36
+ if (this.somethingSelected()) {
37
+ if (!options.hint.supportsSelection) return;
38
+ // Don't try with cross-line selections
39
+ for (var i = 0; i < selections.length; i++)
40
+ if (selections[i].head.line != selections[i].anchor.line) return;
41
+ }
42
+
43
+ if (this.state.completionActive) this.state.completionActive.close();
44
+ var completion = this.state.completionActive = new Completion(this, options);
45
+ if (!completion.options.hint) return;
46
+
47
+ CodeMirror.signal(this, "startCompletion", this);
48
+ completion.update(true);
49
+ });
50
+
51
+ CodeMirror.defineExtension("closeHint", function() {
52
+ if (this.state.completionActive) this.state.completionActive.close()
53
+ })
54
+
55
+ function Completion(cm, options) {
56
+ this.cm = cm;
57
+ this.options = options;
58
+ this.widget = null;
59
+ this.debounce = 0;
60
+ this.tick = 0;
61
+ this.startPos = this.cm.getCursor("start");
62
+ this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
63
+
64
+ if (this.options.updateOnCursorActivity) {
65
+ var self = this;
66
+ cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
67
+ }
68
+ }
69
+
70
+ var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
71
+ return setTimeout(fn, 1000/60);
72
+ };
73
+ var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
74
+
75
+ Completion.prototype = {
76
+ close: function() {
77
+ if (!this.active()) return;
78
+ this.cm.state.completionActive = null;
79
+ this.tick = null;
80
+ if (this.options.updateOnCursorActivity) {
81
+ this.cm.off("cursorActivity", this.activityFunc);
82
+ }
83
+
84
+ if (this.widget && this.data) CodeMirror.signal(this.data, "close");
85
+ if (this.widget) this.widget.close();
86
+ CodeMirror.signal(this.cm, "endCompletion", this.cm);
87
+ },
88
+
89
+ active: function() {
90
+ return this.cm.state.completionActive == this;
91
+ },
92
+
93
+ pick: function(data, i) {
94
+ var completion = data.list[i], self = this;
95
+ this.cm.operation(function() {
96
+ if (completion.hint)
97
+ completion.hint(self.cm, data, completion);
98
+ else
99
+ self.cm.replaceRange(getText(completion), completion.from || data.from,
100
+ completion.to || data.to, "complete");
101
+ CodeMirror.signal(data, "pick", completion);
102
+ self.cm.scrollIntoView();
103
+ });
104
+ if (this.options.closeOnPick) {
105
+ this.close();
106
+ }
107
+ },
108
+
109
+ cursorActivity: function() {
110
+ if (this.debounce) {
111
+ cancelAnimationFrame(this.debounce);
112
+ this.debounce = 0;
113
+ }
114
+
115
+ var identStart = this.startPos;
116
+ if(this.data) {
117
+ identStart = this.data.from;
118
+ }
119
+
120
+ var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
121
+ if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
122
+ pos.ch < identStart.ch || this.cm.somethingSelected() ||
123
+ (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
124
+ this.close();
125
+ } else {
126
+ var self = this;
127
+ this.debounce = requestAnimationFrame(function() {self.update();});
128
+ if (this.widget) this.widget.disable();
129
+ }
130
+ },
131
+
132
+ update: function(first) {
133
+ if (this.tick == null) return
134
+ var self = this, myTick = ++this.tick
135
+ fetchHints(this.options.hint, this.cm, this.options, function(data) {
136
+ if (self.tick == myTick) self.finishUpdate(data, first)
137
+ })
138
+ },
139
+
140
+ finishUpdate: function(data, first) {
141
+ if (this.data) CodeMirror.signal(this.data, "update");
142
+
143
+ var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
144
+ if (this.widget) this.widget.close();
145
+
146
+ this.data = data;
147
+
148
+ if (data && data.list.length) {
149
+ if (picked && data.list.length == 1) {
150
+ this.pick(data, 0);
151
+ } else {
152
+ this.widget = new Widget(this, data);
153
+ CodeMirror.signal(data, "shown");
154
+ }
155
+ }
156
+ }
157
+ };
158
+
159
+ function parseOptions(cm, pos, options) {
160
+ var editor = cm.options.hintOptions;
161
+ var out = {};
162
+ for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
163
+ if (editor) for (var prop in editor)
164
+ if (editor[prop] !== undefined) out[prop] = editor[prop];
165
+ if (options) for (var prop in options)
166
+ if (options[prop] !== undefined) out[prop] = options[prop];
167
+ if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
168
+ return out;
169
+ }
170
+
171
+ function getText(completion) {
172
+ if (typeof completion == "string") return completion;
173
+ else return completion.text;
174
+ }
175
+
176
+ function buildKeyMap(completion, handle) {
177
+ var baseMap = {
178
+ Up: function() {handle.moveFocus(-1);},
179
+ Down: function() {handle.moveFocus(1);},
180
+ PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
181
+ PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
182
+ Home: function() {handle.setFocus(0);},
183
+ End: function() {handle.setFocus(handle.length - 1);},
184
+ Enter: handle.pick,
185
+ Tab: handle.pick,
186
+ Esc: handle.close
187
+ };
188
+
189
+ var mac = /Mac/.test(navigator.platform);
190
+
191
+ if (mac) {
192
+ baseMap["Ctrl-P"] = function() {handle.moveFocus(-1);};
193
+ baseMap["Ctrl-N"] = function() {handle.moveFocus(1);};
194
+ }
195
+
196
+ var custom = completion.options.customKeys;
197
+ var ourMap = custom ? {} : baseMap;
198
+ function addBinding(key, val) {
199
+ var bound;
200
+ if (typeof val != "string")
201
+ bound = function(cm) { return val(cm, handle); };
202
+ // This mechanism is deprecated
203
+ else if (baseMap.hasOwnProperty(val))
204
+ bound = baseMap[val];
205
+ else
206
+ bound = val;
207
+ ourMap[key] = bound;
208
+ }
209
+ if (custom)
210
+ for (var key in custom) if (custom.hasOwnProperty(key))
211
+ addBinding(key, custom[key]);
212
+ var extra = completion.options.extraKeys;
213
+ if (extra)
214
+ for (var key in extra) if (extra.hasOwnProperty(key))
215
+ addBinding(key, extra[key]);
216
+ return ourMap;
217
+ }
218
+
219
+ function getHintElement(hintsElement, el) {
220
+ while (el && el != hintsElement) {
221
+ if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
222
+ el = el.parentNode;
223
+ }
224
+ }
225
+
226
+ function Widget(completion, data) {
227
+ this.id = "cm-complete-" + Math.floor(Math.random(1e6))
228
+ this.completion = completion;
229
+ this.data = data;
230
+ this.picked = false;
231
+ var widget = this, cm = completion.cm;
232
+ var ownerDocument = cm.getInputField().ownerDocument;
233
+ var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
234
+
235
+ var hints = this.hints = ownerDocument.createElement("ul");
236
+ hints.setAttribute("role", "listbox")
237
+ hints.setAttribute("aria-expanded", "true")
238
+ hints.id = this.id
239
+ var theme = completion.cm.options.theme;
240
+ hints.className = "CodeMirror-hints " + theme;
241
+ this.selectedHint = data.selectedHint || 0;
242
+
243
+ var completions = data.list;
244
+ for (var i = 0; i < completions.length; ++i) {
245
+ var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i];
246
+ var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
247
+ if (cur.className != null) className = cur.className + " " + className;
248
+ elt.className = className;
249
+ if (i == this.selectedHint) elt.setAttribute("aria-selected", "true")
250
+ elt.id = this.id + "-" + i
251
+ elt.setAttribute("role", "option")
252
+ if (cur.render) cur.render(elt, data, cur);
253
+ else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
254
+ elt.hintId = i;
255
+ }
256
+
257
+ var container = completion.options.container || ownerDocument.body;
258
+ var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
259
+ var left = pos.left, top = pos.bottom, below = true;
260
+ var offsetLeft = 0, offsetTop = 0;
261
+ if (container !== ownerDocument.body) {
262
+ // We offset the cursor position because left and top are relative to the offsetParent's top left corner.
263
+ var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
264
+ var offsetParent = isContainerPositioned ? container : container.offsetParent;
265
+ var offsetParentPosition = offsetParent.getBoundingClientRect();
266
+ var bodyPosition = ownerDocument.body.getBoundingClientRect();
267
+ offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
268
+ offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
269
+ }
270
+ hints.style.left = (left - offsetLeft) + "px";
271
+ hints.style.top = (top - offsetTop) + "px";
272
+
273
+ // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
274
+ var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
275
+ var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
276
+ container.appendChild(hints);
277
+ cm.getInputField().setAttribute("aria-autocomplete", "list")
278
+ cm.getInputField().setAttribute("aria-owns", this.id)
279
+ cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint)
280
+
281
+ var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
282
+ var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
283
+
284
+ // Compute in the timeout to avoid reflow on init
285
+ var startScroll;
286
+ setTimeout(function() { startScroll = cm.getScrollInfo(); });
287
+
288
+ var overlapY = box.bottom - winH;
289
+ if (overlapY > 0) { // Does not fit below
290
+ var height = box.bottom - box.top, spaceAbove = box.top - (pos.bottom - pos.top) - 2
291
+ if (winH - box.top < spaceAbove) { // More room at the top
292
+ if (height > spaceAbove) hints.style.height = (height = spaceAbove) + "px";
293
+ hints.style.top = ((top = pos.top - height) - offsetTop) + "px";
294
+ below = false;
295
+ } else {
296
+ hints.style.height = (winH - box.top - 2) + "px";
297
+ }
298
+ }
299
+ var overlapX = box.right - winW;
300
+ if (scrolls) overlapX += cm.display.nativeBarWidth;
301
+ if (overlapX > 0) {
302
+ if (box.right - box.left > winW) {
303
+ hints.style.width = (winW - 5) + "px";
304
+ overlapX -= (box.right - box.left) - winW;
305
+ }
306
+ hints.style.left = (left = Math.max(pos.left - overlapX - offsetLeft, 0)) + "px";
307
+ }
308
+ if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
309
+ node.style.paddingRight = cm.display.nativeBarWidth + "px"
310
+
311
+ cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
312
+ moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
313
+ setFocus: function(n) { widget.changeActive(n); },
314
+ menuSize: function() { return widget.screenAmount(); },
315
+ length: completions.length,
316
+ close: function() { completion.close(); },
317
+ pick: function() { widget.pick(); },
318
+ data: data
319
+ }));
320
+
321
+ if (completion.options.closeOnUnfocus) {
322
+ var closingOnBlur;
323
+ cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
324
+ cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
325
+ }
326
+
327
+ cm.on("scroll", this.onScroll = function() {
328
+ var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
329
+ if (!startScroll) startScroll = cm.getScrollInfo();
330
+ var newTop = top + startScroll.top - curScroll.top;
331
+ var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
332
+ if (!below) point += hints.offsetHeight;
333
+ if (point <= editor.top || point >= editor.bottom) return completion.close();
334
+ hints.style.top = newTop + "px";
335
+ hints.style.left = (left + startScroll.left - curScroll.left) + "px";
336
+ });
337
+
338
+ CodeMirror.on(hints, "dblclick", function(e) {
339
+ var t = getHintElement(hints, e.target || e.srcElement);
340
+ if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
341
+ });
342
+
343
+ CodeMirror.on(hints, "click", function(e) {
344
+ var t = getHintElement(hints, e.target || e.srcElement);
345
+ if (t && t.hintId != null) {
346
+ widget.changeActive(t.hintId);
347
+ if (completion.options.completeOnSingleClick) widget.pick();
348
+ }
349
+ });
350
+
351
+ CodeMirror.on(hints, "mousedown", function() {
352
+ setTimeout(function(){cm.focus();}, 20);
353
+ });
354
+
355
+ // The first hint doesn't need to be scrolled to on init
356
+ var selectedHintRange = this.getSelectedHintRange();
357
+ if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
358
+ this.scrollToActive();
359
+ }
360
+
361
+ CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
362
+ return true;
363
+ }
364
+
365
+ Widget.prototype = {
366
+ close: function() {
367
+ if (this.completion.widget != this) return;
368
+ this.completion.widget = null;
369
+ if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
370
+ this.completion.cm.removeKeyMap(this.keyMap);
371
+ var input = this.completion.cm.getInputField()
372
+ input.removeAttribute("aria-activedescendant")
373
+ input.removeAttribute("aria-owns")
374
+
375
+ var cm = this.completion.cm;
376
+ if (this.completion.options.closeOnUnfocus) {
377
+ cm.off("blur", this.onBlur);
378
+ cm.off("focus", this.onFocus);
379
+ }
380
+ cm.off("scroll", this.onScroll);
381
+ },
382
+
383
+ disable: function() {
384
+ this.completion.cm.removeKeyMap(this.keyMap);
385
+ var widget = this;
386
+ this.keyMap = {Enter: function() { widget.picked = true; }};
387
+ this.completion.cm.addKeyMap(this.keyMap);
388
+ },
389
+
390
+ pick: function() {
391
+ this.completion.pick(this.data, this.selectedHint);
392
+ },
393
+
394
+ changeActive: function(i, avoidWrap) {
395
+ if (i >= this.data.list.length)
396
+ i = avoidWrap ? this.data.list.length - 1 : 0;
397
+ else if (i < 0)
398
+ i = avoidWrap ? 0 : this.data.list.length - 1;
399
+ if (this.selectedHint == i) return;
400
+ var node = this.hints.childNodes[this.selectedHint];
401
+ if (node) {
402
+ node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
403
+ node.removeAttribute("aria-selected")
404
+ }
405
+ node = this.hints.childNodes[this.selectedHint = i];
406
+ node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
407
+ node.setAttribute("aria-selected", "true")
408
+ this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id)
409
+ this.scrollToActive()
410
+ CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
411
+ },
412
+
413
+ scrollToActive: function() {
414
+ var selectedHintRange = this.getSelectedHintRange();
415
+ var node1 = this.hints.childNodes[selectedHintRange.from];
416
+ var node2 = this.hints.childNodes[selectedHintRange.to];
417
+ var firstNode = this.hints.firstChild;
418
+ if (node1.offsetTop < this.hints.scrollTop)
419
+ this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
420
+ else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
421
+ this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
422
+ },
423
+
424
+ screenAmount: function() {
425
+ return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
426
+ },
427
+
428
+ getSelectedHintRange: function() {
429
+ var margin = this.completion.options.scrollMargin || 0;
430
+ return {
431
+ from: Math.max(0, this.selectedHint - margin),
432
+ to: Math.min(this.data.list.length - 1, this.selectedHint + margin),
433
+ };
434
+ }
435
+ };
436
+
437
+ function applicableHelpers(cm, helpers) {
438
+ if (!cm.somethingSelected()) return helpers
439
+ var result = []
440
+ for (var i = 0; i < helpers.length; i++)
441
+ if (helpers[i].supportsSelection) result.push(helpers[i])
442
+ return result
443
+ }
444
+
445
+ function fetchHints(hint, cm, options, callback) {
446
+ if (hint.async) {
447
+ hint(cm, callback, options)
448
+ } else {
449
+ var result = hint(cm, options)
450
+ if (result && result.then) result.then(callback)
451
+ else callback(result)
452
+ }
453
+ }
454
+
455
+ function resolveAutoHints(cm, pos) {
456
+ var helpers = cm.getHelpers(pos, "hint"), words
457
+ if (helpers.length) {
458
+ var resolved = function(cm, callback, options) {
459
+ var app = applicableHelpers(cm, helpers);
460
+ function run(i) {
461
+ if (i == app.length) return callback(null)
462
+ fetchHints(app[i], cm, options, function(result) {
463
+ if (result && result.list.length > 0) callback(result)
464
+ else run(i + 1)
465
+ })
466
+ }
467
+ run(0)
468
+ }
469
+ resolved.async = true
470
+ resolved.supportsSelection = true
471
+ return resolved
472
+ } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
473
+ return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
474
+ } else if (CodeMirror.hint.anyword) {
475
+ return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
476
+ } else {
477
+ return function() {}
478
+ }
479
+ }
480
+
481
+ CodeMirror.registerHelper("hint", "auto", {
482
+ resolve: resolveAutoHints
483
+ });
484
+
485
+ CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
486
+ var cur = cm.getCursor(), token = cm.getTokenAt(cur)
487
+ var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
488
+ if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
489
+ term = token.string.substr(0, cur.ch - token.start)
490
+ } else {
491
+ term = ""
492
+ from = cur
493
+ }
494
+ var found = [];
495
+ for (var i = 0; i < options.words.length; i++) {
496
+ var word = options.words[i];
497
+ if (word.slice(0, term.length) == term)
498
+ found.push(word);
499
+ }
500
+
501
+ if (found.length) return {list: found, from: from, to: to};
502
+ });
503
+
504
+ CodeMirror.commands.autocomplete = CodeMirror.showHint;
505
+
506
+ var defaultOptions = {
507
+ hint: CodeMirror.hint.auto,
508
+ completeSingle: true,
509
+ alignWithWord: true,
510
+ closeCharacters: /[\s()\[\]{};:>,]/,
511
+ closeOnPick: true,
512
+ closeOnUnfocus: true,
513
+ updateOnCursorActivity: true,
514
+ completeOnSingleClick: true,
515
+ container: null,
516
+ customKeys: null,
517
+ extraKeys: null,
518
+ paddingForScrollbar: true,
519
+ moveOnOverlap: true,
520
+ };
521
+
522
+ CodeMirror.defineOption("hintOptions", null);
523
+ });
package/lib/sdk-bridge.js CHANGED
@@ -795,6 +795,9 @@ function createSDKBridge(opts) {
795
795
  }
796
796
 
797
797
  function handlePreToolUsePolicy(session, toolName, input) {
798
+ var youTool = /^(?:mcp__clay-you__)?(?:search_user_knowledge|read_user_knowledge|report_user_observation|list_user_observations|curate_user_knowledge)$/.test(toolName);
799
+ if (session.youCurator && !youTool) return { behavior: "deny", message: "User Knowledge review may only use Clay's owner-bound knowledge tools." };
800
+ if (youTool) return { behavior: "allow", updatedInput: input };
798
801
  var debateDecision = homeDebateToolPolicy.initialToolDecision(session, toolName, input);
799
802
  if (debateDecision) return debateDecision;
800
803
  // The dynamic proposal tool is bound to this exact query session. It only
@@ -1107,6 +1110,7 @@ function createSDKBridge(opts) {
1107
1110
  if (codexCatalogCandidate.userInputVersion) session.codexUserInputToolCatalogVersion = codexCatalogCandidate.userInputVersion;
1108
1111
  if (codexCatalogCandidate.sharedBrowserVersion) session.codexSharedBrowserToolCatalogVersion = codexCatalogCandidate.sharedBrowserVersion;
1109
1112
  if (codexCatalogCandidate.issuesVersion) session.codexIssuesToolCatalogVersion = codexCatalogCandidate.issuesVersion;
1113
+ if (codexCatalogCandidate.youVersion) session.codexYouToolCatalogVersion = codexCatalogCandidate.youVersion;
1110
1114
  if (codexCatalogCandidate.linearVersion) session.codexLinearToolCatalogVersion = codexCatalogCandidate.linearVersion;
1111
1115
  sm.saveSessionFile(session);
1112
1116
  codexCatalogCandidate = null;
@@ -1730,6 +1734,10 @@ function createSDKBridge(opts) {
1730
1734
  // still reaches Clay's canUseTool callback, as before.
1731
1735
  claudeOpts.permissionMode = modeToApply || "default";
1732
1736
  }
1737
+ if (session.youCurator) {
1738
+ claudeOpts.permissionMode = "default";
1739
+ claudeOpts.allowDangerouslySkipPermissions = false;
1740
+ }
1733
1741
  // Clear one-shot acceptEditsAfterStart regardless of which branch ran above,
1734
1742
  // so the flag does not linger into subsequent turns.
1735
1743
  if (session.acceptEditsAfterStart) delete session.acceptEditsAfterStart;
@@ -1789,6 +1797,9 @@ function createSDKBridge(opts) {
1789
1797
  // delivered by this provider.
1790
1798
  var sessionToolDefs = getSessionToolDefs(session) || [];
1791
1799
  var queryGeneration = Number(session._sdkQueryGeneration || 0);
1800
+ var hasYouCatalog = sessionToolDefs.some(function (tool) { return tool.name === "search_user_knowledge"; });
1801
+ var recoverCodexYouTools = sessionAdapter.vendor === "codex" && !!session.cliSessionId
1802
+ && hasYouCatalog && Number(session.codexYouToolCatalogVersion || 0) < 1;
1792
1803
  var hasLinearCatalog = sessionToolDefs.some(function (tool) { return tool.name === "link_session_linear"; });
1793
1804
  var recoverCodexLinearTools = sessionAdapter.vendor === "codex" && !!session.cliSessionId
1794
1805
  && hasLinearCatalog && Number(session.codexLinearToolCatalogVersion || 0) < 1 && canUseSessionTools(session) === true;
@@ -1975,7 +1986,7 @@ function createSDKBridge(opts) {
1975
1986
  dynamicTools: sessionToolDefs,
1976
1987
  // Codex persists dynamic tools with a thread. A stale authorized Driver
1977
1988
  // gets this exact-query bridge; its handlers still reauthorize live.
1978
- sessionMcpServer: (recoverCodexIssueTools || recoverCodexQuestionTools || recoverCodexBrowserTools || recoverCodexLinearTools) ? getCodexSessionMcpServer(session, queryGeneration) : undefined,
1989
+ sessionMcpServer: (recoverCodexIssueTools || recoverCodexQuestionTools || recoverCodexBrowserTools || recoverCodexLinearTools || recoverCodexYouTools) ? getCodexSessionMcpServer(session, queryGeneration) : undefined,
1979
1990
  callDynamicTool: function (toolName, args) {
1980
1991
  var toolDef = findSessionToolDef(toolName);
1981
1992
  if (toolDef && typeof toolDef.handler === "function") {
@@ -2023,8 +2034,8 @@ function createSDKBridge(opts) {
2023
2034
  // Codex's native approval prompts are terminal-based and cannot be
2024
2035
  // relayed through Clay's web UI, causing MCP tool calls to hang.
2025
2036
  approvalPolicy: "never",
2026
- sandboxMode: codexConfig.sandbox,
2027
- webSearchMode: codexConfig.webSearch,
2037
+ sandboxMode: session.youCurator ? "read-only" : codexConfig.sandbox,
2038
+ webSearchMode: session.youCurator ? "disabled" : codexConfig.webSearch,
2028
2039
  },
2029
2040
  ACP: {
2030
2041
  mcpServers: getAcpMcpServers(session),
@@ -2194,6 +2205,7 @@ function createSDKBridge(opts) {
2194
2205
  if (requiredCatalogTools.ask_user_questions) {
2195
2206
  codexCatalogCandidate = Object.assign({}, codexCatalogCandidate || {}, { generation: queryGeneration, userInputVersion: 1 });
2196
2207
  }
2208
+ if (hasYouCatalog) codexCatalogCandidate = Object.assign({}, codexCatalogCandidate || {}, { generation: queryGeneration, youVersion: 1 });
2197
2209
  if (hasLinearCatalog) codexCatalogCandidate = Object.assign({}, codexCatalogCandidate || {}, { generation: queryGeneration, linearVersion: 1 });
2198
2210
  if (hasSharedBrowserCatalog) {
2199
2211
  codexCatalogCandidate = Object.assign({}, codexCatalogCandidate || {}, { generation: queryGeneration, sharedBrowserVersion: 5 });
@@ -19,6 +19,17 @@ function attachAdmin(ctx) {
19
19
  var onProjectOwnerChanged = ctx.onProjectOwnerChanged;
20
20
 
21
21
  function handleRequest(req, res, fullUrl) {
22
+ var mateAccessRoute = /^\/api\/admin\/projects\/([^/]+)\/(visibility|owner|users|access)$/.exec(fullUrl);
23
+ if (mateAccessRoute) {
24
+ var target = projects.get(mateAccessRoute[1]);
25
+ var status = target && target.getStatus();
26
+ if ((status && status.isMate) || mateAccessRoute[1].indexOf("mate-") === 0) {
27
+ res.writeHead(403, { "Content-Type": "application/json" });
28
+ res.end(JSON.stringify({ error: "Clay and Mate ownership is private and cannot be shared or transferred." }));
29
+ return true;
30
+ }
31
+ }
32
+
22
33
 
23
34
  // --- Admin API endpoints (multi-user mode only) ---
24
35
 
@@ -297,7 +297,7 @@ function transformEvent(event, mateId, session, requestId, stableSessionId) {
297
297
  }
298
298
  if (event.type === "debate_proposal_resolved" && event.proposalId) return Object.assign({ type: "home_debate_proposal_resolved", proposalId: event.proposalId, action: event.action || "cancel", error: event.error || "" }, metadata);
299
299
  if (session && session.mateCreationMode === true && event.type === "mate_creation_proposal" && event.proposal) return Object.assign({ type: "home_mate_creation_proposal", proposal: event.proposal }, metadata);
300
- if (session && session.mateCreationMode === true && event.type === "mate_creation_proposal_resolved" && event.proposalId) return Object.assign({ type: "home_mate_creation_proposal_resolved", proposalId: event.proposalId, action: event.action || "cancel", mateId: event.mateId || null, mateName: event.mateName || null, error: event.error || "" }, metadata);
300
+ if (session && session.mateCreationMode === true && event.type === "mate_creation_proposal_resolved" && event.proposalId) return Object.assign({ type: "home_mate_creation_proposal_resolved", proposalId: event.proposalId, action: event.action || "cancel", createdMateId: event.mateId || null, mateName: event.mateName || null, error: event.error || "" }, metadata);
301
301
  if (session && session.debateSetupMode === true && event.type === "tool_executing" && event.name === "AskUserQuestion" && event.id && event.input) {
302
302
  return Object.assign({ type: "home_debate_question", toolId: event.id, questions: homeDebateQuestions(event.input) }, metadata);
303
303
  }