clay-server 5.1.1-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 (588) hide show
  1. package/lib/account-auth-policy.js +21 -0
  2. package/lib/account-auth-socket.js +30 -0
  3. package/lib/account-auth-throttle.js +44 -0
  4. package/lib/account-auth-transport.js +48 -0
  5. package/lib/account-login-page.js +28 -0
  6. package/lib/account-passkey-challenges.js +31 -0
  7. package/lib/account-passkey-page.js +89 -0
  8. package/lib/account-passkey-policy.js +39 -0
  9. package/lib/account-password-page.js +69 -0
  10. package/lib/account-passwords.js +36 -0
  11. package/lib/account-remembered.js +77 -0
  12. package/lib/account-session-page.js +51 -0
  13. package/lib/account-session-store.js +82 -0
  14. package/lib/builtin-mates.js +19 -16
  15. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  16. package/lib/canonical-clay-record-authority.js +15 -0
  17. package/lib/canonical-clay-scheduling-authority.js +19 -0
  18. package/lib/claude-hook-installer.js +1 -239
  19. package/lib/claude-jsonl-watcher.js +1 -204
  20. package/lib/clay-control-presentation-binding.js +96 -0
  21. package/lib/clay-control-presentation.js +128 -0
  22. package/lib/clay-control-target-projection.js +26 -0
  23. package/lib/clay-mate-chat-receipts.js +26 -0
  24. package/lib/clay-mate-chat.js +88 -0
  25. package/lib/clay-mate-knowledge-input.js +26 -0
  26. package/lib/clay-mate-knowledge.js +95 -0
  27. package/lib/clay-mate-lifecycle.js +95 -0
  28. package/lib/clay-product-control-input.js +33 -0
  29. package/lib/clay-product-control-tools.js +51 -0
  30. package/lib/clay-product-control.js +247 -0
  31. package/lib/clay-project-lifecycle.js +154 -0
  32. package/lib/clay-project-record-input.js +44 -0
  33. package/lib/clay-project-records.js +84 -0
  34. package/lib/clay-scheduling-input.js +21 -0
  35. package/lib/clay-scheduling-receipts.js +26 -0
  36. package/lib/clay-scheduling.js +119 -0
  37. package/lib/clay-screen-controls.js +104 -0
  38. package/lib/clay-skill-install.js +1 -33
  39. package/lib/clay-workspace-controls.js +84 -0
  40. package/lib/clay-workspace-input.js +17 -0
  41. package/lib/clay-workspace-receipts.js +26 -0
  42. package/lib/cli-sessions.js +1 -300
  43. package/lib/codex-defaults.js +1 -28
  44. package/lib/context-usage.js +3 -2
  45. package/lib/contextual-screen-snapshot.js +38 -0
  46. package/lib/daemon-project-access.js +11 -0
  47. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  48. package/lib/daemon-project-lifecycle.js +262 -0
  49. package/lib/daemon-projects.js +1 -1
  50. package/lib/daemon.js +80 -276
  51. package/lib/default-ai-runtime.js +4 -8
  52. package/lib/dm-digest-cursor.js +120 -0
  53. package/lib/email-mcp-server.js +1 -1
  54. package/lib/issues-service.js +29 -15
  55. package/lib/kiro-defaults.js +1 -22
  56. package/lib/knowledge-db-import-validation.js +46 -0
  57. package/lib/knowledge-db-import.js +99 -0
  58. package/lib/knowledge-db-service.js +24 -33
  59. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  60. package/lib/knowledge-db-storage-nedb.js +66 -0
  61. package/lib/knowledge-db-storage.js +72 -0
  62. package/lib/knowledge-db-validation.js +0 -0
  63. package/lib/knowledge-document-index.js +2 -1
  64. package/lib/knowledge-file-store.js +7 -1
  65. package/lib/knowledge-product-operations.js +46 -0
  66. package/lib/mate-avatar-catalog.js +12 -0
  67. package/lib/mate-avatar-migration.js +41 -0
  68. package/lib/mate-context-service.js +138 -0
  69. package/lib/mate-context-tools.js +21 -0
  70. package/lib/mate-creation-mcp-server.js +2 -0
  71. package/lib/mate-knowledge-canonical-access.js +10 -0
  72. package/lib/mate-knowledge-mate-bound.js +53 -0
  73. package/lib/mate-knowledge-mcp-server.js +55 -8
  74. package/lib/mate-knowledge-service.js +16 -34
  75. package/lib/mate-knowledge-text-tools.js +106 -0
  76. package/lib/mate-lifecycle-service.js +94 -0
  77. package/lib/mate-message-delivery.js +43 -0
  78. package/lib/mate-ready-creation.js +9 -1
  79. package/lib/mate-schedule-input.js +29 -0
  80. package/lib/mate-schedule-lifecycle.js +151 -0
  81. package/lib/mate-scheduling.js +103 -0
  82. package/lib/mates.js +18 -6
  83. package/lib/mcp-agent-tools.js +117 -0
  84. package/lib/mcp-connection-store.js +119 -15
  85. package/lib/mcp-import-credentials.js +31 -0
  86. package/lib/mcp-local-transport.js +13 -0
  87. package/lib/mcp-oauth.js +8 -6
  88. package/lib/mcp-proxy.js +2 -32
  89. package/lib/mcp-query-bridge.js +30 -0
  90. package/lib/mcp-remote-connections.js +74 -20
  91. package/lib/mcp-source-adapters.js +1 -0
  92. package/lib/mcp-source-context.js +1 -0
  93. package/lib/mcp-source-discovery.js +1 -0
  94. package/lib/mcp-source-plugins.js +1 -0
  95. package/lib/mcp-source-restrictions.js +1 -0
  96. package/lib/mcp-tool-policy.js +9 -0
  97. package/lib/migrate-single-user.js +3 -23
  98. package/lib/notes-checklist.js +50 -0
  99. package/lib/notes.js +49 -3
  100. package/lib/os-user-diagnostics.js +2 -4
  101. package/lib/os-users.js +24 -70
  102. package/lib/pane-pending-interactions.js +20 -0
  103. package/lib/pane-session-activation.js +114 -0
  104. package/lib/pane-session-transport.js +26 -0
  105. package/lib/project-admin-overview.js +51 -0
  106. package/lib/project-ask-user.js +8 -4
  107. package/lib/project-connection.js +14 -10
  108. package/lib/project-control-git-view.js +12 -0
  109. package/lib/project-debate.js +1 -0
  110. package/lib/project-delegated-follow-up.js +2 -1
  111. package/lib/project-directory-claim.js +65 -0
  112. package/lib/project-file-operations.js +61 -0
  113. package/lib/project-filesystem.js +15 -85
  114. package/lib/project-full-access.js +23 -2
  115. package/lib/project-http.js +7 -4
  116. package/lib/project-knowledge.js +32 -18
  117. package/lib/project-lifecycle-operations.js +98 -0
  118. package/lib/project-lifecycle-process-witness.js +32 -0
  119. package/lib/project-lifecycle-runtime.js +50 -0
  120. package/lib/project-linux-access.js +22 -0
  121. package/lib/project-logs-canonical-clay.js +27 -0
  122. package/lib/project-logs-clay-query.js +16 -0
  123. package/lib/project-logs-schema.js +4 -2
  124. package/lib/project-logs-service.js +8 -7
  125. package/lib/project-logs.js +1 -0
  126. package/lib/project-loop.js +1 -0
  127. package/lib/project-mate-chat-control.js +55 -0
  128. package/lib/project-mate-creation-proposal.js +18 -3
  129. package/lib/project-mate-interaction.js +40 -62
  130. package/lib/project-mcp.js +54 -16
  131. package/lib/project-models.js +14 -31
  132. package/lib/project-notifications.js +76 -17
  133. package/lib/project-ownership.js +77 -0
  134. package/lib/project-pair-result-delivery.js +14 -3
  135. package/lib/project-pair-usage.js +12 -13
  136. package/lib/project-pending-message-queue.js +4 -1
  137. package/lib/project-product-control.js +89 -0
  138. package/lib/project-product-session-queue.js +46 -0
  139. package/lib/project-push-access.js +28 -0
  140. package/lib/project-scheduled-message-queue.js +30 -0
  141. package/lib/project-scheduled-messages.js +67 -68
  142. package/lib/project-scheduled-task-control.js +83 -0
  143. package/lib/project-scheduled-tasks.js +13 -2
  144. package/lib/project-scheduling-access.js +10 -0
  145. package/lib/project-server-settings.js +1 -0
  146. package/lib/project-session-actions.js +65 -0
  147. package/lib/project-session-delete.js +8 -1
  148. package/lib/project-session-document.js +27 -7
  149. package/lib/project-session-github.js +63 -19
  150. package/lib/project-session-history-actions.js +167 -0
  151. package/lib/project-session-linear.js +14 -6
  152. package/lib/project-session-notes.js +7 -3
  153. package/lib/project-session-pair.js +1 -1
  154. package/lib/project-session-runtime-actions.js +64 -0
  155. package/lib/project-session-spawn.js +2 -3
  156. package/lib/project-session-vendor.js +55 -0
  157. package/lib/project-sessions.js +103 -272
  158. package/lib/project-shared-browser.js +78 -17
  159. package/lib/project-studio-presentation.js +58 -0
  160. package/lib/project-user-knowledge.js +2 -1
  161. package/lib/project-user-message.js +67 -1
  162. package/lib/project-vendor-login.js +6 -36
  163. package/lib/project-workspace-operations.js +126 -0
  164. package/lib/project-workspace-query.js +19 -2
  165. package/lib/project.js +178 -45
  166. package/lib/public/app.js +46 -0
  167. package/lib/public/appearance-bootstrap.js +16 -0
  168. package/lib/public/auth/account-login.css +98 -0
  169. package/lib/public/auth/account-login.js +104 -0
  170. package/lib/public/css/clay-tool-activity.css +51 -0
  171. package/lib/public/css/clay-workspace.css +29 -0
  172. package/lib/public/css/command-palette.css +12 -33
  173. package/lib/public/css/contextual-clay.css +240 -0
  174. package/lib/public/css/home-debate-planning.css +2 -0
  175. package/lib/public/css/home-mate-creation.css +5 -0
  176. package/lib/public/css/input.css +6 -0
  177. package/lib/public/css/mate-avatar-gallery.css +12 -0
  178. package/lib/public/css/mate-conversation.css +10 -5
  179. package/lib/public/css/messages.css +6 -2
  180. package/lib/public/css/overlays.css +4 -2
  181. package/lib/public/css/project-admin-overview.css +13 -0
  182. package/lib/public/css/session-folders.css +11 -0
  183. package/lib/public/css/session-github.css +46 -1
  184. package/lib/public/css/shared-browser.css +35 -1
  185. package/lib/public/css/sticky-notes.css +87 -1
  186. package/lib/public/css/user-settings-sessions.css +42 -0
  187. package/lib/public/index.html +28 -10
  188. package/lib/public/mate-avatars/B01.png +0 -0
  189. package/lib/public/mate-avatars/B02.png +0 -0
  190. package/lib/public/mate-avatars/B03.png +0 -0
  191. package/lib/public/mate-avatars/B04.png +0 -0
  192. package/lib/public/mate-avatars/B05.png +0 -0
  193. package/lib/public/mate-avatars/B06.png +0 -0
  194. package/lib/public/mate-avatars/B07.png +0 -0
  195. package/lib/public/mate-avatars/B08.png +0 -0
  196. package/lib/public/mate-avatars/B09.png +0 -0
  197. package/lib/public/mate-avatars/B10.png +0 -0
  198. package/lib/public/mate-avatars/B11.png +0 -0
  199. package/lib/public/mate-avatars/B12.png +0 -0
  200. package/lib/public/mate-avatars/B13.png +0 -0
  201. package/lib/public/mate-avatars/B14.png +0 -0
  202. package/lib/public/mate-avatars/B15.png +0 -0
  203. package/lib/public/mate-avatars/B16.png +0 -0
  204. package/lib/public/mate-avatars/B17.png +0 -0
  205. package/lib/public/mate-avatars/B18.png +0 -0
  206. package/lib/public/mate-avatars/B19.png +0 -0
  207. package/lib/public/mate-avatars/B20.png +0 -0
  208. package/lib/public/mate-avatars/B21.png +0 -0
  209. package/lib/public/mate-avatars/B22.png +0 -0
  210. package/lib/public/mate-avatars/B23.png +0 -0
  211. package/lib/public/mate-avatars/B24.png +0 -0
  212. package/lib/public/mate-avatars/B25.png +0 -0
  213. package/lib/public/mate-avatars/B26.png +0 -0
  214. package/lib/public/mate-avatars/B27.png +0 -0
  215. package/lib/public/mate-avatars/B28.png +0 -0
  216. package/lib/public/mate-avatars/B29.png +0 -0
  217. package/lib/public/mate-avatars/B30.png +0 -0
  218. package/lib/public/mate-avatars/B31.png +0 -0
  219. package/lib/public/mate-avatars/B32.png +0 -0
  220. package/lib/public/mate-avatars/B33.png +0 -0
  221. package/lib/public/mate-avatars/B34.png +0 -0
  222. package/lib/public/mate-avatars/B35.png +0 -0
  223. package/lib/public/mate-avatars/B36.png +0 -0
  224. package/lib/public/mate-avatars/B37.png +0 -0
  225. package/lib/public/mate-avatars/B38.png +0 -0
  226. package/lib/public/mate-avatars/B39.png +0 -0
  227. package/lib/public/mate-avatars/B40.png +0 -0
  228. package/lib/public/mate-avatars/B41.png +0 -0
  229. package/lib/public/mate-avatars/B42.png +0 -0
  230. package/lib/public/mate-avatars/B43.png +0 -0
  231. package/lib/public/mate-avatars/B44.png +0 -0
  232. package/lib/public/mate-avatars/B45.png +0 -0
  233. package/lib/public/mate-avatars/B46.png +0 -0
  234. package/lib/public/mate-avatars/B47.png +0 -0
  235. package/lib/public/mate-avatars/B48.png +0 -0
  236. package/lib/public/mate-avatars/C01.png +0 -0
  237. package/lib/public/mate-avatars/C02.png +0 -0
  238. package/lib/public/mate-avatars/C03.png +0 -0
  239. package/lib/public/mate-avatars/C04.png +0 -0
  240. package/lib/public/mate-avatars/C05.png +0 -0
  241. package/lib/public/mate-avatars/C06.png +0 -0
  242. package/lib/public/mate-avatars/C07.png +0 -0
  243. package/lib/public/mate-avatars/C08.png +0 -0
  244. package/lib/public/mate-avatars/C09.png +0 -0
  245. package/lib/public/mate-avatars/C10.png +0 -0
  246. package/lib/public/mate-avatars/C11.png +0 -0
  247. package/lib/public/mate-avatars/C12.png +0 -0
  248. package/lib/public/mate-avatars/C13.png +0 -0
  249. package/lib/public/mate-avatars/C14.png +0 -0
  250. package/lib/public/mate-avatars/C15.png +0 -0
  251. package/lib/public/mate-avatars/C16.png +0 -0
  252. package/lib/public/mate-avatars/C17.png +0 -0
  253. package/lib/public/mate-avatars/C18.png +0 -0
  254. package/lib/public/mate-avatars/C19.png +0 -0
  255. package/lib/public/mate-avatars/C20.png +0 -0
  256. package/lib/public/mate-avatars/C21.png +0 -0
  257. package/lib/public/mate-avatars/C22.png +0 -0
  258. package/lib/public/mate-avatars/C23.png +0 -0
  259. package/lib/public/mate-avatars/C24.png +0 -0
  260. package/lib/public/mate-avatars/C25.png +0 -0
  261. package/lib/public/mate-avatars/C26.png +0 -0
  262. package/lib/public/mate-avatars/C27.png +0 -0
  263. package/lib/public/mate-avatars/C28.png +0 -0
  264. package/lib/public/mate-avatars/C29.png +0 -0
  265. package/lib/public/mate-avatars/C30.png +0 -0
  266. package/lib/public/mate-avatars/C31.png +0 -0
  267. package/lib/public/mate-avatars/C32.png +0 -0
  268. package/lib/public/mate-avatars/C33.png +0 -0
  269. package/lib/public/mate-avatars/C34.png +0 -0
  270. package/lib/public/mate-avatars/C35.png +0 -0
  271. package/lib/public/mate-avatars/C36.png +0 -0
  272. package/lib/public/mate-avatars/C37.png +0 -0
  273. package/lib/public/mate-avatars/C38.png +0 -0
  274. package/lib/public/mate-avatars/C39.png +0 -0
  275. package/lib/public/mate-avatars/C40.png +0 -0
  276. package/lib/public/mate-avatars/C41.png +0 -0
  277. package/lib/public/mate-avatars/C42.png +0 -0
  278. package/lib/public/mate-avatars/C43.png +0 -0
  279. package/lib/public/mate-avatars/C44.png +0 -0
  280. package/lib/public/mate-avatars/C45.png +0 -0
  281. package/lib/public/mate-avatars/C46.png +0 -0
  282. package/lib/public/mate-avatars/C47.png +0 -0
  283. package/lib/public/mate-avatars/C48.png +0 -0
  284. package/lib/public/mate-avatars/catalog.json +482 -0
  285. package/lib/public/mate-avatars/lead-clay.png +0 -0
  286. package/lib/public/modules/account-auth-settings.js +71 -0
  287. package/lib/public/modules/account-transport-settings.js +51 -0
  288. package/lib/public/modules/admin-settings-projects.js +6 -2
  289. package/lib/public/modules/app-connection.js +11 -1
  290. package/lib/public/modules/app-favicon.js +18 -9
  291. package/lib/public/modules/app-header.js +7 -4
  292. package/lib/public/modules/app-loop-ui.js +2 -0
  293. package/lib/public/modules/app-message-router.js +22 -1
  294. package/lib/public/modules/app-messages.js +119 -17
  295. package/lib/public/modules/app-misc.js +3 -1
  296. package/lib/public/modules/app-notifications.js +11 -5
  297. package/lib/public/modules/app-panels.js +61 -123
  298. package/lib/public/modules/app-projects.js +13 -0
  299. package/lib/public/modules/app-rate-limit.js +7 -27
  300. package/lib/public/modules/app-rendering.js +4 -3
  301. package/lib/public/modules/avatar.js +15 -41
  302. package/lib/public/modules/chat-render-runtime.js +20 -0
  303. package/lib/public/modules/clay-browser-links.js +47 -0
  304. package/lib/public/modules/clay-control-activity.js +214 -0
  305. package/lib/public/modules/clay-control-copy.js +36 -0
  306. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  307. package/lib/public/modules/clay-control-object-targets.js +52 -0
  308. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  309. package/lib/public/modules/clay-control-targets.js +44 -0
  310. package/lib/public/modules/clay-log-links.js +23 -0
  311. package/lib/public/modules/clay-navigation-render.js +52 -0
  312. package/lib/public/modules/clay-owner-navigation.js +33 -0
  313. package/lib/public/modules/clay-session-links.js +31 -0
  314. package/lib/public/modules/clay-studio-bridge.js +20 -0
  315. package/lib/public/modules/clay-studio-document.js +67 -0
  316. package/lib/public/modules/clay-studio-render.js +146 -0
  317. package/lib/public/modules/clay-tool-activity.js +140 -0
  318. package/lib/public/modules/clay-tool-presentation.js +342 -0
  319. package/lib/public/modules/command-palette.js +162 -40
  320. package/lib/public/modules/contextual-ask-session.js +26 -0
  321. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  322. package/lib/public/modules/contextual-clay-session.js +130 -0
  323. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  324. package/lib/public/modules/contextual-clay.js +250 -0
  325. package/lib/public/modules/contextual-composer.js +91 -0
  326. package/lib/public/modules/contextual-mate-context.js +117 -0
  327. package/lib/public/modules/contextual-mate-hint.js +40 -0
  328. package/lib/public/modules/contextual-mate-identity.js +23 -0
  329. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  330. package/lib/public/modules/contextual-search.js +137 -0
  331. package/lib/public/modules/contextual-session-citations.js +58 -0
  332. package/lib/public/modules/debate.js +1 -0
  333. package/lib/public/modules/default-ai.js +11 -3
  334. package/lib/public/modules/elicitation-form.js +5 -0
  335. package/lib/public/modules/filebrowser.js +20 -1
  336. package/lib/public/modules/generation-stop.js +8 -5
  337. package/lib/public/modules/git-panel.js +3 -1
  338. package/lib/public/modules/history-replay-batch.js +13 -1
  339. package/lib/public/modules/home-debate-live.js +2 -0
  340. package/lib/public/modules/home-debate-planning.js +7 -7
  341. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  342. package/lib/public/modules/home-mate-chat.js +8 -6
  343. package/lib/public/modules/home-mate-creation.js +73 -1
  344. package/lib/public/modules/home-mate-settings.js +19 -12
  345. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  346. package/lib/public/modules/input.js +88 -10
  347. package/lib/public/modules/issues-render.js +3 -2
  348. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  349. package/lib/public/modules/markdown.js +6 -34
  350. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  351. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  352. package/lib/public/modules/mate-management.js +40 -7
  353. package/lib/public/modules/mcp-connection-view.js +31 -13
  354. package/lib/public/modules/mcp-discovery-view.js +31 -0
  355. package/lib/public/modules/mcp-ui.js +23 -4
  356. package/lib/public/modules/mention.js +3 -0
  357. package/lib/public/modules/message-delivery.js +20 -2
  358. package/lib/public/modules/model-picker.js +2 -0
  359. package/lib/public/modules/pane-activation.js +214 -0
  360. package/lib/public/modules/pane-binding.js +82 -0
  361. package/lib/public/modules/pane-bridge.js +7 -4
  362. package/lib/public/modules/pane-browser-bridge.js +22 -0
  363. package/lib/public/modules/pane-file-bridge.js +4 -0
  364. package/lib/public/modules/pane-issue-bridge.js +4 -1
  365. package/lib/public/modules/passkey-browser.js +69 -0
  366. package/lib/public/modules/passkey-server-settings.js +57 -0
  367. package/lib/public/modules/pending-message-queue.js +1 -0
  368. package/lib/public/modules/permission-control.js +5 -4
  369. package/lib/public/modules/personal-settings-dialog.js +7 -1
  370. package/lib/public/modules/product-review.js +26 -0
  371. package/lib/public/modules/profile.js +1 -238
  372. package/lib/public/modules/project-access-recovery.js +17 -0
  373. package/lib/public/modules/project-admin-overview.js +21 -0
  374. package/lib/public/modules/project-chat-identity.js +13 -4
  375. package/lib/public/modules/project-logs-render.js +6 -2
  376. package/lib/public/modules/project-mate-navigation.js +144 -22
  377. package/lib/public/modules/rewind.js +5 -0
  378. package/lib/public/modules/scheduled-tasks.js +2 -0
  379. package/lib/public/modules/scheduler.js +2 -0
  380. package/lib/public/modules/search-clay-chat.js +5 -440
  381. package/lib/public/modules/server-settings-controls.js +10 -0
  382. package/lib/public/modules/server-settings.js +7 -2
  383. package/lib/public/modules/session-actions.js +5 -2
  384. package/lib/public/modules/session-context-menu.js +5 -0
  385. package/lib/public/modules/session-create-form.js +10 -10
  386. package/lib/public/modules/session-folder-layout.js +1 -1
  387. package/lib/public/modules/session-folder-view-menu.js +9 -0
  388. package/lib/public/modules/session-github.js +85 -14
  389. package/lib/public/modules/session-rich-drafts.js +21 -0
  390. package/lib/public/modules/session-switch-defer.js +67 -0
  391. package/lib/public/modules/session-work-primary.js +51 -0
  392. package/lib/public/modules/settings-defaults.js +27 -28
  393. package/lib/public/modules/shared-browser-settings.js +112 -0
  394. package/lib/public/modules/shared-browser-tabs.js +13 -3
  395. package/lib/public/modules/shared-browser.js +29 -6
  396. package/lib/public/modules/sidebar-mobile.js +4 -3
  397. package/lib/public/modules/sidebar-projects.js +1 -0
  398. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  399. package/lib/public/modules/sidebar-sessions.js +1 -0
  400. package/lib/public/modules/split-group-restore.js +68 -0
  401. package/lib/public/modules/split-pair-ui.js +1 -0
  402. package/lib/public/modules/split-pane-reconciler.js +15 -0
  403. package/lib/public/modules/split-pane-renderer.js +87 -6
  404. package/lib/public/modules/split-session-boundary.js +1 -1
  405. package/lib/public/modules/split-view.js +60 -68
  406. package/lib/public/modules/sticky-note-markdown.js +72 -6
  407. package/lib/public/modules/sticky-notes-actions.js +30 -0
  408. package/lib/public/modules/sticky-notes-browser.js +9 -2
  409. package/lib/public/modules/sticky-notes-card.js +23 -7
  410. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  411. package/lib/public/modules/sticky-notes-editor.js +108 -44
  412. package/lib/public/modules/sticky-notes-shared.js +50 -2
  413. package/lib/public/modules/sticky-notes-state.js +66 -0
  414. package/lib/public/modules/sticky-notes.js +34 -51
  415. package/lib/public/modules/stt-controller.js +4 -1
  416. package/lib/public/modules/stt-recording.js +1 -1
  417. package/lib/public/modules/stt.js +7 -2
  418. package/lib/public/modules/terminal.js +9 -0
  419. package/lib/public/modules/theme.js +8 -1
  420. package/lib/public/modules/thinking-lifecycle.js +33 -3
  421. package/lib/public/modules/thinking-view.js +23 -1
  422. package/lib/public/modules/tools.js +60 -11
  423. package/lib/public/modules/tui-grab.js +1 -2
  424. package/lib/public/modules/user-settings-account.js +14 -1
  425. package/lib/public/modules/user-settings-appearance.js +10 -3
  426. package/lib/public/modules/user-settings-editors.js +1 -1
  427. package/lib/public/modules/user-settings-layout.js +11 -2
  428. package/lib/public/modules/user-settings-preferences.js +6 -2
  429. package/lib/public/modules/user-settings-profile.js +12 -2
  430. package/lib/public/modules/user-settings-sessions.js +120 -0
  431. package/lib/public/modules/user-settings.js +6 -2
  432. package/lib/public/modules/vendor-login-browser.js +5 -3
  433. package/lib/public/modules/vendor-login.js +2 -2
  434. package/lib/public/modules/vendor-priority.js +15 -1
  435. package/lib/public/modules/wireframe-workbench.js +5 -2
  436. package/lib/public/modules/you-activity.js +3 -1
  437. package/lib/public/modules/you.js +91 -6
  438. package/lib/public/muse-avatar.svg +4 -0
  439. package/lib/public/style.css +6 -0
  440. package/lib/public/sw.js +3 -1
  441. package/lib/safe-bash-commands.js +3 -45
  442. package/lib/scheduled-task-records.js +3 -1
  443. package/lib/scheduler.js +2 -0
  444. package/lib/sdk-bridge.js +342 -401
  445. package/lib/sdk-foreground-admission.js +16 -0
  446. package/lib/sdk-mcp-descriptors.js +2 -37
  447. package/lib/sdk-message-processor.js +52 -17
  448. package/lib/sdk-quota-snapshot.js +1 -1
  449. package/lib/sdk-response-recovery.js +1 -0
  450. package/lib/sdk-worker.js +2 -677
  451. package/lib/server-account-passkeys.js +186 -0
  452. package/lib/server-account-passwords.js +127 -0
  453. package/lib/server-account-security.js +53 -0
  454. package/lib/server-admin.js +63 -16
  455. package/lib/server-appearance-settings.js +13 -1
  456. package/lib/server-auth.js +107 -79
  457. package/lib/server-contextual-clay-settings.js +40 -0
  458. package/lib/server-contextual-mate-sessions.js +70 -0
  459. package/lib/server-dm.js +2 -1
  460. package/lib/server-global-ws.js +10 -20
  461. package/lib/server-home-chat-events.js +18 -4
  462. package/lib/server-home-chat.js +22 -20
  463. package/lib/server-home-clay-entry.js +23 -4
  464. package/lib/server-home-clay-session-links.js +29 -9
  465. package/lib/server-home-mate-creation.js +1 -0
  466. package/lib/server-home-mcp-consent.js +14 -0
  467. package/lib/server-mates.js +25 -62
  468. package/lib/server-owner-ui.js +118 -0
  469. package/lib/server-path-access.js +38 -0
  470. package/lib/server-project-removal.js +22 -0
  471. package/lib/server-settings.js +8 -2
  472. package/lib/server.js +165 -43
  473. package/lib/session-config-transition.js +45 -0
  474. package/lib/session-folders.js +7 -2
  475. package/lib/session-fork-history.js +21 -0
  476. package/lib/session-github.js +9 -2
  477. package/lib/session-hygiene.js +3 -35
  478. package/lib/session-permission-mode.js +4 -3
  479. package/lib/session-skill-scope.js +11 -0
  480. package/lib/session-visibility.js +5 -2
  481. package/lib/session-work-primary.js +50 -0
  482. package/lib/sessions.js +64 -99
  483. package/lib/shared-browser-cookie-sync.js +32 -0
  484. package/lib/shared-browser-cookies.js +79 -0
  485. package/lib/shared-browser-runtime.js +25 -9
  486. package/lib/shared-browser-storage-sync.js +43 -0
  487. package/lib/shared-browser-storage.js +101 -0
  488. package/lib/shared-browser-tools.js +2 -1
  489. package/lib/shared-browser-worker.js +46 -10
  490. package/lib/terminal-manager.js +65 -6
  491. package/lib/tool-llm.js +1 -1
  492. package/lib/tui-transcript-index.js +1 -132
  493. package/lib/user-knowledge-service.js +23 -1
  494. package/lib/users-auth.js +38 -3
  495. package/lib/users-contextual-clay-preferences.js +31 -0
  496. package/lib/users-create.js +97 -0
  497. package/lib/users-permissions.js +2 -8
  498. package/lib/users-server-pin.js +37 -0
  499. package/lib/users.js +18 -84
  500. package/lib/vendor-login-browser.js +1 -11
  501. package/lib/workspace-assignment-service.js +25 -0
  502. package/lib/workspace-query-access.js +4 -1
  503. package/lib/workspace-query-mcp-server.js +1 -1
  504. package/lib/workspace-query-service.js +13 -2
  505. package/lib/ws-request.js +1 -0
  506. package/lib/ws-schema.js +18 -2
  507. package/lib/yoke/acp-agent-profiles.js +7 -5
  508. package/lib/yoke/adapters/antigravity.js +3 -14
  509. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  510. package/lib/yoke/adapters/claude.js +54 -50
  511. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  512. package/lib/yoke/adapters/codex.js +53 -111
  513. package/lib/yoke/adapters/kiro.js +3 -1
  514. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  515. package/lib/yoke/adapters/muse.js +122 -0
  516. package/lib/yoke/auth-events.js +17 -0
  517. package/lib/yoke/claude-hook-installer.js +271 -0
  518. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  519. package/lib/yoke/claude-maintenance.js +55 -0
  520. package/lib/yoke/claude-permission-patterns.js +53 -0
  521. package/lib/yoke/claude-response-recovery.js +155 -0
  522. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  523. package/lib/yoke/claude-worker-startup.js +28 -0
  524. package/lib/yoke/clay-skill-install.js +33 -0
  525. package/lib/yoke/cli-sessions.js +300 -0
  526. package/lib/yoke/codex-app-server.js +7 -12
  527. package/lib/yoke/codex-idle-recovery.js +81 -1
  528. package/lib/yoke/codex-recovery-admission.js +164 -0
  529. package/lib/yoke/configuration.js +13 -0
  530. package/lib/yoke/discovery.js +70 -0
  531. package/lib/yoke/errors.js +8 -0
  532. package/lib/yoke/host-environment.js +7 -0
  533. package/lib/yoke/index.js +9 -51
  534. package/lib/yoke/interface.js +116 -0
  535. package/lib/yoke/kiro-acp-server.js +5 -5
  536. package/lib/yoke/legacy-sessions.js +89 -0
  537. package/lib/yoke/login-protocol.js +25 -0
  538. package/lib/yoke/maintenance.js +12 -0
  539. package/lib/yoke/mcp-proxy.js +32 -0
  540. package/lib/yoke/mcp-source-adapters.js +91 -0
  541. package/lib/yoke/mcp-source-context.js +42 -0
  542. package/lib/yoke/mcp-source-discovery.js +169 -0
  543. package/lib/yoke/mcp-source-plugins.js +68 -0
  544. package/lib/yoke/mcp-source-restrictions.js +47 -0
  545. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  546. package/lib/yoke/model-preferences.js +6 -0
  547. package/lib/yoke/muse-artifacts.js +36 -0
  548. package/lib/yoke/muse-controls.js +50 -0
  549. package/lib/yoke/muse-input.js +64 -0
  550. package/lib/yoke/muse-items.js +157 -0
  551. package/lib/yoke/muse-policy.js +52 -0
  552. package/lib/yoke/muse-query.js +428 -0
  553. package/lib/yoke/muse-runtime.js +211 -0
  554. package/lib/yoke/muse-services.js +79 -0
  555. package/lib/yoke/muse-skills.js +79 -0
  556. package/lib/yoke/muse-turns.js +71 -0
  557. package/lib/yoke/options/acp.js +2 -0
  558. package/lib/yoke/options/antigravity.js +2 -0
  559. package/lib/yoke/options/claude.js +21 -0
  560. package/lib/yoke/options/codex-defaults.js +29 -0
  561. package/lib/yoke/options/codex-settings.js +21 -0
  562. package/lib/yoke/options/codex.js +6 -0
  563. package/lib/yoke/options/kiro-defaults.js +22 -0
  564. package/lib/yoke/options/kiro.js +5 -0
  565. package/lib/yoke/options/muse.js +5 -0
  566. package/lib/yoke/provider-contract.js +5 -0
  567. package/lib/yoke/providers/antigravity-executable.js +8 -0
  568. package/lib/yoke/providers/claude-executable.js +40 -0
  569. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  570. package/lib/yoke/providers/claude-process.js +97 -0
  571. package/lib/yoke/providers/claude-provision.js +75 -0
  572. package/lib/yoke/providers/codex-errors.js +8 -0
  573. package/lib/yoke/providers/muse-executable.js +17 -0
  574. package/lib/yoke/provisioning.js +6 -0
  575. package/lib/yoke/query-options.js +10 -0
  576. package/lib/yoke/response-recovery.js +41 -0
  577. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  578. package/lib/yoke/sdk-server-factory.js +7 -0
  579. package/lib/yoke/session-history.js +8 -0
  580. package/lib/yoke/session-tool-transport.js +34 -13
  581. package/lib/yoke/settings.js +23 -0
  582. package/lib/yoke/source-locations.js +4 -0
  583. package/lib/yoke/title-query.js +18 -7
  584. package/lib/yoke/tui-transcript-index.js +132 -0
  585. package/lib/yoke/usage.js +48 -0
  586. package/lib/yoke/user-input.js +13 -0
  587. package/lib/yoke/vendor-registry.js +81 -1
  588. package/package.json +11 -4
