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

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 (339) hide show
  1. package/lib/account-auth-socket.js +1 -0
  2. package/lib/builtin-mates.js +19 -16
  3. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  4. package/lib/canonical-clay-record-authority.js +15 -0
  5. package/lib/canonical-clay-scheduling-authority.js +19 -0
  6. package/lib/claude-hook-installer.js +28 -0
  7. package/lib/clay-mate-chat-receipts.js +26 -0
  8. package/lib/clay-mate-chat.js +87 -0
  9. package/lib/clay-mate-knowledge-input.js +26 -0
  10. package/lib/clay-mate-knowledge.js +95 -0
  11. package/lib/clay-mate-lifecycle.js +95 -0
  12. package/lib/clay-product-control-input.js +33 -0
  13. package/lib/clay-product-control-tools.js +51 -0
  14. package/lib/clay-product-control.js +237 -0
  15. package/lib/clay-project-lifecycle.js +154 -0
  16. package/lib/clay-project-record-input.js +44 -0
  17. package/lib/clay-project-records.js +83 -0
  18. package/lib/clay-scheduling-input.js +21 -0
  19. package/lib/clay-scheduling-receipts.js +26 -0
  20. package/lib/clay-scheduling.js +119 -0
  21. package/lib/clay-screen-controls.js +96 -0
  22. package/lib/clay-workspace-controls.js +83 -0
  23. package/lib/clay-workspace-input.js +17 -0
  24. package/lib/clay-workspace-receipts.js +26 -0
  25. package/lib/daemon-project-access.js +11 -0
  26. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  27. package/lib/daemon-project-lifecycle.js +262 -0
  28. package/lib/daemon-projects.js +1 -1
  29. package/lib/daemon.js +73 -221
  30. package/lib/issues-service.js +29 -15
  31. package/lib/knowledge-db-import.js +5 -4
  32. package/lib/knowledge-db-service.js +9 -6
  33. package/lib/knowledge-document-index.js +2 -1
  34. package/lib/knowledge-file-store.js +7 -1
  35. package/lib/knowledge-product-operations.js +46 -0
  36. package/lib/mate-avatar-catalog.js +12 -0
  37. package/lib/mate-avatar-migration.js +41 -0
  38. package/lib/mate-creation-mcp-server.js +2 -0
  39. package/lib/mate-knowledge-canonical-access.js +10 -0
  40. package/lib/mate-knowledge-service.js +7 -4
  41. package/lib/mate-lifecycle-service.js +94 -0
  42. package/lib/mate-message-delivery.js +43 -0
  43. package/lib/mate-ready-creation.js +9 -1
  44. package/lib/mate-schedule-input.js +29 -0
  45. package/lib/mate-schedule-lifecycle.js +151 -0
  46. package/lib/mate-scheduling.js +103 -0
  47. package/lib/mates.js +18 -6
  48. package/lib/mcp-agent-tools.js +117 -0
  49. package/lib/mcp-connection-store.js +119 -15
  50. package/lib/mcp-import-credentials.js +31 -0
  51. package/lib/mcp-local-transport.js +13 -0
  52. package/lib/mcp-oauth.js +8 -6
  53. package/lib/mcp-query-bridge.js +30 -0
  54. package/lib/mcp-remote-connections.js +74 -20
  55. package/lib/mcp-source-adapters.js +91 -0
  56. package/lib/mcp-source-context.js +42 -0
  57. package/lib/mcp-source-discovery.js +169 -0
  58. package/lib/mcp-source-plugins.js +68 -0
  59. package/lib/mcp-source-restrictions.js +47 -0
  60. package/lib/mcp-tool-policy.js +34 -0
  61. package/lib/notes-checklist.js +50 -0
  62. package/lib/notes.js +49 -3
  63. package/lib/os-users.js +20 -5
  64. package/lib/project-admin-overview.js +51 -0
  65. package/lib/project-ask-user.js +8 -4
  66. package/lib/project-debate.js +1 -0
  67. package/lib/project-delegated-follow-up.js +2 -1
  68. package/lib/project-directory-claim.js +65 -0
  69. package/lib/project-file-operations.js +61 -0
  70. package/lib/project-filesystem.js +13 -87
  71. package/lib/project-full-access.js +23 -2
  72. package/lib/project-knowledge.js +32 -18
  73. package/lib/project-lifecycle-operations.js +98 -0
  74. package/lib/project-lifecycle-process-witness.js +32 -0
  75. package/lib/project-lifecycle-runtime.js +50 -0
  76. package/lib/project-linux-access.js +22 -0
  77. package/lib/project-logs-canonical-clay.js +27 -0
  78. package/lib/project-logs-clay-query.js +16 -0
  79. package/lib/project-logs-schema.js +4 -2
  80. package/lib/project-logs-service.js +8 -7
  81. package/lib/project-logs.js +1 -0
  82. package/lib/project-loop.js +1 -0
  83. package/lib/project-mate-chat-control.js +55 -0
  84. package/lib/project-mate-creation-proposal.js +18 -3
  85. package/lib/project-mate-interaction.js +8 -0
  86. package/lib/project-mcp.js +54 -16
  87. package/lib/project-models.js +14 -31
  88. package/lib/project-notifications.js +74 -16
  89. package/lib/project-ownership.js +77 -0
  90. package/lib/project-pair-result-delivery.js +14 -3
  91. package/lib/project-pending-message-queue.js +1 -0
  92. package/lib/project-product-control.js +87 -0
  93. package/lib/project-product-session-queue.js +46 -0
  94. package/lib/project-push-access.js +28 -0
  95. package/lib/project-scheduled-message-queue.js +30 -0
  96. package/lib/project-scheduled-messages.js +63 -64
  97. package/lib/project-scheduled-task-control.js +83 -0
  98. package/lib/project-scheduled-tasks.js +13 -2
  99. package/lib/project-scheduling-access.js +10 -0
  100. package/lib/project-session-actions.js +65 -0
  101. package/lib/project-session-delete.js +8 -1
  102. package/lib/project-session-document.js +8 -3
  103. package/lib/project-session-github.js +63 -19
  104. package/lib/project-session-history-actions.js +165 -0
  105. package/lib/project-session-linear.js +14 -6
  106. package/lib/project-session-notes.js +7 -3
  107. package/lib/project-session-runtime-actions.js +63 -0
  108. package/lib/project-session-vendor.js +54 -0
  109. package/lib/project-sessions.js +68 -241
  110. package/lib/project-shared-browser.js +56 -12
  111. package/lib/project-user-message.js +30 -1
  112. package/lib/project-workspace-operations.js +126 -0
  113. package/lib/project-workspace-query.js +9 -2
  114. package/lib/project.js +144 -37
  115. package/lib/public/app.js +5 -0
  116. package/lib/public/appearance-bootstrap.js +14 -0
  117. package/lib/public/css/clay-tool-activity.css +51 -0
  118. package/lib/public/css/clay-workspace.css +29 -0
  119. package/lib/public/css/home-debate-planning.css +2 -0
  120. package/lib/public/css/home-mate-creation.css +5 -0
  121. package/lib/public/css/mate-avatar-gallery.css +12 -0
  122. package/lib/public/css/mate-conversation.css +10 -5
  123. package/lib/public/css/overlays.css +4 -2
  124. package/lib/public/css/project-admin-overview.css +13 -0
  125. package/lib/public/css/session-folders.css +11 -0
  126. package/lib/public/css/session-github.css +46 -1
  127. package/lib/public/css/shared-browser.css +35 -1
  128. package/lib/public/css/sticky-notes.css +61 -1
  129. package/lib/public/index.html +11 -5
  130. package/lib/public/mate-avatars/B01.png +0 -0
  131. package/lib/public/mate-avatars/B02.png +0 -0
  132. package/lib/public/mate-avatars/B03.png +0 -0
  133. package/lib/public/mate-avatars/B04.png +0 -0
  134. package/lib/public/mate-avatars/B05.png +0 -0
  135. package/lib/public/mate-avatars/B06.png +0 -0
  136. package/lib/public/mate-avatars/B07.png +0 -0
  137. package/lib/public/mate-avatars/B08.png +0 -0
  138. package/lib/public/mate-avatars/B09.png +0 -0
  139. package/lib/public/mate-avatars/B10.png +0 -0
  140. package/lib/public/mate-avatars/B11.png +0 -0
  141. package/lib/public/mate-avatars/B12.png +0 -0
  142. package/lib/public/mate-avatars/B13.png +0 -0
  143. package/lib/public/mate-avatars/B14.png +0 -0
  144. package/lib/public/mate-avatars/B15.png +0 -0
  145. package/lib/public/mate-avatars/B16.png +0 -0
  146. package/lib/public/mate-avatars/B17.png +0 -0
  147. package/lib/public/mate-avatars/B18.png +0 -0
  148. package/lib/public/mate-avatars/B19.png +0 -0
  149. package/lib/public/mate-avatars/B20.png +0 -0
  150. package/lib/public/mate-avatars/B21.png +0 -0
  151. package/lib/public/mate-avatars/B22.png +0 -0
  152. package/lib/public/mate-avatars/B23.png +0 -0
  153. package/lib/public/mate-avatars/B24.png +0 -0
  154. package/lib/public/mate-avatars/B25.png +0 -0
  155. package/lib/public/mate-avatars/B26.png +0 -0
  156. package/lib/public/mate-avatars/B27.png +0 -0
  157. package/lib/public/mate-avatars/B28.png +0 -0
  158. package/lib/public/mate-avatars/B29.png +0 -0
  159. package/lib/public/mate-avatars/B30.png +0 -0
  160. package/lib/public/mate-avatars/B31.png +0 -0
  161. package/lib/public/mate-avatars/B32.png +0 -0
  162. package/lib/public/mate-avatars/B33.png +0 -0
  163. package/lib/public/mate-avatars/B34.png +0 -0
  164. package/lib/public/mate-avatars/B35.png +0 -0
  165. package/lib/public/mate-avatars/B36.png +0 -0
  166. package/lib/public/mate-avatars/B37.png +0 -0
  167. package/lib/public/mate-avatars/B38.png +0 -0
  168. package/lib/public/mate-avatars/B39.png +0 -0
  169. package/lib/public/mate-avatars/B40.png +0 -0
  170. package/lib/public/mate-avatars/B41.png +0 -0
  171. package/lib/public/mate-avatars/B42.png +0 -0
  172. package/lib/public/mate-avatars/B43.png +0 -0
  173. package/lib/public/mate-avatars/B44.png +0 -0
  174. package/lib/public/mate-avatars/B45.png +0 -0
  175. package/lib/public/mate-avatars/B46.png +0 -0
  176. package/lib/public/mate-avatars/B47.png +0 -0
  177. package/lib/public/mate-avatars/B48.png +0 -0
  178. package/lib/public/mate-avatars/C01.png +0 -0
  179. package/lib/public/mate-avatars/C02.png +0 -0
  180. package/lib/public/mate-avatars/C03.png +0 -0
  181. package/lib/public/mate-avatars/C04.png +0 -0
  182. package/lib/public/mate-avatars/C05.png +0 -0
  183. package/lib/public/mate-avatars/C06.png +0 -0
  184. package/lib/public/mate-avatars/C07.png +0 -0
  185. package/lib/public/mate-avatars/C08.png +0 -0
  186. package/lib/public/mate-avatars/C09.png +0 -0
  187. package/lib/public/mate-avatars/C10.png +0 -0
  188. package/lib/public/mate-avatars/C11.png +0 -0
  189. package/lib/public/mate-avatars/C12.png +0 -0
  190. package/lib/public/mate-avatars/C13.png +0 -0
  191. package/lib/public/mate-avatars/C14.png +0 -0
  192. package/lib/public/mate-avatars/C15.png +0 -0
  193. package/lib/public/mate-avatars/C16.png +0 -0
  194. package/lib/public/mate-avatars/C17.png +0 -0
  195. package/lib/public/mate-avatars/C18.png +0 -0
  196. package/lib/public/mate-avatars/C19.png +0 -0
  197. package/lib/public/mate-avatars/C20.png +0 -0
  198. package/lib/public/mate-avatars/C21.png +0 -0
  199. package/lib/public/mate-avatars/C22.png +0 -0
  200. package/lib/public/mate-avatars/C23.png +0 -0
  201. package/lib/public/mate-avatars/C24.png +0 -0
  202. package/lib/public/mate-avatars/C25.png +0 -0
  203. package/lib/public/mate-avatars/C26.png +0 -0
  204. package/lib/public/mate-avatars/C27.png +0 -0
  205. package/lib/public/mate-avatars/C28.png +0 -0
  206. package/lib/public/mate-avatars/C29.png +0 -0
  207. package/lib/public/mate-avatars/C30.png +0 -0
  208. package/lib/public/mate-avatars/C31.png +0 -0
  209. package/lib/public/mate-avatars/C32.png +0 -0
  210. package/lib/public/mate-avatars/C33.png +0 -0
  211. package/lib/public/mate-avatars/C34.png +0 -0
  212. package/lib/public/mate-avatars/C35.png +0 -0
  213. package/lib/public/mate-avatars/C36.png +0 -0
  214. package/lib/public/mate-avatars/C37.png +0 -0
  215. package/lib/public/mate-avatars/C38.png +0 -0
  216. package/lib/public/mate-avatars/C39.png +0 -0
  217. package/lib/public/mate-avatars/C40.png +0 -0
  218. package/lib/public/mate-avatars/C41.png +0 -0
  219. package/lib/public/mate-avatars/C42.png +0 -0
  220. package/lib/public/mate-avatars/C43.png +0 -0
  221. package/lib/public/mate-avatars/C44.png +0 -0
  222. package/lib/public/mate-avatars/C45.png +0 -0
  223. package/lib/public/mate-avatars/C46.png +0 -0
  224. package/lib/public/mate-avatars/C47.png +0 -0
  225. package/lib/public/mate-avatars/C48.png +0 -0
  226. package/lib/public/mate-avatars/catalog.json +482 -0
  227. package/lib/public/mate-avatars/lead-clay.png +0 -0
  228. package/lib/public/modules/admin-settings-projects.js +6 -2
  229. package/lib/public/modules/app-connection.js +8 -1
  230. package/lib/public/modules/app-message-router.js +4 -0
  231. package/lib/public/modules/app-messages.js +31 -5
  232. package/lib/public/modules/app-projects.js +5 -0
  233. package/lib/public/modules/app-rendering.js +1 -1
  234. package/lib/public/modules/avatar.js +15 -41
  235. package/lib/public/modules/chat-render-runtime.js +10 -1
  236. package/lib/public/modules/clay-browser-links.js +47 -0
  237. package/lib/public/modules/clay-log-links.js +1 -1
  238. package/lib/public/modules/clay-owner-navigation.js +27 -0
  239. package/lib/public/modules/clay-tool-activity.js +140 -0
  240. package/lib/public/modules/clay-tool-presentation.js +338 -0
  241. package/lib/public/modules/command-palette.js +2 -2
  242. package/lib/public/modules/debate.js +1 -0
  243. package/lib/public/modules/default-ai.js +11 -3
  244. package/lib/public/modules/history-replay-batch.js +5 -1
  245. package/lib/public/modules/home-debate-live.js +2 -0
  246. package/lib/public/modules/home-debate-planning.js +7 -7
  247. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  248. package/lib/public/modules/home-mate-chat.js +8 -6
  249. package/lib/public/modules/home-mate-creation.js +73 -1
  250. package/lib/public/modules/home-mate-settings.js +19 -12
  251. package/lib/public/modules/markdown.js +4 -0
  252. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  253. package/lib/public/modules/mate-management.js +40 -7
  254. package/lib/public/modules/mcp-connection-view.js +31 -13
  255. package/lib/public/modules/mcp-discovery-view.js +31 -0
  256. package/lib/public/modules/mcp-ui.js +23 -4
  257. package/lib/public/modules/mention.js +3 -0
  258. package/lib/public/modules/pane-browser-bridge.js +20 -0
  259. package/lib/public/modules/personal-settings-dialog.js +7 -1
  260. package/lib/public/modules/profile.js +1 -238
  261. package/lib/public/modules/project-access-recovery.js +17 -0
  262. package/lib/public/modules/project-admin-overview.js +21 -0
  263. package/lib/public/modules/project-mate-navigation.js +99 -14
  264. package/lib/public/modules/search-clay-chat.js +16 -2
  265. package/lib/public/modules/session-folder-layout.js +1 -1
  266. package/lib/public/modules/session-folder-view-menu.js +9 -0
  267. package/lib/public/modules/session-github.js +85 -14
  268. package/lib/public/modules/session-work-primary.js +51 -0
  269. package/lib/public/modules/shared-browser-settings.js +112 -0
  270. package/lib/public/modules/shared-browser-tabs.js +13 -3
  271. package/lib/public/modules/shared-browser.js +27 -6
  272. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  273. package/lib/public/modules/split-view.js +2 -0
  274. package/lib/public/modules/sticky-note-markdown.js +72 -6
  275. package/lib/public/modules/sticky-notes-actions.js +30 -0
  276. package/lib/public/modules/sticky-notes-browser.js +9 -2
  277. package/lib/public/modules/sticky-notes-card.js +23 -7
  278. package/lib/public/modules/sticky-notes-checklist.js +71 -0
  279. package/lib/public/modules/sticky-notes-editor.js +108 -44
  280. package/lib/public/modules/sticky-notes-shared.js +50 -2
  281. package/lib/public/modules/sticky-notes-state.js +66 -0
  282. package/lib/public/modules/sticky-notes.js +34 -51
  283. package/lib/public/modules/theme.js +8 -1
  284. package/lib/public/modules/thinking-lifecycle.js +33 -3
  285. package/lib/public/modules/thinking-view.js +23 -1
  286. package/lib/public/modules/tools.js +36 -7
  287. package/lib/public/modules/user-settings-appearance.js +10 -3
  288. package/lib/public/modules/user-settings-editors.js +1 -1
  289. package/lib/public/modules/user-settings-layout.js +11 -2
  290. package/lib/public/modules/user-settings-preferences.js +6 -2
  291. package/lib/public/modules/user-settings-profile.js +12 -2
  292. package/lib/public/modules/user-settings.js +3 -2
  293. package/lib/public/style.css +3 -0
  294. package/lib/public/sw.js +3 -1
  295. package/lib/scheduled-task-records.js +3 -1
  296. package/lib/scheduler.js +2 -0
  297. package/lib/sdk-bridge.js +228 -23
  298. package/lib/sdk-message-processor.js +2 -0
  299. package/lib/sdk-response-recovery.js +155 -0
  300. package/lib/server-admin.js +63 -16
  301. package/lib/server-appearance-settings.js +13 -1
  302. package/lib/server-dm.js +2 -1
  303. package/lib/server-global-ws.js +10 -20
  304. package/lib/server-home-chat-events.js +18 -4
  305. package/lib/server-home-chat.js +12 -16
  306. package/lib/server-home-mate-creation.js +1 -0
  307. package/lib/server-home-mcp-consent.js +14 -0
  308. package/lib/server-mates.js +25 -62
  309. package/lib/server-owner-ui.js +77 -0
  310. package/lib/server-path-access.js +38 -0
  311. package/lib/server-project-removal.js +22 -0
  312. package/lib/server-settings.js +4 -1
  313. package/lib/server.js +144 -41
  314. package/lib/session-config-transition.js +45 -0
  315. package/lib/session-folders.js +7 -2
  316. package/lib/session-github.js +9 -2
  317. package/lib/session-visibility.js +5 -2
  318. package/lib/session-work-primary.js +50 -0
  319. package/lib/sessions.js +13 -0
  320. package/lib/shared-browser-cookie-sync.js +32 -0
  321. package/lib/shared-browser-cookies.js +79 -0
  322. package/lib/shared-browser-runtime.js +25 -9
  323. package/lib/shared-browser-storage-sync.js +43 -0
  324. package/lib/shared-browser-storage.js +101 -0
  325. package/lib/shared-browser-tools.js +2 -1
  326. package/lib/shared-browser-worker.js +46 -10
  327. package/lib/terminal-manager.js +52 -0
  328. package/lib/users-permissions.js +2 -8
  329. package/lib/users.js +4 -0
  330. package/lib/workspace-query-access.js +4 -1
  331. package/lib/ws-schema.js +8 -2
  332. package/lib/yoke/acp-agent-profiles.js +2 -2
  333. package/lib/yoke/adapters/claude.js +47 -8
  334. package/lib/yoke/adapters/codex.js +52 -111
  335. package/lib/yoke/claude-worker-startup.js +28 -0
  336. package/lib/yoke/codex-idle-recovery.js +81 -1
  337. package/lib/yoke/codex-recovery-admission.js +164 -0
  338. package/lib/yoke/session-tool-transport.js +3 -0
  339. package/package.json +5 -1
