clay-server 2.34.0-beta.7 → 2.34.0-beta.9
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/os-users.js +13 -0
- package/lib/project-connection.js +0 -9
- package/lib/project-sessions.js +5 -4
- package/lib/project-user-message.js +4 -3
- package/lib/project.js +23 -3
- package/package.json +1 -1
package/lib/os-users.js
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
var fs = require("fs");
|
|
5
5
|
var path = require("path");
|
|
6
6
|
var execFileSync = require("child_process").execFileSync;
|
|
7
|
+
var _aclGrantCache = Object.create(null);
|
|
8
|
+
|
|
9
|
+
function aclCacheKey(projectPath, linuxUser) {
|
|
10
|
+
return path.resolve(projectPath) + "::" + linuxUser;
|
|
11
|
+
}
|
|
7
12
|
|
|
8
13
|
function isSafeLinuxUsername(username) {
|
|
9
14
|
return typeof username === "string" && /^[a-z_][a-z0-9_-]*[$]?$/.test(username);
|
|
@@ -191,6 +196,10 @@ function grantProjectAccess(projectPath, linuxUser) {
|
|
|
191
196
|
console.error("[os-users] Invalid Linux username for ACL grant: " + linuxUser);
|
|
192
197
|
return;
|
|
193
198
|
}
|
|
199
|
+
var cacheKey = aclCacheKey(projectPath, linuxUser);
|
|
200
|
+
if (_aclGrantCache[cacheKey]) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
194
203
|
try {
|
|
195
204
|
// Recursive ACL for existing files
|
|
196
205
|
execFileSync("setfacl", ["-R", "-m", "u:" + linuxUser + ":rwX", projectPath], {
|
|
@@ -204,8 +213,10 @@ function grantProjectAccess(projectPath, linuxUser) {
|
|
|
204
213
|
timeout: 30000,
|
|
205
214
|
stdio: "pipe",
|
|
206
215
|
});
|
|
216
|
+
_aclGrantCache[cacheKey] = true;
|
|
207
217
|
console.log("[os-users] Granted ACL access for " + linuxUser + " on " + projectPath);
|
|
208
218
|
} catch (e) {
|
|
219
|
+
delete _aclGrantCache[cacheKey];
|
|
209
220
|
var errMsg = (e.stderr || e.message || "").toString();
|
|
210
221
|
if (errMsg.indexOf("not found") !== -1 || errMsg.indexOf("ENOENT") !== -1) {
|
|
211
222
|
var cmd = getAclInstallCommand();
|
|
@@ -229,6 +240,7 @@ function revokeProjectAccess(projectPath, linuxUser) {
|
|
|
229
240
|
console.error("[os-users] Invalid Linux username for ACL revoke: " + linuxUser);
|
|
230
241
|
return;
|
|
231
242
|
}
|
|
243
|
+
var cacheKey = aclCacheKey(projectPath, linuxUser);
|
|
232
244
|
try {
|
|
233
245
|
execFileSync("setfacl", ["-R", "-x", "u:" + linuxUser, projectPath], {
|
|
234
246
|
encoding: "utf8",
|
|
@@ -240,6 +252,7 @@ function revokeProjectAccess(projectPath, linuxUser) {
|
|
|
240
252
|
timeout: 30000,
|
|
241
253
|
stdio: "pipe",
|
|
242
254
|
});
|
|
255
|
+
delete _aclGrantCache[cacheKey];
|
|
243
256
|
console.log("[os-users] Revoked ACL access for " + linuxUser + " on " + projectPath);
|
|
244
257
|
} catch (e) {
|
|
245
258
|
var errMsg = (e.stderr || e.message || "").toString();
|
|
@@ -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;
|
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;
|
|
@@ -803,7 +804,7 @@ function attachSessions(ctx) {
|
|
|
803
804
|
session.sentToolResults = {};
|
|
804
805
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
805
806
|
if (!session.queryInstance && !session.worker) {
|
|
806
|
-
sdk.startQuery(session, answerText, undefined,
|
|
807
|
+
sdk.startQuery(session, answerText, undefined, ensureProjectAccessForSession(session));
|
|
807
808
|
} else {
|
|
808
809
|
sdk.pushMessage(session, answerText);
|
|
809
810
|
}
|
|
@@ -932,7 +933,7 @@ function attachSessions(ctx) {
|
|
|
932
933
|
newSession.sentToolResults = {};
|
|
933
934
|
sendToSession(newSession.localId, { type: "status", status: "processing" });
|
|
934
935
|
newSession.acceptEditsAfterStart = true;
|
|
935
|
-
sdk.startQuery(newSession, planPrompt, undefined,
|
|
936
|
+
sdk.startQuery(newSession, planPrompt, undefined, ensureProjectAccessForSession(newSession));
|
|
936
937
|
} catch (e) {
|
|
937
938
|
console.error("[project] Error starting plan execution:", e);
|
|
938
939
|
sendTo(ws, { type: "error", text: "Failed to start plan execution: " + (e.message || e) });
|
|
@@ -963,7 +964,7 @@ function attachSessions(ctx) {
|
|
|
963
964
|
session.sentToolResults = {};
|
|
964
965
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
965
966
|
if (!session.queryInstance && !session.worker) {
|
|
966
|
-
sdk.startQuery(session, feedback, undefined,
|
|
967
|
+
sdk.startQuery(session, feedback, undefined, ensureProjectAccessForSession(session));
|
|
967
968
|
} else {
|
|
968
969
|
sdk.pushMessage(session, feedback);
|
|
969
970
|
}
|
|
@@ -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");
|
|
@@ -160,6 +160,7 @@ function createProjectContext(opts) {
|
|
|
160
160
|
var serverTls = opts.tls || false;
|
|
161
161
|
var serverAuthToken = opts.authToken || null;
|
|
162
162
|
var latestVersion = null;
|
|
163
|
+
var sessionTitleMigrationScheduled = false;
|
|
163
164
|
|
|
164
165
|
// --- YOKE adapters (multi-vendor, lazy init) ---
|
|
165
166
|
var _yokeState = yoke.createAdapters({ cwd: cwd, slug: slug });
|
|
@@ -187,6 +188,14 @@ function createProjectContext(opts) {
|
|
|
187
188
|
return user.linuxUser;
|
|
188
189
|
}
|
|
189
190
|
|
|
191
|
+
function ensureProjectAccessForSession(session) {
|
|
192
|
+
var linuxUser = getLinuxUserForSession(session);
|
|
193
|
+
if (linuxUser) {
|
|
194
|
+
grantProjectAccess(cwd, linuxUser);
|
|
195
|
+
}
|
|
196
|
+
return linuxUser;
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
function getLinuxUserForWs(ws) {
|
|
191
200
|
if (!osUsers) return null;
|
|
192
201
|
if (!ws._clayUser || !ws._clayUser.linuxUser) return null;
|
|
@@ -799,7 +808,7 @@ function createProjectContext(opts) {
|
|
|
799
808
|
session.isProcessing = true;
|
|
800
809
|
onProcessingChanged();
|
|
801
810
|
sendToSession(session.localId, { type: "status", status: "processing" });
|
|
802
|
-
sdk.startQuery(session, text, null,
|
|
811
|
+
sdk.startQuery(session, text, null, ensureProjectAccessForSession(session));
|
|
803
812
|
sm.broadcastSessionList();
|
|
804
813
|
}, schedDelay),
|
|
805
814
|
};
|
|
@@ -1133,6 +1142,7 @@ function createProjectContext(opts) {
|
|
|
1133
1142
|
pushModule: pushModule,
|
|
1134
1143
|
getSessionForWs: getSessionForWs,
|
|
1135
1144
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1145
|
+
ensureProjectAccessForSession: ensureProjectAccessForSession,
|
|
1136
1146
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
1137
1147
|
hydrateImageRefs: hydrateImageRefs,
|
|
1138
1148
|
onProcessingChanged: onProcessingChanged,
|
|
@@ -1181,6 +1191,7 @@ function createProjectContext(opts) {
|
|
|
1181
1191
|
matesModule: matesModule,
|
|
1182
1192
|
getSessionForWs: getSessionForWs,
|
|
1183
1193
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1194
|
+
ensureProjectAccessForSession: ensureProjectAccessForSession,
|
|
1184
1195
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
1185
1196
|
hydrateImageRefs: hydrateImageRefs,
|
|
1186
1197
|
saveImageFile: saveImageFile,
|
|
@@ -1380,7 +1391,16 @@ function createProjectContext(opts) {
|
|
|
1380
1391
|
warmup: function () {
|
|
1381
1392
|
sdk.warmup();
|
|
1382
1393
|
sdk.startIdleReaper();
|
|
1383
|
-
|
|
1394
|
+
if (!osUsers && !sessionTitleMigrationScheduled) {
|
|
1395
|
+
sessionTitleMigrationScheduled = true;
|
|
1396
|
+
setTimeout(function () {
|
|
1397
|
+
try {
|
|
1398
|
+
sm.migrateSessionTitles(adapter, cwd);
|
|
1399
|
+
} catch (e) {
|
|
1400
|
+
console.error("[project] Session title migration failed for " + slug + ":", e && e.message ? e.message : e);
|
|
1401
|
+
}
|
|
1402
|
+
}, 5000);
|
|
1403
|
+
}
|
|
1384
1404
|
},
|
|
1385
1405
|
});
|
|
1386
1406
|
|