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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/lib/account-auth-socket.js +1 -0
  2. package/lib/builtin-mates.js +19 -16
  3. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  4. package/lib/canonical-clay-record-authority.js +15 -0
  5. package/lib/canonical-clay-scheduling-authority.js +19 -0
  6. package/lib/claude-hook-installer.js +28 -0
  7. package/lib/clay-mate-chat-receipts.js +26 -0
  8. package/lib/clay-mate-chat.js +87 -0
  9. package/lib/clay-mate-knowledge-input.js +26 -0
  10. package/lib/clay-mate-knowledge.js +95 -0
  11. package/lib/clay-mate-lifecycle.js +95 -0
  12. package/lib/clay-product-control-input.js +33 -0
  13. package/lib/clay-product-control-tools.js +51 -0
  14. package/lib/clay-product-control.js +237 -0
  15. package/lib/clay-project-lifecycle.js +154 -0
  16. package/lib/clay-project-record-input.js +44 -0
  17. package/lib/clay-project-records.js +83 -0
  18. package/lib/clay-scheduling-input.js +21 -0
  19. package/lib/clay-scheduling-receipts.js +26 -0
  20. package/lib/clay-scheduling.js +119 -0
  21. package/lib/clay-screen-controls.js +96 -0
  22. package/lib/clay-workspace-controls.js +83 -0
  23. package/lib/clay-workspace-input.js +17 -0
  24. package/lib/clay-workspace-receipts.js +26 -0
  25. package/lib/daemon-project-access.js +11 -0
  26. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  27. package/lib/daemon-project-lifecycle.js +262 -0
  28. package/lib/daemon-projects.js +1 -1
  29. package/lib/daemon.js +73 -221
  30. package/lib/issues-service.js +29 -15
  31. package/lib/knowledge-db-import.js +5 -4
  32. package/lib/knowledge-db-service.js +9 -6
  33. package/lib/knowledge-document-index.js +2 -1
  34. package/lib/knowledge-file-store.js +7 -1
  35. package/lib/knowledge-product-operations.js +46 -0
  36. package/lib/mate-avatar-catalog.js +12 -0
  37. package/lib/mate-avatar-migration.js +41 -0
  38. package/lib/mate-creation-mcp-server.js +2 -0
  39. package/lib/mate-knowledge-canonical-access.js +10 -0
  40. package/lib/mate-knowledge-service.js +7 -4
  41. package/lib/mate-lifecycle-service.js +94 -0
  42. package/lib/mate-message-delivery.js +43 -0
  43. package/lib/mate-ready-creation.js +9 -1
  44. package/lib/mate-schedule-input.js +29 -0
  45. package/lib/mate-schedule-lifecycle.js +151 -0
  46. package/lib/mate-scheduling.js +103 -0
  47. package/lib/mates.js +18 -6
  48. package/lib/mcp-agent-tools.js +117 -0
  49. package/lib/mcp-connection-store.js +119 -15
  50. package/lib/mcp-import-credentials.js +31 -0
  51. package/lib/mcp-local-transport.js +13 -0
  52. package/lib/mcp-oauth.js +8 -6
  53. package/lib/mcp-query-bridge.js +30 -0
  54. package/lib/mcp-remote-connections.js +74 -20
  55. package/lib/mcp-source-adapters.js +91 -0
  56. package/lib/mcp-source-context.js +42 -0
  57. package/lib/mcp-source-discovery.js +169 -0
  58. package/lib/mcp-source-plugins.js +68 -0
  59. package/lib/mcp-source-restrictions.js +47 -0
  60. package/lib/mcp-tool-policy.js +34 -0
  61. package/lib/notes-checklist.js +50 -0
  62. package/lib/notes.js +49 -3
  63. package/lib/os-users.js +20 -5
  64. package/lib/project-admin-overview.js +51 -0
  65. package/lib/project-ask-user.js +8 -4
  66. package/lib/project-debate.js +1 -0
  67. package/lib/project-delegated-follow-up.js +2 -1
  68. package/lib/project-directory-claim.js +65 -0
  69. package/lib/project-file-operations.js +61 -0
  70. package/lib/project-filesystem.js +13 -87
  71. package/lib/project-full-access.js +23 -2
  72. package/lib/project-knowledge.js +32 -18
  73. package/lib/project-lifecycle-operations.js +98 -0
  74. package/lib/project-lifecycle-process-witness.js +32 -0
  75. package/lib/project-lifecycle-runtime.js +50 -0
  76. package/lib/project-linux-access.js +22 -0
  77. package/lib/project-logs-canonical-clay.js +27 -0
  78. package/lib/project-logs-clay-query.js +16 -0
  79. package/lib/project-logs-schema.js +4 -2
  80. package/lib/project-logs-service.js +8 -7
  81. package/lib/project-logs.js +1 -0
  82. package/lib/project-loop.js +1 -0
  83. package/lib/project-mate-chat-control.js +55 -0
  84. package/lib/project-mate-creation-proposal.js +18 -3
  85. package/lib/project-mate-interaction.js +8 -0
  86. package/lib/project-mcp.js +54 -16
  87. package/lib/project-models.js +14 -31
  88. package/lib/project-notifications.js +74 -16
  89. package/lib/project-ownership.js +77 -0
  90. package/lib/project-pair-result-delivery.js +14 -3
  91. package/lib/project-pending-message-queue.js +1 -0
  92. package/lib/project-product-control.js +87 -0
  93. package/lib/project-product-session-queue.js +46 -0
  94. package/lib/project-push-access.js +28 -0
  95. package/lib/project-scheduled-message-queue.js +30 -0
  96. package/lib/project-scheduled-messages.js +63 -64
  97. package/lib/project-scheduled-task-control.js +83 -0
  98. package/lib/project-scheduled-tasks.js +13 -2
  99. package/lib/project-scheduling-access.js +10 -0
  100. package/lib/project-session-actions.js +65 -0
  101. package/lib/project-session-delete.js +8 -1
  102. package/lib/project-session-document.js +8 -3
  103. package/lib/project-session-github.js +63 -19
  104. package/lib/project-session-history-actions.js +165 -0
  105. package/lib/project-session-linear.js +14 -6
  106. package/lib/project-session-notes.js +7 -3
  107. package/lib/project-session-runtime-actions.js +63 -0
  108. package/lib/project-session-vendor.js +54 -0
  109. package/lib/project-sessions.js +68 -241
  110. package/lib/project-shared-browser.js +56 -12
  111. package/lib/project-user-message.js +30 -1
  112. package/lib/project-workspace-operations.js +126 -0
  113. package/lib/project-workspace-query.js +9 -2
  114. package/lib/project.js +144 -37
  115. package/lib/public/app.js +5 -0
  116. package/lib/public/appearance-bootstrap.js +14 -0
  117. package/lib/public/css/clay-tool-activity.css +51 -0
  118. package/lib/public/css/clay-workspace.css +29 -0
  119. package/lib/public/css/home-debate-planning.css +2 -0
  120. package/lib/public/css/home-mate-creation.css +5 -0
  121. package/lib/public/css/mate-avatar-gallery.css +12 -0
  122. package/lib/public/css/mate-conversation.css +10 -5
  123. package/lib/public/css/overlays.css +4 -2
  124. package/lib/public/css/project-admin-overview.css +13 -0
  125. package/lib/public/css/session-folders.css +11 -0
  126. package/lib/public/css/session-github.css +46 -1
  127. package/lib/public/css/shared-browser.css +35 -1
  128. package/lib/public/css/sticky-notes.css +61 -1
  129. package/lib/public/index.html +11 -5
  130. package/lib/public/mate-avatars/B01.png +0 -0
  131. package/lib/public/mate-avatars/B02.png +0 -0
  132. package/lib/public/mate-avatars/B03.png +0 -0
  133. package/lib/public/mate-avatars/B04.png +0 -0
  134. package/lib/public/mate-avatars/B05.png +0 -0
  135. package/lib/public/mate-avatars/B06.png +0 -0
  136. package/lib/public/mate-avatars/B07.png +0 -0
  137. package/lib/public/mate-avatars/B08.png +0 -0
  138. package/lib/public/mate-avatars/B09.png +0 -0
  139. package/lib/public/mate-avatars/B10.png +0 -0
  140. package/lib/public/mate-avatars/B11.png +0 -0
  141. package/lib/public/mate-avatars/B12.png +0 -0
  142. package/lib/public/mate-avatars/B13.png +0 -0
  143. package/lib/public/mate-avatars/B14.png +0 -0
  144. package/lib/public/mate-avatars/B15.png +0 -0
  145. package/lib/public/mate-avatars/B16.png +0 -0
  146. package/lib/public/mate-avatars/B17.png +0 -0
  147. package/lib/public/mate-avatars/B18.png +0 -0
  148. package/lib/public/mate-avatars/B19.png +0 -0
  149. package/lib/public/mate-avatars/B20.png +0 -0
  150. package/lib/public/mate-avatars/B21.png +0 -0
  151. package/lib/public/mate-avatars/B22.png +0 -0
  152. package/lib/public/mate-avatars/B23.png +0 -0
  153. package/lib/public/mate-avatars/B24.png +0 -0
  154. package/lib/public/mate-avatars/B25.png +0 -0
  155. package/lib/public/mate-avatars/B26.png +0 -0
  156. package/lib/public/mate-avatars/B27.png +0 -0
  157. package/lib/public/mate-avatars/B28.png +0 -0
  158. package/lib/public/mate-avatars/B29.png +0 -0
  159. package/lib/public/mate-avatars/B30.png +0 -0
  160. package/lib/public/mate-avatars/B31.png +0 -0
  161. package/lib/public/mate-avatars/B32.png +0 -0
  162. package/lib/public/mate-avatars/B33.png +0 -0
  163. package/lib/public/mate-avatars/B34.png +0 -0
  164. package/lib/public/mate-avatars/B35.png +0 -0
  165. package/lib/public/mate-avatars/B36.png +0 -0
  166. package/lib/public/mate-avatars/B37.png +0 -0
  167. package/lib/public/mate-avatars/B38.png +0 -0
  168. package/lib/public/mate-avatars/B39.png +0 -0
  169. package/lib/public/mate-avatars/B40.png +0 -0
  170. package/lib/public/mate-avatars/B41.png +0 -0
  171. package/lib/public/mate-avatars/B42.png +0 -0
  172. package/lib/public/mate-avatars/B43.png +0 -0
  173. package/lib/public/mate-avatars/B44.png +0 -0
  174. package/lib/public/mate-avatars/B45.png +0 -0
  175. package/lib/public/mate-avatars/B46.png +0 -0
  176. package/lib/public/mate-avatars/B47.png +0 -0
  177. package/lib/public/mate-avatars/B48.png +0 -0
  178. package/lib/public/mate-avatars/C01.png +0 -0
  179. package/lib/public/mate-avatars/C02.png +0 -0
  180. package/lib/public/mate-avatars/C03.png +0 -0
  181. package/lib/public/mate-avatars/C04.png +0 -0
  182. package/lib/public/mate-avatars/C05.png +0 -0
  183. package/lib/public/mate-avatars/C06.png +0 -0
  184. package/lib/public/mate-avatars/C07.png +0 -0
  185. package/lib/public/mate-avatars/C08.png +0 -0
  186. package/lib/public/mate-avatars/C09.png +0 -0
  187. package/lib/public/mate-avatars/C10.png +0 -0
  188. package/lib/public/mate-avatars/C11.png +0 -0
  189. package/lib/public/mate-avatars/C12.png +0 -0
  190. package/lib/public/mate-avatars/C13.png +0 -0
  191. package/lib/public/mate-avatars/C14.png +0 -0
  192. package/lib/public/mate-avatars/C15.png +0 -0
  193. package/lib/public/mate-avatars/C16.png +0 -0
  194. package/lib/public/mate-avatars/C17.png +0 -0
  195. package/lib/public/mate-avatars/C18.png +0 -0
  196. package/lib/public/mate-avatars/C19.png +0 -0
  197. package/lib/public/mate-avatars/C20.png +0 -0
  198. package/lib/public/mate-avatars/C21.png +0 -0
  199. package/lib/public/mate-avatars/C22.png +0 -0
  200. package/lib/public/mate-avatars/C23.png +0 -0
  201. package/lib/public/mate-avatars/C24.png +0 -0
  202. package/lib/public/mate-avatars/C25.png +0 -0
  203. package/lib/public/mate-avatars/C26.png +0 -0
  204. package/lib/public/mate-avatars/C27.png +0 -0
  205. package/lib/public/mate-avatars/C28.png +0 -0
  206. package/lib/public/mate-avatars/C29.png +0 -0
  207. package/lib/public/mate-avatars/C30.png +0 -0
  208. package/lib/public/mate-avatars/C31.png +0 -0
  209. package/lib/public/mate-avatars/C32.png +0 -0
  210. package/lib/public/mate-avatars/C33.png +0 -0
  211. package/lib/public/mate-avatars/C34.png +0 -0
  212. package/lib/public/mate-avatars/C35.png +0 -0
  213. package/lib/public/mate-avatars/C36.png +0 -0
  214. package/lib/public/mate-avatars/C37.png +0 -0
  215. package/lib/public/mate-avatars/C38.png +0 -0
  216. package/lib/public/mate-avatars/C39.png +0 -0
  217. package/lib/public/mate-avatars/C40.png +0 -0
  218. package/lib/public/mate-avatars/C41.png +0 -0
  219. package/lib/public/mate-avatars/C42.png +0 -0
  220. package/lib/public/mate-avatars/C43.png +0 -0
  221. package/lib/public/mate-avatars/C44.png +0 -0
  222. package/lib/public/mate-avatars/C45.png +0 -0
  223. package/lib/public/mate-avatars/C46.png +0 -0
  224. package/lib/public/mate-avatars/C47.png +0 -0
  225. package/lib/public/mate-avatars/C48.png +0 -0
  226. package/lib/public/mate-avatars/catalog.json +482 -0
  227. package/lib/public/mate-avatars/lead-clay.png +0 -0
  228. package/lib/public/modules/admin-settings-projects.js +6 -2
  229. package/lib/public/modules/app-connection.js +8 -1
  230. package/lib/public/modules/app-message-router.js +4 -0
  231. package/lib/public/modules/app-messages.js +31 -5
  232. package/lib/public/modules/app-projects.js +5 -0
  233. package/lib/public/modules/app-rendering.js +1 -1
  234. package/lib/public/modules/avatar.js +15 -41
  235. package/lib/public/modules/chat-render-runtime.js +10 -1
  236. package/lib/public/modules/clay-browser-links.js +47 -0
  237. package/lib/public/modules/clay-log-links.js +1 -1
  238. package/lib/public/modules/clay-owner-navigation.js +27 -0
  239. package/lib/public/modules/clay-tool-activity.js +140 -0
  240. package/lib/public/modules/clay-tool-presentation.js +338 -0
  241. package/lib/public/modules/command-palette.js +2 -2
  242. package/lib/public/modules/debate.js +1 -0
  243. package/lib/public/modules/default-ai.js +11 -3
  244. package/lib/public/modules/history-replay-batch.js +5 -1
  245. package/lib/public/modules/home-debate-live.js +2 -0
  246. package/lib/public/modules/home-debate-planning.js +7 -7
  247. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  248. package/lib/public/modules/home-mate-chat.js +8 -6
  249. package/lib/public/modules/home-mate-creation.js +73 -1
  250. package/lib/public/modules/home-mate-settings.js +19 -12
  251. package/lib/public/modules/markdown.js +4 -0
  252. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  253. package/lib/public/modules/mate-management.js +40 -7
  254. package/lib/public/modules/mcp-connection-view.js +31 -13
  255. package/lib/public/modules/mcp-discovery-view.js +31 -0
  256. package/lib/public/modules/mcp-ui.js +23 -4
  257. package/lib/public/modules/mention.js +3 -0
  258. package/lib/public/modules/pane-browser-bridge.js +20 -0
  259. package/lib/public/modules/personal-settings-dialog.js +7 -1
  260. package/lib/public/modules/profile.js +1 -238
  261. package/lib/public/modules/project-access-recovery.js +17 -0
  262. package/lib/public/modules/project-admin-overview.js +21 -0
  263. package/lib/public/modules/project-mate-navigation.js +99 -14
  264. package/lib/public/modules/search-clay-chat.js +16 -2
  265. package/lib/public/modules/session-folder-layout.js +1 -1
  266. package/lib/public/modules/session-folder-view-menu.js +9 -0
  267. package/lib/public/modules/session-github.js +85 -14
  268. package/lib/public/modules/session-work-primary.js +51 -0
  269. package/lib/public/modules/shared-browser-settings.js +112 -0
  270. package/lib/public/modules/shared-browser-tabs.js +13 -3
  271. package/lib/public/modules/shared-browser.js +27 -6
  272. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  273. package/lib/public/modules/split-view.js +2 -0
  274. package/lib/public/modules/sticky-note-markdown.js +72 -6
  275. package/lib/public/modules/sticky-notes-actions.js +30 -0
  276. package/lib/public/modules/sticky-notes-browser.js +9 -2
  277. package/lib/public/modules/sticky-notes-card.js +23 -7
  278. package/lib/public/modules/sticky-notes-checklist.js +71 -0
  279. package/lib/public/modules/sticky-notes-editor.js +108 -44
  280. package/lib/public/modules/sticky-notes-shared.js +50 -2
  281. package/lib/public/modules/sticky-notes-state.js +66 -0
  282. package/lib/public/modules/sticky-notes.js +34 -51
  283. package/lib/public/modules/theme.js +8 -1
  284. package/lib/public/modules/thinking-lifecycle.js +33 -3
  285. package/lib/public/modules/thinking-view.js +23 -1
  286. package/lib/public/modules/tools.js +36 -7
  287. package/lib/public/modules/user-settings-appearance.js +10 -3
  288. package/lib/public/modules/user-settings-editors.js +1 -1
  289. package/lib/public/modules/user-settings-layout.js +11 -2
  290. package/lib/public/modules/user-settings-preferences.js +6 -2
  291. package/lib/public/modules/user-settings-profile.js +12 -2
  292. package/lib/public/modules/user-settings.js +3 -2
  293. package/lib/public/style.css +3 -0
  294. package/lib/public/sw.js +3 -1
  295. package/lib/scheduled-task-records.js +3 -1
  296. package/lib/scheduler.js +2 -0
  297. package/lib/sdk-bridge.js +228 -23
  298. package/lib/sdk-message-processor.js +2 -0
  299. package/lib/sdk-response-recovery.js +155 -0
  300. package/lib/server-admin.js +63 -16
  301. package/lib/server-appearance-settings.js +13 -1
  302. package/lib/server-dm.js +2 -1
  303. package/lib/server-global-ws.js +10 -20
  304. package/lib/server-home-chat-events.js +18 -4
  305. package/lib/server-home-chat.js +12 -16
  306. package/lib/server-home-mate-creation.js +1 -0
  307. package/lib/server-home-mcp-consent.js +14 -0
  308. package/lib/server-mates.js +25 -62
  309. package/lib/server-owner-ui.js +77 -0
  310. package/lib/server-path-access.js +38 -0
  311. package/lib/server-project-removal.js +22 -0
  312. package/lib/server-settings.js +4 -1
  313. package/lib/server.js +144 -41
  314. package/lib/session-config-transition.js +45 -0
  315. package/lib/session-folders.js +7 -2
  316. package/lib/session-github.js +9 -2
  317. package/lib/session-visibility.js +5 -2
  318. package/lib/session-work-primary.js +50 -0
  319. package/lib/sessions.js +13 -0
  320. package/lib/shared-browser-cookie-sync.js +32 -0
  321. package/lib/shared-browser-cookies.js +79 -0
  322. package/lib/shared-browser-runtime.js +25 -9
  323. package/lib/shared-browser-storage-sync.js +43 -0
  324. package/lib/shared-browser-storage.js +101 -0
  325. package/lib/shared-browser-tools.js +2 -1
  326. package/lib/shared-browser-worker.js +46 -10
  327. package/lib/terminal-manager.js +52 -0
  328. package/lib/users-permissions.js +2 -8
  329. package/lib/users.js +4 -0
  330. package/lib/workspace-query-access.js +4 -1
  331. package/lib/ws-schema.js +8 -2
  332. package/lib/yoke/acp-agent-profiles.js +2 -2
  333. package/lib/yoke/adapters/claude.js +47 -8
  334. package/lib/yoke/adapters/codex.js +52 -111
  335. package/lib/yoke/claude-worker-startup.js +28 -0
  336. package/lib/yoke/codex-idle-recovery.js +81 -1
  337. package/lib/yoke/codex-recovery-admission.js +164 -0
  338. package/lib/yoke/session-tool-transport.js +3 -0
  339. package/package.json +5 -1