@@ -0,0 +1,97 @@
1
+ // Shared appearance names; stable IDs remain internal catalog identities.
2
+ export var MATE_AVATAR_COLLECTIONS = [{"id":"B","name":"Oddballs","avatars":[{"id":"B01","name":"Indigo Cyclops"},
3
+ {"id":"B02","name":"Coral Sentinel"},
4
+ {"id":"B03","name":"Golden Visor"},
5
+ {"id":"B04","name":"Mint Wide Eyes"},
6
+ {"id":"B05","name":"Ivory Grin"},
7
+ {"id":"B06","name":"Blue Teardrop"},
8
+ {"id":"B07","name":"Peach Orbit"},
9
+ {"id":"B08","name":"Lilac Sleeper"},
10
+ {"id":"B09","name":"Coral Prism"},
11
+ {"id":"B10","name":"Mint Spring"},
12
+ {"id":"B11","name":"Golden Pebbles"},
13
+ {"id":"B12","name":"Periwinkle Orbit"},
14
+ {"id":"B13","name":"Coral Horizon"},
15
+ {"id":"B14","name":"Indigo Stack"},
16
+ {"id":"B15","name":"Mint Button Box"},
17
+ {"id":"B16","name":"Golden Curve"},
18
+ {"id":"B17","name":"Loop Listener"},
19
+ {"id":"B18","name":"Blue Twin Antenna"},
20
+ {"id":"B19","name":"Lilac Daydream"},
21
+ {"id":"B20","name":"Coral Toothsome"},
22
+ {"id":"B21","name":"Ivory Satellite"},
23
+ {"id":"B22","name":"Mint Coil"},
24
+ {"id":"B23","name":"Golden Wonder"},
25
+ {"id":"B24","name":"Slate Smile"},
26
+ {"id":"B25","name":"Lilac Shield"},
27
+ {"id":"B26","name":"Mint Diamond"},
28
+ {"id":"B27","name":"Coral Pebble"},
29
+ {"id":"B28","name":"Golden Horns"},
30
+ {"id":"B29","name":"Blue Trio"},
31
+ {"id":"B30","name":"Ivory Tower"},
32
+ {"id":"B31","name":"Charcoal Grin"},
33
+ {"id":"B32","name":"Teal Cheer"},
34
+ {"id":"B33","name":"Rose Satellite"},
35
+ {"id":"B34","name":"Blue Spool"},
36
+ {"id":"B35","name":"Golden Band"},
37
+ {"id":"B36","name":"Mint Beacon"},
38
+ {"id":"B37","name":"Charcoal Crescent"},
39
+ {"id":"B38","name":"Coral Cyclops"},
40
+ {"id":"B39","name":"Blue Scout"},
41
+ {"id":"B40","name":"Ivory Navigator"},
42
+ {"id":"B41","name":"Golden Porthole"},
43
+ {"id":"B42","name":"Lilac Windup"},
44
+ {"id":"B43","name":"Mint Receiver"},
45
+ {"id":"B44","name":"Coral Stack"},
46
+ {"id":"B45","name":"Indigo Porthole"},
47
+ {"id":"B46","name":"Stone Sprout"},
48
+ {"id":"B47","name":"Mint Sunbeam"},
49
+ {"id":"B48","name":"Golden Cubby"}]},
50
+ {"id":"C","name":"Kindred Bots","avatars":[{"id":"C01","name":"Violet Smile"},
51
+ {"id":"C02","name":"Apricot Joy"},
52
+ {"id":"C03","name":"Sage Curious"},
53
+ {"id":"C04","name":"Golden Wink"},
54
+ {"id":"C05","name":"Blue Sideglance"},
55
+ {"id":"C06","name":"Charcoal Wonder"},
56
+ {"id":"C07","name":"Lilac Specs"},
57
+ {"id":"C08","name":"Coral Giggle"},
58
+ {"id":"C09","name":"Mint Blush"},
59
+ {"id":"C10","name":"Golden Button"},
60
+ {"id":"C11","name":"Sky Smile"},
61
+ {"id":"C12","name":"Plum Joy"},
62
+ {"id":"C13","name":"Teal Diamond"},
63
+ {"id":"C14","name":"Peach Dimple"},
64
+ {"id":"C15","name":"Indigo Delight"},
65
+ {"id":"C16","name":"Sage Sprout"},
66
+ {"id":"C17","name":"Golden Specs"},
67
+ {"id":"C18","name":"Lilac Stargaze"},
68
+ {"id":"C19","name":"Blue Curiosity"},
69
+ {"id":"C20","name":"Coral Heart"},
70
+ {"id":"C21","name":"Mint Bud"},
71
+ {"id":"C22","name":"Ivory Surprise"},
72
+ {"id":"C23","name":"Rose Wink"},
73
+ {"id":"C24","name":"Sky Giggle"},
74
+ {"id":"C25","name":"Ivory Dreamer"},
75
+ {"id":"C26","name":"Mint Loop"},
76
+ {"id":"C27","name":"Violet Glasses"},
77
+ {"id":"C28","name":"Coral Sunshine"},
78
+ {"id":"C29","name":"Slate Sideglance"},
79
+ {"id":"C30","name":"Golden Dimple"},
80
+ {"id":"C31","name":"Teal Listener"},
81
+ {"id":"C32","name":"Peach Cheer"},
82
+ {"id":"C33","name":"Indigo Blush"},
83
+ {"id":"C34","name":"Sage Daydream"},
84
+ {"id":"C35","name":"Rose Wonder"},
85
+ {"id":"C36","name":"Sky Blush"},
86
+ {"id":"C37","name":"Peach Heart"},
87
+ {"id":"C38","name":"Blue Button"},
88
+ {"id":"C39","name":"Lilac Wink"},
89
+ {"id":"C40","name":"Mint Dish"},
90
+ {"id":"C41","name":"Ivory Wonder"},
91
+ {"id":"C42","name":"Violet Cheer"},
92
+ {"id":"C43","name":"Rose Specs"},
93
+ {"id":"C44","name":"Teal Delight"},
94
+ {"id":"C45","name":"Golden Diamond"},
95
+ {"id":"C46","name":"Lilac Surprise"},
96
+ {"id":"C47","name":"Sage Listener"},
97
+ {"id":"C48","name":"Coral Crown"}]}];
@@ -1,12 +1,14 @@
1
1
  // Shared Mate profile and removal flows used by project and Home surfaces.
