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,3 +1,5 @@
1
+ import { contextualAccessReference } from './contextual-mate-context.js';
2
+ import { contextualScreenReference } from './contextual-clay-session.js';
1
3
  import { stopSTT } from './stt-controller.js';
2
4
  import { expectCreatedSession } from './session-create.js';
3
5
  import { hasRecordedSpeechFor, requestRecordedSend } from './stt-recording.js';
@@ -6,6 +8,7 @@ import { setRewindMode, isRewindMode } from './rewind.js';
6
8
  import { renderPicker as renderContextPicker } from './context-sources.js';
7
9
  import { checkForMention, showMentionMenu, hideMentionMenu, isMentionMenuVisible, mentionMenuKeydown, setMentionAtIdx, parseMentionFromInput, clearMentionState, stickyReapplyMention, sendMention, sendUserMention, renderMentionUser, renderUserMention, removeMentionChip } from './mention.js';
8
10
  import { store } from './store.js';
11
+ import { sessionCallback, paneMessageBinding, samePaneBinding } from './pane-binding.js';
9
12
  import { sendAcknowledgedMessage } from './message-delivery.js';
10
13
  import { mateAvatarUrl } from './avatar.js';
11
14
  import { tuiIsActive, tuiSubmitText } from './session-tui-view.js';