@@ -5,12 +5,14 @@ var browserTools = require("./shared-browser-tools");
5
5
  var createRuntime = require("./shared-browser-runtime").createRuntime;
6
6
 
7
7
  function attachSharedBrowser(ctx) {
8
+ var storageStore = ctx.storageStore || require("./shared-browser-storage").attachStorageStore(require("./config").CONFIG_DIR);
8
9
  var records = new Map();
9
10
  var viewers = new Map();
10
11
  var destroyed = false;
11
12
  function allowed(session, ws) {
12
13
  try {
13
- if (ctx.isMate || !session || ctx.sm.sessions.get(session.localId) !== session) return false;
14
+ if (!session || ctx.sm.sessions.get(session.localId) !== session) return false;
15
+ if (ctx.isMate && ctx.usersModule.isMultiUser() && (!ctx.ownerId || session.ownerId !== ctx.ownerId)) return false;
14
16
  if (ctx.usersModule.isMultiUser()) {
15
17
  var user = ctx.usersModule.findUserById(session.ownerId);
16
18
  if (!user || (ws && (!ws._clayUser || String(ws._clayUser.id) !== String(user.id)))) return false;
@@ -35,7 +37,7 @@ function attachSharedBrowser(ctx) {
35
37
  function projection(record) {
36
38
  if (!record) return null;
37
39
  return { id: record.id, phase: record.phase, control: record.control, epoch: record.epoch, handoff: !!record.handoff,
38
- url: record.url, width: record.width, height: record.height, activity: record.activity || null, activityHistory: record.activityHistory || [], pointer: record.pointer || null, error: record.error || "" };
40
+ browserLink: record.url ? "browser:" + record.url : null, incognito: record.incognito, personalCookiesAvailable: !!ctx.isMate, url: record.url, width: record.width, height: record.height, activity: record.activity || null, activityHistory: record.activityHistory || [], pointer: record.pointer || null, error: record.error || "" };
39
41
  }
40
42
  function sessionRecords(session) {
41
43
  return Array.from(records.values()).filter(function (record) { return record.session === session && recordAllowed(record); });
@@ -93,6 +95,13 @@ function attachSharedBrowser(ctx) {
93
95
  if ((record.activity || record.pointer) && record.activityGeneration !== Number(record.session._sdkQueryGeneration || 0)) {
94
96
  activityHistory.interruptActivity(record); record.pointer = null; broadcast(record);
95
97
  }
98
+ if (message.type === "navigation") {
99
+ try { record.navigationUrl = policy.browserUrl(message.navigationUrl || message.url); } catch (error) { record.navigationUrl = null; }
100
+ }
101
+ if (message.type === "navigation" && !record.incognito) {
102
+ try { storageStore.visit(record.cookieOwner, message.url); }
103
+ catch (error) { end(record, "Could not save personal browsing history"); return; }
104
+ }
96
105
  if (message.type === "ready") { record.phase = "live"; record.resolveReady(); }
97
106
  if (message.type === "error") { end(record, message.error); return; }
98
107
  if (message.url !== undefined) record.url = policy.visibleUrl(message.url);
@@ -108,10 +117,12 @@ function attachSharedBrowser(ctx) {
108
117
  }
109
118
  // Every new tab starts shared. Exclusive human mode is explicit, per tab, and only the human clears it,
110
119
  // so an agent open never reuses (or bypasses) an exclusive tab.
111
- function create(session, actor, newTab) {
120
+ function create(session, actor, newTab, incognito) {
112
121
  requireAccess(session);
122
+ if (incognito !== undefined && typeof incognito !== "boolean") throw new Error("Invalid incognito mode");
123
+ var temporary = !ctx.isMate || incognito === true;
113
124
  var tabs = sessionRecords(session);
114
- var previous = !newTab && tabs.find(function (record) { return record.runtime && (actor === "user" || record.control === "agent"); });
125
+ var previous = !newTab && tabs.find(function (record) { return record.runtime && (incognito === undefined || record.incognito === temporary) && (actor === "user" || record.control === "agent"); });
115
126
  if (previous) return previous;
116
127
  if (tabs.length >= 12) {
117
128
  var expired = tabs.find(function (record) { return !record.runtime; });
@@ -122,12 +133,15 @@ function attachSharedBrowser(ctx) {
122
133
  records.forEach(function (record) { if (record.runtime && record.ownerId === session.ownerId) active++; });
123
134
  if (active >= 4) throw new Error("End another browser before opening more than four active tabs");
124
135
  var record = { session: session, ownerId: session.ownerId, identity: identityKey(session), id: crypto.randomUUID(), phase: "starting", control: "agent", epoch: 0,
125
- url: "", width: 1280, height: 800, touched: Date.now(), runtime: null, frame: null };
136
+ cookieOwner: ctx.isMate ? (ctx.ownerId || session.ownerId || "default") : null, incognito: temporary, url: "", width: 1280, height: 800, touched: Date.now(), runtime: null, frame: null };
126
137
  record.ready = new Promise(function (resolve, reject) { record.resolveReady = resolve; record.rejectReady = reject; });
127
138
  record.ready.catch(function () {});
128
139
  records.set(record.id, record);
129
140
  try {
130
- record.runtime = (ctx.createRuntime || createRuntime)({ identity: ctx.getIdentity(session), onEvent: function (message) { receive(record, message); } });
141
+ record.runtime = (ctx.createRuntime || createRuntime)({ identity: ctx.getIdentity(session), storage: temporary ? null : {
142
+ read: function () { if (!recordAllowed(record)) throw new Error("Browser access was revoked"); return storageStore.read(record.cookieOwner); },
143
+ exchange: function (previous, current) { if (!recordAllowed(record)) throw new Error("Browser access was revoked"); return storageStore.exchange(record.cookieOwner, previous, current); },
144
+ }, onEvent: function (message) { receive(record, message); } });
131
145
  } catch (e) { end(record, e.message); }
132
146
  broadcast(record, true);
133
147
  return record;
@@ -161,13 +175,14 @@ function attachSharedBrowser(ctx) {
161
175
  record.touched = Date.now(); broadcast(record);
162
176
  return projection(record);
163
177
  }
164
- async function run(session, record, actor, action, event, intent) {
178
+ async function run(session, record, actor, action, event, intent, presentationStart) {
165
179
  requireAccess(session);
166
180
  if (!record || !record.runtime || !recordAllowed(record)) throw new Error("Open a browser first");
167
181
  if (record.handoff) throw new Error("Browser control is changing; wait for the handoff");
168
182
  // control "agent" = shared (owner and Clay may both act); "user" = exclusive human mode (Clay mutations denied).
169
183
  // The authorized owner is never blocked by control mode and ordinary human input never changes it.
170
184
  if (action !== "inspect" && actor === "agent" && record.control !== "agent") throw new Error("Only the user can control this browser right now (Clay is paused). Wait for them to resume shared control; do not work around it.");
185
+ if (action !== 'inspect') { record.presentationRevision = (record.presentationRevision || 0) + 1; if (presentationStart) presentationStart(record.presentationRevision); }
171
186
  var epoch = record.epoch;
172
187
  var generation = Number(session._sdkQueryGeneration || 0);
173
188
  await record.ready;
@@ -186,19 +201,26 @@ function attachSharedBrowser(ctx) {
186
201
  requireAccess(session);
187
202
  if (actor === "agent" && Number(session._sdkQueryGeneration || 0) !== generation) throw new Error("Browser result belongs to an older query");
188
203
  if (!recordAllowed(record) || records.get(record.id) !== record || record.epoch !== epoch) throw new Error("Browser control changed during the action");
204
+ if (result && result.url !== undefined) record.url = policy.visibleUrl(result.url);
189
205
  return result;
190
206
  }
191
207
  async function tool(session, args) {
208
+ var observer;
192
209
  try {
193
210
  requireAccess(session);
194
211
  if (args.intent !== undefined && (typeof args.intent !== "string" || args.intent.length > 160)) throw new Error("Browser intent must be at most 160 characters");
195
212
  var record = args.action === "status" || args.action === "open" ? null : selectRecord(session, args.browserId);
196
- var value;
213
+ var value, actionRevision = record && (record.presentationRevision || 0);
214
+ function presentationStart(value) { actionRevision = value; }
215
+ if (['status', 'inspect'].indexOf(args.action) < 0 && ctx.getPresentation) { var display = ctx.getPresentation(session); if (display) observer = ctx.studioPresentation ? ctx.studioPresentation.begin(session, 'browser') : display.track('studio', 'browser'); }
197
216
  if (args.action === "status") value = { browsers: sessionRecords(session).map(projection) };
198
217
  else if (args.action === "open") {
218
+ if (args.incognito !== undefined && typeof args.incognito !== "boolean") throw new Error("Invalid incognito mode");
199
219
  var url = args.url ? policy.browserUrl(args.url) : null;
200
- record = args.browserId ? selectRecord(session, args.browserId) : create(session, "agent", args.newTab === true);
201
- if (url) await run(session, record, "agent", "action", { kind: "navigate", url: url }, args.intent);
220
+ record = args.browserId ? selectRecord(session, args.browserId) : create(session, "agent", args.newTab === true, args.incognito);
221
+ if (args.incognito !== undefined && record.incognito !== (!ctx.isMate || args.incognito)) throw new Error("This tab has a different cookie mode. Open a new tab with the requested mode.");
222
+ if (url) await run(session, record, "agent", "action", { kind: "navigate", url: url }, args.intent, presentationStart);
223
+ else actionRevision = record.presentationRevision || 0;
202
224
  value = projection(record);
203
225
  } else if (args.action === "finish") {
204
226
  if (!record || !record.runtime) throw new Error("Open a browser first");
@@ -206,13 +228,38 @@ function attachSharedBrowser(ctx) {
206
228
  } else if (args.action === "inspect") {
207
229
  value = await run(session, record, "agent", "inspect", null, args.intent);
208
230
  value.browserId = record.id;
231
+ value.browserLink = record.url ? "browser:" + record.url : null;
209
232
  var image = value.image; delete value.image;
210
233
  return { content: [{ type: "text", text: JSON.stringify(value) }, { type: "image", mimeType: "image/jpeg", data: image }] };
211
234
  } else {
212
- value = await run(session, record, "agent", "action", policy.validateAction(Object.assign({}, args, { kind: args.action })), args.intent);
235
+ value = await run(session, record, "agent", "action", policy.validateAction(Object.assign({}, args, { kind: args.action })), args.intent, presentationStart);
213
236
  }
237
+ if (observer && observer.present) {
238
+ observer.phase('completed');
239
+ try {
240
+ observer.guard();
241
+ var expectedRecord = record, expectedEpoch = record.epoch, expectedUrl = record.url;
242
+ if ((record.presentationRevision || 0) !== actionRevision || record.control !== 'agent') throw new Error('The browser changed after this action.');
243
+ var view = await run(session, record, 'agent', 'inspect', null, args.intent);
244
+ if (view && view.url && policy.visibleUrl(view.url) !== expectedUrl) throw new Error('The browser navigated after this action.');
245
+ if (!view || typeof view.image !== 'string' || !view.image) throw new Error('No exact browser frame was returned.');
246
+ observer.present({ type: 'shared_browser_frame', sessionId: session.localId, browserId: record.id, data: view.image, width: view.width, height: view.height }, 'browser', record.id, require('./clay-control-target-projection').digest(view.image), function () { requireAccess(session); if (records.get(expectedRecord.id) !== expectedRecord || !recordAllowed(expectedRecord) || expectedRecord.epoch !== expectedEpoch || expectedRecord.url !== expectedUrl || expectedRecord.control !== 'agent' || (expectedRecord.presentationRevision || 0) !== actionRevision || !expectedRecord.runtime) throw new Error('Browser target changed.'); }, function (message, onSent) { return ctx.sendToSession(session.localId, message, onSent); });
247
+ } catch (visibilityError) { observer.noVisibility(); }
248
+ } else if (observer) observer.finish({ status: 'completed' });
249
+ if (value && value.url) value.browserLink = "browser:" + policy.visibleUrl(value.url);
214
250
  return { content: [{ type: "text", text: JSON.stringify(value) }] };
215
- } catch (e) { return { isError: true, content: [{ type: "text", text: e.message }] }; }
251
+ } catch (e) { if (observer) { if (observer.unknown) observer.unknown(); else observer.finish({ outcome: "uncertain" }); } return { isError: true, content: [{ type: "text", text: e.message }] }; }
252
+ }
253
+ async function openLinkedPage(session, url, incognito) {
254
+ var record = sessionRecords(session).find(function (tab) {
255
+ return tab.runtime && ((tab.phase === "live" && (tab.navigationUrl || tab.url) === url) || (tab.linkOpening && tab.linkOpening.url === url));
256
+ });
257
+ if (record) { if (record.linkOpening) await record.linkOpening.promise; return record; }
258
+ record = create(session, "user", true, incognito);
259
+ record.navigationUrl = url;
260
+ record.linkOpening = { url: url, promise: run(session, record, "user", "action", { kind: "navigate", url: url }) };
261
+ try { await record.linkOpening.promise; } finally { record.linkOpening = null; }
262
+ return record;
216
263
  }
217
264
  function handleMessage(ws, msg) {
218
265
  if (!msg.type || msg.type.indexOf("shared_browser_") !== 0) return false;
@@ -221,8 +268,22 @@ function attachSharedBrowser(ctx) {
221
268
  requireAccess(session, ws);
222
269
  if (String(msg.sessionId) !== String(session.localId)) throw new Error("Browser session changed");
223
270
  var record;
271
+ if (msg.type === "shared_browser_settings") {
272
+ if (!ctx.isMate) throw new Error("Personal browser settings are available only in Mates");
273
+ if (typeof msg.requestId !== "string" || msg.requestId.length > 100) throw new Error("Invalid browser settings request");
274
+ var owner = ctx.ownerId || session.ownerId || "default";
275
+ var settings = storageStore.manage(owner, msg.operation, msg.target);
276
+ requireAccess(session, ws);
277
+ ctx.sendTo(ws, { type: "shared_browser_settings", sessionId: session.localId, requestId: msg.requestId, settings: settings });
278
+ return;
279
+ }
224
280
  if (msg.type === "shared_browser_state_request") { sendState(ws, session, sessionRecords(session)[0]); return; }
225
- if (msg.type === "shared_browser_open") { record = create(session, "user", msg.newTab === true); sendState(ws, session, record, true, true); return; }
281
+ if (msg.type === "shared_browser_open") {
282
+ var targetUrl = msg.url === undefined ? null : policy.browserUrl(msg.url);
283
+ if (targetUrl) record = await openLinkedPage(session, targetUrl, msg.incognito);
284
+ else record = create(session, "user", msg.newTab === true, msg.incognito);
285
+ sendState(ws, session, record, true, true); return;
286
+ }
226
287
  record = selectRecord(session, msg.browserId);
227
288
  if (!record || !recordAllowed(record, ws) || msg.browserId !== record.id) throw new Error("Browser session expired");
228
289
  if (msg.type === "shared_browser_view") {
@@ -242,7 +303,7 @@ function attachSharedBrowser(ctx) {
242
303
  await run(session, record, "user", "action", policy.validateAction(msg.event));
243
304
  }
244
305
  }).catch(function (e) {
245
- if (ws.readyState === 1) ctx.sendTo(ws, { type: "shared_browser_error", sessionId: msg.sessionId, error: e.message });
306
+ if (ws.readyState === 1) ctx.sendTo(ws, { type: "shared_browser_error", sessionId: msg.sessionId, error: e.message, requestId: msg.requestId });
246
307
  });
247
308
  return true;
248
309
  }
@@ -257,7 +318,7 @@ function attachSharedBrowser(ctx) {
257
318
  sweep.unref();
258
319
  function getToolDefs(session) {
259
320
  var generation = Number(session && session._sdkQueryGeneration || 0);
260
- return ctx.isMate ? [] : browserTools.getToolDefs(function (args) {
321
+ return browserTools.getToolDefs(function (args) {
261
322
  if (session && Number(session._sdkQueryGeneration || 0) !== generation) {
262
323
  return Promise.resolve({ isError: true, content: [{ type: "text", text: "This browser tool belongs to an older query" }] });
263
324
  }
@@ -267,8 +328,8 @@ function attachSharedBrowser(ctx) {
267
328
  return {
268
329
  handleMessage: handleMessage,
269
330
  getToolDefs: getToolDefs,
270
- getSystemPrompt: function () { return ctx.isMate ? "" : browserTools.PROMPT; },
271
- createMcpServer: function (adapter, session) { return ctx.isMate || !adapter || typeof adapter.createToolServer !== "function" ? null : adapter.createToolServer({ name: "clay-shared-browser", version: "1.0.0", tools: getToolDefs(session) }); },
331
+ getSystemPrompt: function () { return browserTools.PROMPT; },
332
+ createMcpServer: function (adapter, session) { return !adapter || typeof adapter.createToolServer !== "function" ? null : adapter.createToolServer({ name: "clay-shared-browser", version: "1.0.0", tools: getToolDefs(session) }); },
272
333
  destroy: function () { destroyed = true; clearInterval(sweep); records.forEach(function (record) { end(record); }); records.clear(); viewers.clear(); },
273
334
  };
274
335
  }
@@ -0,0 +1,58 @@
1
+ var crypto = require('crypto');
2
+
3
+ // Visibility receipts observe existing workbench effects; they dispatch no product action.
4
+ function attachStudioPresentation(ctx) {
5
+ var pending = new Map();
6
+ function begin(session, action) {
7
+ var display = ctx.getPresentation && ctx.getPresentation(session);
8
+ if (!display) return null;
9
+ var source = display.source(), observer = display.track('studio', action);
10
+ if (!observer) return null;
11
+ var id = crypto.randomUUID(), token = crypto.randomUUID(), record;
12
+ function end(status, viewer) {
13
+ if (!record || !pending.has(id)) return;
14
+ pending.delete(id); clearTimeout(record.timer);
15
+ if (viewer) observer.focus(viewer);
16
+ observer.finish({ status: status });
17
+ }
18
+ function cancel() { if (record) { pending.delete(id); clearTimeout(record.timer); } observer.cancel(); }
19
+ return {
20
+ phase: observer.phase,
21
+ guard: observer.guard,
22
+ noVisibility: function () { observer.finish({ status: "render_unknown" }); },
23
+ fail: function () { cancel(); },
24
+ unknown: function () { observer.finish({ outcome: 'uncertain' }); },
25
+ present: function (message, surface, key, revision, validate, send) {
26
+ observer.guard();
27
+ if (pending.size >= 100) { observer.finish({ status: 'render_unknown' }); return 0; }
28
+ var target = { kind: 'surface', sourceSlug: source.sourceSlug, sourceSessionId: session.localId, sourceSessionOriginId: source.sourceSessionOriginId,
29
+ runtimeId: source.runtimeId, surface: surface, key: key, revision: revision };
30
+ observer.target(target, validate); observer.guard();
31
+ var evidence = Object.assign({ version: 1, id: id, activityId: observer.id, token: token, deadline: Date.now() + 5000, target: target }, source);
32
+ record = { session: session, source: source, evidence: evidence, observer: observer, viewers: new Set(), end: end, cancel: cancel };
33
+ pending.set(id, record);
34
+ record.timer = setTimeout(function () { end('render_unknown'); }, 5000); record.timer.unref();
35
+ var sent = send(Object.assign({}, message, { controlPresentation: evidence }), function (ws) { record.viewers.add(ws); });
36
+ if (sent > 0) { if (surface !== 'browser') observer.phase('delivered'); }
37
+ else end('render_unknown');
38
+ return sent;
39
+ }
40
+ };
41
+ }
42
+ function handleMessage(ws, msg) {
43
+ if (msg.type !== 'clay_studio_rendered') return false;
44
+ var record = pending.get(msg.id);
45
+ if (!record || record.evidence.token !== msg.token || !record.viewers.has(ws)) return true;
46
+ try {
47
+ record.observer.guard();
48
+ if (Date.now() > record.evidence.deadline) { record.end('render_unknown', ws); return true; }
49
+ if (ws.readyState !== 1 || ws._clayAuthCheck && !ws._clayAuthCheck() ||
50
+ ws._clayActiveSession !== record.session.localId || ctx.getSessionForWs(ws) !== record.session || (ws._clayUser && ws._clayUser.id || null) !== record.source.ownerId ||
51
+ msg.sessionOriginId !== record.source.sourceSessionOriginId || msg.revision !== record.evidence.target.revision) throw new Error('Studio viewer or target changed.');
52
+ record.end(msg.visible === true ? 'rendered' : 'render_unknown', ws);
53
+ } catch (error) { record.cancel(); }
54
+ return true;
55
+ }
56
+ return { begin: begin, handleMessage: handleMessage };
57
+ }
58
+ module.exports = { attachStudioPresentation: attachStudioPresentation };
@@ -34,7 +34,7 @@ function attachProjectUserKnowledge(ctx) {
34
34
  } catch(error) {return '';}
35
35
  }
36
36
  function handleMessage(ws,msg) {
37
- if(['you_attention','you_seen','you_list','you_read','you_activity','you_report','you_comment','you_retry'].indexOf(msg.type)===-1) return false;
37
+ if(['you_attention','you_seen','you_list','you_read','you_activity','you_report','you_comment','you_retry','you_delete'].indexOf(msg.type)===-1) return false;
38
38
  var reply={type:'you_result',operation:msg.type,requestId:msg.requestId,ok:false};
39
39
  try {
40
40
  var user=ws._clayUser;
@@ -44,6 +44,7 @@ function attachProjectUserKnowledge(ctx) {
44
44
  if(msg.type==='you_seen') reply.result=ctx.service.acknowledge(id,msg);
45
45
  if(msg.type==='you_list') reply.result=ctx.service.list(id,msg);
46
46
  if(msg.type==='you_read') reply.result=ctx.service.read(id,msg.ref);
47
+ if(msg.type==='you_delete') reply.result=ctx.service.remove(id,{ref:msg.ref,expectedRevision:msg.expectedRevision});
47
48
  if(msg.type==='you_activity') reply.result=ctx.service.activity(id,msg);
48
49
  if(msg.type==='you_comment') reply.result=ctx.service.comment(id,msg,{project:ctx.slug,session:'human',mateId:null});
49
50
  if(msg.type==='you_retry') { ctx.schedule(id); reply.result={pending:ctx.service.pendingCount(id)}; }
@@ -49,6 +49,7 @@ function attachUserMessage(ctx) {
49
49
 
50
50
  var clients = ctx.clients;
51
51
  var opts = ctx.opts;
52
+ var snapshotService = require('./contextual-screen-snapshot').attachContextualScreenSnapshot(ctx);
52
53
 
53
54
  var usersModule = ctx.usersModule;
54
55
  var matesModule = ctx.matesModule;
@@ -118,6 +119,12 @@ function attachUserMessage(ctx) {
118
119
  requestId: msg.requestId || null, ok: !!ok, error: error || null });
119
120
  }
120
121
 
122
+ function noteUpdateResult(ws, msg, ok, note, error) {
123
+ if (!msg.requestId) return;
124
+ sendTo(ws, { type: "note_update_result", projectSlug: slug, noteId: msg.id || null,
125
+ requestId: msg.requestId, ok: !!ok, note: note || null, error: error || null });
126
+ }
127
+
121
128
  // --------------- Main handler ---------------
122
129
 
123
130
  function handleUserMessage(ws, msg, forcedSession, internal) {
@@ -155,7 +162,10 @@ function attachUserMessage(ctx) {
155
162
  }
156
163
 
157
164
  if (msg.type === "note_update") {
158
- if (!msg.id) return true;
165
+ if (!msg.id) {
166
+ noteUpdateResult(ws, msg, false, null, "Note id is required");
167
+ return true;
168
+ }
159
169
  // A legacy `hidden` update is a lifecycle transition, so the actor is
160
170
  // derived from the bound socket rather than taken from the message.
161
171
  var noteChanges = msg;
@@ -166,10 +176,24 @@ function attachUserMessage(ctx) {
166
176
  if (updated) {
167
177
  send({ type: "note_updated", note: updated });
168
178
  if (msg.text !== undefined || msg.hidden !== undefined) syncNotesKnowledge();
179
+ noteUpdateResult(ws, msg, true, updated, null);
180
+ } else {
181
+ noteUpdateResult(ws, msg, false, null, "Note update could not be saved");
169
182
  }
170
183
  return true;
171
184
  }
172
185
 
186
+ if (msg.type === "note_close" && msg.humanClose === true) {
187
+ if (!canHumanManageNotes(ws)) { noteUpdateResult(ws, msg, false, null, "You are not authorized to close notes in this project."); return true; }
188
+ var result = nm.closeHuman(msg.id, msg, notesLifecycle.userActor(ws && ws._clayUser));
189
+ if (!result) { noteUpdateResult(ws, msg, false, null, "The note changed or could not be saved. Review it and retry."); return true; }
190
+ if (result.removed) send({ type: "note_deleted", id: result.removed.id });
191
+ else send({ type: "note_updated", note: result.note });
192
+ noteUpdateResult(ws, msg, true, result.note || null, null);
193
+ syncNotesKnowledge();
194
+ return true;
195
+ }
196
+
173
197
  // Completing a note closes it. `note_delete` is the retired spelling and is
174
198
  // deliberately routed to the same non-destructive close, so an older client
175
199
  // still on the wire cannot erase a record.
@@ -427,6 +451,10 @@ function attachUserMessage(ctx) {
427
451
  return true;
428
452
  }
429
453
 
454
+ var screenSnapshot;
455
+ try { screenSnapshot = snapshotService.capture(ws, session, msg); }
456
+ catch (error) { sendTo(ws, { type: 'error', text: error.message }); finishPendingEarly(false, error.message); return true; }
457
+
430
458
  // A configured Split Worker is Driver-operated: its work arrives through
431
459
  // the Driver's delegation, not from a person typing into its pane. The UI
432
460
  // hides the composer, but the refusal has to live here too — a legacy
@@ -443,9 +471,17 @@ function attachUserMessage(ctx) {
443
471
  finishPendingEarly(false, "Pending messages cannot be delivered to a Driver-operated Split Worker");
444
472
  return true;
445
473
  }
474
+ if (!pendingInternal && ctx.resumeLifecycleProject) {
475
+ try { ctx.resumeLifecycleProject(ws); }
476
+ catch (error) { sendTo(ws, { type: "error", text: error.message }); return true; }
477
+ }
478
+ function reportQueuedContext() {
479
+ if (msg.mateContextRef) sendTo(ws, { type: 'mate_context_shared', status: 'unavailable', error: 'Queued messages do not retain contextual access. Send again from the current view when ready.' });
480
+ }
446
481
  if (!pendingInternal && session._driverContinuationLease && pendingMessageQueue) {
447
482
  var continuationQueued = pendingMessageQueue.admit(session, msg, ws && ws._clayUser);
448
483
  if (continuationQueued.ok) {
484
+ reportQueuedContext();
449
485
  messageDelivery.acknowledge(ws, deliveryReceipt, null, session);
450
486
  sendTo(ws, { type: "message_queued", clientMessageId: msg.clientMessageId || null,
451
487
  sessionId: session.localId, projectSlug: slug, state: "pending",
@@ -459,8 +495,10 @@ function attachUserMessage(ctx) {
459
495
  if (!pendingInternal && pendingMessageQueue && (pendingMessageQueue.hasActive(session) || session.isProcessing || session._queryStarting || session._awaitingTurnResult)) {
460
496
  var queuedResult = pendingMessageQueue.admit(session, msg, ws && ws._clayUser);
461
497
  if (queuedResult.ok) {
498
+ reportQueuedContext();
462
499
  messageDelivery.acknowledge(ws, deliveryReceipt, null, session);
463
500
  sendTo(ws, { type: "message_queued", clientMessageId: msg.clientMessageId || null, sessionId: session.localId, projectSlug: slug, state: "pending", paused: pendingMessageQueue.isPaused(session), revision: pendingMessageQueue.getRevision() });
501
+ if (require('./sdk-foreground-admission').available(session)) setImmediate(function () { consumePendingMessage(session); });
464
502
  } else {
465
503
  sendTo(ws, { type: "error", text: queuedResult.error || "Unable to queue message" });
466
504
  }
@@ -526,6 +564,7 @@ function attachUserMessage(ctx) {
526
564
  if (msg.pastes && msg.pastes.length > 0) {
527
565
  userMsg2.pastes = msg.pastes;
528
566
  }
567
+ if (screenSnapshot) { userMsg2.contextualSnapshot = screenSnapshot.snapshot; userMsg2.sessionOriginId = session.sessionOriginId; }
529
568
  if (deliveryReceipt.clientMessageId) userMsg2.clientMessageId = deliveryReceipt.clientMessageId;
530
569
  if (!userMsg2._ts) userMsg2._ts = Date.now();
531
570
  var transcriptRecorded = false;
@@ -719,6 +758,7 @@ function attachUserMessage(ctx) {
719
758
 
720
759
  function pendingBlockReason() {
721
760
  if (!pendingInternal) return null;
761
+ if (ctx.isLifecycleExecutionPaused && ctx.isLifecycleExecutionPaused()) return "Pending message dispatch paused";
722
762
  if (!pendingMessageQueue.isClaimed(session, pendingInternal.item.id)) return "Pending message was cancelled";
723
763
  if (pendingMessageQueue.isPaused(session) || session._pendingMessageDrainPaused || session.taskStopRequested) return "Pending message dispatch paused";
724
764
  if (typeof ctx.authorizePendingDispatch !== "function" || !ctx.authorizePendingDispatch(session, ws && ws._clayUser, pendingInternal.item)) return "Pending message authorization changed";
@@ -729,7 +769,12 @@ function attachUserMessage(ctx) {
729
769
  return !pendingBlockReason();
730
770
  }
731
771
 
772
+ var contextualAdmission = null, contextualNotified = false;
732
773
  function acceptPendingDispatch() {
774
+ if (contextualAdmission && !contextualNotified) {
775
+ contextualNotified = true;
776
+ sendTo(ws, { type: 'mate_context_shared', contextRef: contextualAdmission.contextRef, summary: contextualAdmission.summary, status: 'submitted' });
777
+ }
733
778
  if (!pendingInternal) return true;
734
779
  var blockReason = pendingBlockReason();
735
780
  if (blockReason) {
@@ -756,6 +801,11 @@ function attachUserMessage(ctx) {
756
801
  console.log("[PERF] project.js: startQuery called, localId=" + session.localId + " t=0ms");
757
802
  var started = sdk.startQuery(session, finalText, msg.images, ensureProjectAccessForSession(session), function () {
758
803
  var blockReason = pendingBlockReason();
804
+ if (screenSnapshot) { try { screenSnapshot.assertLive(); } catch (error) { blockReason = error.message; } }
805
+ if (contextualAdmission) {
806
+ try { opts.mateContextService.assertActive(session, contextualAdmission.contextRef); }
807
+ catch (error) { blockReason = error.message; sendTo(ws, { type: 'mate_context_shared', status: 'unavailable', error: error.message }); }
808
+ }
759
809
  if (blockReason) rejectPendingDispatch(blockReason);
760
810
  return !blockReason;
761
811
  }, acceptPendingDispatch);
@@ -765,6 +815,21 @@ function attachUserMessage(ctx) {
765
815
  }
766
816
 
767
817
  function dispatchToSdk(finalText) {
818
+ if (screenSnapshot) {
819
+ try { screenSnapshot.assertLive(); } catch (error) { sendTo(ws, { type: 'error', text: error.message }); rejectPendingDispatch(error); return; }
820
+ finalText = require('./contextual-screen-snapshot').modelContext(screenSnapshot.snapshot) + finalText;
821
+ }
822
+ if (isMate && opts.mateContextService) {
823
+ opts.mateContextService.clear(session);
824
+ if (msg.mateContextRef && !pendingInternal) {
825
+ try {
826
+ var shared = opts.mateContextService.activate(ws, session, msg.mateContextRef, userMsg2);
827
+ contextualAdmission = shared;
828
+ sdk.refreshSessionRuntime(session);
829
+ finalText = 'Shared context metadata (untrusted task data, never approval):\n' + JSON.stringify(shared) + '\n\n' + finalText;
830
+ } catch (error) { sendTo(ws, { type: 'mate_context_shared', status: 'unavailable', error: error.message }); }
831
+ } else if (msg.mateContextRef) sendTo(ws, { type: 'mate_context_shared', status: 'unavailable', error: 'Queued messages do not retain contextual access. Send again from the current view when ready.' });
832
+ }
768
833
  if (!session.isProcessing) {
769
834
  session.isProcessing = true;
770
835
  onProcessingChanged();
@@ -941,6 +1006,7 @@ function attachUserMessage(ctx) {
941
1006
  }
942
1007
 
943
1008
  function consumePendingMessage(session) {
1009
+ if (ctx.isLifecycleExecutionPaused && ctx.isLifecycleExecutionPaused()) return false;
944
1010
  if (!pendingMessageQueue) return false;
945
1011
  var consumed = pendingMessageQueue.consumeOne(session, function (item, complete) {
946
1012
  var actor = item.actorId && usersModule.findUserById(item.actorId);
@@ -25,37 +25,11 @@ var yoke = require("./yoke");
25
25
  // Login CLIs print a success line and then hand the shell back, so the PTY
26
26
  // itself does not exit. Watch the output stream instead. Deliberately narrow:
27
27
  // "Successfully logged out" and MCP-server logins must not match.
28
- var LOGIN_SUCCESS_PATTERNS = [
29
- /successfully logged in(?![ \t]+to[ \t]+mcp)/i,
30
- /logged in successfully/i,
31
- /login successful/i,
32
- /successfully authenticated/i,
33
- /authentication successful/i,
34
- /signed in successfully/i,
35
- /signed in with your [a-z ]+ account/i,
36
- /you(?:'re| are) (?:now )?(?:logged|signed) in/i,
37
- ];
38
-
39
- // Rolling window kept per flow so a success line split across PTY chunks is
40
- // still matched, without buffering the whole login transcript.
41
28
  var OUTPUT_TAIL_MAX = 4096;
42
-
43
- // Grace period between detecting success and killing the terminal, so the user
44
- // actually sees the confirmation line before the modal closes.
45
29
  var CLOSE_AFTER_SUCCESS_MS = 2000;
46
-
47
- var ANSI_PATTERN = /\x1b\[[0-9;?]*[ -\/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\r/g;
48
-
49
- function stripAnsi(text) {
50
- return String(text).replace(ANSI_PATTERN, "");
51
- }
52
-
53
- function looksLikeLoginSuccess(text) {
54
- for (var i = 0; i < LOGIN_SUCCESS_PATTERNS.length; i++) {
55
- if (LOGIN_SUCCESS_PATTERNS[i].test(text)) return true;
56
- }
57
- return false;
58
- }
30
+ var loginProtocol = require("./yoke/login-protocol");
31
+ var stripAnsi = loginProtocol.stripAnsi;
32
+ var looksLikeLoginSuccess = loginProtocol.successful;
59
33
 
60
34
  /**
61
35
  * ctx fields:
@@ -96,11 +70,7 @@ function attachVendorLogin(ctx) {
96
70
  cancel: function (vendor) { closeFlowTerminal(discardFlow(vendor)); broadcastState(); },
97
71
  });
98
72
 
99
- function loginCommandFor(vendor) {
100
- if (vendor === "claude") return "claude auth login";
101
- var info = vendorRegistry.getVendorInfo(vendor);
102
- return (info && info.loginCommand) || "claude login";
103
- }
73
+ function loginCommandFor(vendor) { return loginProtocol.command(vendor, false); }
104
74
 
105
75
  function vendorDisplayName(vendor) {
106
76
  var info = vendorRegistry.getVendorInfo(vendor);
@@ -284,8 +254,8 @@ function attachVendorLogin(ctx) {
284
254
  var key = flowKey(ws, vendor);
285
255
  var identity = resolveLoginIdentity(ws, msg);
286
256
  var command = loginCommandFor(vendor);
287
- var browserMode = msg.mode === "browser" && (vendor === "claude" || vendor === "codex");
288
- if (browserMode) command = vendor === "codex" ? "codex login" : "claude auth login";
257
+ var browserMode = msg.mode === "browser" && !!(vendorRegistry.getVendorInfo(vendor) || {}).browserLoginCommand;
258
+ if (browserMode) command = loginProtocol.command(vendor, true);
289
259
  var flow = {
290
260
  vendor: vendor,
291
261
  key: key,