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

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 (608) hide show
  1. package/README.md +0 -4
  2. package/lib/account-auth-socket.js +1 -0
  3. package/lib/builtin-mates.js +19 -16
  4. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  5. package/lib/canonical-clay-record-authority.js +15 -0
  6. package/lib/canonical-clay-scheduling-authority.js +19 -0
  7. package/lib/claude-hook-installer.js +1 -239
  8. package/lib/claude-jsonl-watcher.js +1 -204
  9. package/lib/clay-control-presentation-binding.js +96 -0
  10. package/lib/clay-control-presentation.js +128 -0
  11. package/lib/clay-control-target-projection.js +26 -0
  12. package/lib/clay-mate-chat-receipts.js +26 -0
  13. package/lib/clay-mate-chat.js +88 -0
  14. package/lib/clay-mate-knowledge-input.js +26 -0
  15. package/lib/clay-mate-knowledge.js +95 -0
  16. package/lib/clay-mate-lifecycle.js +95 -0
  17. package/lib/clay-product-control-input.js +33 -0
  18. package/lib/clay-product-control-tools.js +52 -0
  19. package/lib/clay-product-control.js +250 -0
  20. package/lib/clay-project-lifecycle.js +154 -0
  21. package/lib/clay-project-record-input.js +44 -0
  22. package/lib/clay-project-records.js +84 -0
  23. package/lib/clay-scheduling-input.js +21 -0
  24. package/lib/clay-scheduling-receipts.js +26 -0
  25. package/lib/clay-scheduling.js +119 -0
  26. package/lib/clay-screen-controls.js +104 -0
  27. package/lib/clay-skill-install.js +1 -33
  28. package/lib/clay-vendor-usage.js +44 -0
  29. package/lib/clay-workspace-controls.js +84 -0
  30. package/lib/clay-workspace-input.js +17 -0
  31. package/lib/clay-workspace-receipts.js +26 -0
  32. package/lib/cli-sessions.js +1 -300
  33. package/lib/codex-defaults.js +1 -28
  34. package/lib/context-usage.js +3 -2
  35. package/lib/contextual-screen-snapshot.js +38 -0
  36. package/lib/daemon-project-access.js +11 -0
  37. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  38. package/lib/daemon-project-lifecycle.js +262 -0
  39. package/lib/daemon-projects.js +1 -1
  40. package/lib/daemon.js +78 -276
  41. package/lib/default-ai-runtime.js +4 -8
  42. package/lib/dm-digest-cursor.js +120 -0
  43. package/lib/email-mcp-server.js +1 -1
  44. package/lib/github-star-count.js +147 -0
  45. package/lib/issues-service.js +29 -15
  46. package/lib/kiro-defaults.js +1 -22
  47. package/lib/knowledge-db-import-validation.js +46 -0
  48. package/lib/knowledge-db-import.js +99 -0
  49. package/lib/knowledge-db-service.js +24 -33
  50. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  51. package/lib/knowledge-db-storage-nedb.js +66 -0
  52. package/lib/knowledge-db-storage.js +72 -0
  53. package/lib/knowledge-db-validation.js +0 -0
  54. package/lib/knowledge-document-index.js +2 -1
  55. package/lib/knowledge-file-store.js +7 -1
  56. package/lib/knowledge-product-operations.js +46 -0
  57. package/lib/mate-avatar-catalog.js +12 -0
  58. package/lib/mate-avatar-migration.js +41 -0
  59. package/lib/mate-context-service.js +138 -0
  60. package/lib/mate-context-tools.js +21 -0
  61. package/lib/mate-creation-mcp-server.js +2 -0
  62. package/lib/mate-knowledge-canonical-access.js +10 -0
  63. package/lib/mate-knowledge-mate-bound.js +53 -0
  64. package/lib/mate-knowledge-mcp-server.js +55 -8
  65. package/lib/mate-knowledge-service.js +16 -34
  66. package/lib/mate-knowledge-text-tools.js +106 -0
  67. package/lib/mate-lifecycle-service.js +94 -0
  68. package/lib/mate-message-delivery.js +43 -0
  69. package/lib/mate-ready-creation.js +9 -1
  70. package/lib/mate-schedule-input.js +29 -0
  71. package/lib/mate-schedule-lifecycle.js +151 -0
  72. package/lib/mate-scheduling.js +103 -0
  73. package/lib/mates.js +18 -6
  74. package/lib/mcp-agent-tools.js +117 -0
  75. package/lib/mcp-connection-store.js +119 -15
  76. package/lib/mcp-import-credentials.js +31 -0
  77. package/lib/mcp-local-transport.js +13 -0
  78. package/lib/mcp-oauth.js +8 -6
  79. package/lib/mcp-proxy.js +2 -32
  80. package/lib/mcp-query-bridge.js +30 -0
  81. package/lib/mcp-remote-connections.js +74 -20
  82. package/lib/mcp-source-adapters.js +1 -0
  83. package/lib/mcp-source-context.js +1 -0
  84. package/lib/mcp-source-discovery.js +1 -0
  85. package/lib/mcp-source-plugins.js +1 -0
  86. package/lib/mcp-source-restrictions.js +1 -0
  87. package/lib/mcp-tool-policy.js +9 -0
  88. package/lib/notes-checklist.js +92 -0
  89. package/lib/notes.js +51 -4
  90. package/lib/os-user-diagnostics.js +2 -4
  91. package/lib/os-users.js +24 -70
  92. package/lib/pane-pending-interactions.js +20 -0
  93. package/lib/pane-session-activation.js +114 -0
  94. package/lib/pane-session-transport.js +26 -0
  95. package/lib/project-admin-overview.js +51 -0
  96. package/lib/project-ask-user.js +8 -4
  97. package/lib/project-connection.js +14 -10
  98. package/lib/project-control-git-view.js +12 -0
  99. package/lib/project-debate.js +1 -0
  100. package/lib/project-delegated-follow-up.js +2 -1
  101. package/lib/project-directory-claim.js +65 -0
  102. package/lib/project-file-operations.js +61 -0
  103. package/lib/project-filesystem.js +15 -85
  104. package/lib/project-full-access.js +23 -2
  105. package/lib/project-http.js +7 -4
  106. package/lib/project-knowledge.js +32 -18
  107. package/lib/project-lifecycle-operations.js +98 -0
  108. package/lib/project-lifecycle-process-witness.js +32 -0
  109. package/lib/project-lifecycle-runtime.js +50 -0
  110. package/lib/project-linux-access.js +22 -0
  111. package/lib/project-logs-canonical-clay.js +27 -0
  112. package/lib/project-logs-clay-query.js +16 -0
  113. package/lib/project-logs-schema.js +4 -2
  114. package/lib/project-logs-service.js +8 -7
  115. package/lib/project-logs.js +1 -0
  116. package/lib/project-loop.js +1 -0
  117. package/lib/project-mate-chat-control.js +55 -0
  118. package/lib/project-mate-creation-proposal.js +18 -3
  119. package/lib/project-mate-interaction.js +40 -62
  120. package/lib/project-mcp.js +54 -16
  121. package/lib/project-models.js +14 -31
  122. package/lib/project-notifications.js +76 -17
  123. package/lib/project-ownership.js +77 -0
  124. package/lib/project-pair-result-delivery.js +14 -3
  125. package/lib/project-pair-usage.js +12 -13
  126. package/lib/project-pending-message-queue.js +4 -1
  127. package/lib/project-product-control.js +89 -0
  128. package/lib/project-product-session-queue.js +46 -0
  129. package/lib/project-push-access.js +28 -0
  130. package/lib/project-scheduled-message-queue.js +30 -0
  131. package/lib/project-scheduled-messages.js +67 -68
  132. package/lib/project-scheduled-task-control.js +83 -0
  133. package/lib/project-scheduled-tasks.js +13 -2
  134. package/lib/project-scheduling-access.js +10 -0
  135. package/lib/project-session-actions.js +65 -0
  136. package/lib/project-session-delete.js +8 -1
  137. package/lib/project-session-document.js +27 -7
  138. package/lib/project-session-github.js +63 -19
  139. package/lib/project-session-history-actions.js +167 -0
  140. package/lib/project-session-linear.js +14 -6
  141. package/lib/project-session-notes.js +40 -11
  142. package/lib/project-session-pair.js +1 -1
  143. package/lib/project-session-runtime-actions.js +64 -0
  144. package/lib/project-session-spawn.js +2 -3
  145. package/lib/project-session-vendor.js +55 -0
  146. package/lib/project-sessions.js +160 -290
  147. package/lib/project-shared-browser.js +78 -17
  148. package/lib/project-start-protocol.js +29 -0
  149. package/lib/project-studio-presentation.js +58 -0
  150. package/lib/project-user-message.js +67 -1
  151. package/lib/project-vendor-login.js +8 -36
  152. package/lib/project-workspace-operations.js +126 -0
  153. package/lib/project-workspace-query.js +19 -2
  154. package/lib/project.js +181 -45
  155. package/lib/public/app.js +71 -17
  156. package/lib/public/appearance-bootstrap.js +16 -0
  157. package/lib/public/css/clay-tool-activity.css +51 -0
  158. package/lib/public/css/clay-workspace.css +29 -0
  159. package/lib/public/css/command-palette.css +12 -33
  160. package/lib/public/css/contextual-clay.css +240 -0
  161. package/lib/public/css/filebrowser.css +1 -1
  162. package/lib/public/css/home-debate-planning.css +2 -0
  163. package/lib/public/css/home-mate-creation.css +5 -0
  164. package/lib/public/css/input.css +6 -0
  165. package/lib/public/css/mate-avatar-gallery.css +12 -0
  166. package/lib/public/css/mate-conversation.css +10 -5
  167. package/lib/public/css/mate-loading-scene.css +21 -0
  168. package/lib/public/css/messages.css +6 -2
  169. package/lib/public/css/overlays.css +68 -258
  170. package/lib/public/css/project-admin-overview.css +13 -0
  171. package/lib/public/css/project-mate-creation.css +5 -6
  172. package/lib/public/css/project-start.css +108 -0
  173. package/lib/public/css/projects-hub.css +53 -14
  174. package/lib/public/css/session-folders.css +11 -0
  175. package/lib/public/css/session-github.css +46 -1
  176. package/lib/public/css/settings-shell.css +103 -0
  177. package/lib/public/css/shared-browser.css +35 -1
  178. package/lib/public/css/sidebar.css +7 -0
  179. package/lib/public/css/sticky-notes.css +87 -1
  180. package/lib/public/css/title-bar.css +79 -0
  181. package/lib/public/index.html +61 -68
  182. package/lib/public/mate-avatars/B01.png +0 -0
  183. package/lib/public/mate-avatars/B02.png +0 -0
  184. package/lib/public/mate-avatars/B03.png +0 -0
  185. package/lib/public/mate-avatars/B04.png +0 -0
  186. package/lib/public/mate-avatars/B05.png +0 -0
  187. package/lib/public/mate-avatars/B06.png +0 -0
  188. package/lib/public/mate-avatars/B07.png +0 -0
  189. package/lib/public/mate-avatars/B08.png +0 -0
  190. package/lib/public/mate-avatars/B09.png +0 -0
  191. package/lib/public/mate-avatars/B10.png +0 -0
  192. package/lib/public/mate-avatars/B11.png +0 -0
  193. package/lib/public/mate-avatars/B12.png +0 -0
  194. package/lib/public/mate-avatars/B13.png +0 -0
  195. package/lib/public/mate-avatars/B14.png +0 -0
  196. package/lib/public/mate-avatars/B15.png +0 -0
  197. package/lib/public/mate-avatars/B16.png +0 -0
  198. package/lib/public/mate-avatars/B17.png +0 -0
  199. package/lib/public/mate-avatars/B18.png +0 -0
  200. package/lib/public/mate-avatars/B19.png +0 -0
  201. package/lib/public/mate-avatars/B20.png +0 -0
  202. package/lib/public/mate-avatars/B21.png +0 -0
  203. package/lib/public/mate-avatars/B22.png +0 -0
  204. package/lib/public/mate-avatars/B23.png +0 -0
  205. package/lib/public/mate-avatars/B24.png +0 -0
  206. package/lib/public/mate-avatars/B25.png +0 -0
  207. package/lib/public/mate-avatars/B26.png +0 -0
  208. package/lib/public/mate-avatars/B27.png +0 -0
  209. package/lib/public/mate-avatars/B28.png +0 -0
  210. package/lib/public/mate-avatars/B29.png +0 -0
  211. package/lib/public/mate-avatars/B30.png +0 -0
  212. package/lib/public/mate-avatars/B31.png +0 -0
  213. package/lib/public/mate-avatars/B32.png +0 -0
  214. package/lib/public/mate-avatars/B33.png +0 -0
  215. package/lib/public/mate-avatars/B34.png +0 -0
  216. package/lib/public/mate-avatars/B35.png +0 -0
  217. package/lib/public/mate-avatars/B36.png +0 -0
  218. package/lib/public/mate-avatars/B37.png +0 -0
  219. package/lib/public/mate-avatars/B38.png +0 -0
  220. package/lib/public/mate-avatars/B39.png +0 -0
  221. package/lib/public/mate-avatars/B40.png +0 -0
  222. package/lib/public/mate-avatars/B41.png +0 -0
  223. package/lib/public/mate-avatars/B42.png +0 -0
  224. package/lib/public/mate-avatars/B43.png +0 -0
  225. package/lib/public/mate-avatars/B44.png +0 -0
  226. package/lib/public/mate-avatars/B45.png +0 -0
  227. package/lib/public/mate-avatars/B46.png +0 -0
  228. package/lib/public/mate-avatars/B47.png +0 -0
  229. package/lib/public/mate-avatars/B48.png +0 -0
  230. package/lib/public/mate-avatars/C01.png +0 -0
  231. package/lib/public/mate-avatars/C02.png +0 -0
  232. package/lib/public/mate-avatars/C03.png +0 -0
  233. package/lib/public/mate-avatars/C04.png +0 -0
  234. package/lib/public/mate-avatars/C05.png +0 -0
  235. package/lib/public/mate-avatars/C06.png +0 -0
  236. package/lib/public/mate-avatars/C07.png +0 -0
  237. package/lib/public/mate-avatars/C08.png +0 -0
  238. package/lib/public/mate-avatars/C09.png +0 -0
  239. package/lib/public/mate-avatars/C10.png +0 -0
  240. package/lib/public/mate-avatars/C11.png +0 -0
  241. package/lib/public/mate-avatars/C12.png +0 -0
  242. package/lib/public/mate-avatars/C13.png +0 -0
  243. package/lib/public/mate-avatars/C14.png +0 -0
  244. package/lib/public/mate-avatars/C15.png +0 -0
  245. package/lib/public/mate-avatars/C16.png +0 -0
  246. package/lib/public/mate-avatars/C17.png +0 -0
  247. package/lib/public/mate-avatars/C18.png +0 -0
  248. package/lib/public/mate-avatars/C19.png +0 -0
  249. package/lib/public/mate-avatars/C20.png +0 -0
  250. package/lib/public/mate-avatars/C21.png +0 -0
  251. package/lib/public/mate-avatars/C22.png +0 -0
  252. package/lib/public/mate-avatars/C23.png +0 -0
  253. package/lib/public/mate-avatars/C24.png +0 -0
  254. package/lib/public/mate-avatars/C25.png +0 -0
  255. package/lib/public/mate-avatars/C26.png +0 -0
  256. package/lib/public/mate-avatars/C27.png +0 -0
  257. package/lib/public/mate-avatars/C28.png +0 -0
  258. package/lib/public/mate-avatars/C29.png +0 -0
  259. package/lib/public/mate-avatars/C30.png +0 -0
  260. package/lib/public/mate-avatars/C31.png +0 -0
  261. package/lib/public/mate-avatars/C32.png +0 -0
  262. package/lib/public/mate-avatars/C33.png +0 -0
  263. package/lib/public/mate-avatars/C34.png +0 -0
  264. package/lib/public/mate-avatars/C35.png +0 -0
  265. package/lib/public/mate-avatars/C36.png +0 -0
  266. package/lib/public/mate-avatars/C37.png +0 -0
  267. package/lib/public/mate-avatars/C38.png +0 -0
  268. package/lib/public/mate-avatars/C39.png +0 -0
  269. package/lib/public/mate-avatars/C40.png +0 -0
  270. package/lib/public/mate-avatars/C41.png +0 -0
  271. package/lib/public/mate-avatars/C42.png +0 -0
  272. package/lib/public/mate-avatars/C43.png +0 -0
  273. package/lib/public/mate-avatars/C44.png +0 -0
  274. package/lib/public/mate-avatars/C45.png +0 -0
  275. package/lib/public/mate-avatars/C46.png +0 -0
  276. package/lib/public/mate-avatars/C47.png +0 -0
  277. package/lib/public/mate-avatars/C48.png +0 -0
  278. package/lib/public/mate-avatars/catalog.json +482 -0
  279. package/lib/public/mate-avatars/lead-clay.png +0 -0
  280. package/lib/public/modules/admin-settings-invitations.js +2 -2
  281. package/lib/public/modules/admin-settings-projects.js +8 -4
  282. package/lib/public/modules/admin-settings-ui.js +20 -4
  283. package/lib/public/modules/admin-settings-users.js +4 -4
  284. package/lib/public/modules/app-connection.js +11 -1
  285. package/lib/public/modules/app-favicon.js +18 -9
  286. package/lib/public/modules/app-header.js +7 -4
  287. package/lib/public/modules/app-home-hub.js +2 -1
  288. package/lib/public/modules/app-loop-ui.js +2 -0
  289. package/lib/public/modules/app-message-router.js +22 -1
  290. package/lib/public/modules/app-messages.js +125 -19
  291. package/lib/public/modules/app-misc.js +3 -1
  292. package/lib/public/modules/app-notifications.js +11 -5
  293. package/lib/public/modules/app-panels.js +61 -123
  294. package/lib/public/modules/app-projects.js +14 -407
  295. package/lib/public/modules/app-rate-limit.js +19 -28
  296. package/lib/public/modules/app-rendering.js +4 -3
  297. package/lib/public/modules/avatar.js +15 -41
  298. package/lib/public/modules/chat-render-runtime.js +20 -0
  299. package/lib/public/modules/clay-browser-links.js +47 -0
  300. package/lib/public/modules/clay-control-activity.js +214 -0
  301. package/lib/public/modules/clay-control-copy.js +36 -0
  302. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  303. package/lib/public/modules/clay-control-object-targets.js +52 -0
  304. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  305. package/lib/public/modules/clay-control-targets.js +44 -0
  306. package/lib/public/modules/clay-log-links.js +23 -0
  307. package/lib/public/modules/clay-navigation-render.js +52 -0
  308. package/lib/public/modules/clay-owner-navigation.js +33 -0
  309. package/lib/public/modules/clay-session-links.js +31 -0
  310. package/lib/public/modules/clay-studio-bridge.js +20 -0
  311. package/lib/public/modules/clay-studio-document.js +67 -0
  312. package/lib/public/modules/clay-studio-render.js +146 -0
  313. package/lib/public/modules/clay-tool-activity.js +140 -0
  314. package/lib/public/modules/clay-tool-presentation.js +343 -0
  315. package/lib/public/modules/command-palette.js +162 -40
  316. package/lib/public/modules/contextual-ask-session.js +26 -0
  317. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  318. package/lib/public/modules/contextual-clay-session.js +130 -0
  319. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  320. package/lib/public/modules/contextual-clay.js +252 -0
  321. package/lib/public/modules/contextual-composer.js +91 -0
  322. package/lib/public/modules/contextual-mate-context.js +117 -0
  323. package/lib/public/modules/contextual-mate-hint.js +40 -0
  324. package/lib/public/modules/contextual-mate-identity.js +23 -0
  325. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  326. package/lib/public/modules/contextual-search.js +137 -0
  327. package/lib/public/modules/contextual-session-citations.js +58 -0
  328. package/lib/public/modules/debate.js +1 -0
  329. package/lib/public/modules/default-ai.js +11 -3
  330. package/lib/public/modules/elicitation-form.js +5 -0
  331. package/lib/public/modules/filebrowser.js +20 -1
  332. package/lib/public/modules/generation-stop.js +8 -5
  333. package/lib/public/modules/git-panel.js +3 -1
  334. package/lib/public/modules/github-star.js +66 -0
  335. package/lib/public/modules/history-replay-batch.js +13 -1
  336. package/lib/public/modules/home-debate-live.js +2 -0
  337. package/lib/public/modules/home-debate-planning.js +7 -7
  338. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  339. package/lib/public/modules/home-mate-chat.js +8 -6
  340. package/lib/public/modules/home-mate-creation.js +73 -1
  341. package/lib/public/modules/home-mate-settings.js +19 -12
  342. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  343. package/lib/public/modules/input.js +88 -10
  344. package/lib/public/modules/issues-render.js +3 -2
  345. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  346. package/lib/public/modules/markdown.js +6 -34
  347. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  348. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  349. package/lib/public/modules/mate-loading-scene.js +17 -0
  350. package/lib/public/modules/mate-management.js +40 -7
  351. package/lib/public/modules/mcp-connection-view.js +31 -13
  352. package/lib/public/modules/mcp-discovery-view.js +31 -0
  353. package/lib/public/modules/mcp-ui.js +23 -4
  354. package/lib/public/modules/mention.js +3 -0
  355. package/lib/public/modules/message-delivery.js +20 -2
  356. package/lib/public/modules/model-picker.js +2 -0
  357. package/lib/public/modules/pane-activation.js +214 -0
  358. package/lib/public/modules/pane-binding.js +82 -0
  359. package/lib/public/modules/pane-bridge.js +7 -4
  360. package/lib/public/modules/pane-browser-bridge.js +22 -0
  361. package/lib/public/modules/pane-file-bridge.js +4 -0
  362. package/lib/public/modules/pane-issue-bridge.js +4 -1
  363. package/lib/public/modules/pending-message-queue.js +1 -0
  364. package/lib/public/modules/permission-control.js +5 -4
  365. package/lib/public/modules/personal-settings-dialog.js +7 -1
  366. package/lib/public/modules/product-review.js +26 -0
  367. package/lib/public/modules/profile.js +12 -241
  368. package/lib/public/modules/project-access-recovery.js +17 -0
  369. package/lib/public/modules/project-admin-overview.js +21 -0
  370. package/lib/public/modules/project-chat-identity.js +13 -4
  371. package/lib/public/modules/project-logs-render.js +3 -0
  372. package/lib/public/modules/project-mate-creation-workspace.js +13 -4
  373. package/lib/public/modules/project-mate-navigation.js +144 -22
  374. package/lib/public/modules/project-session-visibility-settings.js +19 -16
  375. package/lib/public/modules/project-settings.js +119 -129
  376. package/lib/public/modules/project-start-dialog.js +130 -0
  377. package/lib/public/modules/project-start-folder-state.js +78 -0
  378. package/lib/public/modules/project-start-folder-view.js +190 -0
  379. package/lib/public/modules/project-start-forms.js +66 -0
  380. package/lib/public/modules/project-start-path.js +60 -0
  381. package/lib/public/modules/project-start-state.js +54 -0
  382. package/lib/public/modules/project-start-submit.js +67 -0
  383. package/lib/public/modules/projects-hub-view.js +33 -14
  384. package/lib/public/modules/projects-hub.js +10 -6
  385. package/lib/public/modules/rewind.js +5 -0
  386. package/lib/public/modules/scheduled-tasks.js +2 -0
  387. package/lib/public/modules/scheduler.js +2 -0
  388. package/lib/public/modules/search-clay-chat.js +5 -440
  389. package/lib/public/modules/server-settings.js +36 -91
  390. package/lib/public/modules/session-actions.js +5 -2
  391. package/lib/public/modules/session-context-menu.js +5 -0
  392. package/lib/public/modules/session-create-form.js +10 -10
  393. package/lib/public/modules/session-folder-layout.js +1 -1
  394. package/lib/public/modules/session-folder-view-menu.js +9 -0
  395. package/lib/public/modules/session-github.js +85 -14
  396. package/lib/public/modules/session-rich-drafts.js +21 -0
  397. package/lib/public/modules/session-switch-defer.js +67 -0
  398. package/lib/public/modules/session-work-primary.js +51 -0
  399. package/lib/public/modules/settings-defaults.js +27 -28
  400. package/lib/public/modules/settings-project-target.js +56 -0
  401. package/lib/public/modules/settings-select.js +1 -1
  402. package/lib/public/modules/settings-shell-registry.js +88 -0
  403. package/lib/public/modules/settings-shell-view.js +104 -0
  404. package/lib/public/modules/settings-shell.js +342 -0
  405. package/lib/public/modules/shared-browser-settings.js +112 -0
  406. package/lib/public/modules/shared-browser-tabs.js +13 -3
  407. package/lib/public/modules/shared-browser.js +29 -6
  408. package/lib/public/modules/sidebar-mobile.js +12 -33
  409. package/lib/public/modules/sidebar-projects.js +3 -1
  410. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  411. package/lib/public/modules/sidebar-sessions.js +1 -0
  412. package/lib/public/modules/split-group-restore.js +68 -0
  413. package/lib/public/modules/split-pair-ui.js +1 -0
  414. package/lib/public/modules/split-pane-reconciler.js +15 -0
  415. package/lib/public/modules/split-pane-renderer.js +87 -6
  416. package/lib/public/modules/split-session-boundary.js +1 -1
  417. package/lib/public/modules/split-view.js +60 -68
  418. package/lib/public/modules/sticky-note-markdown.js +72 -6
  419. package/lib/public/modules/sticky-notes-actions.js +30 -0
  420. package/lib/public/modules/sticky-notes-browser.js +9 -2
  421. package/lib/public/modules/sticky-notes-card.js +23 -7
  422. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  423. package/lib/public/modules/sticky-notes-editor.js +108 -44
  424. package/lib/public/modules/sticky-notes-shared.js +50 -2
  425. package/lib/public/modules/sticky-notes-state.js +66 -0
  426. package/lib/public/modules/sticky-notes.js +34 -51
  427. package/lib/public/modules/stt-controller.js +4 -1
  428. package/lib/public/modules/stt-recording.js +1 -1
  429. package/lib/public/modules/stt.js +7 -2
  430. package/lib/public/modules/terminal.js +9 -0
  431. package/lib/public/modules/theme.js +18 -3
  432. package/lib/public/modules/thinking-lifecycle.js +33 -3
  433. package/lib/public/modules/thinking-view.js +23 -1
  434. package/lib/public/modules/tools.js +60 -11
  435. package/lib/public/modules/tui-grab.js +1 -2
  436. package/lib/public/modules/user-settings-appearance.js +10 -3
  437. package/lib/public/modules/user-settings-editors.js +1 -1
  438. package/lib/public/modules/user-settings-layout.js +14 -30
  439. package/lib/public/modules/user-settings-preferences.js +6 -2
  440. package/lib/public/modules/user-settings-profile.js +13 -3
  441. package/lib/public/modules/user-settings.js +18 -84
  442. package/lib/public/modules/vendor-login-browser.js +5 -3
  443. package/lib/public/modules/vendor-login.js +2 -2
  444. package/lib/public/modules/vendor-priority.js +15 -1
  445. package/lib/public/modules/vendor-usage-format.js +93 -0
  446. package/lib/public/modules/vendor-usage-list.js +45 -0
  447. package/lib/public/modules/vendor-usage-model.js +215 -0
  448. package/lib/public/modules/vendor-usage-overview.js +312 -0
  449. package/lib/public/modules/wireframe-workbench.js +5 -2
  450. package/lib/public/muse-avatar.svg +4 -0
  451. package/lib/public/style.css +14 -6
  452. package/lib/public/sw.js +3 -1
  453. package/lib/public/welcome-art/conversation-desk.png +0 -0
  454. package/lib/public/welcome-art/mate-clay.png +0 -0
  455. package/lib/public/welcome-art/project-clay.png +0 -0
  456. package/lib/safe-bash-commands.js +3 -45
  457. package/lib/scheduled-task-records.js +3 -1
  458. package/lib/scheduler.js +2 -0
  459. package/lib/sdk-bridge.js +348 -402
  460. package/lib/sdk-foreground-admission.js +16 -0
  461. package/lib/sdk-mcp-descriptors.js +2 -37
  462. package/lib/sdk-message-processor.js +61 -18
  463. package/lib/sdk-quota-snapshot.js +21 -3
  464. package/lib/sdk-response-recovery.js +1 -0
  465. package/lib/sdk-worker.js +2 -677
  466. package/lib/server-admin.js +63 -16
  467. package/lib/server-appearance-settings.js +13 -1
  468. package/lib/server-contextual-clay-settings.js +40 -0
  469. package/lib/server-contextual-mate-sessions.js +70 -0
  470. package/lib/server-dm.js +2 -1
  471. package/lib/server-github-stars.js +39 -0
  472. package/lib/server-global-ws.js +26 -32
  473. package/lib/server-home-chat-events.js +18 -4
  474. package/lib/server-home-chat.js +22 -20
  475. package/lib/server-home-clay-entry.js +23 -4
  476. package/lib/server-home-clay-session-links.js +29 -9
  477. package/lib/server-home-mate-creation.js +1 -0
  478. package/lib/server-home-mcp-consent.js +14 -0
  479. package/lib/server-mates.js +25 -62
  480. package/lib/server-owner-ui.js +118 -0
  481. package/lib/server-path-access.js +38 -0
  482. package/lib/server-project-removal.js +22 -0
  483. package/lib/server-settings.js +6 -1
  484. package/lib/server.js +167 -43
  485. package/lib/session-config-transition.js +45 -0
  486. package/lib/session-folders.js +7 -2
  487. package/lib/session-fork-history.js +21 -0
  488. package/lib/session-github.js +9 -2
  489. package/lib/session-hygiene.js +3 -35
  490. package/lib/session-notes-mcp-server.js +26 -4
  491. package/lib/session-notes-writes.js +88 -0
  492. package/lib/session-permission-mode.js +4 -3
  493. package/lib/session-skill-scope.js +11 -0
  494. package/lib/session-visibility.js +25 -10
  495. package/lib/session-work-primary.js +50 -0
  496. package/lib/sessions.js +66 -99
  497. package/lib/shared-browser-cookie-sync.js +32 -0
  498. package/lib/shared-browser-cookies.js +79 -0
  499. package/lib/shared-browser-runtime.js +25 -9
  500. package/lib/shared-browser-storage-sync.js +43 -0
  501. package/lib/shared-browser-storage.js +101 -0
  502. package/lib/shared-browser-tools.js +2 -1
  503. package/lib/shared-browser-worker.js +46 -10
  504. package/lib/terminal-manager.js +65 -6
  505. package/lib/tool-llm.js +1 -1
  506. package/lib/tui-transcript-index.js +1 -132
  507. package/lib/users-contextual-clay-preferences.js +31 -0
  508. package/lib/users-permissions.js +2 -8
  509. package/lib/users.js +7 -0
  510. package/lib/vendor-login-browser.js +1 -11
  511. package/lib/vendor-usage-acp-readers.js +97 -0
  512. package/lib/vendor-usage-capabilities.js +88 -0
  513. package/lib/vendor-usage-http-readers.js +214 -0
  514. package/lib/vendor-usage-metrics.js +47 -0
  515. package/lib/vendor-usage-native-readers.js +106 -0
  516. package/lib/vendor-usage-overview.js +406 -0
  517. package/lib/vendor-usage-service.js +281 -0
  518. package/lib/workspace-assignment-service.js +25 -0
  519. package/lib/workspace-query-access.js +4 -1
  520. package/lib/workspace-query-mcp-server.js +1 -1
  521. package/lib/workspace-query-service.js +13 -2
  522. package/lib/ws-request.js +1 -0
  523. package/lib/ws-schema.js +22 -4
  524. package/lib/yoke/acp-agent-profiles.js +7 -5
  525. package/lib/yoke/adapters/antigravity.js +3 -14
  526. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  527. package/lib/yoke/adapters/claude.js +66 -50
  528. package/lib/yoke/adapters/codex-query-contract.js +25 -0
  529. package/lib/yoke/adapters/codex.js +98 -123
  530. package/lib/yoke/adapters/kiro.js +3 -1
  531. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  532. package/lib/yoke/adapters/muse.js +122 -0
  533. package/lib/yoke/auth-events.js +17 -0
  534. package/lib/yoke/claude-hook-installer.js +272 -0
  535. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  536. package/lib/yoke/claude-maintenance.js +55 -0
  537. package/lib/yoke/claude-permission-patterns.js +53 -0
  538. package/lib/yoke/claude-response-recovery.js +155 -0
  539. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  540. package/lib/yoke/claude-worker-startup.js +28 -0
  541. package/lib/yoke/clay-skill-install.js +33 -0
  542. package/lib/yoke/cli-sessions.js +300 -0
  543. package/lib/yoke/codex-app-server.js +7 -12
  544. package/lib/yoke/codex-dynamic-tool-names.js +80 -0
  545. package/lib/yoke/codex-idle-recovery.js +81 -1
  546. package/lib/yoke/codex-model-catalog.js +37 -3
  547. package/lib/yoke/codex-recovery-admission.js +164 -0
  548. package/lib/yoke/configuration.js +13 -0
  549. package/lib/yoke/discovery.js +70 -0
  550. package/lib/yoke/errors.js +8 -0
  551. package/lib/yoke/host-environment.js +7 -0
  552. package/lib/yoke/index.js +9 -51
  553. package/lib/yoke/interface.js +116 -0
  554. package/lib/yoke/kiro-acp-server.js +5 -5
  555. package/lib/yoke/legacy-sessions.js +89 -0
  556. package/lib/yoke/login-protocol.js +25 -0
  557. package/lib/yoke/maintenance.js +12 -0
  558. package/lib/yoke/mcp-proxy.js +32 -0
  559. package/lib/yoke/mcp-source-adapters.js +91 -0
  560. package/lib/yoke/mcp-source-context.js +42 -0
  561. package/lib/yoke/mcp-source-discovery.js +169 -0
  562. package/lib/yoke/mcp-source-plugins.js +68 -0
  563. package/lib/yoke/mcp-source-restrictions.js +47 -0
  564. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  565. package/lib/yoke/model-preferences.js +6 -0
  566. package/lib/yoke/muse-artifacts.js +36 -0
  567. package/lib/yoke/muse-controls.js +50 -0
  568. package/lib/yoke/muse-input.js +64 -0
  569. package/lib/yoke/muse-items.js +157 -0
  570. package/lib/yoke/muse-policy.js +52 -0
  571. package/lib/yoke/muse-query.js +428 -0
  572. package/lib/yoke/muse-runtime.js +211 -0
  573. package/lib/yoke/muse-services.js +92 -0
  574. package/lib/yoke/muse-skills.js +79 -0
  575. package/lib/yoke/muse-turns.js +71 -0
  576. package/lib/yoke/options/acp.js +2 -0
  577. package/lib/yoke/options/antigravity.js +2 -0
  578. package/lib/yoke/options/claude.js +21 -0
  579. package/lib/yoke/options/codex-defaults.js +29 -0
  580. package/lib/yoke/options/codex-settings.js +21 -0
  581. package/lib/yoke/options/codex.js +6 -0
  582. package/lib/yoke/options/kiro-defaults.js +22 -0
  583. package/lib/yoke/options/kiro.js +5 -0
  584. package/lib/yoke/options/muse.js +5 -0
  585. package/lib/yoke/provider-contract.js +5 -0
  586. package/lib/yoke/providers/antigravity-executable.js +8 -0
  587. package/lib/yoke/providers/claude-executable.js +40 -0
  588. package/lib/yoke/providers/claude-model-descriptions.js +34 -0
  589. package/lib/yoke/providers/claude-process.js +97 -0
  590. package/lib/yoke/providers/claude-provision.js +75 -0
  591. package/lib/yoke/providers/codex-errors.js +8 -0
  592. package/lib/yoke/providers/muse-executable.js +17 -0
  593. package/lib/yoke/provisioning.js +6 -0
  594. package/lib/yoke/query-options.js +10 -0
  595. package/lib/yoke/response-recovery.js +41 -0
  596. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  597. package/lib/yoke/sdk-server-factory.js +7 -0
  598. package/lib/yoke/session-history.js +8 -0
  599. package/lib/yoke/session-tool-transport.js +34 -13
  600. package/lib/yoke/settings.js +23 -0
  601. package/lib/yoke/source-locations.js +4 -0
  602. package/lib/yoke/title-query.js +18 -7
  603. package/lib/yoke/tui-transcript-index.js +132 -0
  604. package/lib/yoke/usage.js +48 -0
  605. package/lib/yoke/user-input.js +13 -0
  606. package/lib/yoke/vendor-registry.js +87 -3
  607. package/package.json +11 -4
  608. package/lib/public/modules/server-settings-navigation.js +0 -39