2
2
 
3
3
  import { getWs } from './ws-ref.js';
4
- import { showMateProfilePopover } from './profile.js';
4
+ import { store } from './store.js';
5
+ import { openHomeMateSettings } from './home-mate-settings.js';
5
6
  import { showToast } from './utils.js';
6
7
  import { showConfirm, hideConfirm } from './app-misc.js';
7
8
  import { iconHtml, refreshIcons } from './icons.js';
8
9
 
9
10
  var mateMenu = null;
11
+ var mateMenuOpener = null;
10
12
 
11
13
  function send(message) {
12
14
  var ws = getWs();
@@ -15,9 +17,13 @@ function send(message) {
15
17
 
16
18
  export function editMateProfile(anchorEl, mate) {
17
19
  if (!anchorEl || !mate || mate.primary) return;
18
- showMateProfilePopover(anchorEl, mate, function (updates) {
19
- send({ type: "mate_update", mateId: mate.id, updates: updates });
20
- });
20
+ openHomeMateSettings(mate.id, anchorEl);
21
+ }
22
+
23
+ export function changeMateAvatar(anchorEl, mate) {
24
+ var current = (store.get('cachedMatesList') || []).find(function (item) { return mate && item.id === mate.id; });
25
+ if (!anchorEl || !current || current.primary || current.builtinKey === 'clay' || (current.profile || {}).avatarLocked) return false;
26
+ return openHomeMateSettings(current.id, anchorEl, { avatar: true });
21
27
  }
22
28
 
23
29
  export function confirmMateRemoval(anchorEl, mate, onRemoved) {
@@ -76,9 +82,12 @@ export function confirmMateRemoval(anchorEl, mate, onRemoved) {
76
82
  input.focus();
77
83
  }
78
84
 
79
- export function closeMateManagementMenu() {
85
+ export function closeMateManagementMenu(restoreFocus) {
86
+ var opener = mateMenuOpener;
80
87
  if (mateMenu) mateMenu.remove();
81
- mateMenu = null;
88
+ mateMenu = null; mateMenuOpener = null;
89
+ document.removeEventListener("keydown", handleMateMenuKeydown, true);
90
+ if (restoreFocus && opener && opener.isConnected) opener.focus({ preventScroll: true });
82
91
  document.removeEventListener("click", handleMateMenuOutside, true);
83
92
  }
84
93
 
@@ -86,6 +95,18 @@ function handleMateMenuOutside(event) {
86
95
  if (mateMenu && !mateMenu.contains(event.target)) closeMateManagementMenu();
87
96
  }
88
97
 
98
+ function handleMateMenuKeydown(event) {
99
+ if (!mateMenu) return;
100
+ if (event.key === 'Escape') {
101
+ event.preventDefault(); event.stopPropagation(); closeMateManagementMenu(true); return;
102
+ }
103
+ if (event.key === 'Tab') { closeMateManagementMenu(true); return; }
104
+ var items = Array.from(mateMenu.querySelectorAll('[role="menuitem"]:not(:disabled)'));
105
+ var index = items.indexOf(document.activeElement);
106
+ var next = event.key === 'ArrowDown' ? (index + 1) % items.length : event.key === 'ArrowUp' ? (index + items.length - 1) % items.length : event.key === 'Home' ? 0 : event.key === 'End' ? items.length - 1 : -1;
107
+ if (next >= 0) { event.preventDefault(); event.stopPropagation(); items[next].focus(); }
108
+ }
109
+
89
110
  export function showMateManagementMenu(anchorEl, mate, options) {
90
111
  if (!anchorEl || !mate || mate.primary) return;
91
112
  options = options || {};
@@ -93,7 +114,16 @@ export function showMateManagementMenu(anchorEl, mate, options) {
93
114
  if (options.beforeOpen) options.beforeOpen();
94
115
  var menu = document.createElement("div");
95
116
  menu.className = "project-ctx-menu";
117
+ menu.setAttribute('role', 'menu');
118
+ menu.setAttribute('aria-label', 'Actions for ' + ((mate.profile || {}).displayName || mate.name || 'Mate'));
119
+ if (!(mate.profile || {}).avatarLocked && mate.builtinKey !== 'clay') {
120
+ var avatar = document.createElement('button'); avatar.type = 'button'; avatar.className = 'project-ctx-item'; avatar.setAttribute('role', 'menuitem');
121
+ avatar.innerHTML = iconHtml('image') + ' <span>Change avatar</span>';
122
+ avatar.addEventListener('click', function (event) { event.stopPropagation(); closeMateManagementMenu(); changeMateAvatar(anchorEl, mate); });
123
+ menu.appendChild(avatar);
124
+ }
96
125
  var edit = document.createElement("button");
126
+ edit.type = "button"; edit.setAttribute("role", "menuitem");
97
127
  edit.className = "project-ctx-item";
98
128
  edit.innerHTML = iconHtml("edit-2") + " <span>Edit Profile</span>";
99
129
  edit.addEventListener("click", function (event) {
@@ -102,6 +132,7 @@ export function showMateManagementMenu(anchorEl, mate, options) {
102
132
  editMateProfile(anchorEl, mate);
103
133
  });
104
134
  var remove = document.createElement("button");
135
+ remove.type = "button"; remove.setAttribute("role", "menuitem");
105
136
  remove.className = "project-ctx-item project-ctx-delete";
106
137
  remove.innerHTML = iconHtml(mate.builtinKey ? "minus-circle" : "trash-2")
107
138
  + " <span>" + (mate.builtinKey ? "Remove mate" : "Delete mate") + "</span>";
@@ -113,7 +144,9 @@ export function showMateManagementMenu(anchorEl, mate, options) {
113
144
  menu.appendChild(edit);
114
145
  menu.appendChild(remove);
115
146
  document.body.appendChild(menu);
116
- mateMenu = menu;
147
+ mateMenu = menu; mateMenuOpener = anchorEl;
148
+ document.addEventListener("keydown", handleMateMenuKeydown, true);
149
+ menu.querySelector("[role=menuitem]").focus();
117
150
  refreshIcons();
118
151
  requestAnimationFrame(function () {
119
152
  var rect = anchorEl.getBoundingClientRect();
@@ -1,3 +1,5 @@
1
+ import { enhanceSettingsSelects } from './settings-select.js';
2
+ import { discoveryView, credentialsView } from './mcp-discovery-view.js';
1
3
  import { escapeHtml } from './utils.js';
2
4
  import { iconHtml, refreshIcons } from './icons.js';
3
5
  import { store } from './store.js';
@@ -13,11 +15,11 @@ function heading(title, subtitle, icon) {
13
15
  }
14
16
  function status(row) { return '<span class="mc-status" data-status="' + text(row.status) + '"><span aria-hidden="true"></span>' + text(labels[row.status] || 'Unavailable') + '</span>'; }
15
17
  function switchControl(row, busy) {
16
- return '<button type="button" class="mc-switch" role="switch" aria-checked="' + !!row.projectEnabled + '" aria-label="Enable ' + text(row.label || row.name) + ' in this project" data-toggle="' + text(row.id) + '"' + (busy ? ' disabled' : '') + '><span></span></button>';
18
+ return '<button type="button" class="mc-switch" role="switch" aria-checked="' + !!row.projectEnabled + '" aria-label="Enable ' + text(row.label || row.name) + (row.source === 'computer' ? ' in this project' : ' for your private sessions and Mates') + '" data-toggle="' + text(row.id) + '"' + (busy ? ' disabled' : '') + '><span></span></button>';
17
19
  }
18
20
  function rows(servers, busy) {
19
21
  return '<div class="mc-list">' + servers.map(function (row) {
20
- return '<div class="mc-row"><button type="button" class="mc-row-open" data-open="' + text(row.id) + '"><span class="mc-server-icon">' + iconHtml(row.source === 'url' ? 'globe' : 'monitor') + '</span><span class="mc-row-info"><strong>' + text(row.label || row.name) + '</strong><span>' + (row.source === 'url' ? 'Remote' : 'Your computer') + ' · ' + row.toolCount + ' tools</span>' + status(row) + '</span></button>' + switchControl(row, busy) + '</div>';
22
+ return '<div class="mc-row"><button type="button" class="mc-row-open" data-open="' + text(row.id) + '"><span class="mc-server-icon">' + iconHtml(row.source === 'url' ? 'globe' : 'monitor') + '</span><span class="mc-row-info"><strong>' + text(row.label || row.name) + '</strong><span>' + (row.source === 'url' ? 'Remote' : row.source === 'local' ? 'Clay server' : 'Your computer') + ' · ' + row.toolCount + ' tools</span>' + status(row) + '</span></button>' + switchControl(row, busy) + '</div>';
21
23
  }).join('') + '</div>';
22
24
  }
23
25
  function search(value, placeholder) { return '<label class="mc-search">' + iconHtml('search') + '<input type="search" data-search value="' + text(value) + '" placeholder="' + placeholder + '" aria-label="' + placeholder + '"></label>'; }
@@ -25,11 +27,12 @@ function listView(state) {
25
27
  if (!state.loaded) return heading('Your connections', 'Loading your MCP servers…', 'cable');
26
28
  if (!state.servers.length) return '<div class="mc-empty">' + heading('Connect tools to Clay', 'Let your agent work with the services and tools you choose.', 'cable') + button('Add connection', 'add', true, 'plus') + '<p>Connect a remote service or tools on your computer.</p></div>';
27
29
  var servers = state.servers.filter(function (row) { return (row.label || row.name).toLowerCase().includes((state.search || '').toLowerCase()); });
28
- return search(state.search, 'Search servers…') + '<div class="mc-section-heading"><h2>Your connections</h2>' + button('Add', 'add', false, 'plus') + '</div>' + rows(servers, !!state.pending) + (!servers.length ? '<p class="mc-muted">No matching connections.</p>' : '') + '<p class="mc-footnote">Enabled connections are available to your private sessions in this project. In multi-user Clay, shared conversations cannot use personal connections.</p>';
30
+ return search(state.search, 'Search servers…') + '<div class="mc-section-heading"><h2>Your connections</h2>' + button('Add', 'add', false, 'plus') + '</div>' + rows(servers, !!state.pending) + (!servers.length ? '<p class="mc-muted">No matching connections.</p>' : '') + '<p class="mc-footnote">Imported and remote connections are available to your private sessions and Mates. Computer preferences are scoped to this project. In multi-user Clay, shared conversations cannot use personal connections.</p>';
29
31
  }
30
32
  function addView() {
31
33
  return heading('Add connection', 'Choose where your tools are available.') + '<div class="mc-choices">' +
32
34
  '<button class="mc-choice" data-action="remote"><span class="mc-choice-icon">' + iconHtml('globe') + '</span><span><strong>Remote MCP URL</strong><small>Connect a hosted service using its MCP server address.</small></span>' + iconHtml('arrow-right') + '</button>' +
35
+ '<button class="mc-choice" data-action="discovery"><span class="mc-choice-icon">' + iconHtml('folder-search') + '</span><span><strong>Import vendor config</strong><small>Inspect Claude, Codex, Kiro and other supported runtime sources.</small></span>' + iconHtml('arrow-right') + '</button>' +
33
36
  '<button class="mc-choice" data-action="computer"><span class="mc-choice-icon">' + iconHtml('monitor') + '</span><span><strong>On your computer</strong><small>Connect local tools through the Clay browser extension.</small></span>' + iconHtml('arrow-right') + '</button></div>';
34
37
  }
35
38
  function remoteView(state) {
@@ -53,10 +56,12 @@ function permissionsView(row) {
53
56
  [['', 'Use session default'], ['auto', 'AI review'], ['default', 'Ask every time']].map(function (item) { return '<option value="' + item[0] + '"' + (selected === item[0] ? ' selected' : '') + '>' + item[1] + '</option>'; }).join('') + '</select></label>' + (!availability.applicable ? '<p class="mc-muted">' + text(availability.reason) + '</p>' : '') + '</div>';
54
57
  }
55
58
  function detailView(state, row) {
56
- var remote = row.source === 'url';
57
- var html = heading(row.label || row.name, remote ? 'Remote MCP connection' : 'Connected through your browser extension', remote ? 'globe' : 'monitor');
58
- html += status(row) + '<div class="mc-enable"><span>Enabled in this project</span>' + switchControl(row, !!state.pending) + '</div>';
59
- html += '<dl class="mc-metadata"><dt>Access</dt><dd>Your account only</dd><dt>' + (remote ? 'Server' : 'Location') + '</dt><dd>' + (remote ? text(row.url) : 'Your computer') + '</dd></dl>';
59
+ var remote = row.source === 'url', local = row.source === 'local', managed = remote || local;
60
+ var html = heading(row.label || row.name, remote ? 'Remote MCP connection' : local ? 'MCP process on the Clay server' : 'Connected through your browser extension', remote ? 'globe' : 'monitor');
61
+ html += status(row) + '<div class="mc-enable"><span>' + (managed ? 'Enabled for your private sessions and Mates' : 'Enabled in this project') + '</span>' + switchControl(row, !!state.pending) + '</div>';
62
+ html += '<dl class="mc-metadata"><dt>Access</dt><dd>Your account only</dd><dt>' + (remote ? 'Server' : 'Location') + '</dt><dd>' + (remote ? text(row.url) : (local ? 'Clay server · your account' : 'Your computer')) + '</dd></dl>';
63
+ if (row.provenance) html += '<p class="mc-muted">Imported from ' + text(row.provenance.vendor + ' · ' + row.provenance.scope + ' · ' + row.provenance.file) + '</p>';
64
+ html += credentialsView(row);
60
65
  if (row.error) html += '<div class="mc-alert" role="status">' + iconHtml('circle-alert') + '<span>' + text(row.error) + '</span></div>';
61
66
  if (remote && row.status === 'auth_required') html += '<div class="mc-auth">' + button('Sign in with Clay browser', 'signin', true, 'log-in') + '<p class="mc-muted">Only you can view and control this sign-in browser.</p></div>';
62
67
  if (remote) html += '<details class="mc-token"><summary>Use an access token</summary><form data-form="token" class="mc-form"><label>Access token<input name="token" type="password" required maxlength="8192" autocomplete="new-password" placeholder="Paste your access token"></label><button type="submit" class="mc-button">Save and connect</button></form></details>';
@@ -67,15 +72,15 @@ function detailView(state, row) {
67
72
  var tools = (row.tools || []).filter(function (tool) { return (tool.name + ' ' + (tool.description || '')).toLowerCase().includes((state.search || '').toLowerCase()); });
68
73
  html += '<div class="mc-tools">' + tools.map(function (tool) { return '<details><summary>' + text(tool.name) + '</summary><p>' + text(tool.description || 'No description provided.') + '</p><h4>Inputs</h4><pre>' + text(JSON.stringify(tool.inputSchema || {}, null, 2)) + '</pre></details>'; }).join('') + (!tools.length ? '<p class="mc-muted">' + (row.toolCount ? 'No matching tools.' : 'No tools available. Test the connection to refresh its catalog.') + '</p>' : '') + '</div>';
69
74
  }
70
- html += '<div class="mc-detail-actions">' + (remote ? button('Test connection', 'test', false, 'refresh-cw') + (row.status === 'auth_required' ? '' : button('Sign in again', 'signin', false, 'log-in')) : button('Computer setup', 'computer', false, 'monitor')) + '</div>';
71
- if (remote) html += '<details class="mc-manage"><summary>Manage connection</summary><form data-form="rename" class="mc-form"><label>Name<input name="label" required maxlength="100" value="' + text(row.label) + '"></label><button type="submit" class="mc-button">Save name</button></form>' + button('Remove connection', 'remove', false, 'trash-2') + '</details>';
75
+ html += '<div class="mc-detail-actions">' + (managed ? button('Test connection', 'test', false, 'refresh-cw') + (!remote || row.status === 'auth_required' ? '' : button('Sign in again', 'signin', false, 'log-in')) : button('Computer setup', 'computer', false, 'monitor')) + '</div>';
76
+ if (managed) html += '<details class="mc-manage"><summary>Manage connection</summary><form data-form="rename" class="mc-form"><label>Name<input name="label" required maxlength="100" value="' + text(row.label) + '"></label><button type="submit" class="mc-button">Save name</button></form>' + button('Remove connection', 'remove', false, 'trash-2') + '</details>';
72
77
  return html;
73
78
  }
74
79
  export function renderConnections(root, state, events) {
75
80
  var sameScreen = root.dataset.screenKey === (state.screen || 'list') + ':' + (state.selected || '');
76
81
  var disclosures = sameScreen ? Array.from(root.querySelectorAll('details[open]')).map(function (el) { return el.className || el.querySelector('summary').textContent; }) : [];
77
82
  var drafts = {};
78
- if (sameScreen) root.querySelectorAll('input[name]').forEach(function (el) { drafts[el.name] = el.value; });
83
+ if (sameScreen) root.querySelectorAll('input[name]:not([type="password"])').forEach(function (el) { drafts[el.name] = el.value; });
79
84
  var focused = root.contains(document.activeElement) ? document.activeElement : null;
80
85
  var searchFocused = focused && focused.hasAttribute('data-search');
81
86
  var start = focused && focused.tagName === 'INPUT' ? focused.selectionStart : null;
@@ -84,18 +89,20 @@ export function renderConnections(root, state, events) {
84
89
  var screen = state.screen || 'list';
85
90
  var html = screen !== 'list' ? '<button type="button" class="mc-back" data-action="back">' + iconHtml('arrow-left') + 'MCP Servers</button>' : '';
86
91
  if (state.error) html += '<div class="mc-alert" role="alert">' + iconHtml('circle-alert') + '<span>' + text(state.error) + '</span></div>';
92
+ html += '<p class="mc-muted">Clay connections work in supported native and ACP sessions. Antigravity’s current agy stream-json adapter cannot mount session-bound Clay tools; use another runtime for these connections.</p>';
87
93
  if (state.notice) html += '<p class="mc-notice" role="status">' + text(state.notice) + '</p>';
88
94
  if (screen === 'add') html += addView();
89
95
  else if (screen === 'remote') html += remoteView(state);
96
+ else if (screen === 'discovery') html += discoveryView(state);
90
97
  else if (screen === 'computer') html += computerView(state);
91
- else if (screen === 'remove' && row) html += heading('Remove ' + row.label + '?', 'This removes saved credentials and disables its tools in this project.') + '<div role="group" aria-label="Confirm removal">' + button('Cancel', 'cancel-remove', false) + button('Remove connection', 'confirm-remove', true, 'trash-2') + '</div>';
98
+ else if (screen === 'remove' && row) html += heading('Remove ' + row.label + '?', 'This removes saved credentials and disables this connection for your private sessions and Mates.') + '<div role="group" aria-label="Confirm removal">' + button('Cancel', 'cancel-remove', false) + button('Remove connection', 'confirm-remove', true, 'trash-2') + '</div>';
92
99
  else if (screen === 'detail' && row) html += detailView(state, row);
93
100
  else html += listView(state);
94
101
  if (state.pending && screen !== 'remote') html += '<p class="mc-working" role="status">' + iconHtml('loader-circle') + 'Updating connection…</p>';
95
102
  root.innerHTML = '<div class="mc-screen">' + html + '</div>';
96
103
  root.dataset.screenKey = screen + ':' + (state.selected || '');
97
104
  root.querySelectorAll('details').forEach(function (el) { el.open = disclosures.indexOf(el.className || el.querySelector('summary').textContent) >= 0; });
98
- root.querySelectorAll('input[name]').forEach(function (el) {
105
+ root.querySelectorAll('input[name]:not([type="password"])').forEach(function (el) {
99
106
  if (Object.prototype.hasOwnProperty.call(drafts, el.name)) el.value = drafts[el.name];
100
107
  if (focusedName === el.name) { el.focus(); try { el.setSelectionRange(start, start); } catch (error) {} }
101
108
  });
@@ -106,31 +113,42 @@ export function renderConnections(root, state, events) {
106
113
  if (state.pending && ['signin', 'test', 'remove', 'confirm-remove'].includes(action)) el.disabled = true;
107
114
  el.onclick = function () {
108
115
  if (action === 'back') events.navigate('list');
109
- else if (['add', 'remote', 'computer'].includes(action)) events.navigate(action);
116
+ else if (['add', 'remote', 'computer', 'discovery'].includes(action)) events.navigate(action);
110
117
  else if (action === 'remove' && row) events.remove(row);
111
118
  else if (action === 'cancel-remove') events.navigate('detail', row.id);
112
119
  else if (action === 'confirm-remove') events.action('remove', { id: row.id });
120
+ else if (action === 'discover') events.discover();
113
121
  else if (action === 'refresh') events.refresh();
114
122
  else if (action === 'setup') events.setup();
115
123
  else if (action === 'copy') navigator.clipboard.writeText('npx clay-mcp-bridge install ' + (state.extensionId || '<extension-id>')).then(function () { el.textContent = 'Copied'; }).catch(function () { el.textContent = 'Select command to copy'; });
116
124
  else events.action(action);
117
125
  };
118
126
  });
127
+ root.querySelectorAll('[data-import]').forEach(function (el) { el.onclick = function () { events.action('import', { scanId: state.discovery.scanId, candidateId: el.dataset.import }); }; });
119
128
  root.querySelectorAll('[data-open]').forEach(function (el) { el.onclick = function () { events.navigate('detail', el.dataset.open); }; });
120
129
  root.querySelectorAll('[data-toggle]').forEach(function (el) { el.onclick = function () { var item = state.servers.find(function (server) { return server.id === el.dataset.toggle; }); if (item) events.toggle(item, !item.projectEnabled); }; });
121
130
  root.querySelectorAll('[data-tab]').forEach(function (el) { el.onclick = function () { store.set({ mcpConnections: Object.assign({}, store.get('mcpConnections'), { detailTab: el.dataset.tab, search: '' }) }); }; });
122
131
  var input = root.querySelector('[data-search]');
123
132
  if (input) { input.oninput = function () { events.search(input.value); }; if (searchFocused) { input.focus(); try { input.setSelectionRange(start, start); } catch (error) {} } }
133
+ var discoveryForm = root.querySelector('[data-form="discovery"]');
134
+ if (discoveryForm) {
135
+ function saveSourceDraft() { events.sourceDraft({ vendor: discoveryForm.elements.vendor.value, file: discoveryForm.elements.file.value }); }
136
+ discoveryForm.elements.vendor.onchange = saveSourceDraft;
137
+ discoveryForm.elements.file.oninput = saveSourceDraft;
138
+ }
124
139
  var urlInput = root.querySelector('[name="url"]'); if (urlInput) urlInput.oninput = function () { events.draft(urlInput.value); };
125
140
  root.querySelectorAll('form').forEach(function (form) {
126
141
  form.onsubmit = function (event) {
127
142
  event.preventDefault(); if (state.pending) return;
128
143
  if (form.dataset.form === 'remote') events.action('add', { url: form.elements.url.value });
129
144
  if (form.dataset.form === 'token') { var token = form.elements.token.value; form.reset(); events.action('token', { token: token }); }
145
+ if (form.dataset.form === 'discovery') events.discover({ vendor: form.elements.vendor.value.trim(), file: form.elements.file.value.trim() });
146
+ if (form.dataset.form === 'credentials') { var values = {}; Array.from(form.querySelectorAll('input')).forEach(function (input) { values[input.name] = input.value; }); form.reset(); events.action('credentials', { values: values }); }
130
147
  if (form.dataset.form === 'rename') events.action('rename', { label: form.elements.label.value });
131
148
  };
132
149
  });
133
150
  var permission = root.querySelector('[data-permission]');
134
151
  if (permission) permission.onchange = function () { sendMcpPermissionMode(store.get('currentSlug'), store.get('activeSessionId'), row.name, permission.value); };
152
+ enhanceSettingsSelects(root);
135
153
  refreshIcons(root);
136
154
  }
@@ -0,0 +1,31 @@
1
+ import { escapeHtml } from './utils.js';
2
+ import { iconHtml } from './icons.js';
3
+ function text(value) { return escapeHtml(String(value || '')); }
4
+ export function discoveryView(state) {
5
+ var discovery = state.discovery || {}, pending = !!state.pending;
6
+ var draft = state.sourceDraft || {};
7
+ var vendors = { claude: 'Claude Code', codex: 'Codex', kiro: 'Kiro', opencode: 'OpenCode', kimi: 'Kimi Code', copilot: 'GitHub Copilot', qwen: 'Qwen Code', junie: 'Junie', grok: 'Grok', antigravity: 'Antigravity', acp: 'ACP' };
8
+ var options = Object.keys(vendors).map(function (key) { return '<option value="' + key + '"' + ((draft.vendor || 'claude') === key ? ' selected' : '') + '>' + vendors[key] + '</option>'; }).join('');
9
+ var html = '<div class="mc-heading"><h2 tabindex="-1">Import vendor connections</h2><p>Inspect MCP configurations on the Clay server. Import saves a disabled copy for your account; enabling or testing can start its command or contact its service.</p></div>' +
10
+ '<button type="button" class="mc-button" data-action="discover"' + (pending ? ' disabled' : '') + '>' + iconHtml('refresh-cw') + 'Scan vendor configurations</button>' +
11
+ '<details class="mc-manage"><summary>Configured source file</summary><form data-form="discovery" class="mc-form"><label>Vendor format<select name="vendor" aria-label="Vendor format">' + options + '</select></label><label>Absolute config path<input name="file" value="' + text(draft.file) + '" required placeholder="/home/you/agent/mcp.json" maxlength="4096"></label><button type="submit" class="mc-button"' + (pending ? ' disabled' : '') + '>Inspect source</button></form></details>';
12
+ if (!discovery.scanId) return html + '<p class="mc-muted">Vendor OAuth tokens stay with their vendor. Use Clay sign-in or enter credentials after importing.</p>';
13
+ html += '<div class="mc-list">' + (discovery.candidates || []).map(function (row) {
14
+ return '<div class="mc-row"><span class="mc-row-info"><strong>' + text(row.name) + '</strong><span>' + text(row.vendor + ' · ' + row.scope + ' · ' + row.transport) + '</span><small>' + text(row.file) + '</small><small>' + text('Dependency: ' + row.dependency) + '</small>' +
15
+ (row.references.length ? '<small>Requires: ' + text(row.references.join(', ')) + '</small>' : '') +
16
+ (row.blocked ? '<small>' + text(row.blocked) + '</small>' : '') +
17
+ (row.pluginVersion ? '<small>Plugin version: ' + text(row.pluginVersion) + '</small>' : '') +
18
+ (row.conflict ? '<small>Different definitions use this name. Import the source you intend to use.</small>' : row.duplicate ? '<small>Matching definition found in another source.</small>' : '') +
19
+ '<small>' + (row.sourceEnabled === true ? 'Enabled in source' : row.sourceEnabled === false ? 'Disabled in source' : 'Source enablement unknown') + ' · imports disabled</small></span><button class="mc-button" type="button" data-import="' + text(row.id) + '"' + (pending || row.imported || row.blocked ? ' disabled' : '') + '>' + (row.imported ? 'Imported' : row.blocked ? 'Blocked' : 'Import') + '</button></div>';
20
+ }).join('') + '</div>';
21
+ if (!(discovery.candidates || []).length) html += '<p class="mc-muted">No supported MCP definitions found.</p>';
22
+ html += (discovery.diagnostics || []).map(function (item) { return '<p class="mc-muted">' + text(item.vendor + ' · ' + item.scope + (item.name ? ' · ' + item.name : '') + ': ' + item.message) + '</p>'; }).join('');
23
+ return html;
24
+ }
25
+ export function credentialsView(row) {
26
+ if (!row.references || !row.references.length) return '';
27
+ if (row.references.indexOf('Unsupported reference') >= 0) return '<p class="mc-muted">This definition needs a vendor-specific helper or file reference. Configure a direct Clay connection instead.</p>';
28
+ return '<details class="mc-token"><summary>Required credentials</summary><form data-form="credentials" class="mc-form">' + row.references.map(function (name) {
29
+ return '<label>' + text(name) + '<input type="password" name="' + text(name) + '" required maxlength="8192" autocomplete="new-password"></label>';
30
+ }).join('') + '<button type="submit" class="mc-button">Save credentials</button></form></details>';
31
+ }
@@ -9,7 +9,8 @@ function patch(value) { store.set({ mcpConnections: Object.assign({}, state(), v
9
9
  function send(message) {
10
10
  var ws = getWs();
11
11
  if (!ws || ws.readyState !== 1) { patch({ error: 'Reconnect to Clay to manage connections.' }); return false; }
12
- ws.send(JSON.stringify(message)); return true;
12
+ try { if (ws.send(JSON.stringify(message)) === false) throw new Error('Not sent'); return true; }
13
+ catch (error) { patch({ error: 'Could not send the request. Reconnect and try again.' }); return false; }
13
14
  }
14
15
  function requestState() { send({ type: 'mcp_state_request' }); }
15
16
  function clearActionTimer() { var timer = store.get('mcpActionTimer'); if (timer) clearTimeout(timer); store.set({ mcpActionTimer: null }); }
@@ -24,8 +25,18 @@ function action(name, args) {
24
25
  }, 90000) });
25
26
  if (!send(Object.assign({ type: 'mcp_connection_action', action: name, requestId: requestId, id: state().selected }, args || {}))) { clearActionTimer(); patch({ pending: null }); }
26
27
  }
28
+ function discover(options) {
29
+ if (state().pending) return;
30
+ var requestId = crypto.randomUUID();
31
+ patch({ pending: { requestId: requestId, action: 'discover' }, error: '' });
32
+ clearActionTimer();
33
+ store.set({ mcpActionTimer: setTimeout(function () {
34
+ if (state().pending && state().pending.requestId === requestId) { clearActionTimer(); patch({ pending: null, error: 'The scan did not respond. Your draft and previous results are retained. Reconnect or scan again.' }); }
35
+ }, 30000) });
36
+ if (!send(Object.assign({ type: 'mcp_discovery_request', requestId: requestId }, options || {}))) { clearActionTimer(); patch({ pending: null }); }
37
+ }
27
38
  function toggle(row, value) {
28
- if (row.source === 'url') action('enable', { id: row.id, enabled: value });
39
+ if (row.source !== 'computer') action('enable', { id: row.id, enabled: value });
29
40
  else send({ type: 'mcp_toggle_server', name: row.name, enabled: value });
30
41
  }
31
42
  function render() {
@@ -35,7 +46,8 @@ function render() {
35
46
  var extension = document.getElementById('ext-pill-wrap');
36
47
  if (extension) extension.hidden = current.screen !== 'computer';
37
48
  renderConnections(element, current, {
38
- navigate: navigate, action: action, toggle: toggle,
49
+ navigate: navigate, action: action, toggle: toggle, discover: discover,
50
+ sourceDraft: function (value) { patch({ sourceDraft: value }); },
39
51
  search: function (value) { patch({ search: value }); },
40
52
  draft: function (value) { store.set({ mcpConnectionDraft: value }); },
41
53
  refresh: requestState,
@@ -72,12 +84,19 @@ export function setExtensionConnected(value) { patch({ extensionConnected: !!val
72
84
  export function getMcpServers() { return state().servers; }
73
85
  export function handleMcpConnectionMessage(msg) {
74
86
  if (msg.slug && msg.slug !== store.get('currentSlug')) return false;
87
+ if (msg.type === 'mcp_discovery_result') {
88
+ var scanPending = state().pending;
89
+ if (!scanPending || scanPending.requestId !== msg.requestId) return true;
90
+ clearActionTimer();
91
+ patch({ pending: null, discovery: msg.ok ? { scanId: msg.scanId, candidates: msg.candidates, diagnostics: msg.diagnostics } : state().discovery, error: msg.ok ? '' : msg.error });
92
+ return true;
93
+ }
75
94
  if (msg.type === 'mcp_action_result') {
76
95
  var pending = state().pending;
77
96
  if (msg.requestId && (!pending || msg.requestId !== pending.requestId)) return true;
78
97
  clearActionTimer();
79
98
  patch({ pending: null, error: msg.ok ? '' : msg.error || 'Could not update connection.' });
80
- if (msg.ok && msg.action === 'add') { store.set({ mcpConnectionDraft: '' }); navigate('detail', msg.id); }
99
+ if (msg.ok && (msg.action === 'add' || msg.action === 'import')) { store.set({ mcpConnectionDraft: '' }); navigate('detail', msg.id); }
81
100
  if (msg.ok && msg.action === 'remove') navigate('list');
82
101
  if (msg.ok && msg.action === 'enable') patch({ notice: 'Saved. Tool availability updates on the next turn; some runtimes may need a new session.' });
83
102
  return true;
@@ -482,6 +482,8 @@ export function handleMentionStart(msg) {
482
482
  mateId: msg.mateId,
483
483
  mateName: msg.mateName,
484
484
  avatarColor: msg.avatarColor,
485
+ avatarCatalogId: msg.avatarCatalogId,
486
+ avatarCustom: msg.avatarCustom,
485
487
  avatarStyle: msg.avatarStyle,
486
488
  avatarSeed: msg.avatarSeed,
487
489
  };
@@ -762,6 +764,7 @@ function buildMentionAvatarUrl(meta) {
762
764
  return mateAvatarUrl({
763
765
  id: meta.mateId,
764
766
  profile: {
767
+ avatarCatalogId: meta.avatarCatalogId || "",
765
768
  avatarStyle: meta.avatarStyle || "imprint",
766
769
  avatarSeed: meta.avatarSeed || meta.mateId,
767
770
  avatarColor: meta.avatarColor || "#5857fc",
@@ -0,0 +1,20 @@
1
+ import { store } from './store.js';
2
+ import { showToast } from './utils.js';
3
+
4
+ export function forwardPaneBrowserLink(url) {
5
+ if (!store.get('paneMode') || window.parent === window) return false;
6
+ window.parent.postMessage({ type: 'clay-pane-open-browser', url: url, projectSlug: store.get('currentSlug'), sessionId: String(store.get('activeSessionId')) }, window.location.origin);
7
+ return true;
8
+ }
9
+ export function handlePaneBrowserMessage(event, host) {
10
+ if (!event || event.origin !== window.location.origin || !host || !event.data || event.data.type !== 'clay-pane-open-browser') return false;
11
+ var msg = event.data, s = store.snap();
12
+ var frame = Array.from(host.querySelectorAll('.split-pane-frame')).find(function (item) { return item.contentWindow === event.source; });
13
+ var pane = frame && s.splitPanes && s.splitPanes.panes && s.splitPanes.panes.find(function (item) { return String(item.slug) === frame.dataset.projectSlug && String(item.sessionId) === frame.dataset.sessionId; });
14
+ if (!pane || msg.projectSlug !== s.currentSlug || msg.projectSlug !== frame.dataset.projectSlug || String(msg.sessionId) !== frame.dataset.sessionId) return true;
15
+ var expected = new URL('/p/' + encodeURIComponent(pane.slug) + '/?pane=1&session=' + encodeURIComponent(pane.sessionId), window.location.href).href;
16
+ if (frame.src !== expected) return true;
17
+ // The authenticated host owns the browser; a live same-project pane supplies only a URL.
18
+ import('./shared-browser.js').then(function (module) { module.openSharedBrowserAt(msg.url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
19
+ return true;
20
+ }
@@ -17,7 +17,13 @@ export function preparePersonalConnectionDialog(overlay, inline) {
17
17
  if (label && input) label.htmlFor = input.id;
18
18
  });
19
19
  enhanceSettingsSelects(overlay);
20
- function markDirty() { dirty = true; if (inline) store.set({personalEmailDirty:true}); }
20
+ var fields = Array.from(overlay.querySelectorAll('input,select,textarea'));
21
+ function value(field) {return field.type === 'checkbox' ? field.checked : field.value;}
22
+ var baseline = fields.map(value);
23
+ function markDirty() {
24
+ dirty = fields.some(function (field, index) {return value(field) !== baseline[index];});
25
+ if (inline) store.set({personalEmailDirty:dirty});
26
+ }
21
27
  overlay.addEventListener('input', markDirty);
22
28
  overlay.addEventListener('change', markDirty);
23
29
  var unsubscribe = inline ? store.subscribe(function (state, previousState) {