clay-server 2.11.0-beta.19 → 2.11.0-beta.20

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/daemon.js CHANGED
@@ -107,7 +107,7 @@ var relay = createServer({
107
107
  osUsers: config.osUsers || false,
108
108
  lanHost: lanIp ? lanIp + ":" + config.port : null,
109
109
  getRemovedProjects: function (userId) { return getFilteredRemovedProjects(userId); },
110
- onAddProject: function (absPath) {
110
+ onAddProject: function (absPath, wsUser) {
111
111
  // Check if already registered
112
112
  for (var j = 0; j < config.projects.length; j++) {
113
113
  if (config.projects[j].path === absPath) {
@@ -117,7 +117,13 @@ var relay = createServer({
117
117
  var slugs = config.projects.map(function (p) { return p.slug; });
118
118
  var slug = generateSlug(absPath, slugs);
119
119
  relay.addProject(absPath, slug);
120
- config.projects.push({ path: absPath, slug: slug, addedAt: Date.now() });
120
+ var projectEntry = { path: absPath, slug: slug, addedAt: Date.now() };
121
+ // Non-admin users own their projects and they default to private
122
+ if (wsUser && wsUser.id && wsUser.role !== "admin") {
123
+ projectEntry.ownerId = wsUser.id;
124
+ projectEntry.visibility = "private";
125
+ }
126
+ config.projects.push(projectEntry);
121
127
  // Remove from removedProjects if present
122
128
  if (config.removedProjects) {
123
129
  config.removedProjects = config.removedProjects.filter(function (rp) { return rp.path !== absPath; });
@@ -187,8 +193,13 @@ var relay = createServer({
187
193
  }
188
194
  // Register project
189
195
  var projectEntry = { path: targetDir, slug: slug, addedAt: Date.now() };
190
- if (config.osUsers && wsUser) {
191
- projectEntry.ownerId = wsUser.id;
196
+ if (wsUser && wsUser.id) {
197
+ if (config.osUsers || wsUser.role !== "admin") {
198
+ projectEntry.ownerId = wsUser.id;
199
+ }
200
+ if (wsUser.role !== "admin") {
201
+ projectEntry.visibility = "private";
202
+ }
192
203
  }
193
204
  relay.addProject(targetDir, slug);
194
205
  config.projects.push(projectEntry);
@@ -254,8 +265,13 @@ var relay = createServer({
254
265
  }
255
266
  // Register project
256
267
  var projectEntry = { path: targetDir, slug: slug, addedAt: Date.now() };
257
- if (config.osUsers && wsUser) {
258
- projectEntry.ownerId = wsUser.id;
268
+ if (wsUser && wsUser.id) {
269
+ if (config.osUsers || wsUser.role !== "admin") {
270
+ projectEntry.ownerId = wsUser.id;
271
+ }
272
+ if (wsUser.role !== "admin") {
273
+ projectEntry.visibility = "private";
274
+ }
259
275
  }
260
276
  relay.addProject(targetDir, slug);
261
277
  config.projects.push(projectEntry);
package/lib/project.js CHANGED
@@ -1980,7 +1980,7 @@ function createProjectContext(opts) {
1980
1980
  return;
1981
1981
  }
1982
1982
  if (typeof opts.onAddProject === "function") {
1983
- var result = opts.onAddProject(addAbs);
1983
+ var result = opts.onAddProject(addAbs, ws._clayUser);
1984
1984
  sendTo(ws, { type: "add_project_result", ok: result.ok, slug: result.slug, error: result.error, existing: result.existing });
1985
1985
  } else {
1986
1986
  sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
package/lib/sdk-bridge.js CHANGED
@@ -571,20 +571,38 @@ function createSDKBridge(opts) {
571
571
 
572
572
  // --- Worker process management (OS-level multi-user) ---
573
573
 
574
- // Copy sdk-worker.js to a world-readable temp location so OS-level users
575
- // can execute it (the source may be under /root/.npm/_npx/ which is 700)
576
- var WORKER_SCRIPT_SRC = path.join(__dirname, "sdk-worker.js");
577
- var WORKER_SCRIPT = (function () {
578
- var tmpWorker = path.join(os.tmpdir(), "clay-sdk-worker.js");
574
+ var WORKER_SCRIPT = path.join(__dirname, "sdk-worker.js");
575
+
576
+ // Ensure the package directory tree is world-readable so OS-level users
577
+ // can access the worker script and its dependencies (the install path
578
+ // may be under /root/.npm/_npx/ which defaults to 700)
579
+ (function ensurePackageReadable() {
579
580
  try {
580
- // Always copy to ensure it stays in sync with the running version
581
- fs.copyFileSync(WORKER_SCRIPT_SRC, tmpWorker);
582
- fs.chmodSync(tmpWorker, 0o644);
583
- return tmpWorker;
584
- } catch (e) {
585
- // Fallback to source path if copy fails
586
- return WORKER_SCRIPT_SRC;
587
- }
581
+ // Walk up from __dirname to find the package root (where node_modules lives)
582
+ var pkgDir = path.join(__dirname, "..");
583
+ // Open read+execute on each ancestor directory up to and including the
584
+ // npx cache entry so that non-root users can traverse the path
585
+ var dir = pkgDir;
586
+ var dirs = [];
587
+ while (dir !== path.dirname(dir)) {
588
+ dirs.push(dir);
589
+ // Stop once we leave the npm cache tree
590
+ if (dir.indexOf(".npm") === -1 && dir.indexOf("node_modules") === -1) break;
591
+ dir = path.dirname(dir);
592
+ }
593
+ for (var di = 0; di < dirs.length; di++) {
594
+ try {
595
+ var st = fs.statSync(dirs[di]);
596
+ // Add o+rx if not already present
597
+ if ((st.mode & 0o005) !== 0o005) {
598
+ fs.chmodSync(dirs[di], st.mode | 0o005);
599
+ }
600
+ } catch (e) {}
601
+ }
602
+ // Recursively make the package contents readable
603
+ var { execSync: chmodExec } = require("child_process");
604
+ chmodExec("chmod -R o+rX " + JSON.stringify(pkgDir), { stdio: "ignore", timeout: 5000 });
605
+ } catch (e) {}
588
606
  })();
589
607
 
590
608
  // resolveLinuxUser delegates to shared os-users utility
@@ -657,7 +675,7 @@ function createSDKBridge(opts) {
657
675
  HOME: userInfo.home,
658
676
  USER: linuxUser,
659
677
  PATH: process.env.PATH || "/usr/local/bin:/usr/bin:/bin",
660
- NODE_PATH: path.join(__dirname, "..", "node_modules") + (process.env.NODE_PATH ? ":" + process.env.NODE_PATH : ""),
678
+ NODE_PATH: process.env.NODE_PATH || "",
661
679
  LANG: process.env.LANG || "en_US.UTF-8",
662
680
  };
663
681
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.11.0-beta.19",
3
+ "version": "2.11.0-beta.20",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",