@@ -1,4 +1,5 @@
1
1
  var mateCreationMcp = require("./mate-creation-mcp-server");
2
+ var scheduleInput = require("./mate-schedule-input");
2
3
  var selectCatalogModel = require("./project-models").selectCatalogModel;
3
4
 
4
5
  function attachMateCreationProposal(ctx) {
@@ -19,6 +20,8 @@ function attachMateCreationProposal(ctx) {
19
20
  communicationStyle: Array.isArray(source.communicationStyle) ? source.communicationStyle.slice(0, 12) : [],
20
21
  autonomy: clean(source.autonomy, 500),
21
22
  identityMarkdown: clean(source.identityMarkdown, 30000),
23
+ scheduleIntent: source.scheduleIntent || null,
24
+ scheduleTimezone: scheduleInput.timezone(),
22
25
  };
23
26
  }
24
27
 
@@ -30,7 +33,8 @@ function attachMateCreationProposal(ctx) {
30
33
  var projectOwnerId = typeof ctx.getProjectOwnerId === "function" ? ctx.getProjectOwnerId() : null;
31
34
  var ownerValid = typeof ctx.isMultiUser === "function" && ctx.isMultiUser() ? !!(session && session.ownerId && (!projectOwnerId || session.ownerId === projectOwnerId)) : !!(session && !session.ownerId);
32
35
  return !!(session && ctx.isMate === true && ctx.isHostAgent === true && session.mateCreationMode === true
33
- && ownerValid);
36
+ && ownerValid && !session.destroying && !session._mcpForeignInput
37
+ && (!ctx.isLive || ctx.isLive(session)));
34
38
  }