@@ -120,6 +123,10 @@ function showPreThinkingForTurn() {
120
123
 
121
124
  // --- Send ---
122
125
  export function sendMessage() {
126
+ if (store.get('deferredSessionSwitch') || store.get('panePendingBinding') || store.get('paneSuspended')) return;
127
+ if (store.get('paneCommittedBinding') && !store.get('paneReady')) return;
128
+ var actionBinding = paneMessageBinding();
129
+ if (store.get('contextualWriterSuspended')) return;
123
130
  if (ctx && requestRecordedSend(ctx.inputEl, sendMessage)) return;
124
131
  stopSTT();
125
132
  // Debate ended mode intercept: route to resume handler
@@ -343,13 +350,17 @@ export function sendMessage() {
343
350
  store.set({ pendingScheduleAdmissions: admissions, pendingScheduleAdmission: admissions[scheduleRequestId] });
344
351
  ctx.ws.send(JSON.stringify({
345
352
  type: "schedule_message", requestId: scheduleRequestId,
353
+ paneBinding: actionBinding || undefined,
346
354
  projectSlug: scheduleContext.projectSlug, sessionId: scheduleContext.sessionId, accountId: scheduleContext.accountId,
347
355
  text: text || "", images: images, pastes: pastes, resetsAt: resetsAt,
348
356
  }));
349
357
  return;
350
358
  }
351
359
 
360
+ var screenReference = contextualScreenReference();
352
361
  var payload = { type: "message", text: text || "" };
362
+ if (actionBinding) payload.paneBinding = actionBinding;
363
+ if (screenReference) payload.contextualSnapshot = screenReference;
353
364
  if (images.length > 0) {
354
365
  payload.images = images;
355
366
  }
@@ -359,6 +370,8 @@ export function sendMessage() {
359
370
  // Include selected vendor for session binding (server uses on first message)
360
371
  var _selVendor = store.get("currentVendor") || null;
361
372
  if (_selVendor) payload.vendor = _selVendor;
373
+ var contextRef = contextualAccessReference();
374
+ if (contextRef) payload.mateContextRef = contextRef;
362
375
  if (!prepareAutonomousPayload(payload)) return;
363
376
  ctx.currentMsgTs = Date.now();
364
377
  sendAcknowledgedMessage(payload);
@@ -433,6 +446,7 @@ export function sendTextMessage(text) {
433
446
  export function sendShellResultToAgent(msg) {
434
447
  if (!ctx || !ctx.connected || !msg || msg.error || !msg.command) return false;
435
448
  if (String(msg.sessionId) !== String(store.get("activeSessionId"))) return false;
449
+ if (store.get('paneCommittedBinding') && !samePaneBinding(msg.paneActivation, store.get('paneCommittedBinding'))) return false;
436
450
  var payload = {
437
451
  type: "message",
438
452
  text: "$ " + msg.command,
@@ -440,7 +454,8 @@ export function sendShellResultToAgent(msg) {
440
454
  };
441
455
  var selectedVendor = store.get("currentVendor") || null;
442
456
  if (selectedVendor) payload.vendor = selectedVendor;
443
- ctx.ws.send(JSON.stringify(payload));
457
+ if (msg.paneActivation) payload.paneBinding = msg.paneActivation;
458
+ if (ctx.ws.send(JSON.stringify(payload)) === false) return false;
444
459
  commitVendorForTurn();
445
460
  showPreThinkingForTurn();
446
461
  return true;
@@ -448,7 +463,9 @@ export function sendShellResultToAgent(msg) {
448
463
 
449
464
  export function autoResize() {
450
465
  ctx.inputEl.style.height = "auto";
451
- ctx.inputEl.style.height = Math.min(ctx.inputEl.scrollHeight, 120) + "px";
466
+ var border = ctx.inputEl.offsetHeight - ctx.inputEl.clientHeight;
467
+ ctx.inputEl.style.height = Math.min(ctx.inputEl.scrollHeight + border, 120) + "px";
468
+ ctx.inputEl.style.overflowY = ctx.inputEl.scrollHeight > ctx.inputEl.clientHeight ? "auto" : "hidden";
452
469
  // Defensive: sync send/stop button whenever input size changes
453
470
  if (ctx.processing && ctx.setSendBtnMode) {
454
471
  ctx.setSendBtnMode(hasSendableContent() ? "send" : "stop");
@@ -533,6 +550,38 @@ function removePendingImage(idx) {
533
550
  renderInputPreviews();
534
551
  }
535
552
 
553
+ // Move composer ownership between two authenticated views of the same session.
554
+ export function composerDepartureReason() {
555
+ if (uploadingCount) return 'Wait for attachments to finish uploading before changing views.';
556
+ if (store.get('speechActive') || ctx && hasRecordedSpeechFor(ctx.inputEl)) return 'Finish or discard the voice recording before changing views.';
557
+ var retry = store.get('speechRetry');
558
+ if (retry && ctx && retry.input === ctx.inputEl) return 'Retry or discard the voice recording before changing views.';
559
+ return '';
560
+ }
561
+ export function takeComposerDraft() {
562
+ var reason = composerDepartureReason();
563
+ if (reason) throw new Error(reason);
564
+ if (document.dispatchEvent) document.dispatchEvent(new CustomEvent('clay-composer-handoff'));
565
+ var input = ctx.inputEl;
566
+ var draft = { text: input.value, start: input.selectionStart, end: input.selectionEnd, direction: input.selectionDirection, images: pendingImages, pastes: pendingPastes, files: pendingFiles, delay: scheduleDelayMs };
567
+ input.value = '';
568
+ clearPendingImages();
569
+ clearScheduleDelay();
570
+ autoResize();
571
+ return draft;
572
+ }
573
+ export function restoreComposerDraft(draft) {
574
+ if (!draft) return;
575
+ pendingImages = draft.images || [];
576
+ pendingPastes = draft.pastes || [];
577
+ pendingFiles = draft.files || [];
578
+ ctx.inputEl.value = draft.text || '';
579
+ ctx.inputEl.setSelectionRange(draft.start || 0, draft.end || 0, draft.direction || 'none');
580
+ setScheduleDelayMs(draft.delay || 0);
581
+ renderInputPreviews();
582
+ autoResize();
583
+ }
584
+
536
585
  export function clearPendingImages() {
537
586
  pendingImages = [];
538
587
  pendingPastes = [];
@@ -552,14 +601,14 @@ function pastePreview(text) {
552
601
  }
553
602
 
554
603
  function editPendingPaste(idx) {
555
- showPasteModal(pendingPastes[idx].text, function (text) {
604
+ showPasteModal(pendingPastes[idx].text, sessionCallback(function (text) {
556
605
  if (!text) {
557
606
  removePendingPaste(idx);
558
607
  return;
559
608
  }
560
609
  pendingPastes[idx] = { text: text, preview: pastePreview(text) };
561
610
  renderInputPreviews();
562
- });
611
+ }));
563
612
  }
564
613
 
565
614
  function removePendingFile(idx) {
@@ -693,6 +742,7 @@ function uploadFile(file) {
693
742
  return;
694
743
  }
695
744
  uploadingCount++;
745
+ store.set({ composerUploadingCount: uploadingCount });
696
746
  renderInputPreviews();
697
747
  var reader = new FileReader();
698
748
  reader.onload = function (ev) {
@@ -705,12 +755,14 @@ function uploadFile(file) {
705
755
  xhr.setRequestHeader("Content-Type", "application/json");
706
756
  xhr.onload = function () {
707
757
  uploadingCount--;
758
+ store.set({ composerUploadingCount: uploadingCount });
708
759
  if (xhr.status === 200) {
709
760
  try {
710
761
  var resp = JSON.parse(xhr.responseText);
711
762
  pendingFiles.push({ name: resp.name || uploadName, path: resp.path });
712
- } catch (e) {}
763
+ } catch (e) { showToast('Upload response could not be read: ' + uploadName + '. Your draft is preserved.', 'error'); }
713
764
  } else {
765
+ showToast('Upload failed: ' + uploadName + '. Your draft is preserved.', 'error');
714
766
  if (ctx.addSystemMessage) ctx.addSystemMessage("Upload failed: " + uploadName, true);
715
767
  }
716
768
  renderInputPreviews();
@@ -720,6 +772,8 @@ function uploadFile(file) {
720
772
  };
721
773
  xhr.onerror = function () {
722
774
  uploadingCount--;
775
+ store.set({ composerUploadingCount: uploadingCount });
776
+ showToast('Upload failed: ' + uploadName + '. Your draft is preserved.', 'error');
723
777
  if (ctx.addSystemMessage) ctx.addSystemMessage("Upload failed: " + uploadName, true);
724
778
  renderInputPreviews();
725
779
  if (ctx.processing && ctx.setSendBtnMode) {
@@ -728,6 +782,7 @@ function uploadFile(file) {
728
782
  };
729
783
  xhr.send(JSON.stringify({ name: uploadName, data: b64 }));
730
784
  };
785
+ reader.onerror = function () { uploadingCount--; store.set({ composerUploadingCount: uploadingCount }); renderInputPreviews(); showToast('Attachment could not be read. Your draft is preserved.', 'error'); };
731
786
  reader.readAsDataURL(file);
732
787
  }
733
788
 
@@ -739,7 +794,14 @@ function readImageBlob(blob) {
739
794
  uploadFile(blob);
740
795
  return;
741
796
  }
797
+ uploadingCount++; store.set({ composerUploadingCount: uploadingCount });
798
+ var completed = false;
799
+ function finish() {
800
+ if (completed) return; completed = true; uploadingCount--;
801
+ store.set({ composerUploadingCount: uploadingCount }); renderInputPreviews();
802
+ }
742
803
  var reader = new FileReader();
804
+ reader.onerror = function () { finish(); showToast('Image could not be read. Your draft is preserved.', 'error'); };
743
805
  reader.onload = function (ev) {
744
806
  var dataUrl = ev.target.result;
745
807
  // Check base64 payload size (~3/4 of base64 length)
@@ -748,7 +810,7 @@ function readImageBlob(blob) {
748
810
  var estimatedBytes = b64.length * 0.75;
749
811
 
750
812
  if (estimatedBytes <= MAX_IMAGE_BYTES) {
751
- addPendingImage(dataUrl);
813
+ addPendingImage(dataUrl); finish();
752
814
  return;
753
815
  }
754
816
 
@@ -766,8 +828,9 @@ function readImageBlob(blob) {
766
828
  var cx = canvas.getContext("2d");
767
829
  cx.drawImage(img, 0, 0, nw, nh);
768
830
  var resized = canvas.toDataURL("image/jpeg", RESIZE_QUALITY);
769
- addPendingImage(resized);
831
+ addPendingImage(resized); finish();
770
832
  };
833
+ img.onerror = function () { finish(); showToast('Image could not be loaded. Your draft is preserved.', 'error'); };
771
834
  img.src = dataUrl;
772
835
  };
773
836
  reader.readAsDataURL(blob);
@@ -836,10 +899,13 @@ function sendInputSync() {
836
899
  if (dk) ctx.ws.send(JSON.stringify({ type: "dm_typing", dmKey: dk, typing: hasText }));
837
900
  return;
838
901
  }
839
- ctx.ws.send(JSON.stringify({ type: "input_sync", text: ctx.inputEl.value }));
902
+ var speech = store.get('speechActive');
903
+ ctx.ws.send(JSON.stringify({ type: "input_sync", text: ctx.inputEl.value,
904
+ paneBinding: speech && speech.writing ? speech.paneBinding || undefined : undefined }));
840
905
  }
841
906
 
842
907
  export function handleInputSync(text) {
908
+ if (store.get('contextualWriterSuspended')) return;
843
909
  isRemoteInput = true;
844
910
  ctx.inputEl.value = text;
845
911
  autoResize();
@@ -859,7 +925,7 @@ function createFileInput(accept, capture, multiple) {
859
925
  input.style.display = "none";
860
926
  document.body.appendChild(input);
861
927
 
862
- input.addEventListener("change", function () {
928
+ var selectFiles = sessionCallback(function () {
863
929
  if (input.files) {
864
930
  for (var i = 0; i < input.files.length; i++) {
865
931
  if (input.files[i].type.indexOf("image/") === 0) {
@@ -869,6 +935,9 @@ function createFileInput(accept, capture, multiple) {
869
935
  }
870
936
  }
871
937
  }
938
+ });
939
+ input.addEventListener("change", function () {
940
+ selectFiles();
872
941
  document.body.removeChild(input);
873
942
  });
874
943
 
@@ -957,6 +1026,14 @@ export function initInput(_ctx) {
957
1026
  }
958
1027
  }
959
1028
 
1029
+ document.addEventListener('clay-composer-handoff', function () {
1030
+ if (scheduleInlineInput) {
1031
+ var minutes = parseInt(scheduleInlineInput.value, 10);
1032
+ if (minutes >= 1 && minutes <= 1440) setScheduleDelayMs(minutes * 60000);
1033
+ }
1034
+ collapseScheduleBtn();
1035
+ });
1036
+
960
1037
  function setScheduleDelay(ms) {
961
1038
  scheduleDelayMs = ms;
962
1039
  if (!scheduleBtn) return;
@@ -986,7 +1063,7 @@ export function initInput(_ctx) {
986
1063
  scheduleInlineInput.className = "schedule-inline-input";
987
1064
  scheduleBtn.appendChild(scheduleInlineInput);
988
1065
 
989
- setTimeout(function () { scheduleInlineInput.focus(); }, 0);
1066
+ setTimeout(sessionCallback(function () { if (scheduleInlineInput) scheduleInlineInput.focus(); }), 0);
990
1067
 
991
1068
  scheduleInlineInput.addEventListener("click", function (e) { e.stopPropagation(); });
992
1069
  scheduleInlineInput.addEventListener("keydown", function (e) {
@@ -1005,6 +1082,7 @@ export function initInput(_ctx) {
1005
1082
 
1006
1083
  // Close on outside click
1007
1084
  setTimeout(function () {
1085
+ if (!scheduleInlineInput) return;
1008
1086
  scheduleOutsideHandler = function (ev) {
1009
1087
  if (!scheduleBtn.contains(ev.target)) {
1010
1088
  if (scheduleInlineInput) {
@@ -1,3 +1,4 @@
1
+ import { store } from './store.js';
1
2
  import { githubWorkMarkup } from './session-github.js';
2
3
  import { issueGithubAction } from './issues-github.js';
3
4
  import { escapeHtml } from './utils.js';
@@ -18,7 +19,7 @@ export function renderIssueList(result) {
18
19
  var meta = [authorLine(entry), relativeTime(entry.updatedAt || entry.createdAt)];
19
20
  if (entry.revision > 1) meta.push('v' + entry.revision);
20
21
  if (entry.commentCount) meta.push(entry.commentCount + (entry.commentCount === 1 ? ' comment' : ' comments'));
21
- return '<button type="button" class="issue-row" data-open-issue="' + esc(entry.ref) + '">' +
22
+ return '<button type="button" class="issue-row" data-control-runtime="' + esc(store.get("controlRuntimeId")) + '" data-control-revision="' + esc(entry.revision) + '" data-open-issue="' + esc(entry.ref) + '">' +
22
23
  '<div class="issue-row-head"><span class="issue-type">' + esc(entry.type) + '</span>' + priorityChip(entry.priority) + '<strong>' + esc(entry.title) + '</strong></div>' +
23
24
  (entry.summary ? '<p>' + esc(entry.summary) + '</p>' : '') +
24
25
  '<div class="issue-row-meta">' + statusChip(entry.status) + '<span>' + esc(meta.filter(Boolean).join(' · ')) + '</span></div></button>';
@@ -35,7 +36,7 @@ export function renderIssueDetail(entry) {
35
36
  var closed = entry.status === 'resolved' || entry.status === 'closed';
36
37
  var time = entry.updatedAt || entry.createdAt;
37
38
  var byline = [authorLine(entry), time ? new Date(time).toLocaleString() : '', 'v' + entry.revision].filter(Boolean).join(' · ');
38
- return '<article class="issue-detail"><div class="issue-doc-chips"><span class="issue-type">' + esc(entry.type) + '</span>' + priorityChip(entry.priority) + statusChip(entry.status) + '</div>' +
39
+ return '<article class="issue-detail" data-control-ref="' + esc(entry.ref) + '" data-control-runtime="' + esc(store.get("controlRuntimeId")) + '" data-control-revision="' + esc(entry.revision) + '"><div class="issue-doc-chips"><span class="issue-type">' + esc(entry.type) + '</span>' + priorityChip(entry.priority) + statusChip(entry.status) + '</div>' +
39
40
  githubWorkMarkup(entry, true) +
40
41
  '<h2 class="issue-doc-title">' + esc(entry.title) + '</h2>' + prose(entry.summary, 'issue-doc-summary') + '<div class="issue-byline">' + esc(byline) + '</div>' +
41
42
  '<div class="issue-actions">' + action('data-issue-work', 'play', 'Start work', ' class="issue-primary"' + (closed ? ' disabled title="Reopen this issue to start work"' : '')) +
@@ -125,7 +125,7 @@ export function handleKnowledgeDbClick(event, panel) {
125
125
  if (event.target.closest('[data-db-create-submit]')) { submitCreate(panel); return true; }
126
126
  if (event.target.closest('[data-db-create-cancel]')) { patchState(workspaceKey(), { createDraft: null }); patchMain(workspaceKey(), { fullscreen: false }); if (renderOwner) renderOwner({ forceDocument: true }); return true; }
127
127
  var reference = event.target.closest('[data-db-reference]'); if (reference) { var referenceKey = workspaceKey(); if (reference.dataset.dbReferenceType === 'text') { if (openOwnerDocument) openOwnerDocument('local:' + reference.dataset.dbReference); } else { var databaseIdentity = identityOwner ? identityOwner({ id: reference.dataset.dbReferenceDatabase, itemType: 'db', common: false }) : 'local:' + reference.dataset.dbReferenceDatabase; if (openOwnerDocument) openOwnerDocument(databaseIdentity); openRecord(reference.dataset.dbReferenceDatabase, reference.dataset.dbReference, referenceKey); } return true; }
128
- var row = event.target.closest('[data-db-record]'); if (row) { openRecord(row.dataset.dbDatabase, row.dataset.dbRecord); return true; }
128
+ var row = event.target.closest('tr[data-db-record]'); if (row) { openRecord(row.dataset.dbDatabase, row.dataset.dbRecord); return true; }
129
129
  var edit = event.target.closest('[data-db-edit-record]'); if (edit) { beginRecordEdit(edit.dataset.dbEditRecord, false); return true; }
130
130
  var add = event.target.closest('[data-db-add-record]'); if (add) { beginRecordEdit(add.dataset.dbAddRecord, true); return true; }
131
131
  var save = event.target.closest('[data-db-save-record]'); if (save) { submitRecord(panel, save.dataset.dbSaveRecord); return true; }
@@ -155,7 +155,7 @@ export function handleKnowledgeDbClick(event, panel) {
155
155
  }
156
156
 
157
157
  export function handleKnowledgeDbKeydown(event, panel) {
158
- var keyboardRow = event.target.closest && event.target.closest('[data-db-record]'); if (keyboardRow && (event.key === 'Enter' || event.key === ' ')) { event.preventDefault(); openRecord(keyboardRow.dataset.dbDatabase, keyboardRow.dataset.dbRecord); return true; }
158
+ var keyboardRow = event.target.closest && event.target.closest('tr[data-db-record]'); if (keyboardRow && (event.key === 'Enter' || event.key === ' ')) { event.preventDefault(); openRecord(keyboardRow.dataset.dbDatabase, keyboardRow.dataset.dbRecord); return true; }
159
159
  var dialog = panel && panel.querySelector('.knowledge-db-dialog'); if (!dialog) return false;
160
160
  if (event.key === 'Escape') { event.preventDefault(); closeArchiveDialog(panel); return true; }
161
161
  if (event.key !== 'Tab') return false; var controls = dialog.querySelectorAll('button:not(:disabled)'); if (!controls.length) return false; var first = controls[0]; var last = controls[controls.length - 1];
@@ -175,10 +175,10 @@ function renderDatabaseRecovery(body, toolbar, draft) { toolbar.innerHTML = '<sp
175
175
  function renderTable(body, dbState) {
176
176
  var database = dbState.database; var view = database.views.filter(function (item) { return item.id === dbState.selectedViewId; })[0] || database.views[0] || { columns: database.schema.filter(function (field) { return !field.archived; }).map(function (field) { return field.id; }) }; var fields = view.columns.map(function (id) { return fieldById(database, id); }).filter(Boolean);
177
177
  var html = '<div class="knowledge-db-table-wrap"><table class="knowledge-db-table"><thead><tr>' + fields.map(function (field) { return '<th scope="col">' + escapeText(field.name) + '</th>'; }).join('') + '</tr></thead><tbody>';
178
- html += dbState.records.map(function (record) { return '<tr tabindex="0" data-db-record="' + escapeText(record.id) + '" data-db-database="' + escapeText(database.id) + '">' + fields.map(function (field) { return '<td>' + displayValue(field, record.values[field.id], record.references) + '</td>'; }).join('') + '</tr>'; }).join('');
178
+ html += dbState.records.map(function (record) { return '<tr data-control-runtime="' + escapeText(store.get('controlRuntimeId')) + '" data-control-revision="' + escapeText(record.revision) + '" tabindex="0" data-db-record="' + escapeText(record.id) + '" data-db-database="' + escapeText(database.id) + '">' + fields.map(function (field) { return '<td>' + displayValue(field, record.values[field.id], record.references) + '</td>'; }).join('') + '</tr>'; }).join('');
179
179
  html += '</tbody></table>' + (!dbState.records.length && !dbState.loading ? '<p class="knowledge-empty">No records in this view.</p>' : '') + (dbState.nextCursor ? '<button type="button" class="knowledge-search-more" data-db-more="' + escapeText(database.id) + '">Load more</button>' : '') + '</div>'; body.innerHTML = html;
180
180
  }
181
- function renderRecord(body, dbState) { var detail = selectedRecordState(workspaceKey(), dbState.database.id); if (!detail) { body.innerHTML = '<p class="knowledge-empty">Loading record…</p>'; return; } var history = (detail.history || []).map(function (entry) { return '<li><b>' + escapeText(entry.action || 'update') + '</b><span>Revision ' + escapeText(entry.revision) + ' · ' + new Date(entry.at).toLocaleString() + '</span></li>'; }).join(''); body.innerHTML = '<article class="knowledge-db-record"><button type="button" data-db-record-back="' + escapeText(dbState.database.id) + '">' + iconHtml('arrow-left') + 'Table</button><h2>' + escapeText(detail.title) + '</h2><dl>' + dbState.database.schema.filter(function (field) { return !field.archived; }).map(function (field) { return '<dt>' + escapeText(field.name) + '</dt><dd>' + displayValue(field, detail.record.values[field.id], detail.record.references) + '</dd>'; }).join('') + '</dl><p class="knowledge-db-attribution">Revision ' + detail.record.revision + ' · updated ' + new Date(detail.record.updatedAt).toLocaleString() + '</p>' + (history ? '<h3>Recent history</h3><ol class="knowledge-db-history">' + history + '</ol>' : '') + '</article>'; }
181
+ function renderRecord(body, dbState) { var detail = selectedRecordState(workspaceKey(), dbState.database.id); if (!detail) { body.innerHTML = '<p class="knowledge-empty">Loading record…</p>'; return; } var history = (detail.history || []).map(function (entry) { return '<li><b>' + escapeText(entry.action || 'update') + '</b><span>Revision ' + escapeText(entry.revision) + ' · ' + new Date(entry.at).toLocaleString() + '</span></li>'; }).join(''); body.innerHTML = '<article class="knowledge-db-record" data-control-runtime="' + escapeText(store.get('controlRuntimeId')) + '" data-control-revision="' + escapeText(detail.record.revision) + '" data-db-record="' + escapeText(detail.record.id) + '" data-db-database="' + escapeText(dbState.database.id) + '"><button type="button" data-db-record-back="' + escapeText(dbState.database.id) + '">' + iconHtml('arrow-left') + 'Table</button><h2>' + escapeText(detail.title) + '</h2><dl>' + dbState.database.schema.filter(function (field) { return !field.archived; }).map(function (field) { return '<dt>' + escapeText(field.name) + '</dt><dd>' + displayValue(field, detail.record.values[field.id], detail.record.references) + '</dd>'; }).join('') + '</dl><p class="knowledge-db-attribution">Revision ' + detail.record.revision + ' · updated ' + new Date(detail.record.updatedAt).toLocaleString() + '</p>' + (history ? '<h3>Recent history</h3><ol class="knowledge-db-history">' + history + '</ol>' : '') + '</article>'; }
182
182
  function renderRecordForm(body, toolbar, dbState) { var edit = dbState.edit; var values = edit.values || {}; toolbar.innerHTML = '<span class="knowledge-preview-name">' + (edit.creating ? 'New record' : 'Edit record') + '</span>' + (!edit.creating ? '<button type="button" class="danger" data-db-archive-record="' + escapeText(dbState.database.id) + '">Archive</button>' : '') + '<button type="button" data-db-cancel-edit>Cancel</button><button type="button" class="primary" data-db-save-record="' + escapeText(dbState.database.id) + '">' + (edit.saving ? 'Retry save' : 'Save') + '</button>'; body.innerHTML = '<form class="knowledge-db-form" onsubmit="return false"><h2>' + (edit.creating ? 'New record' : 'Edit record') + '</h2>' + dbState.database.schema.filter(function (field) { return !field.archived; }).map(function (field) { return '<label>' + escapeText(field.name) + fieldInput(field, values[field.id]) + '</label>'; }).join('') + (edit.error ? '<p class="knowledge-inline-error">' + escapeText(edit.error) + '</p>' : '') + '</form>'; }
183
183
  function renderSettings(body, toolbar, dbState) { var edit = dbState.edit; toolbar.innerHTML = '<span class="knowledge-preview-name">Database settings</span><button type="button" data-db-cancel-edit>Cancel</button><button type="button" class="primary" data-db-save-settings="' + escapeText(dbState.database.id) + '">' + (edit.saving ? 'Retry rename' : 'Save name') + '</button>'; body.innerHTML = '<form class="knowledge-db-form" onsubmit="return false"><h2>Database settings</h2><label>Name<input data-db-settings-name value="' + escapeText(edit.name) + '" maxlength="120"></label>' + (edit.error ? '<p class="knowledge-inline-error">' + escapeText(edit.error) + '</p>' : '') + '<section class="knowledge-danger-zone"><h3>Archive database</h3><p>Records, schema, views, and history remain recoverable.</p><button type="button" class="danger" data-db-archive-database="' + escapeText(dbState.database.id) + '">Archive database</button></section></form>'; }
184
184
  function renderRecover(body, toolbar, dbState) { var edit = dbState.edit; toolbar.innerHTML = '<span class="knowledge-preview-name">Recover record</span><button type="button" data-db-cancel-edit>Cancel</button><button type="button" class="primary" data-db-confirm-recover-record="' + escapeText(dbState.database.id) + '">' + (edit.saving ? 'Retry recovery' : 'Recover') + '</button>'; body.innerHTML = '<div class="knowledge-db-form"><h2>Recover archived record?</h2><p>This restores the exact record at revision ' + escapeText(edit.baseVersion) + '.</p>' + (edit.error ? '<p class="knowledge-inline-error">' + escapeText(edit.error) + '</p>' : '') + '</div>'; }
@@ -1,3 +1,5 @@
1
+ import { enhanceSessionCitations } from './clay-session-links.js';
2
+ import { renderBrowserLink, enhanceBrowserLinks } from './clay-browser-links.js';
1
3
  import { renderWireframeBlocks } from './wireframe-chat.js';
2
4
  import { copyToClipboard, escapeHtml } from './utils.js';
3
5
  import { refreshIcons } from './icons.js';
@@ -14,6 +16,8 @@ marked.use({ gfm: true, breaks: false });
14
16
  marked.use({
15
17
  renderer: {
16
18
  link({ href, title, tokens, text }) {
19
+ var browserLink = renderBrowserLink(href, title, text);
20
+ if (browserLink) return browserLink;
17
21
  var recordLink = renderClayRecordLink(href, text);
18
22
  if (recordLink) return recordLink;
19
23
  var localLink = renderLocalFileLink(href, title, text);
@@ -67,42 +71,10 @@ export function renderMarkdown(text) {
67
71
 
68
72
  export function enhanceClaySessionLinks(root) {
69
73
  if (!root || typeof document === "undefined") return;
70
- var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
71
- var nodes = [];
72
- var node;
73
- while ((node = walker.nextNode())) {
74
- if (!node.parentElement || node.parentElement.closest("code, pre, a, button")) continue;
75
- if (/\[clayos\/session:[A-Za-z0-9_-]{24}(?:\s+[\u2014-]\s+[^\]\n]{1,80})?\]/.test(node.nodeValue || "")) nodes.push(node);
76
- }
77
- for (var i = 0; i < nodes.length; i++) {
78
- var text = nodes[i].nodeValue || "";
79
- var pattern = /\[clayos\/(session:[A-Za-z0-9_-]{24})(?:\s+[\u2014-]\s+([^\]\n]{1,80}))?\]/g;
80
- var fragment = document.createDocumentFragment();
81
- var offset = 0;
82
- var match;
83
- while ((match = pattern.exec(text))) {
84
- fragment.appendChild(document.createTextNode(text.slice(offset, match.index)));
85
- var button = document.createElement("button");
86
- button.type = "button";
87
- button.className = "clayos-session-link";
88
- button.dataset.sessionRef = match[1];
89
- button.setAttribute("aria-label", "Open session" + (match[2] ? " from " + match[2].trim() : ""));
90
- var label = document.createElement("span");
91
- label.textContent = "Session";
92
- button.appendChild(label);
93
- if (match[2]) {
94
- var meta = document.createElement("small");
95
- meta.textContent = match[2].trim();
96
- button.appendChild(meta);
97
- }
98
- fragment.appendChild(button);
99
- offset = pattern.lastIndex;
100
- }
101
- fragment.appendChild(document.createTextNode(text.slice(offset)));
102
- nodes[i].parentNode.replaceChild(fragment, nodes[i]);
103
- }
74
+ enhanceSessionCitations(root);
104
75
  enhanceClayLogLinks(root);
105
76
  enhanceClayFileLinks(root);
77
+ enhanceBrowserLinks(root);
106
78
  }
107
79
 
108
80
  /**
@@ -0,0 +1,97 @@
1
+ // Shared appearance names; stable IDs remain internal catalog identities.
2
+ export var MATE_AVATAR_COLLECTIONS = [{"id":"B","name":"Oddballs","avatars":[{"id":"B01","name":"Indigo Cyclops"},
3
+ {"id":"B02","name":"Coral Sentinel"},
4
+ {"id":"B03","name":"Golden Visor"},
5
+ {"id":"B04","name":"Mint Wide Eyes"},
6
+ {"id":"B05","name":"Ivory Grin"},
7
+ {"id":"B06","name":"Blue Teardrop"},
8
+ {"id":"B07","name":"Peach Orbit"},
9
+ {"id":"B08","name":"Lilac Sleeper"},
10
+ {"id":"B09","name":"Coral Prism"},
11
+ {"id":"B10","name":"Mint Spring"},
12
+ {"id":"B11","name":"Golden Pebbles"},
13
+ {"id":"B12","name":"Periwinkle Orbit"},
14
+ {"id":"B13","name":"Coral Horizon"},
15
+ {"id":"B14","name":"Indigo Stack"},
16
+ {"id":"B15","name":"Mint Button Box"},
17
+ {"id":"B16","name":"Golden Curve"},
18
+ {"id":"B17","name":"Loop Listener"},
19
+ {"id":"B18","name":"Blue Twin Antenna"},
20
+ {"id":"B19","name":"Lilac Daydream"},
21
+ {"id":"B20","name":"Coral Toothsome"},
22
+ {"id":"B21","name":"Ivory Satellite"},
23
+ {"id":"B22","name":"Mint Coil"},
24
+ {"id":"B23","name":"Golden Wonder"},
25
+ {"id":"B24","name":"Slate Smile"},
26
+ {"id":"B25","name":"Lilac Shield"},
27
+ {"id":"B26","name":"Mint Diamond"},
28
+ {"id":"B27","name":"Coral Pebble"},
29
+ {"id":"B28","name":"Golden Horns"},
30
+ {"id":"B29","name":"Blue Trio"},
31
+ {"id":"B30","name":"Ivory Tower"},
32
+ {"id":"B31","name":"Charcoal Grin"},
33
+ {"id":"B32","name":"Teal Cheer"},
34
+ {"id":"B33","name":"Rose Satellite"},
35
+ {"id":"B34","name":"Blue Spool"},
36
+ {"id":"B35","name":"Golden Band"},
37
+ {"id":"B36","name":"Mint Beacon"},
38
+ {"id":"B37","name":"Charcoal Crescent"},
39
+ {"id":"B38","name":"Coral Cyclops"},
40
+ {"id":"B39","name":"Blue Scout"},
41
+ {"id":"B40","name":"Ivory Navigator"},
42
+ {"id":"B41","name":"Golden Porthole"},
43
+ {"id":"B42","name":"Lilac Windup"},
44
+ {"id":"B43","name":"Mint Receiver"},
45
+ {"id":"B44","name":"Coral Stack"},
46
+ {"id":"B45","name":"Indigo Porthole"},
47
+ {"id":"B46","name":"Stone Sprout"},
48
+ {"id":"B47","name":"Mint Sunbeam"},
49
+ {"id":"B48","name":"Golden Cubby"}]},
50
+ {"id":"C","name":"Kindred Bots","avatars":[{"id":"C01","name":"Violet Smile"},
51
+ {"id":"C02","name":"Apricot Joy"},
52
+ {"id":"C03","name":"Sage Curious"},
53
+ {"id":"C04","name":"Golden Wink"},
54
+ {"id":"C05","name":"Blue Sideglance"},
55
+ {"id":"C06","name":"Charcoal Wonder"},
56
+ {"id":"C07","name":"Lilac Specs"},
57
+ {"id":"C08","name":"Coral Giggle"},
58
+ {"id":"C09","name":"Mint Blush"},
59
+ {"id":"C10","name":"Golden Button"},
60
+ {"id":"C11","name":"Sky Smile"},
61
+ {"id":"C12","name":"Plum Joy"},
62
+ {"id":"C13","name":"Teal Diamond"},
63
+ {"id":"C14","name":"Peach Dimple"},
64
+ {"id":"C15","name":"Indigo Delight"},
65
+ {"id":"C16","name":"Sage Sprout"},
66
+ {"id":"C17","name":"Golden Specs"},
67
+ {"id":"C18","name":"Lilac Stargaze"},
68
+ {"id":"C19","name":"Blue Curiosity"},
69
+ {"id":"C20","name":"Coral Heart"},
70
+ {"id":"C21","name":"Mint Bud"},
71
+ {"id":"C22","name":"Ivory Surprise"},
72
+ {"id":"C23","name":"Rose Wink"},
73
+ {"id":"C24","name":"Sky Giggle"},
74
+ {"id":"C25","name":"Ivory Dreamer"},
75
+ {"id":"C26","name":"Mint Loop"},
76
+ {"id":"C27","name":"Violet Glasses"},
77
+ {"id":"C28","name":"Coral Sunshine"},
78
+ {"id":"C29","name":"Slate Sideglance"},
79
+ {"id":"C30","name":"Golden Dimple"},
80
+ {"id":"C31","name":"Teal Listener"},
81
+ {"id":"C32","name":"Peach Cheer"},
82
+ {"id":"C33","name":"Indigo Blush"},
83
+ {"id":"C34","name":"Sage Daydream"},
84
+ {"id":"C35","name":"Rose Wonder"},
85
+ {"id":"C36","name":"Sky Blush"},
86
+ {"id":"C37","name":"Peach Heart"},
87
+ {"id":"C38","name":"Blue Button"},
88
+ {"id":"C39","name":"Lilac Wink"},
89
+ {"id":"C40","name":"Mint Dish"},
90
+ {"id":"C41","name":"Ivory Wonder"},
91
+ {"id":"C42","name":"Violet Cheer"},
92
+ {"id":"C43","name":"Rose Specs"},
93
+ {"id":"C44","name":"Teal Delight"},
94
+ {"id":"C45","name":"Golden Diamond"},
95
+ {"id":"C46","name":"Lilac Surprise"},
96
+ {"id":"C47","name":"Sage Listener"},
97
+ {"id":"C48","name":"Coral Crown"}]}];
@@ -350,7 +350,7 @@ function renderExplorer() {
350
350
  files.forEach(function (file) {
351
351
  var parts = file.name.split('/'); var folder = parts.length > 1 ? parts.slice(0, -1).join('/') : '';
352
352
  if (!state.query.trim() && folder !== lastFolder) { var folderRow = document.createElement('div'); folderRow.className = 'knowledge-folder-row'; folderRow.innerHTML = iconHtml('folder') + '<span>' + escapeText(folder || 'Top level') + '</span>'; list.appendChild(folderRow); lastFolder = folder; }
353
- var id = documentIdentity(file); var button = document.createElement('button'); button.type = 'button'; button.className = 'knowledge-file-row'; button.dataset.openDocument = id; button.style.setProperty('--knowledge-depth', String(Math.min(parts.length - 1, 6))); if (id === state.selected) button.setAttribute('aria-current', 'true');
353
+ var id = documentIdentity(file); var button = document.createElement('button'); button.type = 'button'; button.className = 'knowledge-file-row'; button.dataset.openDocument = id; button.dataset.controlRevision = String(file.revision || ''); button.dataset.controlRuntime = store.get('controlRuntimeId') || ''; button.style.setProperty('--knowledge-depth', String(Math.min(parts.length - 1, 6))); if (id === state.selected) button.setAttribute('aria-current', 'true');
354
354
  button.innerHTML = iconHtml(file.itemType === 'db' || file.name.endsWith('.jsonl') ? 'database' : 'file-text') + '<span>' + escapeText(parts[parts.length - 1].replace(/\.(md|jsonl)$/i, '')) + (file.snippet ? '<em>' + escapeText(file.snippet) + '</em>' : '') + '</span>' + (file.common ? '<small>shared</small>' : ''); list.appendChild(button);
355
355
  });
356
356
  if (state.query.trim() && state.searchFiles.length < state.searchTotal) { var more = document.createElement('button'); more.type = 'button'; more.className = 'knowledge-search-more'; more.dataset.searchMore = ''; more.disabled = state.searching; more.textContent = state.searching ? 'Loading more…' : 'Load more results'; list.appendChild(more); }
@@ -0,0 +1,17 @@
1
+ // Decorative opening state; conversation readiness remains with its host.
2
+ export function mateLoadingMarkup() {
3
+ return '<div data-clay-loading class="mate-loading" role="status" aria-live="polite">' +
4
+ '<div class="mate-loading-scene" aria-hidden="true">' +
5
+ '<img class="mate-loading-avatar" alt="">' +
6
+ '<img class="mate-loading-desk" src="/welcome-art/conversation-desk.png" alt="" decoding="async">' +
7
+ '</div><p class="mate-loading-label"></p>' +
8
+ '<div class="mate-loading-dots" aria-hidden="true"><span></span><span></span><span></span></div></div>';
9
+ }
10
+
11
+ export function updateMateLoadingScene(element, name, avatar) {
12
+ var image = element.querySelector('.mate-loading-avatar');
13
+ if (image.getAttribute('src') !== avatar) image.setAttribute('src', avatar);
14
+ var label = element.querySelector('.mate-loading-label');
15
+ var text = 'Getting ready with ' + name;
16
+ if (label.textContent !== text) label.textContent = text;
17
+ }
@@ -1,12 +1,14 @@
1
1
  // Shared Mate profile and removal flows used by project and Home surfaces.
2
2
 
3
3
  import { getWs } from './ws-ref.js';
4
- import { showMateProfilePopover } from './profile.js';
4
+ import { store } from './store.js';
5
+ import { openHomeMateSettings } from './home-mate-settings.js';
5
6
  import { showToast } from './utils.js';
6
7
  import { showConfirm, hideConfirm } from './app-misc.js';
7
8
  import { iconHtml, refreshIcons } from './icons.js';
8
9
 
9
10
  var mateMenu = null;
11
+ var mateMenuOpener = null;
10
12
 
11
13
  function send(message) {
12
14
  var ws = getWs();
@@ -15,9 +17,13 @@ function send(message) {
15
17
 
16
18
  export function editMateProfile(anchorEl, mate) {
17
19
  if (!anchorEl || !mate || mate.primary) return;
18
- showMateProfilePopover(anchorEl, mate, function (updates) {
19
- send({ type: "mate_update", mateId: mate.id, updates: updates });
20
- });
20
+ openHomeMateSettings(mate.id, anchorEl);
21
+ }
22
+
23
+ export function changeMateAvatar(anchorEl, mate) {
24
+ var current = (store.get('cachedMatesList') || []).find(function (item) { return mate && item.id === mate.id; });
25
+ if (!anchorEl || !current || current.primary || current.builtinKey === 'clay' || (current.profile || {}).avatarLocked) return false;
26
+ return openHomeMateSettings(current.id, anchorEl, { avatar: true });
21
27
  }
22
28
 
23
29
  export function confirmMateRemoval(anchorEl, mate, onRemoved) {
@@ -76,9 +82,12 @@ export function confirmMateRemoval(anchorEl, mate, onRemoved) {
76
82
  input.focus();
77
83
  }
78
84
 
79
- export function closeMateManagementMenu() {
85
+ export function closeMateManagementMenu(restoreFocus) {
86
+ var opener = mateMenuOpener;
80
87
  if (mateMenu) mateMenu.remove();
81
- mateMenu = null;
88
+ mateMenu = null; mateMenuOpener = null;
89
+ document.removeEventListener("keydown", handleMateMenuKeydown, true);
90
+ if (restoreFocus && opener && opener.isConnected) opener.focus({ preventScroll: true });
82
91
  document.removeEventListener("click", handleMateMenuOutside, true);
83
92
  }
84
93
 
@@ -86,6 +95,18 @@ function handleMateMenuOutside(event) {
86
95
  if (mateMenu && !mateMenu.contains(event.target)) closeMateManagementMenu();
87
96
  }
88
97
 
98
+ function handleMateMenuKeydown(event) {
99
+ if (!mateMenu) return;
100
+ if (event.key === 'Escape') {
101
+ event.preventDefault(); event.stopPropagation(); closeMateManagementMenu(true); return;
102
+ }
103
+ if (event.key === 'Tab') { closeMateManagementMenu(true); return; }
104
+ var items = Array.from(mateMenu.querySelectorAll('[role="menuitem"]:not(:disabled)'));
105
+ var index = items.indexOf(document.activeElement);
106
+ var next = event.key === 'ArrowDown' ? (index + 1) % items.length : event.key === 'ArrowUp' ? (index + items.length - 1) % items.length : event.key === 'Home' ? 0 : event.key === 'End' ? items.length - 1 : -1;
107
+ if (next >= 0) { event.preventDefault(); event.stopPropagation(); items[next].focus(); }
108
+ }
109
+
89
110
  export function showMateManagementMenu(anchorEl, mate, options) {
90
111
  if (!anchorEl || !mate || mate.primary) return;
91
112
  options = options || {};
@@ -93,7 +114,16 @@ export function showMateManagementMenu(anchorEl, mate, options) {
93
114
  if (options.beforeOpen) options.beforeOpen();
94
115
  var menu = document.createElement("div");
95
116
  menu.className = "project-ctx-menu";
117
+ menu.setAttribute('role', 'menu');
118
+ menu.setAttribute('aria-label', 'Actions for ' + ((mate.profile || {}).displayName || mate.name || 'Mate'));
119
+ if (!(mate.profile || {}).avatarLocked && mate.builtinKey !== 'clay') {
120
+ var avatar = document.createElement('button'); avatar.type = 'button'; avatar.className = 'project-ctx-item'; avatar.setAttribute('role', 'menuitem');
121
+ avatar.innerHTML = iconHtml('image') + ' <span>Change avatar</span>';
122
+ avatar.addEventListener('click', function (event) { event.stopPropagation(); closeMateManagementMenu(); changeMateAvatar(anchorEl, mate); });
123
+ menu.appendChild(avatar);
124
+ }
96
125
  var edit = document.createElement("button");
126
+ edit.type = "button"; edit.setAttribute("role", "menuitem");
97
127
  edit.className = "project-ctx-item";
98
128
  edit.innerHTML = iconHtml("edit-2") + " <span>Edit Profile</span>";
99
129
  edit.addEventListener("click", function (event) {
@@ -102,6 +132,7 @@ export function showMateManagementMenu(anchorEl, mate, options) {
102
132
  editMateProfile(anchorEl, mate);
103
133
  });
104
134
  var remove = document.createElement("button");
135
+ remove.type = "button"; remove.setAttribute("role", "menuitem");
105
136
  remove.className = "project-ctx-item project-ctx-delete";
106
137
  remove.innerHTML = iconHtml(mate.builtinKey ? "minus-circle" : "trash-2")
107
138
  + " <span>" + (mate.builtinKey ? "Remove mate" : "Delete mate") + "</span>";
@@ -113,7 +144,9 @@ export function showMateManagementMenu(anchorEl, mate, options) {
113
144
  menu.appendChild(edit);
114
145
  menu.appendChild(remove);
115
146
  document.body.appendChild(menu);
116
- mateMenu = menu;
147
+ mateMenu = menu; mateMenuOpener = anchorEl;
148
+ document.addEventListener("keydown", handleMateMenuKeydown, true);
149
+ menu.querySelector("[role=menuitem]").focus();
117
150
  refreshIcons();
118
151
  requestAnimationFrame(function () {
119
152
  var rect = anchorEl.getBoundingClientRect();