@@ -1,37 +1,11 @@
1
1
  // Centralized local avatar URL builder for people and Mates.
2
- import { imprintDataUrl, mateMarkDataUrl } from './avatar-imprint.js';
3
-
4
- var mateMarkCache = new Map();
5
-
6
- // Historical DiceBear 9.x choices, now generated by Clay's local server.
7
- export var MATE_AVATAR_STYLES = [
8
- { id: 'thumbs', name: 'Thumbs' },
9
- { id: 'bottts', name: 'Bots' },
10
- { id: 'pixel-art', name: 'Pixel' },
11
- { id: 'adventurer', name: 'Adventurer' },
12
- { id: 'micah', name: 'Micah' },
13
- { id: 'fun-emoji', name: 'Emoji' },
14
- { id: 'icons', name: 'Icons' },
15
- ];
2
+ import { imprintDataUrl } from './avatar-imprint.js';
16
3
 
17
4
  export function avatarUrl(style, seed, size) {
18
5
  // Legacy user styles remain part of the seed identity, never the artwork.
19
6
  return imprintDataUrl({ style: style || 'imprint', seed: seed || 'anonymous', size: size || 64 });
20
7
  }
21
8
 
22
- export function mateStyleAvatarUrl(style, seed, size) {
23
- var normalizedStyle = style || 'imprint';
24
- var normalizedSeed = seed || 'anonymous';
25
- var normalizedSize = size || 64;
26
- var isHistorical = MATE_AVATAR_STYLES.some(function (entry) { return entry.id === normalizedStyle; });
27
- if (isHistorical) {
28
- return '/api/generated-avatar?style=' + encodeURIComponent(normalizedStyle)
29
- + '&seed=' + encodeURIComponent(normalizedSeed)
30
- + '&size=' + encodeURIComponent(normalizedSize);
31
- }
32
- return imprintDataUrl({ style: normalizedStyle, seed: normalizedSeed, size: normalizedSize });
33
- }
34
-
35
9
  // Use the same bounded account identity for fresh fallbacks across every surface.
