clay-server 5.2.0-beta.3 → 5.2.0-beta.4

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 (193) hide show
  1. package/lib/builtin-mates.js +2 -2
  2. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  3. package/lib/knowledge-file-store.js +7 -1
  4. package/lib/mate-avatar-catalog.js +12 -0
  5. package/lib/mate-avatar-migration.js +41 -0
  6. package/lib/mates.js +14 -3
  7. package/lib/mcp-agent-tools.js +117 -0
  8. package/lib/mcp-connection-store.js +119 -15
  9. package/lib/mcp-import-credentials.js +31 -0
  10. package/lib/mcp-local-transport.js +13 -0
  11. package/lib/mcp-oauth.js +8 -6
  12. package/lib/mcp-query-bridge.js +30 -0
  13. package/lib/mcp-remote-connections.js +74 -20
  14. package/lib/mcp-source-adapters.js +91 -0
  15. package/lib/mcp-source-context.js +42 -0
  16. package/lib/mcp-source-discovery.js +169 -0
  17. package/lib/mcp-source-plugins.js +68 -0
  18. package/lib/mcp-source-restrictions.js +47 -0
  19. package/lib/mcp-tool-policy.js +34 -0
  20. package/lib/project-ask-user.js +6 -4
  21. package/lib/project-debate.js +1 -0
  22. package/lib/project-mate-interaction.js +8 -0
  23. package/lib/project-mcp.js +54 -16
  24. package/lib/project-session-document.js +8 -3
  25. package/lib/project-session-github.js +16 -7
  26. package/lib/project-session-linear.js +14 -6
  27. package/lib/project-session-notes.js +7 -3
  28. package/lib/project-sessions.js +6 -2
  29. package/lib/project-shared-browser.js +56 -12
  30. package/lib/project.js +49 -34
  31. package/lib/public/app.js +5 -0
  32. package/lib/public/appearance-bootstrap.js +14 -0
  33. package/lib/public/css/clay-workspace.css +29 -0
  34. package/lib/public/css/home-debate-planning.css +2 -0
  35. package/lib/public/css/mate-avatar-gallery.css +12 -0
  36. package/lib/public/css/mate-conversation.css +10 -5
  37. package/lib/public/css/session-github.css +43 -1
  38. package/lib/public/css/shared-browser.css +35 -1
  39. package/lib/public/index.html +10 -4
  40. package/lib/public/mate-avatars/B01.png +0 -0
  41. package/lib/public/mate-avatars/B02.png +0 -0
  42. package/lib/public/mate-avatars/B03.png +0 -0
  43. package/lib/public/mate-avatars/B04.png +0 -0
  44. package/lib/public/mate-avatars/B05.png +0 -0
  45. package/lib/public/mate-avatars/B06.png +0 -0
  46. package/lib/public/mate-avatars/B07.png +0 -0
  47. package/lib/public/mate-avatars/B08.png +0 -0
  48. package/lib/public/mate-avatars/B09.png +0 -0
  49. package/lib/public/mate-avatars/B10.png +0 -0
  50. package/lib/public/mate-avatars/B11.png +0 -0
  51. package/lib/public/mate-avatars/B12.png +0 -0
  52. package/lib/public/mate-avatars/B13.png +0 -0
  53. package/lib/public/mate-avatars/B14.png +0 -0
  54. package/lib/public/mate-avatars/B15.png +0 -0
  55. package/lib/public/mate-avatars/B16.png +0 -0
  56. package/lib/public/mate-avatars/B17.png +0 -0
  57. package/lib/public/mate-avatars/B18.png +0 -0
  58. package/lib/public/mate-avatars/B19.png +0 -0
  59. package/lib/public/mate-avatars/B20.png +0 -0
  60. package/lib/public/mate-avatars/B21.png +0 -0
  61. package/lib/public/mate-avatars/B22.png +0 -0
  62. package/lib/public/mate-avatars/B23.png +0 -0
  63. package/lib/public/mate-avatars/B24.png +0 -0
  64. package/lib/public/mate-avatars/B25.png +0 -0
  65. package/lib/public/mate-avatars/B26.png +0 -0
  66. package/lib/public/mate-avatars/B27.png +0 -0
  67. package/lib/public/mate-avatars/B28.png +0 -0
  68. package/lib/public/mate-avatars/B29.png +0 -0
  69. package/lib/public/mate-avatars/B30.png +0 -0
  70. package/lib/public/mate-avatars/B31.png +0 -0
  71. package/lib/public/mate-avatars/B32.png +0 -0
  72. package/lib/public/mate-avatars/B33.png +0 -0
  73. package/lib/public/mate-avatars/B34.png +0 -0
  74. package/lib/public/mate-avatars/B35.png +0 -0
  75. package/lib/public/mate-avatars/B36.png +0 -0
  76. package/lib/public/mate-avatars/B37.png +0 -0
  77. package/lib/public/mate-avatars/B38.png +0 -0
  78. package/lib/public/mate-avatars/B39.png +0 -0
  79. package/lib/public/mate-avatars/B40.png +0 -0
  80. package/lib/public/mate-avatars/B41.png +0 -0
  81. package/lib/public/mate-avatars/B42.png +0 -0
  82. package/lib/public/mate-avatars/B43.png +0 -0
  83. package/lib/public/mate-avatars/B44.png +0 -0
  84. package/lib/public/mate-avatars/B45.png +0 -0
  85. package/lib/public/mate-avatars/B46.png +0 -0
  86. package/lib/public/mate-avatars/B47.png +0 -0
  87. package/lib/public/mate-avatars/B48.png +0 -0
  88. package/lib/public/mate-avatars/C01.png +0 -0
  89. package/lib/public/mate-avatars/C02.png +0 -0
  90. package/lib/public/mate-avatars/C03.png +0 -0
  91. package/lib/public/mate-avatars/C04.png +0 -0
  92. package/lib/public/mate-avatars/C05.png +0 -0
  93. package/lib/public/mate-avatars/C06.png +0 -0
  94. package/lib/public/mate-avatars/C07.png +0 -0
  95. package/lib/public/mate-avatars/C08.png +0 -0
  96. package/lib/public/mate-avatars/C09.png +0 -0
  97. package/lib/public/mate-avatars/C10.png +0 -0
  98. package/lib/public/mate-avatars/C11.png +0 -0
  99. package/lib/public/mate-avatars/C12.png +0 -0
  100. package/lib/public/mate-avatars/C13.png +0 -0
  101. package/lib/public/mate-avatars/C14.png +0 -0
  102. package/lib/public/mate-avatars/C15.png +0 -0
  103. package/lib/public/mate-avatars/C16.png +0 -0
  104. package/lib/public/mate-avatars/C17.png +0 -0
  105. package/lib/public/mate-avatars/C18.png +0 -0
  106. package/lib/public/mate-avatars/C19.png +0 -0
  107. package/lib/public/mate-avatars/C20.png +0 -0
  108. package/lib/public/mate-avatars/C21.png +0 -0
  109. package/lib/public/mate-avatars/C22.png +0 -0
  110. package/lib/public/mate-avatars/C23.png +0 -0
  111. package/lib/public/mate-avatars/C24.png +0 -0
  112. package/lib/public/mate-avatars/C25.png +0 -0
  113. package/lib/public/mate-avatars/C26.png +0 -0
  114. package/lib/public/mate-avatars/C27.png +0 -0
  115. package/lib/public/mate-avatars/C28.png +0 -0
  116. package/lib/public/mate-avatars/C29.png +0 -0
  117. package/lib/public/mate-avatars/C30.png +0 -0
  118. package/lib/public/mate-avatars/C31.png +0 -0
  119. package/lib/public/mate-avatars/C32.png +0 -0
  120. package/lib/public/mate-avatars/C33.png +0 -0
  121. package/lib/public/mate-avatars/C34.png +0 -0
  122. package/lib/public/mate-avatars/C35.png +0 -0
  123. package/lib/public/mate-avatars/C36.png +0 -0
  124. package/lib/public/mate-avatars/C37.png +0 -0
  125. package/lib/public/mate-avatars/C38.png +0 -0
  126. package/lib/public/mate-avatars/C39.png +0 -0
  127. package/lib/public/mate-avatars/C40.png +0 -0
  128. package/lib/public/mate-avatars/C41.png +0 -0
  129. package/lib/public/mate-avatars/C42.png +0 -0
  130. package/lib/public/mate-avatars/C43.png +0 -0
  131. package/lib/public/mate-avatars/C44.png +0 -0
  132. package/lib/public/mate-avatars/C45.png +0 -0
  133. package/lib/public/mate-avatars/C46.png +0 -0
  134. package/lib/public/mate-avatars/C47.png +0 -0
  135. package/lib/public/mate-avatars/C48.png +0 -0
  136. package/lib/public/mate-avatars/catalog.json +482 -0
  137. package/lib/public/mate-avatars/lead-clay.png +0 -0
  138. package/lib/public/modules/app-message-router.js +4 -0
  139. package/lib/public/modules/app-messages.js +13 -2
  140. package/lib/public/modules/app-rendering.js +1 -1
  141. package/lib/public/modules/avatar.js +15 -41
  142. package/lib/public/modules/chat-render-runtime.js +10 -1
  143. package/lib/public/modules/clay-browser-links.js +47 -0
  144. package/lib/public/modules/clay-log-links.js +1 -1
  145. package/lib/public/modules/command-palette.js +1 -1
  146. package/lib/public/modules/debate.js +1 -0
  147. package/lib/public/modules/history-replay-batch.js +5 -1
  148. package/lib/public/modules/home-debate-live.js +2 -0
  149. package/lib/public/modules/home-debate-planning.js +7 -7
  150. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  151. package/lib/public/modules/home-mate-chat.js +6 -6
  152. package/lib/public/modules/home-mate-settings.js +19 -12
  153. package/lib/public/modules/markdown.js +4 -0
  154. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  155. package/lib/public/modules/mate-management.js +40 -7
  156. package/lib/public/modules/mcp-connection-view.js +31 -13
  157. package/lib/public/modules/mcp-discovery-view.js +31 -0
  158. package/lib/public/modules/mcp-ui.js +23 -4
  159. package/lib/public/modules/mention.js +3 -0
  160. package/lib/public/modules/pane-browser-bridge.js +20 -0
  161. package/lib/public/modules/profile.js +1 -238
  162. package/lib/public/modules/project-mate-navigation.js +99 -14
  163. package/lib/public/modules/search-clay-chat.js +16 -2
  164. package/lib/public/modules/session-github.js +23 -9
  165. package/lib/public/modules/session-work-primary.js +51 -0
  166. package/lib/public/modules/shared-browser-settings.js +112 -0
  167. package/lib/public/modules/shared-browser-tabs.js +13 -3
  168. package/lib/public/modules/shared-browser.js +27 -6
  169. package/lib/public/modules/split-view.js +2 -0
  170. package/lib/public/modules/theme.js +8 -1
  171. package/lib/public/modules/tools.js +2 -1
  172. package/lib/public/style.css +1 -0
  173. package/lib/public/sw.js +3 -1
  174. package/lib/sdk-bridge.js +9 -3
  175. package/lib/server-appearance-settings.js +13 -1
  176. package/lib/server-dm.js +1 -0
  177. package/lib/server-home-chat-events.js +14 -4
  178. package/lib/server-home-chat.js +10 -2
  179. package/lib/server-home-mcp-consent.js +14 -0
  180. package/lib/server-mates.js +6 -1
  181. package/lib/server-settings.js +4 -1
  182. package/lib/server.js +45 -12
  183. package/lib/session-work-primary.js +50 -0
  184. package/lib/sessions.js +3 -0
  185. package/lib/shared-browser-cookie-sync.js +32 -0
  186. package/lib/shared-browser-cookies.js +79 -0
  187. package/lib/shared-browser-runtime.js +25 -9
  188. package/lib/shared-browser-storage-sync.js +43 -0
  189. package/lib/shared-browser-storage.js +101 -0
  190. package/lib/shared-browser-tools.js +2 -1
  191. package/lib/shared-browser-worker.js +46 -10
  192. package/lib/yoke/acp-agent-profiles.js +2 -2
  193. package/package.json +5 -1
