clay-server 2.34.0-beta.8 → 2.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/project-connection.js +1 -9
- package/lib/project-sessions.js +38 -4
- package/lib/project-user-message.js +4 -3
- package/lib/project.js +12 -2
- package/lib/public/css/mobile-nav.css +0 -14
- package/lib/public/css/notifications-center.css +23 -19
- package/lib/public/css/sidebar.css +326 -101
- package/lib/public/index.html +7 -10
- package/lib/public/modules/diff.js +21 -7
- package/lib/public/modules/sidebar-mobile.js +10 -20
- package/lib/public/modules/sidebar-sessions.js +490 -113
- package/lib/public/modules/sidebar.js +8 -6
- package/lib/public/modules/tools.js +37 -10
- package/lib/public/sw.js +1 -1
- package/lib/sessions.js +90 -0
- package/lib/ws-schema.js +2 -0
- package/lib/yoke/adapters/codex.js +31 -4
- package/package.json +1 -1
|
@@ -82,16 +82,7 @@ function attachConnection(ctx) {
|
|
|
82
82
|
setTimeout(function() { _loop.resumeLoop(); }, 500);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// Auto-assign owner if project has none and a user connects (e.g. IPC-added projects)
|
|
86
85
|
var projectOwnerId = getProjectOwnerId();
|
|
87
|
-
if (!projectOwnerId && ws._clayUser && ws._clayUser.id && !isMate) {
|
|
88
|
-
setProjectOwnerId(ws._clayUser.id);
|
|
89
|
-
projectOwnerId = ws._clayUser.id;
|
|
90
|
-
if (opts.onProjectOwnerChanged) {
|
|
91
|
-
opts.onProjectOwnerChanged(slug, projectOwnerId);
|
|
92
|
-
}
|
|
93
|
-
console.log("[project] Auto-assigned owner for " + slug + ": " + projectOwnerId);
|
|
94
|
-
}
|
|
95
86
|
|
|
96
87
|
// Send cached state
|
|
97
88
|
var _userId = ws._clayUser ? ws._clayUser.id : null;
|
|
@@ -155,6 +146,7 @@ function attachConnection(ctx) {
|
|
|
155
146
|
ownerId: s.ownerId || null,
|
|
156
147
|
sessionVisibility: s.sessionVisibility || "shared",
|
|
157
148
|
bookmarked: !!s.bookmarked,
|
|
149
|
+
favoriteOrder: typeof s.favoriteOrder === "number" ? s.favoriteOrder : null,
|
|
158
150
|
};
|
|
159
151
|
}),
|
|
160
152
|
});
|
package/lib/project-sessions.js
CHANGED
|
@@ -39,7 +39,7 @@ function formatAskUserAnswerAsMessage(input, answers) {
|
|
|
39
39
|
* sm, sdk, tm, clients,
|
|
40
40
|
* send, sendTo, sendToAdmins, sendToSession, sendToSessionOthers,
|
|
41
41
|
* opts, usersModule, userPresence, matesModule, pushModule,
|
|
42
|
-
* getSessionForWs, getLinuxUserForSession, getOsUserInfoForWs,
|
|
42
|
+
* getSessionForWs, getLinuxUserForSession, ensureProjectAccessForSession, getOsUserInfoForWs,
|
|
43
43
|
* hydrateImageRefs, onProcessingChanged, broadcastPresence,
|
|
44
44
|
* adapter, getProjectList, getProjectCount, getScheduleCount,
|
|
45
45
|
* moveScheduleToProject, moveAllSchedulesToProject, getHubSchedules,
|
|
@@ -70,6 +70,7 @@ function attachSessions(ctx) {
|
|
|
70
70
|
var pushModule = ctx.pushModule;
|
|
71
71
|
var getSessionForWs = ctx.getSessionForWs;
|
|
72
72
|
var getLinuxUserForSession = ctx.getLinuxUserForSession;
|
|
73
|
+
var ensureProjectAccessForSession = ctx.ensureProjectAccessForSession;
|
|
73
74
|
var getOsUserInfoForWs = ctx.getOsUserInfoForWs;
|
|
74
75
|
var hydrateImageRefs = ctx.hydrateImageRefs;
|
|
75
76
|
var onProcessingChanged = ctx.onProcessingChanged;
|
|
@@ -163,6 +164,39 @@ function attachSessions(ctx) {
|
|
|
163
164
|
return true;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
if (msg.type === "reorder_session_bookmarks") {
|
|
168
|
+
if (typeof msg.sourceId === "number" && typeof msg.targetId === "number" && msg.sourceId !== msg.targetId) {
|
|
169
|
+
var source = sm.sessions.get(msg.sourceId);
|
|
170
|
+
var target = sm.sessions.get(msg.targetId);
|
|
171
|
+
if (!source || !target) return true;
|
|
172
|
+
if (usersModule.isMultiUser() && ws._clayUser) {
|
|
173
|
+
if (!usersModule.canAccessSession(ws._clayUser.id, source, { visibility: "public" })) return true;
|
|
174
|
+
if (!usersModule.canAccessSession(ws._clayUser.id, target, { visibility: "public" })) return true;
|
|
175
|
+
}
|
|
176
|
+
sm.reorderBookmarkedSessions(msg.sourceId, msg.targetId, msg.insertBefore !== false);
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (msg.type === "bulk_delete_sessions") {
|
|
182
|
+
if (!Array.isArray(msg.sessionIds) || msg.sessionIds.length === 0) return true;
|
|
183
|
+
var deletableIds = [];
|
|
184
|
+
for (var di = 0; di < msg.sessionIds.length; di++) {
|
|
185
|
+
var bulkId = msg.sessionIds[di];
|
|
186
|
+
if (typeof bulkId !== "number") continue;
|
|
187
|
+
var bulkTarget = sm.sessions.get(bulkId);
|
|
188
|
+
if (!bulkTarget) continue;
|
|
189
|
+
if (usersModule.isMultiUser() && ws._clayUser) {
|
|
190
|
+
if (!usersModule.canAccessSession(ws._clayUser.id, bulkTarget, { visibility: "public" })) continue;
|
|
191
|
+
}
|
|
192
|
+
deletableIds.push(bulkId);
|
|
193
|
+
}
|
|
194
|
+
if (deletableIds.length > 0) {
|
|
195
|
+
sm.deleteSessionsBulk(deletableIds, ws);
|
|
196
|
+
}
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
|
|
166
200
|
if (msg.type === "transfer_project_owner") {
|
|
167
201
|
// Home directory projects: ownership is permanently locked
|
|
168
202
|
if (osUsers && osUsers.length > 0 && /^\/home\/[^/]+\//.test(cwd)) {
|
|
@@ -803,7 +837,7 @@ function attachSessions(ctx) {
|
|
|
803
837
|
session.sentToolResults = {};
|
|
804
838
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
805
839
|
if (!session.queryInstance && !session.worker) {
|
|
806
|
-
sdk.startQuery(session, answerText, undefined,
|
|
840
|
+
sdk.startQuery(session, answerText, undefined, ensureProjectAccessForSession(session));
|
|
807
841
|
} else {
|
|
808
842
|
sdk.pushMessage(session, answerText);
|
|
809
843
|
}
|
|
@@ -932,7 +966,7 @@ function attachSessions(ctx) {
|
|
|
932
966
|
newSession.sentToolResults = {};
|
|
933
967
|
sendToSession(newSession.localId, { type: "status", status: "processing" });
|
|
934
968
|
newSession.acceptEditsAfterStart = true;
|
|
935
|
-
sdk.startQuery(newSession, planPrompt, undefined,
|
|
969
|
+
sdk.startQuery(newSession, planPrompt, undefined, ensureProjectAccessForSession(newSession));
|
|
936
970
|
} catch (e) {
|
|
937
971
|
console.error("[project] Error starting plan execution:", e);
|
|
938
972
|
sendTo(ws, { type: "error", text: "Failed to start plan execution: " + (e.message || e) });
|
|
@@ -963,7 +997,7 @@ function attachSessions(ctx) {
|
|
|
963
997
|
session.sentToolResults = {};
|
|
964
998
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
965
999
|
if (!session.queryInstance && !session.worker) {
|
|
966
|
-
sdk.startQuery(session, feedback, undefined,
|
|
1000
|
+
sdk.startQuery(session, feedback, undefined, ensureProjectAccessForSession(session));
|
|
967
1001
|
} else {
|
|
968
1002
|
sdk.pushMessage(session, feedback);
|
|
969
1003
|
}
|
|
@@ -13,7 +13,7 @@ var fs = require("fs");
|
|
|
13
13
|
* send, sendTo, sendToSession, sendToSessionOthers,
|
|
14
14
|
* clients, opts,
|
|
15
15
|
* usersModule, matesModule,
|
|
16
|
-
* getSessionForWs, getLinuxUserForSession, getOsUserInfoForWs,
|
|
16
|
+
* getSessionForWs, getLinuxUserForSession, ensureProjectAccessForSession, getOsUserInfoForWs,
|
|
17
17
|
* hydrateImageRefs, saveImageFile, imagesDir,
|
|
18
18
|
* onProcessingChanged, onSessionDone,
|
|
19
19
|
* _loop - { handleLoopMessage: fn(ws, msg) }
|
|
@@ -49,6 +49,7 @@ function attachUserMessage(ctx) {
|
|
|
49
49
|
|
|
50
50
|
var getSessionForWs = ctx.getSessionForWs;
|
|
51
51
|
var getLinuxUserForSession = ctx.getLinuxUserForSession;
|
|
52
|
+
var ensureProjectAccessForSession = ctx.ensureProjectAccessForSession;
|
|
52
53
|
var getOsUserInfoForWs = ctx.getOsUserInfoForWs;
|
|
53
54
|
|
|
54
55
|
var hydrateImageRefs = ctx.hydrateImageRefs;
|
|
@@ -281,7 +282,7 @@ function attachUserMessage(ctx) {
|
|
|
281
282
|
nowSession.isProcessing = true;
|
|
282
283
|
onProcessingChanged();
|
|
283
284
|
sendToSession(nowSession.localId, { type: "status", status: "processing" });
|
|
284
|
-
sdk.startQuery(nowSession, schedText, null,
|
|
285
|
+
sdk.startQuery(nowSession, schedText, null, ensureProjectAccessForSession(nowSession));
|
|
285
286
|
sm.broadcastSessionList();
|
|
286
287
|
return true;
|
|
287
288
|
}
|
|
@@ -484,7 +485,7 @@ function attachUserMessage(ctx) {
|
|
|
484
485
|
// No active query (or worker idle between queries): start a new query
|
|
485
486
|
session._queryStartTs = Date.now();
|
|
486
487
|
console.log("[PERF] project.js: startQuery called, localId=" + session.localId + " t=0ms");
|
|
487
|
-
sdk.startQuery(session, finalText, msg.images,
|
|
488
|
+
sdk.startQuery(session, finalText, msg.images, ensureProjectAccessForSession(session));
|
|
488
489
|
} else {
|
|
489
490
|
sdk.pushMessage(session, finalText, msg.images);
|
|
490
491
|
}
|
package/lib/project.js
CHANGED
|
@@ -9,7 +9,7 @@ var { createNotesManager } = require("./notes");
|
|
|
9
9
|
var { fetchLatestVersion, fetchVersion, isNewer } = require("./updater");
|
|
10
10
|
var { execFileSync, spawn } = require("child_process");
|
|
11
11
|
var usersModule = require("./users");
|
|
12
|
-
var { resolveOsUserInfo, fsAsUser } = require("./os-users");
|
|
12
|
+
var { resolveOsUserInfo, fsAsUser, grantProjectAccess } = require("./os-users");
|
|
13
13
|
var crisisSafety = require("./crisis-safety");
|
|
14
14
|
var matesModule = require("./mates");
|
|
15
15
|
var sessionSearch = require("./session-search");
|
|
@@ -188,6 +188,14 @@ function createProjectContext(opts) {
|
|
|
188
188
|
return user.linuxUser;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
function ensureProjectAccessForSession(session) {
|
|
192
|
+
var linuxUser = getLinuxUserForSession(session);
|
|
193
|
+
if (linuxUser) {
|
|
194
|
+
grantProjectAccess(cwd, linuxUser);
|
|
195
|
+
}
|
|
196
|
+
return linuxUser;
|
|
197
|
+
}
|
|
198
|
+
|
|
191
199
|
function getLinuxUserForWs(ws) {
|
|
192
200
|
if (!osUsers) return null;
|
|
193
201
|
if (!ws._clayUser || !ws._clayUser.linuxUser) return null;
|
|
@@ -800,7 +808,7 @@ function createProjectContext(opts) {
|
|
|
800
808
|
session.isProcessing = true;
|
|
801
809
|
onProcessingChanged();
|
|
802
810
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
803
|
-
sdk.startQuery(session, text, null,
|
|
811
|
+
sdk.startQuery(session, text, null, ensureProjectAccessForSession(session));
|
|
804
812
|
sm.broadcastSessionList();
|
|
805
813
|
}, schedDelay),
|
|
806
814
|
};
|
|
@@ -1134,6 +1142,7 @@ function createProjectContext(opts) {
|
|
|
1134
1142
|
pushModule: pushModule,
|
|
1135
1143
|
getSessionForWs: getSessionForWs,
|
|
1136
1144
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1145
|
+
ensureProjectAccessForSession: ensureProjectAccessForSession,
|
|
1137
1146
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
1138
1147
|
hydrateImageRefs: hydrateImageRefs,
|
|
1139
1148
|
onProcessingChanged: onProcessingChanged,
|
|
@@ -1182,6 +1191,7 @@ function createProjectContext(opts) {
|
|
|
1182
1191
|
matesModule: matesModule,
|
|
1183
1192
|
getSessionForWs: getSessionForWs,
|
|
1184
1193
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1194
|
+
ensureProjectAccessForSession: ensureProjectAccessForSession,
|
|
1185
1195
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
1186
1196
|
hydrateImageRefs: hydrateImageRefs,
|
|
1187
1197
|
saveImageFile: saveImageFile,
|
|
@@ -526,20 +526,6 @@
|
|
|
526
526
|
white-space: nowrap;
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
.mobile-session-bookmark {
|
|
530
|
-
display: inline-flex;
|
|
531
|
-
align-items: center;
|
|
532
|
-
color: var(--accent, #ff7b54);
|
|
533
|
-
flex-shrink: 0;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
.mobile-session-bookmark .lucide,
|
|
537
|
-
.mobile-session-bookmark svg {
|
|
538
|
-
width: 13px;
|
|
539
|
-
height: 13px;
|
|
540
|
-
display: block;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
529
|
.mobile-session-processing {
|
|
544
530
|
width: 7px;
|
|
545
531
|
height: 7px;
|
|
@@ -309,45 +309,49 @@
|
|
|
309
309
|
|
|
310
310
|
.light-theme .notif-banner-clear-all {
|
|
311
311
|
background:
|
|
312
|
-
linear-gradient(180deg, rgba(255,255,255,0.
|
|
313
|
-
rgba(
|
|
314
|
-
|
|
312
|
+
linear-gradient(180deg, rgba(255,255,255,0.54), rgba(255,255,255,0.28)),
|
|
313
|
+
rgba(248,250,255,0.22);
|
|
314
|
+
backdrop-filter: blur(10px) saturate(1.08);
|
|
315
|
+
-webkit-backdrop-filter: blur(10px) saturate(1.08);
|
|
316
|
+
border-color: rgba(255,255,255,0.52);
|
|
315
317
|
color: rgba(36, 45, 66, 0.72);
|
|
316
318
|
box-shadow:
|
|
317
|
-
inset 0 1px 0 rgba(255,255,255,0.
|
|
318
|
-
0 8px 22px rgba(31, 41, 55, 0.
|
|
319
|
+
inset 0 1px 0 rgba(255,255,255,0.78),
|
|
320
|
+
0 8px 22px rgba(31, 41, 55, 0.07);
|
|
319
321
|
}
|
|
320
322
|
|
|
321
323
|
.light-theme .notif-banner-clear-all:hover {
|
|
322
324
|
color: rgba(22, 29, 45, 0.92);
|
|
323
325
|
background:
|
|
324
|
-
linear-gradient(180deg, rgba(255,255,255,0.
|
|
325
|
-
rgba(
|
|
326
|
-
border-color: rgba(
|
|
326
|
+
linear-gradient(180deg, rgba(255,255,255,0.62), rgba(255,255,255,0.34)),
|
|
327
|
+
rgba(248,250,255,0.26);
|
|
328
|
+
border-color: rgba(255,255,255,0.6);
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
.light-theme .notif-banner {
|
|
330
332
|
background:
|
|
331
|
-
linear-gradient(180deg, rgba(255,255,255,0.
|
|
332
|
-
rgba(
|
|
333
|
-
|
|
333
|
+
linear-gradient(180deg, rgba(255,255,255,0.58), rgba(255,255,255,0.22)),
|
|
334
|
+
rgba(248,250,255,0.2);
|
|
335
|
+
backdrop-filter: blur(12px) saturate(1.05);
|
|
336
|
+
-webkit-backdrop-filter: blur(12px) saturate(1.05);
|
|
337
|
+
border: 1px solid rgba(255,255,255,0.5);
|
|
334
338
|
box-shadow:
|
|
335
|
-
inset 0 1px 0 rgba(255,255,255,0.
|
|
336
|
-
0 10px 30px rgba(31, 41, 55, 0.
|
|
339
|
+
inset 0 1px 0 rgba(255,255,255,0.72),
|
|
340
|
+
0 10px 30px rgba(31, 41, 55, 0.09);
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
.light-theme .notif-banner:hover {
|
|
340
|
-
border-color: rgba(
|
|
344
|
+
border-color: rgba(255,255,255,0.62);
|
|
341
345
|
box-shadow:
|
|
342
|
-
inset 0 1px 0 rgba(255,255,255,0.
|
|
343
|
-
0 12px 34px rgba(31, 41, 55, 0.
|
|
346
|
+
inset 0 1px 0 rgba(255,255,255,0.8),
|
|
347
|
+
0 12px 34px rgba(31, 41, 55, 0.11);
|
|
344
348
|
}
|
|
345
349
|
|
|
346
350
|
.light-theme .notif-banner-icon {
|
|
347
|
-
background: linear-gradient(180deg, rgba(255,255,255,0.
|
|
348
|
-
border-color: rgba(
|
|
351
|
+
background: linear-gradient(180deg, rgba(255,255,255,0.72), rgba(246,249,255,0.36));
|
|
352
|
+
border-color: rgba(255,255,255,0.52);
|
|
349
353
|
color: var(--text-secondary);
|
|
350
|
-
box-shadow: inset 0 1px 0 rgba(255,255,255,0.
|
|
354
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.78);
|
|
351
355
|
}
|
|
352
356
|
|
|
353
357
|
.light-theme .notif-banner-project {
|