36
10
  export function userAvatarSeed(user) {
37
11
  var profile = user && user.profile ? user.profile : user;
@@ -48,24 +22,24 @@ export function userAvatarUrl(user, size) {
48
22
  return avatarUrl(style, userAvatarSeed(user), size);
49
23
  }
50
24
 
51
- export function mateMarkUrl(seed, size) {
52
- var cacheKey = [seed || 'mate', size || 64].join('|');
53
- if (mateMarkCache.has(cacheKey)) return mateMarkCache.get(cacheKey);
54
- var url = mateMarkDataUrl({ seed: seed || 'mate', size: size || 64 });
55
- if (mateMarkCache.size >= 256) mateMarkCache.delete(mateMarkCache.keys().next().value);
56
- mateMarkCache.set(cacheKey, url);
57
- return url;
25
+ function mappedMateAvatarId(mate) {
26
+ var p = mate.profile || mate;
27
+ var key = JSON.stringify([mate.id || '', p.avatarStyle || 'imprint', p.avatarSeed || mate.id || p.displayName || mate.name || 'Mate']);
28
+ var hash = 2166136261;
29
+ for (var i = 0; i < key.length; i++) hash = Math.imul(hash ^ key.charCodeAt(i), 16777619) >>> 0;
30
+ var index = hash % 96;
31
+ return (index < 48 ? 'B' : 'C') + String(index % 48 + 1).padStart(2, '0');
32
+ }
33
+
34
+ export function mateCatalogAvatarUrl(id) {
35
+ if (id === 'lead-clay') return '/mate-avatars/lead-clay.png?v=4';
36
+ return typeof id === 'string' && /^[BC](0[1-9]|[1-3][0-9]|4[0-8])$/.test(id) ? '/mate-avatars/' + id + '.png?v=4' : '';
58
37
  }
59
38
 
60
39
  // Build avatar URL for a mate object, preferring custom avatar if set.
61
40
  export function mateAvatarUrl(mate, size) {
62
- if (!mate) return mateMarkUrl('mate', size);
41
+ if (!mate) return mateCatalogAvatarUrl('B01');
63
42
  var p = mate.profile || mate;
64
43
  if (p.avatarCustom || mate.avatarCustom) return p.avatarCustom || mate.avatarCustom;
65
- var identity = p.displayName || mate.name || mate.displayName || 'Mate';
66
- var style = p.avatarStyle || mate.avatarStyle || 'imprint';
67
- if (style !== 'imprint' && style !== 'initial') {
68
- return mateStyleAvatarUrl(style, p.avatarSeed || mate.avatarSeed || mate.id || identity, size);
69
- }
70
- return mateMarkUrl(identity, size);
44
+ return mateCatalogAvatarUrl(p.avatarCatalogId) || mateCatalogAvatarUrl(mate.builtinKey === 'clay' ? 'lead-clay' : mappedMateAvatarId(mate));
71
45
  }
@@ -155,13 +155,22 @@ export function setIsUserScrolledUp(value) { isUserScrolledUp = value; }
155
155
 
156
156
  export function addToMessages(element) {
157
157
  var messagesEl = getMessagesEl();
158
- addHistoryIndex(element, store.get('currentHistoryIndex'));
158
+ addHistoryIndex(element, store.get('currentHistoryIndexes') || store.get('currentHistoryIndex'));
159
159
  if (prependAnchor) messagesEl.insertBefore(element, prependAnchor);
160
160
  else messagesEl.appendChild(element);
161
161
  keepActiveThinkingAtTail();
162
162
  }
163
163
 
164
164
  export function addHistoryIndex(element, historyIndex) {
165
+ if (Array.isArray(historyIndex)) {
166
+ if (!element) return;
167
+ var indexes = new Set((element.dataset.historyIndexes || "").split(",").filter(Boolean));
168
+ for (var i = 0; i < historyIndex.length; i++) {
169
+ if (Number.isSafeInteger(historyIndex[i]) && historyIndex[i] >= 0) indexes.add(String(historyIndex[i]));
170
+ }
171
+ element.dataset.historyIndexes = Array.from(indexes).join(",");
172
+ return;
173
+ }
165
174
  if (!element || !Number.isSafeInteger(historyIndex) || historyIndex < 0) return;
166
175
  var existing = element.dataset.historyIndexes || "";
167
176
  if (existing.split(",").indexOf(String(historyIndex)) !== -1) return;
@@ -0,0 +1,47 @@
1
+ import { store } from './store.js';
2
+ import { iconHtml, refreshIcons } from './icons.js';
3
+ import { showToast } from './utils.js';
4
+ import { forwardPaneBrowserLink } from './pane-browser-bridge.js';
5
+
6
+ function escape(value) { return String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;'); }
7
+ export function browserLinkTarget(href) {
8
+ if (typeof href !== 'string' || !href.startsWith('browser:') || href.length > 8200) return null;
9
+ var raw = href.slice(8);
10
+ if (!/^https?:\/\//i.test(raw) || /[\u0000-\u0020]/.test(raw)) return null;
11
+ try {
12
+ var url = new URL(raw);
13
+ if (url.username || url.password || !['http:', 'https:'].includes(url.protocol)) return null;
14
+ return url.href;
15
+ } catch (error) { return null; }
16
+ }
17
+ export function renderBrowserLink(href, title, text) {
18
+ var url = browserLinkTarget(href);
19
+ if (!url) return null;
20
+ var label = String(text || '').replace(/<[^>]*>/g, '').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#39;/g, "'").trim();
21
+ if (!label || label === href || label === url) label = new URL(url).host;
22
+ return '<button type="button" class="clay-browser-link clayos-record-link" data-browser-url="' + escape(url) + '" data-browser-project="' + escape(store.get('currentSlug') || '') + '" title="' + escape('Open in Clay Browser · ' + url) + '" aria-label="' + escape('Open in Clay Browser: ' + label) + '">' + iconHtml('globe') + '<span>Browser</span><small>' + escape(label) + '</small></button>';
23
+ }
24
+ export function enhanceBrowserLinks(root) {
25
+ if (!root || typeof document === 'undefined') return;
26
+ root.querySelectorAll('a[href]').forEach(function (anchor) {
27
+ if (anchor.closest('pre, code, button')) return;
28
+ var html = renderBrowserLink(anchor.getAttribute('href'), '', anchor.textContent);
29
+ if (html) { var template = document.createElement('template'); template.innerHTML = html; anchor.replaceWith(template.content); }
30
+ });
31
+ initBrowserLinks();
32
+ refreshIcons();
33
+ }
34
+ export function initBrowserLinks() {
35
+ if (store.get('browserLinksBound')) return;
36
+ store.set({ browserLinksBound: true });
37
+ document.addEventListener('click', function (event) {
38
+ var button = event.target.closest && event.target.closest('.clay-browser-link');
39
+ if (!button) return;
40
+ event.preventDefault(); event.stopPropagation();
41
+ var url = browserLinkTarget('browser:' + button.dataset.browserUrl);
42
+ if (!url) { showToast('This browser link is invalid.', 'warn'); return; }
43
+ if (button.dataset.browserProject && button.dataset.browserProject !== store.get('currentSlug')) { showToast('Open this link from its original project.', 'warn'); return; }
44
+ if (forwardPaneBrowserLink(url)) return;
45
+ import('./shared-browser.js').then(function (module) { module.openSharedBrowserAt(url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
46
+ });
47
+ }
@@ -16,7 +16,7 @@ export function renderClaySessionLink(ref, text) {
16
16
  var parsed = parseClaySessionReference(ref);
17
17
  if (!parsed) return null;
18
18
  var label = text ? String(text).trim() : "";
19
- var safeLabel = escapeHtml(label);
19
+ var safeLabel = escapeHtml(label).replace(/"/g, "&quot;");
20
20
  var entryAttr = parsed.entryIndex === null ? "" : ' data-session-entry-index="' + parsed.entryIndex + '"';
21
21
  return '<button type="button" class="clayos-session-link clayos-record-link" data-session-ref="' + parsed.ref + '"' + entryAttr + ' aria-label="Open session' + (safeLabel ? " from " + safeLabel : "") + '"><span>Session</span>' + (safeLabel ? '<small>' + safeLabel + '</small>' : '') + '</button>';
22
22
  }
@@ -0,0 +1,27 @@
1
+ import { store } from './store.js';
2
+ import { getWs } from './ws-ref.js';
3
+ import { navigateToSession } from './command-palette.js';
4
+ function context() {
5
+ return JSON.stringify([store.get('currentSlug'), store.get('activeSessionId'), store.get('dmMode'), store.get('homeShellVisible'), store.get('homeChatMateId'), store.get('homeChatSessionId'), store.get('homeSubSurface')]);
6
+ }
7
+ export function handleOwnerNavigation(msg) {
8
+ if (msg.type !== 'clay_navigation_offer' && msg.type !== 'clay_navigation_apply') return false;
9
+ var ws = getWs();
10
+ if (!ws || ws.readyState !== 1) return true;
11
+ if (msg.type === 'clay_navigation_offer') {
12
+ if (document.hidden || store.get('paneMode')) return true;
13
+ store.set({ clayNavigationOffer: { id: msg.deliveryId, context: context(), socket: ws } });
14
+ ws.send(JSON.stringify({ type: 'clay_navigation_claim', deliveryId: msg.deliveryId }));
15
+ return true;
16
+ }
17
+ var offer = store.get('clayNavigationOffer');
18
+ store.set({ clayNavigationOffer: null });
19
+ var accepted = offer && offer.id === msg.deliveryId && offer.socket === ws && offer.context === context() && !document.hidden && !store.get('paneMode');
20
+ var status = 'refused';
21
+ if (accepted && msg.target && typeof msg.target.projectSlug === 'string' && Number.isSafeInteger(msg.target.sessionId)) {
22
+ try { navigateToSession(msg.target); status = 'accepted'; } catch (error) { status = 'failed'; }
23
+ }
24
+ // This acknowledges navigator invocation only. Rendering may finish after reconnect.
25
+ if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'clay_navigation_ack', deliveryId: msg.deliveryId, status: status }));
26
+ return true;
27
+ }
@@ -0,0 +1,140 @@
1
+ import { clayToolPresentation, clayToolOutcome } from './clay-tool-presentation.js';
2
+ import { store } from './store.js';
3
+ import { iconHtml, refreshIcons } from './icons.js';
4
+
5
+ function bindDisclosure(header, toggle) {
6
+ header.setAttribute('role', 'button');
7
+ header.tabIndex = 0;
8
+ header.addEventListener('click', toggle);
9
+ header.addEventListener('keydown', function (event) {
10
+ if (event.key !== 'Enter' && event.key !== ' ') return;
11
+ event.preventDefault();
12
+ toggle();
13
+ });
14
+ }
15
+
16
+ export function syncToolGroupDisclosure(el) {
17
+ var expanded = !el.classList.contains('collapsed');
18
+ el.querySelector('.tool-group-header').setAttribute('aria-expanded', String(expanded));
19
+ var items = el.querySelector('.tool-group-items');
20
+ items.inert = !expanded;
21
+ items.setAttribute('aria-hidden', String(!expanded));
22
+ }
23
+
24
+ export function bindToolGroupDisclosure(el, onToggle) {
25
+ // History links may expand a group directly; keep disclosure semantics in sync.
26
+ if (typeof MutationObserver !== 'undefined') {
27
+ var observer = new MutationObserver(function () { syncToolGroupDisclosure(el); });
28
+ observer.observe(el, { attributes: true, attributeFilter: ['class'] });
29
+ }
30
+ bindDisclosure(el.querySelector('.tool-group-header'), function () {
31
+ el.classList.toggle('collapsed');
32
+ onToggle();
33
+ syncToolGroupDisclosure(el);
34
+ });
35
+ }
36
+
37
+ function detailsFor(tool) {
38
+ var block = tool.el.querySelector('.clay-tool-evidence');
39
+ if (!block) {
40
+ block = document.createElement('div');
41
+ block.className = 'tool-result-block clay-tool-evidence collapsed';
42
+ tool.el.appendChild(block);
43
+ }
44
+ return block;
45
+ }
46
+ function renderEvidence(tool, block) {
47
+ block.replaceChildren();
48
+ var name = document.createElement('div');
49
+ name.className = 'clay-tool-technical-name';
50
+ name.textContent = tool.name;
51
+ block.appendChild(name);
52
+ [['Input', tool.input], ['Output', tool.clayRawResult]].forEach(function (entry) {
53
+ if (entry[1] === undefined || entry[1] === null) return;
54
+ var heading = document.createElement('div');
55
+ heading.className = 'clay-tool-evidence-label';
56
+ heading.textContent = entry[0];
57
+ var pre = document.createElement('pre');
58
+ pre.textContent = typeof entry[1] === 'string' ? entry[1] : JSON.stringify(entry[1], null, 2);
59
+ block.appendChild(heading);
60
+ block.appendChild(pre);
61
+ });
62
+ }
63
+ function statusIcon(el, selector, phase) {
64
+ var icon = el.querySelector(selector);
65
+ var name = phase === 'error' || phase === 'cancelled' ? 'alert-triangle' : phase === 'pending' ? 'clock' : phase === 'running' ? 'loader' : phase === 'returned' ? 'circle-help' : 'check';
66
+ var cls = phase === 'running' ? 'icon-spin' : phase === 'error' || phase === 'cancelled' ? 'err-icon' : 'check';
67
+ icon.innerHTML = iconHtml(name, cls);
68
+ }
69
+
70
+ export function applyClayToolItem(tool) {
71
+ if (!tool || !tool.el) return false;
72
+ var presentation = clayToolPresentation(tool.name, tool.input, tool.clayOutcome);
73
+ if (!presentation) return false;
74
+ tool.clayActivity = presentation;
75
+ var el = tool.el;
76
+ var header = el.querySelector('.tool-header');
77
+ el.classList.add('clay-tool-activity');
78
+ el.dataset.activityPhase = presentation.phase;
79
+ el.classList.toggle('error', presentation.phase === 'error' || presentation.phase === 'cancelled');
80
+ el.querySelector('.tool-name').textContent = presentation.label;
81
+ el.querySelector('.tool-desc').textContent = presentation.subject;
82
+ el.querySelector('.tool-subtitle').hidden = true;
83
+ header.setAttribute('aria-label', presentation.label + (presentation.subject ? ' · ' + presentation.subject : '') + '. Show technical details');
84
+ if (!tool.clayDisclosureBound) {
85
+ tool.clayDisclosureBound = true;
86
+ bindDisclosure(header, function () {
87
+ var expanded = el.classList.toggle('expanded');
88
+ var block = detailsFor(tool);
89
+ if (expanded) renderEvidence(tool, block);
90
+ block.classList.toggle('collapsed', !expanded);
91
+ header.setAttribute('aria-expanded', String(expanded));
92
+ });
93
+ }
94
+ header.setAttribute('aria-expanded', String(el.classList.contains('expanded')));
95
+ if (el.classList.contains('expanded')) renderEvidence(tool, detailsFor(tool));
96
+ statusIcon(el, '.tool-status-icon', presentation.phase);
97
+ refreshIcons();
98
+ return true;
99
+ }
100
+
101
+ export function finishClayToolItem(tool, group) {
102
+ if (!tool || !clayToolPresentation(tool.name, tool.input)) return false;
103
+ if (!tool.clayOutcome) {
104
+ tool.clayOutcome = { phase: 'returned', status: 'result_unavailable' };
105
+ tool.clayEndedGroup = group;
106
+ var cache = store.get('clayEndedToolRecords');
107
+ if (!cache) { cache = new WeakMap(); store.set({ clayEndedToolRecords: cache }); }
108
+ cache.set(tool.el, tool);
109
+ }
110
+ return applyClayToolItem(tool);
111
+ }
112
+
113
+ // Done clears the live registry; only rows still in this transcript can receive late results.
114
+ export function findEndedClayTool(root, id) {
115
+ var cache = store.get('clayEndedToolRecords');
116
+ if (!cache || !root) return null;
117
+ var rows = root.querySelectorAll('.clay-tool-activity[data-tool-id]');
118
+ for (var i = rows.length - 1; i >= 0; i--) {
119
+ if (rows[i].dataset.toolId === id && cache.has(rows[i])) return cache.get(rows[i]);
120
+ }
121
+ return null;
122
+ }
123
+
124
+ export function clayToolResultGroup(tool, liveGroup) {
125
+ return liveGroup && liveGroup.el.contains(tool.el) ? liveGroup : tool.clayEndedGroup;
126
+ }
127
+
128
+ export function applyClayToolResult(tool, content, isError) {
129
+ if (!clayToolPresentation(tool.name, tool.input)) return false;
130
+ tool.clayRawResult = content;
131
+ tool.clayOutcome = clayToolOutcome(content, isError);
132
+ return applyClayToolItem(tool);
133
+ }
134
+
135
+ export function syncClayToolGroup(group) {
136
+ if (!group.clayActivityPhase) { delete group.el.dataset.activityPhase; return; }
137
+ group.el.dataset.activityPhase = group.clayActivityPhase;
138
+ statusIcon(group.el, '.tool-group-status-icon', group.clayActivityPhase);
139
+ refreshIcons();
140
+ }