@@ -10,11 +10,14 @@ var epoch = 0;
10
10
  var queue = Promise.resolve();
11
11
  var pending = 0;
12
12
  var timer = null;
13
+ var cookieSync = null;
14
+ var cookieTimer = null;
15
+ var closeRequested = false;
13
16
  var activeActivity = null;
14
17
  var pointerSequence = 0;
15
18
  var viewport = { width: 1280, height: 800 };
16
19
  function emit(message) {
17
- if (!closing && process.stdout.writableLength < 3 * 1024 * 1024) process.stdout.write(JSON.stringify(message) + "\n");
20
+ if (!closing && process.stdout.writableLength < 32 * 1024 * 1024) process.stdout.write(JSON.stringify(message) + "\n");
18
21
  }
19
22
  function state() {
20
23
  return { url: page ? policy.visibleUrl(page.url()) : "", width: viewport.width, height: viewport.height };
@@ -33,7 +36,7 @@ async function capture() {
33
36
  } catch (e) {}
34
37
  if (!closing) timer = setTimeout(capture, 250);
35
38
  }
36
- async function start() {
39
+ async function start(message) {
37
40
  var channels = ["chrome", "msedge", null];
38
41
  for (var i = 0; i < channels.length; i++) {
39
42
  try { browser = await chromium.launch({ channel: channels[i] || undefined, headless: true, chromiumSandbox: true, timeout: 15000 }); break; }
@@ -45,6 +48,15 @@ async function start() {
45
48
  var version = await cdp.send("Browser.getVersion");
46
49
  await cdp.detach();
47
50
  context = await browser.newContext({ viewport: viewport, acceptDownloads: false, userAgent: version.userAgent.replace("HeadlessChrome/", "Chrome/") });
51
+ if (message.storage) {
52
+ cookieSync = require("./shared-browser-storage-sync").attachStorageSync(context, message.storage, emit);
53
+ await cookieSync.start();
54
+ scheduleCookieSync();
55
+ } else if (message.cookies) {
56
+ cookieSync = require("./shared-browser-cookie-sync").attachCookieSync(context, message.cookies, emit);
57
+ await cookieSync.start();
58
+ scheduleCookieSync();
59
+ }
48
60
  await context.addInitScript(require("./vendor-login-browser-passkeys").disableLoginPasskeys);
49
61
  await context.route("**/*", function (route) {
50
62
  var protocol = new URL(route.request().url()).protocol;
@@ -55,13 +67,19 @@ async function start() {
55
67
  opened.setDefaultTimeout(10000);
56
68
  opened.on("dialog", function (dialog) { dialog.dismiss().catch(function () {}); });
57
69
  opened.on("download", function (download) { download.cancel().catch(function () {}); });
58
- opened.on("framenavigated", function (frame) { if (frame === opened.mainFrame() && page === opened) emit(Object.assign({ type: "state" }, state())); });
70
+ opened.on("framenavigated", function (frame) { if (frame === opened.mainFrame() && page === opened) emit(Object.assign({ type: "navigation", navigationUrl: opened.url() }, state())); });
59
71
  opened.on("close", function () { var pages = context.pages(); page = pages.length ? pages[pages.length - 1] : null; emit(Object.assign({ type: "state" }, state())); });
60
72
  });
61
73
  page = await context.newPage();
62
74
  emit(Object.assign({ type: "ready" }, state()));
63
75
  capture();
64
76
  }
77
+ function scheduleCookieSync() {
78
+ if (closeRequested || closing) return;
79
+ cookieTimer = setTimeout(function () {
80
+ queue = queue.then(function () { return cookieSync.sync(); }).catch(function () { emit({ type: "error", error: "Could not save personal browser site data" }); }).finally(scheduleCookieSync);
81
+ }, 2000);
82
+ }
65
83
  function reportActivity(phase) {
66
84
  if (activeActivity) emit({ type: "activity", epoch: activeActivity.epoch, generation: activeActivity.generation,
67
85
  activity: { id: activeActivity.id, text: activeActivity.text, phase: phase } });
@@ -126,6 +144,9 @@ async function command(message) {
126
144
  }
127
145
  async function close() {
128
146
  if (closing) return;
147
+ closeRequested = true;
148
+ clearTimeout(cookieTimer);
149
+ if (cookieSync) await cookieSync.sync().catch(function () {});
129
150
  closing = true;
130
151
  clearTimeout(timer);
131
152
  if (browser) await browser.close().catch(function () {});
@@ -133,11 +154,14 @@ async function close() {
133
154
  }
134
155
  var lines = require("readline").createInterface({ input: process.stdin });
135
156
  lines.on("line", function (line) {
136
- if (line.length > 30000 || closing) return;
157
+ if (line.length > 32 * 1024 * 1024 || closing) return;
137
158
  var msg;
138
159
  try { msg = JSON.parse(line); } catch (e) { return; }
160
+ if (msg.type === "cookies" || msg.type === "storage") { if (cookieSync) cookieSync.receive(msg); return; }
161
+ if (msg.type === "close") { closeRequested = true; clearTimeout(cookieTimer); queue = queue.then(close); return; }
162
+ if (closeRequested) return;
139
163
  if (msg.type === "start") {
140
- if (!browser) queue = queue.then(start).catch(function (e) { emit({ type: "error", error: e.message }); });
164
+ if (!browser) queue = queue.then(function () { return start(msg); }).catch(function (e) { emit({ type: "error", error: e.message }); });
141
165
  } else if (msg.type === "viewing") viewing = !!msg.value;
142
166
  else if (msg.type === "control") {
143
167
  epoch = msg.epoch;
@@ -147,17 +171,29 @@ lines.on("line", function (line) {
147
171
  });
148
172
  } else if (msg.type === "settle") {
149
173
  // Resolves only after every earlier queued command has finished and reported its telemetry.
150
- queue = queue.then(function () { emit({ type: "result", id: msg.id, value: { through: msg.id } }); });
174
+ queue = queue.then(async function () {
175
+ if (cookieSync) await cookieSync.sync();
176
+ emit({ type: "result", id: msg.id, value: { through: msg.id } });
177
+ }).catch(function (error) { emit({ type: "result", id: msg.id, error: error.message }); });
151
178
  } else if (msg.type === "command") {
152
179
  if (pending >= 80) { emit({ type: "result", id: msg.id, error: "Browser is busy; retry shortly" }); return; }
153
180
  pending++;
154
- queue = queue.then(function () { return command(msg); }).then(function (value) {
181
+ queue = queue.then(async function () {
182
+ if (cookieSync) await cookieSync.sync();
183
+ try { return await command(msg); }
184
+ finally { if (cookieSync) await cookieSync.sync(); }
185
+ }).then(function (value) {
155
186
  reportActivity("complete"); activeActivity = null;
156
187
  emit({ type: "result", id: msg.id, value: value });
157
188
  emit(Object.assign({ type: "state" }, state()));
158
189
  }, function (e) { reportActivity("failed"); activeActivity = null; emit({ type: "result", id: msg.id, error: e.message }); }).finally(function () { pending--; });
159
190
  }
160
191
  });
161
- lines.on("close", close);
162
- process.on("SIGTERM", close);
163
- process.on("SIGINT", close);
192
+ function requestClose() {
193
+ if (closeRequested) return;
194
+ closeRequested = true; clearTimeout(cookieTimer);
195
+ queue = queue.then(close);
196
+ }
197
+ lines.on("close", requestClose);
198
+ process.on("SIGTERM", requestClose);
199
+ process.on("SIGINT", requestClose);
@@ -50,7 +50,7 @@ function fetchOpenCodeResolvedConfig(binaryPath, cwd, env) {
50
50
  return new Promise(function(resolve, reject) {
51
51
  execFile(binaryPath, ["debug", "config"], {
52
52
  cwd: cwd || process.cwd(),
53
- env: Object.assign({}, process.env, env || {}),
53
+ env: env ? Object.assign({}, env) : process.env,
54
54
  timeout: 30000,
55
55
  maxBuffer: 4 * 1024 * 1024,
56
56
  }, function(err, stdout) {
@@ -141,7 +141,7 @@ var ACP_AGENT_PROFILES = {
141
141
  });
142
142
  },
143
143
  buildProcessOptions: function(ctx, base) {
144
- var existing = (base.env && base.env.OPENCODE_CONFIG_CONTENT) || process.env.OPENCODE_CONFIG_CONTENT;
144
+ var existing = base.env ? base.env.OPENCODE_CONFIG_CONTENT : process.env.OPENCODE_CONFIG_CONTENT;
145
145
  var config = {};
146
146
  if (existing) config = JSON.parse(existing);
147
147
  var agent = Object.assign({}, config.agent || {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "5.2.0-beta.3",
3
+ "version": "5.2.0-beta.4",
4
4
  "description": "Self-hosted team workspace for Claude Code and Codex. Multi-user, browser-based, with persistent AI mates.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js"
@@ -56,6 +56,7 @@
56
56
  "@dicebear/micah": "9.4.3",
57
57
  "@dicebear/pixel-art": "9.4.3",
58
58
  "@dicebear/thumbs": "9.4.3",
59
+ "@iarna/toml": "^2.2.5",
59
60
  "@lydell/node-pty": "^1.2.0-beta.3",
60
61
  "@modelcontextprotocol/sdk": "^1.32.1",
61
62
  "@openai/codex": "^0.162.1",
@@ -64,12 +65,15 @@
64
65
  "codemirror": "^5.65.21",
65
66
  "imapflow": "^1.7.8",
66
67
  "ipaddr.js": "^2.5.0",
68
+ "jsonc-parser": "^3.3.1",
67
69
  "nodemailer": "^9.1.1",
68
70
  "playwright": "1.63.0",
69
71
  "qrcode-terminal": "^0.12.0",
72
+ "semver": "^7.8.5",
70
73
  "undici": "^6.13.0",
71
74
  "web-push": "^3.6.7",
72
75
  "ws": "^8.18.0",
76
+ "yaml": "^2.9.1",
73
77
  "zod": "^4.6.5"
74
78
  },
75
79
  "license": "AGPL-3.0-only",