clay-server 5.2.0-beta.1 → 5.2.0-beta.10

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 (552) 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 +1 -239
  7. package/lib/claude-jsonl-watcher.js +1 -204
  8. package/lib/clay-control-presentation-binding.js +96 -0
  9. package/lib/clay-control-presentation.js +128 -0
  10. package/lib/clay-control-target-projection.js +26 -0
  11. package/lib/clay-mate-chat-receipts.js +26 -0
  12. package/lib/clay-mate-chat.js +88 -0
  13. package/lib/clay-mate-knowledge-input.js +26 -0
  14. package/lib/clay-mate-knowledge.js +95 -0
  15. package/lib/clay-mate-lifecycle.js +95 -0
  16. package/lib/clay-product-control-input.js +33 -0
  17. package/lib/clay-product-control-tools.js +51 -0
  18. package/lib/clay-product-control.js +247 -0
  19. package/lib/clay-project-lifecycle.js +154 -0
  20. package/lib/clay-project-record-input.js +44 -0
  21. package/lib/clay-project-records.js +84 -0
  22. package/lib/clay-scheduling-input.js +21 -0
  23. package/lib/clay-scheduling-receipts.js +26 -0
  24. package/lib/clay-scheduling.js +119 -0
  25. package/lib/clay-screen-controls.js +104 -0
  26. package/lib/clay-skill-install.js +1 -33
  27. package/lib/clay-workspace-controls.js +84 -0
  28. package/lib/clay-workspace-input.js +17 -0
  29. package/lib/clay-workspace-receipts.js +26 -0
  30. package/lib/cli-sessions.js +1 -300
  31. package/lib/codex-defaults.js +1 -28
  32. package/lib/context-usage.js +3 -2
  33. package/lib/contextual-screen-snapshot.js +38 -0
  34. package/lib/daemon-project-access.js +11 -0
  35. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  36. package/lib/daemon-project-lifecycle.js +262 -0
  37. package/lib/daemon-projects.js +1 -1
  38. package/lib/daemon.js +78 -276
  39. package/lib/default-ai-runtime.js +4 -8
  40. package/lib/dm-digest-cursor.js +120 -0
  41. package/lib/email-mcp-server.js +1 -1
  42. package/lib/issues-service.js +29 -15
  43. package/lib/kiro-defaults.js +1 -22
  44. package/lib/knowledge-db-import-validation.js +46 -0
  45. package/lib/knowledge-db-import.js +99 -0
  46. package/lib/knowledge-db-service.js +24 -33
  47. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  48. package/lib/knowledge-db-storage-nedb.js +66 -0
  49. package/lib/knowledge-db-storage.js +72 -0
  50. package/lib/knowledge-db-validation.js +0 -0
  51. package/lib/knowledge-document-index.js +2 -1
  52. package/lib/knowledge-file-store.js +7 -1
  53. package/lib/knowledge-product-operations.js +46 -0
  54. package/lib/mate-avatar-catalog.js +12 -0
  55. package/lib/mate-avatar-migration.js +41 -0
  56. package/lib/mate-context-service.js +138 -0
  57. package/lib/mate-context-tools.js +21 -0
  58. package/lib/mate-creation-mcp-server.js +2 -0
  59. package/lib/mate-knowledge-canonical-access.js +10 -0
  60. package/lib/mate-knowledge-mate-bound.js +53 -0
  61. package/lib/mate-knowledge-mcp-server.js +55 -8
  62. package/lib/mate-knowledge-service.js +16 -34
  63. package/lib/mate-knowledge-text-tools.js +106 -0
  64. package/lib/mate-lifecycle-service.js +94 -0
  65. package/lib/mate-message-delivery.js +43 -0
  66. package/lib/mate-ready-creation.js +9 -1
  67. package/lib/mate-schedule-input.js +29 -0
  68. package/lib/mate-schedule-lifecycle.js +151 -0
  69. package/lib/mate-scheduling.js +103 -0
  70. package/lib/mates.js +18 -6
  71. package/lib/mcp-agent-tools.js +117 -0
  72. package/lib/mcp-connection-store.js +119 -15
  73. package/lib/mcp-import-credentials.js +31 -0
  74. package/lib/mcp-local-transport.js +13 -0
  75. package/lib/mcp-oauth.js +8 -6
  76. package/lib/mcp-proxy.js +2 -32
  77. package/lib/mcp-query-bridge.js +30 -0
  78. package/lib/mcp-remote-connections.js +74 -20
  79. package/lib/mcp-source-adapters.js +1 -0
  80. package/lib/mcp-source-context.js +1 -0
  81. package/lib/mcp-source-discovery.js +1 -0
  82. package/lib/mcp-source-plugins.js +1 -0
  83. package/lib/mcp-source-restrictions.js +1 -0
  84. package/lib/mcp-tool-policy.js +9 -0
  85. package/lib/notes-checklist.js +50 -0
  86. package/lib/notes.js +49 -3
  87. package/lib/os-user-diagnostics.js +2 -4
  88. package/lib/os-users.js +24 -70
  89. package/lib/pane-pending-interactions.js +20 -0
  90. package/lib/pane-session-activation.js +114 -0
  91. package/lib/pane-session-transport.js +26 -0
  92. package/lib/project-admin-overview.js +51 -0
  93. package/lib/project-ask-user.js +8 -4
  94. package/lib/project-connection.js +14 -10
  95. package/lib/project-control-git-view.js +12 -0
  96. package/lib/project-debate.js +1 -0
  97. package/lib/project-delegated-follow-up.js +2 -1
  98. package/lib/project-directory-claim.js +65 -0
  99. package/lib/project-file-operations.js +61 -0
  100. package/lib/project-filesystem.js +15 -85
  101. package/lib/project-full-access.js +23 -2
  102. package/lib/project-http.js +7 -4
  103. package/lib/project-knowledge.js +32 -18
  104. package/lib/project-lifecycle-operations.js +98 -0
  105. package/lib/project-lifecycle-process-witness.js +32 -0
  106. package/lib/project-lifecycle-runtime.js +50 -0
  107. package/lib/project-linux-access.js +22 -0
  108. package/lib/project-logs-canonical-clay.js +27 -0
  109. package/lib/project-logs-clay-query.js +16 -0
  110. package/lib/project-logs-schema.js +4 -2
  111. package/lib/project-logs-service.js +8 -7
  112. package/lib/project-logs.js +1 -0
  113. package/lib/project-loop.js +1 -0
  114. package/lib/project-mate-chat-control.js +55 -0
  115. package/lib/project-mate-creation-proposal.js +18 -3
  116. package/lib/project-mate-interaction.js +40 -62
  117. package/lib/project-mcp.js +54 -16
  118. package/lib/project-models.js +14 -31
  119. package/lib/project-notifications.js +76 -17
  120. package/lib/project-ownership.js +77 -0
  121. package/lib/project-pair-result-delivery.js +14 -3
  122. package/lib/project-pair-usage.js +12 -13
  123. package/lib/project-pending-message-queue.js +4 -1
  124. package/lib/project-product-control.js +89 -0
  125. package/lib/project-product-session-queue.js +46 -0
  126. package/lib/project-push-access.js +28 -0
  127. package/lib/project-scheduled-message-queue.js +30 -0
  128. package/lib/project-scheduled-messages.js +67 -68
  129. package/lib/project-scheduled-task-control.js +83 -0
  130. package/lib/project-scheduled-tasks.js +13 -2
  131. package/lib/project-scheduling-access.js +10 -0
  132. package/lib/project-session-actions.js +65 -0
  133. package/lib/project-session-delete.js +8 -1
  134. package/lib/project-session-document.js +27 -7
  135. package/lib/project-session-github.js +63 -19
  136. package/lib/project-session-history-actions.js +167 -0
  137. package/lib/project-session-linear.js +14 -6
  138. package/lib/project-session-notes.js +7 -3
  139. package/lib/project-session-pair.js +1 -1
  140. package/lib/project-session-runtime-actions.js +64 -0
  141. package/lib/project-session-spawn.js +2 -3
  142. package/lib/project-session-vendor.js +55 -0
  143. package/lib/project-sessions.js +103 -272
  144. package/lib/project-shared-browser.js +78 -17
  145. package/lib/project-studio-presentation.js +58 -0
  146. package/lib/project-user-message.js +67 -1
  147. package/lib/project-vendor-login.js +6 -36
  148. package/lib/project-workspace-operations.js +126 -0
  149. package/lib/project-workspace-query.js +19 -2
  150. package/lib/project.js +178 -45
  151. package/lib/public/app.js +46 -0
  152. package/lib/public/appearance-bootstrap.js +16 -0
  153. package/lib/public/css/clay-tool-activity.css +51 -0
  154. package/lib/public/css/clay-workspace.css +29 -0
  155. package/lib/public/css/command-palette.css +12 -33
  156. package/lib/public/css/contextual-clay.css +240 -0
  157. package/lib/public/css/home-debate-planning.css +2 -0
  158. package/lib/public/css/home-mate-creation.css +5 -0
  159. package/lib/public/css/input.css +6 -0
  160. package/lib/public/css/mate-avatar-gallery.css +12 -0
  161. package/lib/public/css/mate-conversation.css +10 -5
  162. package/lib/public/css/messages.css +6 -2
  163. package/lib/public/css/overlays.css +4 -2
  164. package/lib/public/css/project-admin-overview.css +13 -0
  165. package/lib/public/css/session-folders.css +11 -0
  166. package/lib/public/css/session-github.css +46 -1
  167. package/lib/public/css/shared-browser.css +35 -1
  168. package/lib/public/css/sticky-notes.css +87 -1
  169. package/lib/public/index.html +11 -5
  170. package/lib/public/mate-avatars/B01.png +0 -0
  171. package/lib/public/mate-avatars/B02.png +0 -0
  172. package/lib/public/mate-avatars/B03.png +0 -0
  173. package/lib/public/mate-avatars/B04.png +0 -0
  174. package/lib/public/mate-avatars/B05.png +0 -0
  175. package/lib/public/mate-avatars/B06.png +0 -0
  176. package/lib/public/mate-avatars/B07.png +0 -0
  177. package/lib/public/mate-avatars/B08.png +0 -0
  178. package/lib/public/mate-avatars/B09.png +0 -0
  179. package/lib/public/mate-avatars/B10.png +0 -0
  180. package/lib/public/mate-avatars/B11.png +0 -0
  181. package/lib/public/mate-avatars/B12.png +0 -0
  182. package/lib/public/mate-avatars/B13.png +0 -0
  183. package/lib/public/mate-avatars/B14.png +0 -0
  184. package/lib/public/mate-avatars/B15.png +0 -0
  185. package/lib/public/mate-avatars/B16.png +0 -0
  186. package/lib/public/mate-avatars/B17.png +0 -0
  187. package/lib/public/mate-avatars/B18.png +0 -0
  188. package/lib/public/mate-avatars/B19.png +0 -0
  189. package/lib/public/mate-avatars/B20.png +0 -0
  190. package/lib/public/mate-avatars/B21.png +0 -0
  191. package/lib/public/mate-avatars/B22.png +0 -0
  192. package/lib/public/mate-avatars/B23.png +0 -0
  193. package/lib/public/mate-avatars/B24.png +0 -0
  194. package/lib/public/mate-avatars/B25.png +0 -0
  195. package/lib/public/mate-avatars/B26.png +0 -0
  196. package/lib/public/mate-avatars/B27.png +0 -0
  197. package/lib/public/mate-avatars/B28.png +0 -0
  198. package/lib/public/mate-avatars/B29.png +0 -0
  199. package/lib/public/mate-avatars/B30.png +0 -0
  200. package/lib/public/mate-avatars/B31.png +0 -0
  201. package/lib/public/mate-avatars/B32.png +0 -0
  202. package/lib/public/mate-avatars/B33.png +0 -0
  203. package/lib/public/mate-avatars/B34.png +0 -0
  204. package/lib/public/mate-avatars/B35.png +0 -0
  205. package/lib/public/mate-avatars/B36.png +0 -0
  206. package/lib/public/mate-avatars/B37.png +0 -0
  207. package/lib/public/mate-avatars/B38.png +0 -0
  208. package/lib/public/mate-avatars/B39.png +0 -0
  209. package/lib/public/mate-avatars/B40.png +0 -0
  210. package/lib/public/mate-avatars/B41.png +0 -0
  211. package/lib/public/mate-avatars/B42.png +0 -0
  212. package/lib/public/mate-avatars/B43.png +0 -0
  213. package/lib/public/mate-avatars/B44.png +0 -0
  214. package/lib/public/mate-avatars/B45.png +0 -0
  215. package/lib/public/mate-avatars/B46.png +0 -0
  216. package/lib/public/mate-avatars/B47.png +0 -0
  217. package/lib/public/mate-avatars/B48.png +0 -0
  218. package/lib/public/mate-avatars/C01.png +0 -0
  219. package/lib/public/mate-avatars/C02.png +0 -0
  220. package/lib/public/mate-avatars/C03.png +0 -0
  221. package/lib/public/mate-avatars/C04.png +0 -0
  222. package/lib/public/mate-avatars/C05.png +0 -0
  223. package/lib/public/mate-avatars/C06.png +0 -0
  224. package/lib/public/mate-avatars/C07.png +0 -0
  225. package/lib/public/mate-avatars/C08.png +0 -0
  226. package/lib/public/mate-avatars/C09.png +0 -0
  227. package/lib/public/mate-avatars/C10.png +0 -0
  228. package/lib/public/mate-avatars/C11.png +0 -0
  229. package/lib/public/mate-avatars/C12.png +0 -0
  230. package/lib/public/mate-avatars/C13.png +0 -0
  231. package/lib/public/mate-avatars/C14.png +0 -0
  232. package/lib/public/mate-avatars/C15.png +0 -0
  233. package/lib/public/mate-avatars/C16.png +0 -0
  234. package/lib/public/mate-avatars/C17.png +0 -0
  235. package/lib/public/mate-avatars/C18.png +0 -0
  236. package/lib/public/mate-avatars/C19.png +0 -0
  237. package/lib/public/mate-avatars/C20.png +0 -0
  238. package/lib/public/mate-avatars/C21.png +0 -0
  239. package/lib/public/mate-avatars/C22.png +0 -0
  240. package/lib/public/mate-avatars/C23.png +0 -0
  241. package/lib/public/mate-avatars/C24.png +0 -0
  242. package/lib/public/mate-avatars/C25.png +0 -0
  243. package/lib/public/mate-avatars/C26.png +0 -0
  244. package/lib/public/mate-avatars/C27.png +0 -0
  245. package/lib/public/mate-avatars/C28.png +0 -0
  246. package/lib/public/mate-avatars/C29.png +0 -0
  247. package/lib/public/mate-avatars/C30.png +0 -0
  248. package/lib/public/mate-avatars/C31.png +0 -0
  249. package/lib/public/mate-avatars/C32.png +0 -0
  250. package/lib/public/mate-avatars/C33.png +0 -0
  251. package/lib/public/mate-avatars/C34.png +0 -0
  252. package/lib/public/mate-avatars/C35.png +0 -0
  253. package/lib/public/mate-avatars/C36.png +0 -0
  254. package/lib/public/mate-avatars/C37.png +0 -0
  255. package/lib/public/mate-avatars/C38.png +0 -0
  256. package/lib/public/mate-avatars/C39.png +0 -0
  257. package/lib/public/mate-avatars/C40.png +0 -0
  258. package/lib/public/mate-avatars/C41.png +0 -0
  259. package/lib/public/mate-avatars/C42.png +0 -0
  260. package/lib/public/mate-avatars/C43.png +0 -0
  261. package/lib/public/mate-avatars/C44.png +0 -0
  262. package/lib/public/mate-avatars/C45.png +0 -0
  263. package/lib/public/mate-avatars/C46.png +0 -0
  264. package/lib/public/mate-avatars/C47.png +0 -0
  265. package/lib/public/mate-avatars/C48.png +0 -0
  266. package/lib/public/mate-avatars/catalog.json +482 -0
  267. package/lib/public/mate-avatars/lead-clay.png +0 -0
  268. package/lib/public/modules/admin-settings-projects.js +6 -2
  269. package/lib/public/modules/app-connection.js +11 -1
  270. package/lib/public/modules/app-favicon.js +18 -9
  271. package/lib/public/modules/app-header.js +7 -4
  272. package/lib/public/modules/app-loop-ui.js +2 -0
  273. package/lib/public/modules/app-message-router.js +22 -1
  274. package/lib/public/modules/app-messages.js +115 -17
  275. package/lib/public/modules/app-misc.js +3 -1
  276. package/lib/public/modules/app-notifications.js +11 -5
  277. package/lib/public/modules/app-panels.js +61 -123
  278. package/lib/public/modules/app-projects.js +13 -0
  279. package/lib/public/modules/app-rate-limit.js +7 -27
  280. package/lib/public/modules/app-rendering.js +4 -3
  281. package/lib/public/modules/avatar.js +15 -41
  282. package/lib/public/modules/chat-render-runtime.js +20 -0
  283. package/lib/public/modules/clay-browser-links.js +47 -0
  284. package/lib/public/modules/clay-control-activity.js +214 -0
  285. package/lib/public/modules/clay-control-copy.js +36 -0
  286. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  287. package/lib/public/modules/clay-control-object-targets.js +52 -0
  288. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  289. package/lib/public/modules/clay-control-targets.js +44 -0
  290. package/lib/public/modules/clay-log-links.js +23 -0
  291. package/lib/public/modules/clay-navigation-render.js +52 -0
  292. package/lib/public/modules/clay-owner-navigation.js +33 -0
  293. package/lib/public/modules/clay-session-links.js +31 -0
  294. package/lib/public/modules/clay-studio-bridge.js +20 -0
  295. package/lib/public/modules/clay-studio-document.js +67 -0
  296. package/lib/public/modules/clay-studio-render.js +146 -0
  297. package/lib/public/modules/clay-tool-activity.js +140 -0
  298. package/lib/public/modules/clay-tool-presentation.js +342 -0
  299. package/lib/public/modules/command-palette.js +162 -40
  300. package/lib/public/modules/contextual-ask-session.js +26 -0
  301. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  302. package/lib/public/modules/contextual-clay-session.js +130 -0
  303. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  304. package/lib/public/modules/contextual-clay.js +250 -0
  305. package/lib/public/modules/contextual-composer.js +91 -0
  306. package/lib/public/modules/contextual-mate-context.js +117 -0
  307. package/lib/public/modules/contextual-mate-hint.js +40 -0
  308. package/lib/public/modules/contextual-mate-identity.js +23 -0
  309. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  310. package/lib/public/modules/contextual-search.js +137 -0
  311. package/lib/public/modules/contextual-session-citations.js +58 -0
  312. package/lib/public/modules/debate.js +1 -0
  313. package/lib/public/modules/default-ai.js +11 -3
  314. package/lib/public/modules/elicitation-form.js +5 -0
  315. package/lib/public/modules/filebrowser.js +20 -1
  316. package/lib/public/modules/generation-stop.js +8 -5
  317. package/lib/public/modules/git-panel.js +3 -1
  318. package/lib/public/modules/history-replay-batch.js +13 -1
  319. package/lib/public/modules/home-debate-live.js +2 -0
  320. package/lib/public/modules/home-debate-planning.js +7 -7
  321. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  322. package/lib/public/modules/home-mate-chat.js +8 -6
  323. package/lib/public/modules/home-mate-creation.js +73 -1
  324. package/lib/public/modules/home-mate-settings.js +19 -12
  325. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  326. package/lib/public/modules/input.js +88 -10
  327. package/lib/public/modules/issues-render.js +3 -2
  328. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  329. package/lib/public/modules/markdown.js +6 -34
  330. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  331. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  332. package/lib/public/modules/mate-management.js +40 -7
  333. package/lib/public/modules/mcp-connection-view.js +31 -13
  334. package/lib/public/modules/mcp-discovery-view.js +31 -0
  335. package/lib/public/modules/mcp-ui.js +23 -4
  336. package/lib/public/modules/mention.js +3 -0
  337. package/lib/public/modules/message-delivery.js +20 -2
  338. package/lib/public/modules/model-picker.js +2 -0
  339. package/lib/public/modules/pane-activation.js +214 -0
  340. package/lib/public/modules/pane-binding.js +82 -0
  341. package/lib/public/modules/pane-bridge.js +7 -4
  342. package/lib/public/modules/pane-browser-bridge.js +22 -0
  343. package/lib/public/modules/pane-file-bridge.js +4 -0
  344. package/lib/public/modules/pane-issue-bridge.js +4 -1
  345. package/lib/public/modules/pending-message-queue.js +1 -0
  346. package/lib/public/modules/permission-control.js +5 -4
  347. package/lib/public/modules/personal-settings-dialog.js +7 -1
  348. package/lib/public/modules/product-review.js +26 -0
  349. package/lib/public/modules/profile.js +1 -238
  350. package/lib/public/modules/project-access-recovery.js +17 -0
  351. package/lib/public/modules/project-admin-overview.js +21 -0
  352. package/lib/public/modules/project-chat-identity.js +13 -4
  353. package/lib/public/modules/project-logs-render.js +3 -0
  354. package/lib/public/modules/project-mate-navigation.js +144 -22
  355. package/lib/public/modules/rewind.js +5 -0
  356. package/lib/public/modules/scheduled-tasks.js +2 -0
  357. package/lib/public/modules/scheduler.js +2 -0
  358. package/lib/public/modules/search-clay-chat.js +5 -440
  359. package/lib/public/modules/session-actions.js +5 -2
  360. package/lib/public/modules/session-context-menu.js +5 -0
  361. package/lib/public/modules/session-create-form.js +10 -10
  362. package/lib/public/modules/session-folder-layout.js +1 -1
  363. package/lib/public/modules/session-folder-view-menu.js +9 -0
  364. package/lib/public/modules/session-github.js +85 -14
  365. package/lib/public/modules/session-rich-drafts.js +21 -0
  366. package/lib/public/modules/session-switch-defer.js +67 -0
  367. package/lib/public/modules/session-work-primary.js +51 -0
  368. package/lib/public/modules/settings-defaults.js +27 -28
  369. package/lib/public/modules/shared-browser-settings.js +112 -0
  370. package/lib/public/modules/shared-browser-tabs.js +13 -3
  371. package/lib/public/modules/shared-browser.js +29 -6
  372. package/lib/public/modules/sidebar-mobile.js +4 -3
  373. package/lib/public/modules/sidebar-projects.js +1 -0
  374. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  375. package/lib/public/modules/sidebar-sessions.js +1 -0
  376. package/lib/public/modules/split-group-restore.js +68 -0
  377. package/lib/public/modules/split-pair-ui.js +1 -0
  378. package/lib/public/modules/split-pane-reconciler.js +15 -0
  379. package/lib/public/modules/split-pane-renderer.js +87 -6
  380. package/lib/public/modules/split-session-boundary.js +1 -1
  381. package/lib/public/modules/split-view.js +60 -68
  382. package/lib/public/modules/sticky-note-markdown.js +72 -6
  383. package/lib/public/modules/sticky-notes-actions.js +30 -0
  384. package/lib/public/modules/sticky-notes-browser.js +9 -2
  385. package/lib/public/modules/sticky-notes-card.js +23 -7
  386. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  387. package/lib/public/modules/sticky-notes-editor.js +108 -44
  388. package/lib/public/modules/sticky-notes-shared.js +50 -2
  389. package/lib/public/modules/sticky-notes-state.js +66 -0
  390. package/lib/public/modules/sticky-notes.js +34 -51
  391. package/lib/public/modules/stt-controller.js +4 -1
  392. package/lib/public/modules/stt-recording.js +1 -1
  393. package/lib/public/modules/stt.js +7 -2
  394. package/lib/public/modules/terminal.js +9 -0
  395. package/lib/public/modules/theme.js +8 -1
  396. package/lib/public/modules/thinking-lifecycle.js +33 -3
  397. package/lib/public/modules/thinking-view.js +23 -1
  398. package/lib/public/modules/tools.js +60 -11
  399. package/lib/public/modules/tui-grab.js +1 -2
  400. package/lib/public/modules/user-settings-appearance.js +10 -3
  401. package/lib/public/modules/user-settings-editors.js +1 -1
  402. package/lib/public/modules/user-settings-layout.js +11 -2
  403. package/lib/public/modules/user-settings-preferences.js +6 -2
  404. package/lib/public/modules/user-settings-profile.js +12 -2
  405. package/lib/public/modules/user-settings.js +3 -2
  406. package/lib/public/modules/vendor-login-browser.js +5 -3
  407. package/lib/public/modules/vendor-login.js +2 -2
  408. package/lib/public/modules/vendor-priority.js +15 -1
  409. package/lib/public/modules/wireframe-workbench.js +5 -2
  410. package/lib/public/muse-avatar.svg +4 -0
  411. package/lib/public/style.css +5 -0
  412. package/lib/public/sw.js +3 -1
  413. package/lib/safe-bash-commands.js +3 -45
  414. package/lib/scheduled-task-records.js +3 -1
  415. package/lib/scheduler.js +2 -0
  416. package/lib/sdk-bridge.js +342 -401
  417. package/lib/sdk-foreground-admission.js +16 -0
  418. package/lib/sdk-mcp-descriptors.js +2 -37
  419. package/lib/sdk-message-processor.js +52 -17
  420. package/lib/sdk-quota-snapshot.js +1 -1
  421. package/lib/sdk-response-recovery.js +1 -0
  422. package/lib/sdk-worker.js +2 -677
  423. package/lib/server-admin.js +63 -16
  424. package/lib/server-appearance-settings.js +13 -1
  425. package/lib/server-contextual-clay-settings.js +40 -0
  426. package/lib/server-contextual-mate-sessions.js +70 -0
  427. package/lib/server-dm.js +2 -1
  428. package/lib/server-global-ws.js +10 -20
  429. package/lib/server-home-chat-events.js +18 -4
  430. package/lib/server-home-chat.js +22 -20
  431. package/lib/server-home-clay-entry.js +23 -4
  432. package/lib/server-home-clay-session-links.js +29 -9
  433. package/lib/server-home-mate-creation.js +1 -0
  434. package/lib/server-home-mcp-consent.js +14 -0
  435. package/lib/server-mates.js +25 -62
  436. package/lib/server-owner-ui.js +118 -0
  437. package/lib/server-path-access.js +38 -0
  438. package/lib/server-project-removal.js +22 -0
  439. package/lib/server-settings.js +6 -1
  440. package/lib/server.js +163 -43
  441. package/lib/session-config-transition.js +45 -0
  442. package/lib/session-folders.js +7 -2
  443. package/lib/session-fork-history.js +21 -0
  444. package/lib/session-github.js +9 -2
  445. package/lib/session-hygiene.js +3 -35
  446. package/lib/session-permission-mode.js +4 -3
  447. package/lib/session-skill-scope.js +11 -0
  448. package/lib/session-visibility.js +5 -2
  449. package/lib/session-work-primary.js +50 -0
  450. package/lib/sessions.js +64 -99
  451. package/lib/shared-browser-cookie-sync.js +32 -0
  452. package/lib/shared-browser-cookies.js +79 -0
  453. package/lib/shared-browser-runtime.js +25 -9
  454. package/lib/shared-browser-storage-sync.js +43 -0
  455. package/lib/shared-browser-storage.js +101 -0
  456. package/lib/shared-browser-tools.js +2 -1
  457. package/lib/shared-browser-worker.js +46 -10
  458. package/lib/terminal-manager.js +65 -6
  459. package/lib/tool-llm.js +1 -1
  460. package/lib/tui-transcript-index.js +1 -132
  461. package/lib/users-contextual-clay-preferences.js +31 -0
  462. package/lib/users-permissions.js +2 -8
  463. package/lib/users.js +7 -0
  464. package/lib/vendor-login-browser.js +1 -11
  465. package/lib/workspace-assignment-service.js +25 -0
  466. package/lib/workspace-query-access.js +4 -1
  467. package/lib/workspace-query-mcp-server.js +1 -1
  468. package/lib/workspace-query-service.js +13 -2
  469. package/lib/ws-request.js +1 -0
  470. package/lib/ws-schema.js +18 -2
  471. package/lib/yoke/acp-agent-profiles.js +7 -5
  472. package/lib/yoke/adapters/antigravity.js +3 -14
  473. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  474. package/lib/yoke/adapters/claude.js +54 -50
  475. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  476. package/lib/yoke/adapters/codex.js +53 -111
  477. package/lib/yoke/adapters/kiro.js +3 -1
  478. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  479. package/lib/yoke/adapters/muse.js +122 -0
  480. package/lib/yoke/auth-events.js +17 -0
  481. package/lib/yoke/claude-hook-installer.js +271 -0
  482. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  483. package/lib/yoke/claude-maintenance.js +55 -0
  484. package/lib/yoke/claude-permission-patterns.js +53 -0
  485. package/lib/yoke/claude-response-recovery.js +155 -0
  486. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  487. package/lib/yoke/claude-worker-startup.js +28 -0
  488. package/lib/yoke/clay-skill-install.js +33 -0
  489. package/lib/yoke/cli-sessions.js +300 -0
  490. package/lib/yoke/codex-app-server.js +7 -12
  491. package/lib/yoke/codex-idle-recovery.js +81 -1
  492. package/lib/yoke/codex-recovery-admission.js +164 -0
  493. package/lib/yoke/configuration.js +13 -0
  494. package/lib/yoke/discovery.js +70 -0
  495. package/lib/yoke/errors.js +8 -0
  496. package/lib/yoke/host-environment.js +7 -0
  497. package/lib/yoke/index.js +9 -51
  498. package/lib/yoke/interface.js +116 -0
  499. package/lib/yoke/kiro-acp-server.js +5 -5
  500. package/lib/yoke/legacy-sessions.js +89 -0
  501. package/lib/yoke/login-protocol.js +25 -0
  502. package/lib/yoke/maintenance.js +12 -0
  503. package/lib/yoke/mcp-proxy.js +32 -0
  504. package/lib/yoke/mcp-source-adapters.js +91 -0
  505. package/lib/yoke/mcp-source-context.js +42 -0
  506. package/lib/yoke/mcp-source-discovery.js +169 -0
  507. package/lib/yoke/mcp-source-plugins.js +68 -0
  508. package/lib/yoke/mcp-source-restrictions.js +47 -0
  509. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  510. package/lib/yoke/model-preferences.js +6 -0
  511. package/lib/yoke/muse-artifacts.js +36 -0
  512. package/lib/yoke/muse-controls.js +50 -0
  513. package/lib/yoke/muse-input.js +64 -0
  514. package/lib/yoke/muse-items.js +157 -0
  515. package/lib/yoke/muse-policy.js +52 -0
  516. package/lib/yoke/muse-query.js +428 -0
  517. package/lib/yoke/muse-runtime.js +211 -0
  518. package/lib/yoke/muse-services.js +79 -0
  519. package/lib/yoke/muse-skills.js +79 -0
  520. package/lib/yoke/muse-turns.js +71 -0
  521. package/lib/yoke/options/acp.js +2 -0
  522. package/lib/yoke/options/antigravity.js +2 -0
  523. package/lib/yoke/options/claude.js +21 -0
  524. package/lib/yoke/options/codex-defaults.js +29 -0
  525. package/lib/yoke/options/codex-settings.js +21 -0
  526. package/lib/yoke/options/codex.js +6 -0
  527. package/lib/yoke/options/kiro-defaults.js +22 -0
  528. package/lib/yoke/options/kiro.js +5 -0
  529. package/lib/yoke/options/muse.js +5 -0
  530. package/lib/yoke/provider-contract.js +5 -0
  531. package/lib/yoke/providers/antigravity-executable.js +8 -0
  532. package/lib/yoke/providers/claude-executable.js +40 -0
  533. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  534. package/lib/yoke/providers/claude-process.js +97 -0
  535. package/lib/yoke/providers/claude-provision.js +75 -0
  536. package/lib/yoke/providers/codex-errors.js +8 -0
  537. package/lib/yoke/providers/muse-executable.js +17 -0
  538. package/lib/yoke/provisioning.js +6 -0
  539. package/lib/yoke/query-options.js +10 -0
  540. package/lib/yoke/response-recovery.js +41 -0
  541. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  542. package/lib/yoke/sdk-server-factory.js +7 -0
  543. package/lib/yoke/session-history.js +8 -0
  544. package/lib/yoke/session-tool-transport.js +34 -13
  545. package/lib/yoke/settings.js +23 -0
  546. package/lib/yoke/source-locations.js +4 -0
  547. package/lib/yoke/title-query.js +18 -7
  548. package/lib/yoke/tui-transcript-index.js +132 -0
  549. package/lib/yoke/usage.js +48 -0
  550. package/lib/yoke/user-input.js +13 -0
  551. package/lib/yoke/vendor-registry.js +81 -1
  552. package/package.json +10 -4