35
39
 
36
40
  function hasInterviewAnswer(session) {
@@ -44,10 +48,19 @@ function attachMateCreationProposal(ctx) {
44
48
  return mateCreationMcp.getToolDefs(function (definition) {
45
49
  if (!validateBoundSession(boundSession)) return Promise.resolve({ action: "error", error: "Mate proposals require an owned Clay creation interview." });
46
50
  if (!hasInterviewAnswer(boundSession)) return Promise.resolve({ action: "error", error: "Interview the user before proposing a Mate." });
51
+ if (definition.scheduleIntent && typeof definition.scheduleIntent === "string") {
52
+ try { definition.scheduleIntent = JSON.parse(definition.scheduleIntent); } catch (error) { return Promise.resolve({ action: "error", error: "scheduleIntent must be valid JSON." }); }
53
+ }
54
+ try {
55
+ if (definition.scheduleIntent) {
56
+ var checkedIntent = scheduleInput.normalize(definition.scheduleIntent);
57
+ definition.scheduleIntent = { message: checkedIntent.message, scheduleRule: checkedIntent.rule };
58
+ }
59
+ } catch (error) { return Promise.resolve({ action: "error", error: error.message }); }
47
60
  return new Promise(function (resolve) {
48
61
  var proposalId = "mp_" + Date.now() + "_" + Math.random().toString(36).slice(2, 8);
49
62
  definition.proposalId = proposalId;
50
- pending[proposalId] = { resolve: resolve, definition: definition, session: boundSession };
63
+ pending[proposalId] = { resolve: resolve, definition: definition, session: boundSession, generation: Number(boundSession._sdkQueryGeneration || 0) };
51
64
  record(boundSession, { type: "mate_creation_proposal", proposal: publicProposal(definition) });
52
65
  });
53
66
  });
@@ -72,7 +85,8 @@ function attachMateCreationProposal(ctx) {
72
85
 
73
86
  function handleHomeMessage(ws, msg, session) {
74
87
  var entry = msg && msg.proposalId ? pending[msg.proposalId] : null;
75
- if (!entry || entry.session !== session || !validateBoundSession(session)) return false;
88
+ if (!entry || entry.session !== session || !validateBoundSession(session) || entry.generation !== Number(session._sdkQueryGeneration || 0)) return false;
89
+ if (ctx.isMultiUser && ctx.isMultiUser() && (!ws || !ws._clayUser || ws._clayUser.id !== session.ownerId)) return false;
76
90
  delete pending[msg.proposalId];
77
91
  if (msg.action !== "create") {
78
92
  record(session, { type: "mate_creation_proposal_resolved", proposalId: msg.proposalId, action: "cancel" });
@@ -93,6 +107,7 @@ function attachMateCreationProposal(ctx) {
93
107
  return true;
94
108
  }
95
109
  Promise.resolve(ctx.getVendorModelCatalog(ws, vendor)).then(function (catalog) {
110
+ if (!validateBoundSession(session) || entry.generation !== Number(session._sdkQueryGeneration || 0)) throw new Error("The Mate creation approval is stale.");
96
111
  var selected = catalog && catalog.status === "ready" ? selectCatalogModel(catalog.models || [], catalog.defaultModel, "deep") : null;
97
112
  if (!selected) throw new Error((catalog && catalog.error) || "No high-capability Mate model is available for " + vendor + ".");
98
113
  return ctx.createReadyMate(ws, session.ownerId || null, Object.assign({}, entry.definition, { vendor: vendor, model: selected.value }));
@@ -3,6 +3,7 @@ var fs = require("fs");
3
3
  var path = require("path");
4
4
  var crypto = require("crypto");
5
5
  var mateSync = require("./mate-knowledge-sync");
6
+ var dmDigestCursor = require("./dm-digest-cursor");
6
7
 
7
8
  // Mirror a Mate-owned journal into the Clay-wide Knowledge backend after the
8
9
  // legacy append has already succeeded. Reconciling the whole journal keeps the
@@ -294,6 +295,9 @@ function attachMateInteraction(ctx) {
294
295
  mirrorMateJournal(mateDir, "session-digests.jsonl", job);
295
296
  } catch (e) {
296
297
  console.error("[digest-worker] Write failed for " + job.mateId + ":", e.message);
298
+ if (job.onError) job.onError(e);
299
+ processDigestQueue();
300
+ return;
297
301
  }
298
302
 
299
303
  // Write user observations if present
@@ -422,63 +426,19 @@ function attachMateInteraction(ctx) {
422
426
  // Delta-based: only collects new turns since the last successful digest.
423
427
  // Concurrency debounce: turns that arrive while a digest is in-flight
424
428
  // are naturally batched into the next flush.
425
- var _dmDigestPending = false;
426
- function digestDmTurn(session, responsePreview) {
427
- if (!isMate || _dmDigestPending) return;
429
+ var _dmDigestPending = new WeakSet();
430
+ function digestDmTurn(session) {
431
+ if (!isMate || _dmDigestPending.has(session)) return;
428
432
  var mateId = path.basename(cwd);
429
433
  var mateCtx = matesModule.buildMateCtx(projectOwnerId);
430
434
  if (!matesModule.isMate(mateCtx, mateId)) return;
431
435
 
432
- // Track digest index per session so switching sessions doesn't misalign.
433
- // On resumed sessions (after restart), recover index from the last
434
- // digest_checkpoint entry in history so undigested turns aren't lost.
435
- if (typeof session._dmLastDigestedIndex !== "number") {
436
- session._dmLastDigestedIndex = 0;
437
- for (var ci = session.history.length - 1; ci >= 0; ci--) {
438
- if (session.history[ci].type === "digest_checkpoint") {
439
- session._dmLastDigestedIndex = session.history[ci].digestedIndex;
440
- break;
441
- }
442
- }
443
- }
444
-
445
- // Collect only new turns since the last successful digest
446
- var conversationParts = [];
447
- var totalLen = 0;
448
- var CONV_CAP = 6000;
449
- var startIndex = session._dmLastDigestedIndex;
450
- for (var hi = startIndex; hi < session.history.length; hi++) {
451
- if (totalLen >= CONV_CAP) break;
452
- var entry = session.history[hi];
453
- if (entry.type === "user_message" && entry.text) {
454
- var uText = entry.text;
455
- if (totalLen + uText.length > CONV_CAP) {
456
- uText = uText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
457
- }
458
- conversationParts.push("User: " + uText);
459
- totalLen += uText.length;
460
- } else if (entry.type === "assistant_message" && entry.text) {
461
- var aText = entry.text;
462
- if (totalLen + aText.length > CONV_CAP) {
463
- aText = aText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
464
- }
465
- conversationParts.push("Mate: " + aText);
466
- totalLen += aText.length;
467
- }
468
- }
469
- // If the latest response hasn't landed in history yet, append it
470
- var lastResponseText = responsePreview || "";
471
- if (lastResponseText && conversationParts.length > 0) {
472
- var lastPart = conversationParts[conversationParts.length - 1];
473
- if (lastPart.indexOf("Mate:") !== 0 || lastPart.indexOf(lastResponseText.substring(0, 50)) === -1) {
474
- var rText = lastResponseText;
475
- if (totalLen + rText.length > CONV_CAP) {
476
- rText = rText.substring(0, Math.max(200, CONV_CAP - totalLen)) + "...";
477
- }
478
- conversationParts.push("Mate: " + rText);
479
- }
480
- }
481
- if (conversationParts.length === 0) return;
436
+ // Recover the exact next unread position. Legacy index-only checkpoints
437
+ // remain readable and are treated as fully consumed entries.
438
+ var digestState = dmDigestCursor.readState(session.history);
439
+ var startCursor = digestState.cursor;
440
+ var chunk = dmDigestCursor.collectChunk(session.history, startCursor);
441
+ if (!chunk.conversationContent) return;
482
442
 
483
443
  var mateDir = matesModule.getMateDir(mateCtx, mateId);
484
444
  var knowledgeDir = path.join(mateDir, "knowledge");
@@ -500,8 +460,8 @@ function attachMateInteraction(ctx) {
500
460
  }
501
461
  } catch (e) {}
502
462
 
503
- _dmDigestPending = true;
504
- var snapshotIndex = session.history.length;
463
+ _dmDigestPending.add(session);
464
+ var checkpointCursor = chunk.cursor;
505
465
 
506
466
  enqueueDigest({
507
467
  mateCtx: mateCtx,
@@ -509,17 +469,27 @@ function attachMateInteraction(ctx) {
509
469
  mateId: mateId,
510
470
  type: "dm",
511
471
  priorSummary: priorSummary || "",
512
- conversationContent: conversationParts.join("\n"),
472
+ conversationContent: chunk.conversationContent,
513
473
  onDone: function () {
514
- session._dmLastDigestedIndex = snapshotIndex;
515
- // Persist checkpoint so resumed sessions know where to continue
516
- var checkpoint = { type: "digest_checkpoint", digestedIndex: snapshotIndex };
474
+ // Journal and checkpoint are separate appends: if this append fails,
475
+ // retry may duplicate the saved digest, but must never skip its input.
476
+ var checkpoint = { type: "digest_checkpoint", cursor: checkpointCursor };
477
+ var saved = false;
478
+ try { saved = sm.appendToSessionFile(session, checkpoint) !== false; } catch (e) {
479
+ console.error("[dm-digest] Checkpoint append failed:", e.message);
480
+ }
481
+ if (!saved) {
482
+ _dmDigestPending.delete(session);
483
+ return;
484
+ }
517
485
  session.history.push(checkpoint);
518
- sm.appendToSessionFile(session, checkpoint);
519
- _dmDigestPending = false;
486
+ _dmDigestPending.delete(session);
487
+ if (dmDigestCursor.hasPending(session.history, checkpointCursor)) {
488
+ setImmediate(function () { digestDmTurn(session, ""); });
489
+ }
520
490
  },
521
491
  onError: function () {
522
- _dmDigestPending = false;
492
+ _dmDigestPending.delete(session);
523
493
  },
524
494
  });
525
495
  }
@@ -570,6 +540,8 @@ function attachMateInteraction(ctx) {
570
540
 
571
541
  var mateName = (mate.profile && mate.profile.displayName) || mate.name || "Mate";
572
542
  var avatarColor = (mate.profile && mate.profile.avatarColor) || "#5857fc";
543
+ var avatarCatalogId = (mate.profile && mate.profile.avatarCatalogId) || "";
544
+ var avatarCustom = (mate.profile && mate.profile.avatarCustom) || "";
573
545
  var avatarStyle = (mate.profile && mate.profile.avatarStyle) || "imprint";
574
546
  var avatarSeed = (mate.profile && mate.profile.avatarSeed) || mate.id;
575
547
 
@@ -622,6 +594,8 @@ function attachMateInteraction(ctx) {
622
594
  mateName: mateName,
623
595
  avatarColor: avatarColor,
624
596
  avatarStyle: avatarStyle,
597
+ avatarCatalogId: avatarCatalogId,
598
+ avatarCustom: avatarCustom,
625
599
  avatarSeed: avatarSeed,
626
600
  });
627
601
 
@@ -657,6 +631,8 @@ function attachMateInteraction(ctx) {
657
631
  text: fullText,
658
632
  avatarColor: avatarColor,
659
633
  avatarStyle: avatarStyle,
634
+ avatarCatalogId: avatarCatalogId,
635
+ avatarCustom: avatarCustom,
660
636
  avatarSeed: avatarSeed,
661
637
  };
662
638
  session.history.push(mentionResponseEntry);
@@ -820,6 +796,8 @@ function attachMateInteraction(ctx) {
820
796
  name: (mate.profile && mate.profile.displayName) || mate.name || "Mate",
821
797
  avatarColor: (mate.profile && mate.profile.avatarColor) || "#5857fc",
822
798
  avatarStyle: (mate.profile && mate.profile.avatarStyle) || "imprint",
799
+ avatarCatalogId: (mate.profile && mate.profile.avatarCatalogId) || "",
800
+ avatarCustom: (mate.profile && mate.profile.avatarCustom) || "",
823
801
  avatarSeed: (mate.profile && mate.profile.avatarSeed) || mateId,
824
802
  };
825
803
  }
@@ -1,10 +1,19 @@
1
1
  var crypto = require('crypto');
2
+ var path = require('path');
2
3
  var createProxy = require('./mcp-proxy').createProxy;
3
4
  var createStore = require('./mcp-connection-store').createConnectionStore;
4
5
  var createRemoteConnections = require('./mcp-remote-connections').createRemoteConnections;
6
+ var SHARED_REGISTRIES = new Map();
5
7
 
6
8
  function attachMcp(ctx) {
7
- var devices = new Map(), pending = new Map();
9
+ var storage = ctx.storage || createStore(ctx.root, ctx.slug, { shared: true });
10
+ var namespace = storage.namespace || (ctx.root ? path.resolve(ctx.root) : storage);
11
+ var registry = SHARED_REGISTRIES.get(namespace);
12
+ if (!registry) { registry = { devices: new Map(), pending: new Map(), managers: new Set() }; SHARED_REGISTRIES.set(namespace, registry); }
13
+ var devices = registry.devices, pending = registry.pending, manager = {};
14
+ registry.managers.add(manager);
15
+ function announce(owner) { registry.managers.forEach(function (source) { source.broadcast(owner); }); }
16
+ manager.broadcast = broadcast;
8
17
  function ownerFor(ws) {
9
18
  if (!ctx.canAccess(ws)) throw new Error('MCP access is not permitted.');
10
19
  return ctx.isMultiUser() ? String(ws._clayUser.id) : 'default';
@@ -15,17 +24,32 @@ function attachMcp(ctx) {
15
24
  try { if (ws.readyState === 1 && ownerFor(ws) === owner) ctx.sendTo(ws, Object.assign({ slug: ctx.slug }, msg)); } catch (error) {}
16
25
  });
17
26
  }
27
+ function isSession(subject) { return !!subject && ctx.canUseSession(subject); }
28
+ function sourceIdentity(subject) { return isSession(subject) ? ctx.ownerIdentity(ctx.isMultiUser() ? String(subject.ownerId) : 'default') : ctx.identity(subject); }
29
+ var discovery = require('./yoke/mcp-source-discovery').createDiscovery({ cwd: ctx.cwd || process.cwd(), home: ctx.discoveryHome,
30
+ identity: sourceIdentity, runtimeEnv: function (owner, subject) { return isSession(subject) ? ctx.runtimeEnvForSession(subject) : ctx.runtimeEnv ? ctx.runtimeEnv(owner, subject) : {}; }, authorize: function (owner, subject) {
31
+ var permitted = isSession(subject) ? (ctx.isMultiUser() ? String(subject.ownerId) : 'default') === owner && ctx.canDiscoverSession(subject) : ownerFor(subject) === owner && ctx.canDiscover && ctx.canDiscover(subject);
32
+ if (!permitted) throw new Error('Vendor discovery requires your authorized OS user mapping or a sole account installation.');
33
+ authorizeOwner(owner);
34
+ }, snapshot: function (owner) { return storage.snapshot(owner); } });
18
35
  var remote = createRemoteConnections({
19
36
  remoteFetch: ctx.remoteFetch, createLoginBrowser: ctx.createLoginBrowser,
20
- storage: ctx.storage || createStore(ctx.root, ctx.slug), authorize: authorizeOwner,
21
- changed: function (owner) { broadcast(owner); }, sendOwner: sendOwner, sendTo: function (ws, msg) { ctx.sendTo(ws, Object.assign({ slug: ctx.slug }, msg)); },
37
+ storage: storage, authorize: authorizeOwner,
38
+ changed: function (owner) { announce(owner); }, sendOwner: sendOwner, sendTo: function (ws, msg) { ctx.sendTo(ws, Object.assign({ slug: ctx.slug }, msg)); },
39
+ ownerIdentity: ctx.ownerIdentity, selectImport: discovery.selected,
22
40
  identity: ctx.identity,
23
41
  canAccess: function (ws, owner) { try { return ownerFor(ws) === owner; } catch (error) { return false; } },
24
42
  });
43
+ var agentTools = require('./mcp-agent-tools').attachMcpAgentTools({
44
+ available: function (session) { return typeof ctx.canDiscoverSession === "function" && typeof ctx.runtimeEnvForSession === "function" && ctx.canDiscoverSession(session); },
45
+ clients: ctx.clients, isMultiUser: ctx.isMultiUser, ownerFor: ownerFor, canUseSession: ctx.canUseSession,
46
+ authorizeOwner: authorizeOwner, discovery: discovery, importConnection: remote.importConnection,
47
+ userInput: ctx.userInput, consentTimeout: ctx.consentTimeout,
48
+ });
25
49
  function deviceFor(owner) {
26
50
  var device = devices.get(owner);
27
51
  if (!device || device.ws.readyState !== 1) return null;
28
- try { if (ownerFor(device.ws) !== owner) return null; } catch (error) { return null; }
52
+ try { authorizeOwner(owner); if (!device.authorized()) return null; } catch (error) { return null; }
29
53
  return device;
30
54
  }
31
55
  function enabled(owner, name) {
@@ -59,13 +83,18 @@ function attachMcp(ctx) {
59
83
  if (call.ws !== device.ws) return;
60
84
  clearTimeout(call.timer); pending.delete(id); call.reject(new Error('Your computer disconnected.'));
61
85
  });
62
- broadcast(owner);
86
+ announce(owner);
63
87
  });
64
88
  }
65
89
  function handleMcpMessage(ws, msg) {
66
90
  if (!msg || typeof msg.type !== 'string' || (msg.type.indexOf('mcp_') !== 0 && msg.type !== 'mcp_toggle_server')) return false;
67
91
  var owner;
68
92
  try { owner = ownerFor(ws); } catch (error) { return true; }
93
+ if (msg.type === 'mcp_discovery_request') {
94
+ try { ctx.sendTo(ws, Object.assign({ type: 'mcp_discovery_result', slug: ctx.slug, requestId: msg.requestId, ok: true }, discovery.scan(owner, ws, msg.file ? { file: msg.file, vendor: msg.vendor } : null))); }
95
+ catch (error) { ctx.sendTo(ws, { type: 'mcp_discovery_result', slug: ctx.slug, requestId: msg.requestId, ok: false, error: error.message }); }
96
+ return true;
97
+ }
69
98
  if (msg.type === 'mcp_state_request') { sendConnectionState(ws); return true; }
70
99
  if (msg.type === 'mcp_servers_available') {
71
100
  var servers = Array.isArray(msg.servers) ? msg.servers : [];
@@ -75,8 +104,10 @@ function attachMcp(ctx) {
75
104
  });
76
105
  var old = devices.get(owner);
77
106
  if (old && old.ws !== ws) disconnectDevice(old.ws);
78
- devices.set(owner, { ws: ws, servers: servers, hostConnected: !!msg.hostConnected, extensionId: ctx.extensionId(ws) });
79
- broadcast(owner); return true;
107
+ devices.set(owner, { ws: ws, servers: servers, hostConnected: !!msg.hostConnected, extensionId: ctx.extensionId(ws), manager: manager,
108
+ authorized: function () { return ctx.clients.has(ws) && ownerFor(ws) === owner && ctx.canUseOwner(owner); },
109
+ send: function (message) { ctx.sendTo(ws, Object.assign({ slug: ctx.slug }, message)); } });
110
+ announce(owner); return true;
80
111
  }
81
112
  if (msg.type === 'mcp_tool_result' || msg.type === 'mcp_tool_error') {
82
113
  var call = pending.get(msg.callId);
@@ -114,35 +145,42 @@ function attachMcp(ctx) {
114
145
  if (!row || !row.tools.some(function (item) { return item.name === tool; })) throw new Error('Computer tool is unavailable.');
115
146
  var id = crypto.randomUUID();
116
147
  var timer = setTimeout(function () { pending.delete(id); reject(new Error('Computer tool timed out.')); }, 60000);
117
- pending.set(id, { owner: owner, ws: device.ws, resolve: resolve, reject: reject, timer: timer, authorize: function () {
148
+ pending.set(id, { owner: owner, ws: device.ws, manager: manager, resolve: resolve, reject: reject, timer: timer, authorize: function () {
118
149
  authorize(); if (!enabled(owner, server) || deviceFor(owner) !== device) throw new Error('Computer access changed.');
119
150
  } });
120
- ctx.sendTo(device.ws, { type: 'mcp_tool_call', callId: id, server: server, method: 'tools/call', params: { name: tool, arguments: args } });
151
+ device.send({ type: 'mcp_tool_call', callId: id, server: server, method: 'tools/call', params: { name: tool, arguments: args } });
121
152
  });
122
153
  }
123
- function getMcpServers(session) {
124
- if (!session || !ctx.canUseSession(session)) return {};
154
+ function getMcpServers(session, allowManagement) {
155
+ if (!session || !ctx.canUseSession(session) || !require('./yoke/session-tool-transport').capability(ctx.sessionVendor ? ctx.sessionVendor(session) : session.vendor || 'claude').supported) return {};
125
156
  var owner = ctx.isMultiUser() ? String(session.ownerId) : 'default';
126
157
  function authorize() {
127
158
  authorizeOwner(owner);
128
159
  if (!ctx.canUseSession(session) || (ctx.isMultiUser() && String(session.ownerId) !== owner)) throw new Error('Session MCP access changed.');
129
160
  }
130
- var result = {};
161
+ var result = {}, management = allowManagement === false ? null : agentTools.getServer(session);
162
+ if (management) result['clay-mcp-connections'] = management;
131
163
  buildState(owner).servers.forEach(function (server) {
132
164
  if (!server.projectEnabled || !server.extensionEnabled || !server.tools.length) return;
133
165
  try {
134
166
  result[server.name] = createProxy(server.name, server.tools, function (tool, args) {
135
- return server.source === 'url' ? remote.call(owner, server.id, tool, args, authorize) : callComputer(owner, server.name, tool, args, authorize);
167
+ return server.source !== 'computer' ? remote.call(owner, server.id, tool, args, authorize) : callComputer(owner, server.name, tool, args, authorize);
136
168
  });
137
169
  } catch (error) { /* Unsupported schemas are not advertised as callable tools. */ }
138
170
  });
139
171
  return result;
140
172
  }
141
173
  function destroy() {
142
- pending.forEach(function (call) { clearTimeout(call.timer); call.reject(new Error('MCP closed.')); }); pending.clear();
143
- devices.clear(); remote.destroy();
174
+ var removedSockets = [];
175
+ devices.forEach(function (device, owner) { if (device.manager === manager) { removedSockets.push(device.ws); devices.delete(owner); } });
176
+ pending.forEach(function (call, id) {
177
+ if (call.manager === manager || removedSockets.indexOf(call.ws) >= 0) { clearTimeout(call.timer); call.reject(new Error('MCP closed.')); pending.delete(id); }
178
+ });
179
+ agentTools.destroy(); remote.destroy(); discovery.destroy();
180
+ registry.managers.delete(manager);
181
+ if (!registry.managers.size) SHARED_REGISTRIES.delete(namespace);
144
182
  }
145
- return { handleMcpMessage: handleMcpMessage, getMcpServers: getMcpServers, sendConnectionState: sendConnectionState,
183
+ return { registerConsentViewer: agentTools.registerViewer, handleMcpMessage: handleMcpMessage, getMcpServers: getMcpServers, sendConnectionState: sendConnectionState,
146
184
  handleExtensionDisconnect: disconnectDevice, rebuildAndBroadcast: function () { devices.forEach(function (device, owner) { broadcast(owner); }); }, destroy: destroy };
147
185
  }
148
186
  module.exports = { attachMcp: attachMcp };
@@ -331,48 +331,30 @@ function attachModels(ctx) {
331
331
  });
332
332
  }
333
333
 
334
+ async function selectSessionModel(session, model, vendor, options) {
335
+ if (!session || sm.sessions.get(session.localId) !== session) throw new Error("Session was deleted or replaced.");
336
+ var sessionVendor = session.vendor || sm.defaultVendor || "claude";
337
+ if (vendor && vendor !== sessionVendor) throw new Error("The session vendor changed before model selection.");
338
+ var models = (sm.modelsByVendor && sm.modelsByVendor[sessionVendor]) || [];
339
+ if (models.length && !models.some(function (entry) { return modelEntryMatches(entry, model); })) throw new Error("That model is not available for the selected vendor.");
340
+ return sdk.setModel(session, model, options);
341
+ }
342
+
334
343
  async function selectModel(ws, msg) {
335
344
  var session = getSessionForWs(ws);
336
345
  if (!session) {
337
346
  sendTo(ws, { type: "model_selection_result", requestId: msg.requestId || null, ok: false, error: "No active session." });
338
347
  return;
339
348
  }
340
- var sessionVendor = session.vendor || sm.defaultVendor || "claude";
341
- if (msg.vendor && msg.vendor !== sessionVendor) {
342
- sendTo(ws, {
343
- type: "model_selection_result",
344
- requestId: msg.requestId || null,
345
- ok: false,
346
- error: "The session vendor changed before the model selection completed.",
347
- });
348
- return;
349
- }
350
- var knownModels = (sm.modelsByVendor && sm.modelsByVendor[sessionVendor]) || [];
351
- if (knownModels.length > 0) {
352
- var known = false;
353
- for (var i = 0; i < knownModels.length; i++) {
354
- if (modelEntryMatches(knownModels[i], msg.model)) {
355
- known = true;
356
- break;
357
- }
358
- }
359
- if (!known) {
360
- sendTo(ws, {
361
- type: "model_selection_result",
362
- requestId: msg.requestId || null,
363
- ok: false,
364
- error: "That model is not available for the selected vendor.",
365
- });
366
- return;
367
- }
368
- }
369
- var result = await sdk.setModel(session, msg.model);
349
+ var result;
350
+ try { result = await selectSessionModel(session, msg.model, msg.vendor); }
351
+ catch (error) { result = { ok: false, error: error.message }; }
370
352
  sendTo(ws, {
371
353
  type: "model_selection_result",
372
354
  requestId: msg.requestId || null,
373
355
  ok: !!(result && result.ok),
374
356
  model: result && result.model ? result.model : msg.model,
375
- vendor: sessionVendor,
357
+ vendor: session.vendor || sm.defaultVendor || "claude",
376
358
  error: result && result.error ? result.error : "",
377
359
  });
378
360
  }
@@ -400,6 +382,7 @@ function attachModels(ctx) {
400
382
  resolveConfiguredModel: resolveConfiguredModel,
401
383
  loadVendorModels: loadVendorModels,
402
384
  selectModel: selectModel,
385
+ selectSessionModel: selectSessionModel,
403
386
  };
404
387
  }
405
388
 
@@ -154,6 +154,21 @@ function attachNotifications(ctx) {
154
154
  return notifications.length;
155
155
  }
156
156
 
157
+ function controlProjection(item) { var value = Object.assign({}, item); delete value.controlRevision; return Object.assign(value, { controlRevision: require('./clay-control-target-projection').digest(value) }); }
158
+ function visible(ws) {
159
+ return notifications.filter(function (notification) { return !ctx.canView || ctx.canView(ws, notification); }).map(controlProjection);
160
+ }
161
+
162
+ function publish(payload) {
163
+ if (!ctx.forEachClient) return broadcastAll(payload);
164
+ ctx.forEachClient(function (ws) {
165
+ if (ws.readyState !== 1) return;
166
+ if (payload.notification && !ctx.canView(ws, payload.notification)) return;
167
+ var list = visible(ws);
168
+ ws.send(JSON.stringify(Object.assign({}, payload, { notification: payload.notification ? controlProjection(payload.notification) : undefined, unreadCount: list.length })));
169
+ });
170
+ }
171
+
157
172
  // --- Core API ---
158
173
 
159
174
  function notify(event, data) {
@@ -183,12 +198,13 @@ function attachNotifications(ctx) {
183
198
  saveNotifications();
184
199
  var payload = {
185
200
  type: "notification_created",
186
- notification: notif,
201
+ notification: controlProjection(notif),
187
202
  unreadCount: getUnreadCount(),
188
203
  };
189
- // If targeted at a specific user, deliver only to that user's connections.
190
- // Otherwise broadcast to everyone (existing behavior).
191
- if (notif.targetUserId && typeof sendToUser === "function") {
204
+ // Project/session previews are projected for each authenticated viewer.
205
+ if (ctx.forEachClient) {
206
+ publish(payload);
207
+ } else if (notif.targetUserId && typeof sendToUser === "function") {
192
208
  sendToUser(notif.targetUserId, payload);
193
209
  } else {
194
210
  broadcastAll(payload);
@@ -196,12 +212,14 @@ function attachNotifications(ctx) {
196
212
  return notif;
197
213
  }
198
214
 
199
- function dismiss(ids) {
215
+ function dismiss(ids, ws) {
216
+ var permitted = visible(ws).map(function (notification) { return notification.id; });
217
+ ids = ids.filter(function (id) { return permitted.indexOf(id) !== -1; });
200
218
  var before = notifications.length;
201
219
  notifications = notifications.filter(function(n) { return ids.indexOf(n.id) === -1; });
202
220
  if (notifications.length !== before) {
203
221
  saveNotifications();
204
- broadcastAll({
222
+ publish({
205
223
  type: "notification_dismissed",
206
224
  ids: ids,
207
225
  unreadCount: getUnreadCount(),
@@ -209,12 +227,41 @@ function attachNotifications(ctx) {
209
227
  }
210
228
  }
211
229
 
212
- function dismissAll() {
213
- if (notifications.length > 0) {
214
- notifications = [];
215
- saveNotifications();
216
- broadcastAll({ type: "notification_dismissed_all", unreadCount: 0 });
217
- }
230
+ function canReadOwned(principal, item) {
231
+ var owner = principal.userId || null;
232
+ return (owner ? (item.targetUserId === owner || item.ownerId === owner) && (!item.targetUserId || item.targetUserId === owner) : !item.ownerId && !item.targetUserId) &&
233
+ (!ctx.canViewPrincipal || ctx.canViewPrincipal(principal, item));
234
+ }
235
+ function authorizeOwned(principal, items) {
236
+ if (items.some(function (item) { return !canReadOwned(principal, item); })) throw new Error('Owned notification access changed.');
237
+ }
238
+ function listOwned(principal) {
239
+ return notifications.filter(function (item) { return canReadOwned(principal, item); }).slice(0, 100).map(function (item) { return JSON.parse(JSON.stringify(controlProjection(item))); });
240
+ }
241
+ function inspectOwned(principal, ids) {
242
+ var owned = listOwned(principal);
243
+ return ids.map(function (id) {
244
+ var item = owned.find(function (entry) { return entry.id === id; });
245
+ if (!item) throw new Error('The exact owned notification is absent or inaccessible.');
246
+ return item;
247
+ });
248
+ }
249
+ function dismissOwned(principal, ids, revalidate) {
250
+ revalidate(); inspectOwned(principal, ids);
251
+ var previous = notifications;
252
+ notifications = notifications.filter(function (item) { return ids.indexOf(item.id) < 0; });
253
+ var tmp = NOTIF_FILE + '.tmp';
254
+ try { fs.writeFileSync(tmp, JSON.stringify(notifications, null, 2)); fs.renameSync(tmp, NOTIF_FILE); }
255
+ catch (error) { notifications = previous; throw error; }
256
+ // Use the ordinary per-viewer notification state; no private IDs are broadcast.
257
+ var published = true;
258
+ if (ctx.forEachClient) ctx.forEachClient(function (ws) { try { sendConnectionState(ws, function (client, payload) { if (client.readyState === 1) client.send(JSON.stringify(payload)); }); } catch (error) { published = false; } });
259
+ try { revalidate(); } catch (error) { return { status: 'failed', persisted: true, dismissedIds: ids, error: error.message, retrySafe: false }; }
260
+ return { status: published ? 'completed' : 'failed', persisted: true, dismissedIds: ids, viewerPublication: published ? 'sent' : 'partial', retrySafe: false };
261
+ }
262
+
263
+ function dismissAll(ws) {
264
+ dismiss(visible(ws).map(function (notification) { return notification.id; }), ws);
218
265
  }
219
266
 
220
267
  // --- Periodic reminder ---
@@ -222,8 +269,15 @@ function attachNotifications(ctx) {
222
269
  function startReminder() {
223
270
  if (reminderTimer) return;
224
271
  reminderTimer = setInterval(function () {
272
+ if (ctx.canView && ctx.getUsers && pushModule && pushModule.sendPushToUser) {
273
+ ctx.getUsers().forEach(function (user) {
274
+ var count = visible({ _clayUser: user }).length;
275
+ if (count) pushModule.sendPushToUser(user.id, { type: "reminder", title: "Clay", body: count + " unread notification" + (count > 1 ? "s" : ""), tag: "clay-notif-reminder" });
276
+ });
277
+ return;
278
+ }
225
279
  var count = getUnreadCount();
226
- if (count > 0 && pushModule) {
280
+ if (count > 0 && pushModule && !ctx.canView) {
227
281
  pushModule.sendPush({
228
282
  type: "reminder",
229
283
  title: "Clay",
@@ -244,10 +298,11 @@ function attachNotifications(ctx) {
244
298
 
245
299
  function sendConnectionState(ws, sendTo) {
246
300
  if (!sendTo) return;
301
+ var list = visible(ws);
247
302
  sendTo(ws, {
248
303
  type: "notifications_state",
249
- notifications: notifications,
250
- unreadCount: getUnreadCount(),
304
+ notifications: list,
305
+ unreadCount: list.length,
251
306
  });
252
307
  }
253
308
 
@@ -255,17 +310,21 @@ function attachNotifications(ctx) {
255
310
 
256
311
  function handleNotificationMessage(ws, msg) {
257
312
  if (msg.type === "notification_dismiss") {
258
- dismiss(msg.ids || []);
313
+ dismiss(msg.ids || [], ws);
259
314
  return true;
260
315
  }
261
316
  if (msg.type === "notification_dismiss_all") {
262
- dismissAll();
317
+ dismissAll(ws);
263
318
  return true;
264
319
  }
265
320
  return false;
266
321
  }
267
322
 
268
323
  return {
324
+ authorizeOwned: authorizeOwned,
325
+ listOwned: listOwned,
326
+ inspectOwned: inspectOwned,
327
+ dismissOwned: dismissOwned,
269
328
  notify: notify,
270
329
  getUnreadCount: getUnreadCount,
271
330
  sendConnectionState: sendConnectionState,