@@ -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 require a runtime that supports session-bound tools. Availability follows the selected runtime’s capabilities.</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",
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { store } from './store.js';
4
4
  import { getWs } from './ws-ref.js';
5
+ import { paneMessageBinding } from './pane-binding.js';
5
6
 
6
7
  var ACK_TIMEOUT_MS = 5000;
7
8
  var ACK_RETRY_LIMIT = 3;
@@ -152,7 +153,7 @@ function transmit(entry, automatic) {
152
153
  }
153
154
  socketRefs[entry.payload.clientMessageId] = socket;
154
155
  try {
155
- socket.send(JSON.stringify(entry.payload));
156
+ if (socket.send(JSON.stringify(entry.payload)) === false) { markUnconfirmed(entry); return false; }
156
157
  armAckTimer(entry.payload.clientMessageId, socket);
157
158
  return true;
158
159
  } catch (e) {
@@ -163,6 +164,8 @@ function transmit(entry, automatic) {
163
164
 
164
165
  export function sendAcknowledgedMessage(payload) {
165
166
  var nextPayload = Object.assign({}, payload, { clientMessageId: createClientMessageId() });
167
+ var binding = paneMessageBinding();
168
+ if (binding && !nextPayload.paneBinding) nextPayload.paneBinding = binding;
166
169
  var entry = {
167
170
  projectSlug: store.get('currentSlug'),
168
171
  sessionId: store.get('activeSessionId'),
@@ -179,6 +182,7 @@ export function sendAcknowledgedMessage(payload) {
179
182
  nextPayload.cliSessionId = entry.cliSessionId;
180
183
  nextPayload.sessionOriginId = entry.sessionOriginId;
181
184
  entry.payload = nextPayload;
185
+ if (nextPayload.contextualSnapshot) store.set({ contextualSnapshotSubmissions: (store.get('contextualSnapshotSubmissions') || []).concat([{ clientMessageId: nextPayload.clientMessageId, accountId: entry.accountId, projectSlug: entry.projectSlug, sessionId: entry.sessionId, sessionOriginId: entry.sessionOriginId, snapshot: nextPayload.contextualSnapshot }]).slice(-64) });
182
186
  replacePending(pendingMessages().concat([entry]));
183
187
  if (!transmit(entry, false)) {
184
188
  if (!getWs() || getWs().readyState !== 1) markUnconfirmed(entry);
@@ -192,7 +196,12 @@ export function sendAcknowledgedMessage(payload) {
192
196
  export function retryPendingMessage(clientMessageId) {
193
197
  var entry = pendingEntry(clientMessageId);
194
198
  if (!matchesActivatedContext(entry) || hasKnownCliMismatch(entry)) return false;
195
- var retryEntry = Object.assign({}, entry, { attempts: 0, status: "pending" });
199
+ // An explicit Retry in the same durable conversation may use its new live
200
+ // binding. Automatic retry retains the original action binding and refuses.
201
+ var payload = Object.assign({}, entry.payload);
202
+ var binding = paneMessageBinding();
203
+ if (binding) payload.paneBinding = binding;
204
+ var retryEntry = Object.assign({}, entry, { payload: payload, attempts: 0, status: "pending" });
196
205
  replacePending(pendingMessages().map(function (candidate) {
197
206
  return candidate.payload.clientMessageId === clientMessageId ? retryEntry : candidate;
198
207
  }));
@@ -204,6 +213,15 @@ export function retryPendingMessage(clientMessageId) {
204
213
  return false;
205
214
  }
206
215
 
216
+ // Stop retains the uncertain receipt but prevents automatic retransmission.
217
+ export function pausePendingMessage(clientMessageId) {
218
+ var entry = pendingEntry(clientMessageId);
219
+ if (!entry || !matchesCurrentContext(entry)) return false;
220
+ clearAckTimer(clientMessageId);
221
+ markUnconfirmed(entry);
222
+ return true;
223
+ }
224
+
207
225
  export function acknowledgeMessage(clientMessageId) {
208
226
  if (typeof clientMessageId !== "string") return null;
209
227
  var pending = pendingMessages();
@@ -50,6 +50,8 @@ export function setupModelPicker() {
50
50
 
51
51
  export function resetModelPickerState() {
52
52
  clearRequestTimer();
53
+ if (configPopover) configPopover.classList.add('hidden');
54
+ if (configChip) configChip.classList.remove('active');
53
55
  store.set({
54
56
  modelListVendor: "",
55
57
  modelListStatus: "idle",