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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (588) hide show
  1. package/lib/account-auth-policy.js +21 -0
  2. package/lib/account-auth-socket.js +30 -0
  3. package/lib/account-auth-throttle.js +44 -0
  4. package/lib/account-auth-transport.js +48 -0
  5. package/lib/account-login-page.js +28 -0
  6. package/lib/account-passkey-challenges.js +31 -0
  7. package/lib/account-passkey-page.js +89 -0
  8. package/lib/account-passkey-policy.js +39 -0
  9. package/lib/account-password-page.js +69 -0
  10. package/lib/account-passwords.js +36 -0
  11. package/lib/account-remembered.js +77 -0
  12. package/lib/account-session-page.js +51 -0
  13. package/lib/account-session-store.js +82 -0
  14. package/lib/builtin-mates.js +19 -16
  15. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  16. package/lib/canonical-clay-record-authority.js +15 -0
  17. package/lib/canonical-clay-scheduling-authority.js +19 -0
  18. package/lib/claude-hook-installer.js +1 -239
  19. package/lib/claude-jsonl-watcher.js +1 -204
  20. package/lib/clay-control-presentation-binding.js +96 -0
  21. package/lib/clay-control-presentation.js +128 -0
  22. package/lib/clay-control-target-projection.js +26 -0
  23. package/lib/clay-mate-chat-receipts.js +26 -0
  24. package/lib/clay-mate-chat.js +88 -0
  25. package/lib/clay-mate-knowledge-input.js +26 -0
  26. package/lib/clay-mate-knowledge.js +95 -0
  27. package/lib/clay-mate-lifecycle.js +95 -0
  28. package/lib/clay-product-control-input.js +33 -0
  29. package/lib/clay-product-control-tools.js +51 -0
  30. package/lib/clay-product-control.js +247 -0
  31. package/lib/clay-project-lifecycle.js +154 -0
  32. package/lib/clay-project-record-input.js +44 -0
  33. package/lib/clay-project-records.js +84 -0
  34. package/lib/clay-scheduling-input.js +21 -0
  35. package/lib/clay-scheduling-receipts.js +26 -0
  36. package/lib/clay-scheduling.js +119 -0
  37. package/lib/clay-screen-controls.js +104 -0
  38. package/lib/clay-skill-install.js +1 -33
  39. package/lib/clay-workspace-controls.js +84 -0
  40. package/lib/clay-workspace-input.js +17 -0
  41. package/lib/clay-workspace-receipts.js +26 -0
  42. package/lib/cli-sessions.js +1 -300
  43. package/lib/codex-defaults.js +1 -28
  44. package/lib/context-usage.js +3 -2
  45. package/lib/contextual-screen-snapshot.js +38 -0
  46. package/lib/daemon-project-access.js +11 -0
  47. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  48. package/lib/daemon-project-lifecycle.js +262 -0
  49. package/lib/daemon-projects.js +1 -1
  50. package/lib/daemon.js +80 -276
  51. package/lib/default-ai-runtime.js +4 -8
  52. package/lib/dm-digest-cursor.js +120 -0
  53. package/lib/email-mcp-server.js +1 -1
  54. package/lib/issues-service.js +29 -15
  55. package/lib/kiro-defaults.js +1 -22
  56. package/lib/knowledge-db-import-validation.js +46 -0
  57. package/lib/knowledge-db-import.js +99 -0
  58. package/lib/knowledge-db-service.js +24 -33
  59. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  60. package/lib/knowledge-db-storage-nedb.js +66 -0
  61. package/lib/knowledge-db-storage.js +72 -0
  62. package/lib/knowledge-db-validation.js +0 -0
  63. package/lib/knowledge-document-index.js +2 -1
  64. package/lib/knowledge-file-store.js +7 -1
  65. package/lib/knowledge-product-operations.js +46 -0
  66. package/lib/mate-avatar-catalog.js +12 -0
  67. package/lib/mate-avatar-migration.js +41 -0
  68. package/lib/mate-context-service.js +138 -0
  69. package/lib/mate-context-tools.js +21 -0
  70. package/lib/mate-creation-mcp-server.js +2 -0
  71. package/lib/mate-knowledge-canonical-access.js +10 -0
  72. package/lib/mate-knowledge-mate-bound.js +53 -0
  73. package/lib/mate-knowledge-mcp-server.js +55 -8
  74. package/lib/mate-knowledge-service.js +16 -34
  75. package/lib/mate-knowledge-text-tools.js +106 -0
  76. package/lib/mate-lifecycle-service.js +94 -0
  77. package/lib/mate-message-delivery.js +43 -0
  78. package/lib/mate-ready-creation.js +9 -1
  79. package/lib/mate-schedule-input.js +29 -0
  80. package/lib/mate-schedule-lifecycle.js +151 -0
  81. package/lib/mate-scheduling.js +103 -0
  82. package/lib/mates.js +18 -6
  83. package/lib/mcp-agent-tools.js +117 -0
  84. package/lib/mcp-connection-store.js +119 -15
  85. package/lib/mcp-import-credentials.js +31 -0
  86. package/lib/mcp-local-transport.js +13 -0
  87. package/lib/mcp-oauth.js +8 -6
  88. package/lib/mcp-proxy.js +2 -32
  89. package/lib/mcp-query-bridge.js +30 -0
  90. package/lib/mcp-remote-connections.js +74 -20
  91. package/lib/mcp-source-adapters.js +1 -0
  92. package/lib/mcp-source-context.js +1 -0
  93. package/lib/mcp-source-discovery.js +1 -0
  94. package/lib/mcp-source-plugins.js +1 -0
  95. package/lib/mcp-source-restrictions.js +1 -0
  96. package/lib/mcp-tool-policy.js +9 -0
  97. package/lib/migrate-single-user.js +3 -23
  98. package/lib/notes-checklist.js +50 -0
  99. package/lib/notes.js +49 -3
  100. package/lib/os-user-diagnostics.js +2 -4
  101. package/lib/os-users.js +24 -70
  102. package/lib/pane-pending-interactions.js +20 -0
  103. package/lib/pane-session-activation.js +114 -0
  104. package/lib/pane-session-transport.js +26 -0
  105. package/lib/project-admin-overview.js +51 -0
  106. package/lib/project-ask-user.js +8 -4
  107. package/lib/project-connection.js +14 -10
  108. package/lib/project-control-git-view.js +12 -0
  109. package/lib/project-debate.js +1 -0
  110. package/lib/project-delegated-follow-up.js +2 -1
  111. package/lib/project-directory-claim.js +65 -0
  112. package/lib/project-file-operations.js +61 -0
  113. package/lib/project-filesystem.js +15 -85
  114. package/lib/project-full-access.js +23 -2
  115. package/lib/project-http.js +7 -4
  116. package/lib/project-knowledge.js +32 -18
  117. package/lib/project-lifecycle-operations.js +98 -0
  118. package/lib/project-lifecycle-process-witness.js +32 -0
  119. package/lib/project-lifecycle-runtime.js +50 -0
  120. package/lib/project-linux-access.js +22 -0
  121. package/lib/project-logs-canonical-clay.js +27 -0
  122. package/lib/project-logs-clay-query.js +16 -0
  123. package/lib/project-logs-schema.js +4 -2
  124. package/lib/project-logs-service.js +8 -7
  125. package/lib/project-logs.js +1 -0
  126. package/lib/project-loop.js +1 -0
  127. package/lib/project-mate-chat-control.js +55 -0
  128. package/lib/project-mate-creation-proposal.js +18 -3
  129. package/lib/project-mate-interaction.js +40 -62
  130. package/lib/project-mcp.js +54 -16
  131. package/lib/project-models.js +14 -31
  132. package/lib/project-notifications.js +76 -17
  133. package/lib/project-ownership.js +77 -0
  134. package/lib/project-pair-result-delivery.js +14 -3
  135. package/lib/project-pair-usage.js +12 -13
  136. package/lib/project-pending-message-queue.js +4 -1
  137. package/lib/project-product-control.js +89 -0
  138. package/lib/project-product-session-queue.js +46 -0
  139. package/lib/project-push-access.js +28 -0
  140. package/lib/project-scheduled-message-queue.js +30 -0
  141. package/lib/project-scheduled-messages.js +67 -68
  142. package/lib/project-scheduled-task-control.js +83 -0
  143. package/lib/project-scheduled-tasks.js +13 -2
  144. package/lib/project-scheduling-access.js +10 -0
  145. package/lib/project-server-settings.js +1 -0
  146. package/lib/project-session-actions.js +65 -0
  147. package/lib/project-session-delete.js +8 -1
  148. package/lib/project-session-document.js +27 -7
  149. package/lib/project-session-github.js +63 -19
  150. package/lib/project-session-history-actions.js +167 -0
  151. package/lib/project-session-linear.js +14 -6
  152. package/lib/project-session-notes.js +7 -3
  153. package/lib/project-session-pair.js +1 -1
  154. package/lib/project-session-runtime-actions.js +64 -0
  155. package/lib/project-session-spawn.js +2 -3
  156. package/lib/project-session-vendor.js +55 -0
  157. package/lib/project-sessions.js +103 -272
  158. package/lib/project-shared-browser.js +78 -17
  159. package/lib/project-studio-presentation.js +58 -0
  160. package/lib/project-user-knowledge.js +2 -1
  161. package/lib/project-user-message.js +67 -1
  162. package/lib/project-vendor-login.js +6 -36
  163. package/lib/project-workspace-operations.js +126 -0
  164. package/lib/project-workspace-query.js +19 -2
  165. package/lib/project.js +178 -45
  166. package/lib/public/app.js +46 -0
  167. package/lib/public/appearance-bootstrap.js +16 -0
  168. package/lib/public/auth/account-login.css +98 -0
  169. package/lib/public/auth/account-login.js +104 -0
  170. package/lib/public/css/clay-tool-activity.css +51 -0
  171. package/lib/public/css/clay-workspace.css +29 -0
  172. package/lib/public/css/command-palette.css +12 -33
  173. package/lib/public/css/contextual-clay.css +240 -0
  174. package/lib/public/css/home-debate-planning.css +2 -0
  175. package/lib/public/css/home-mate-creation.css +5 -0
  176. package/lib/public/css/input.css +6 -0
  177. package/lib/public/css/mate-avatar-gallery.css +12 -0
  178. package/lib/public/css/mate-conversation.css +10 -5
  179. package/lib/public/css/messages.css +6 -2
  180. package/lib/public/css/overlays.css +4 -2
  181. package/lib/public/css/project-admin-overview.css +13 -0
  182. package/lib/public/css/session-folders.css +11 -0
  183. package/lib/public/css/session-github.css +46 -1
  184. package/lib/public/css/shared-browser.css +35 -1
  185. package/lib/public/css/sticky-notes.css +87 -1
  186. package/lib/public/css/user-settings-sessions.css +42 -0
  187. package/lib/public/index.html +28 -10
  188. package/lib/public/mate-avatars/B01.png +0 -0
  189. package/lib/public/mate-avatars/B02.png +0 -0
  190. package/lib/public/mate-avatars/B03.png +0 -0
  191. package/lib/public/mate-avatars/B04.png +0 -0
  192. package/lib/public/mate-avatars/B05.png +0 -0
  193. package/lib/public/mate-avatars/B06.png +0 -0
  194. package/lib/public/mate-avatars/B07.png +0 -0
  195. package/lib/public/mate-avatars/B08.png +0 -0
  196. package/lib/public/mate-avatars/B09.png +0 -0
  197. package/lib/public/mate-avatars/B10.png +0 -0
  198. package/lib/public/mate-avatars/B11.png +0 -0
  199. package/lib/public/mate-avatars/B12.png +0 -0
  200. package/lib/public/mate-avatars/B13.png +0 -0
  201. package/lib/public/mate-avatars/B14.png +0 -0
  202. package/lib/public/mate-avatars/B15.png +0 -0
  203. package/lib/public/mate-avatars/B16.png +0 -0
  204. package/lib/public/mate-avatars/B17.png +0 -0
  205. package/lib/public/mate-avatars/B18.png +0 -0
  206. package/lib/public/mate-avatars/B19.png +0 -0
  207. package/lib/public/mate-avatars/B20.png +0 -0
  208. package/lib/public/mate-avatars/B21.png +0 -0
  209. package/lib/public/mate-avatars/B22.png +0 -0
  210. package/lib/public/mate-avatars/B23.png +0 -0
  211. package/lib/public/mate-avatars/B24.png +0 -0
  212. package/lib/public/mate-avatars/B25.png +0 -0
  213. package/lib/public/mate-avatars/B26.png +0 -0
  214. package/lib/public/mate-avatars/B27.png +0 -0
  215. package/lib/public/mate-avatars/B28.png +0 -0
  216. package/lib/public/mate-avatars/B29.png +0 -0
  217. package/lib/public/mate-avatars/B30.png +0 -0
  218. package/lib/public/mate-avatars/B31.png +0 -0
  219. package/lib/public/mate-avatars/B32.png +0 -0
  220. package/lib/public/mate-avatars/B33.png +0 -0
  221. package/lib/public/mate-avatars/B34.png +0 -0
  222. package/lib/public/mate-avatars/B35.png +0 -0
  223. package/lib/public/mate-avatars/B36.png +0 -0
  224. package/lib/public/mate-avatars/B37.png +0 -0
  225. package/lib/public/mate-avatars/B38.png +0 -0
  226. package/lib/public/mate-avatars/B39.png +0 -0
  227. package/lib/public/mate-avatars/B40.png +0 -0
  228. package/lib/public/mate-avatars/B41.png +0 -0
  229. package/lib/public/mate-avatars/B42.png +0 -0
  230. package/lib/public/mate-avatars/B43.png +0 -0
  231. package/lib/public/mate-avatars/B44.png +0 -0
  232. package/lib/public/mate-avatars/B45.png +0 -0
  233. package/lib/public/mate-avatars/B46.png +0 -0
  234. package/lib/public/mate-avatars/B47.png +0 -0
  235. package/lib/public/mate-avatars/B48.png +0 -0
  236. package/lib/public/mate-avatars/C01.png +0 -0
  237. package/lib/public/mate-avatars/C02.png +0 -0
  238. package/lib/public/mate-avatars/C03.png +0 -0
  239. package/lib/public/mate-avatars/C04.png +0 -0
  240. package/lib/public/mate-avatars/C05.png +0 -0
  241. package/lib/public/mate-avatars/C06.png +0 -0
  242. package/lib/public/mate-avatars/C07.png +0 -0
  243. package/lib/public/mate-avatars/C08.png +0 -0
  244. package/lib/public/mate-avatars/C09.png +0 -0
  245. package/lib/public/mate-avatars/C10.png +0 -0
  246. package/lib/public/mate-avatars/C11.png +0 -0
  247. package/lib/public/mate-avatars/C12.png +0 -0
  248. package/lib/public/mate-avatars/C13.png +0 -0
  249. package/lib/public/mate-avatars/C14.png +0 -0
  250. package/lib/public/mate-avatars/C15.png +0 -0
  251. package/lib/public/mate-avatars/C16.png +0 -0
  252. package/lib/public/mate-avatars/C17.png +0 -0
  253. package/lib/public/mate-avatars/C18.png +0 -0
  254. package/lib/public/mate-avatars/C19.png +0 -0
  255. package/lib/public/mate-avatars/C20.png +0 -0
  256. package/lib/public/mate-avatars/C21.png +0 -0
  257. package/lib/public/mate-avatars/C22.png +0 -0
  258. package/lib/public/mate-avatars/C23.png +0 -0
  259. package/lib/public/mate-avatars/C24.png +0 -0
  260. package/lib/public/mate-avatars/C25.png +0 -0
  261. package/lib/public/mate-avatars/C26.png +0 -0
  262. package/lib/public/mate-avatars/C27.png +0 -0
  263. package/lib/public/mate-avatars/C28.png +0 -0
  264. package/lib/public/mate-avatars/C29.png +0 -0
  265. package/lib/public/mate-avatars/C30.png +0 -0
  266. package/lib/public/mate-avatars/C31.png +0 -0
  267. package/lib/public/mate-avatars/C32.png +0 -0
  268. package/lib/public/mate-avatars/C33.png +0 -0
  269. package/lib/public/mate-avatars/C34.png +0 -0
  270. package/lib/public/mate-avatars/C35.png +0 -0
  271. package/lib/public/mate-avatars/C36.png +0 -0
  272. package/lib/public/mate-avatars/C37.png +0 -0
  273. package/lib/public/mate-avatars/C38.png +0 -0
  274. package/lib/public/mate-avatars/C39.png +0 -0
  275. package/lib/public/mate-avatars/C40.png +0 -0
  276. package/lib/public/mate-avatars/C41.png +0 -0
  277. package/lib/public/mate-avatars/C42.png +0 -0
  278. package/lib/public/mate-avatars/C43.png +0 -0
  279. package/lib/public/mate-avatars/C44.png +0 -0
  280. package/lib/public/mate-avatars/C45.png +0 -0
  281. package/lib/public/mate-avatars/C46.png +0 -0
  282. package/lib/public/mate-avatars/C47.png +0 -0
  283. package/lib/public/mate-avatars/C48.png +0 -0
  284. package/lib/public/mate-avatars/catalog.json +482 -0
  285. package/lib/public/mate-avatars/lead-clay.png +0 -0
  286. package/lib/public/modules/account-auth-settings.js +71 -0
  287. package/lib/public/modules/account-transport-settings.js +51 -0
  288. package/lib/public/modules/admin-settings-projects.js +6 -2
  289. package/lib/public/modules/app-connection.js +11 -1
  290. package/lib/public/modules/app-favicon.js +18 -9
  291. package/lib/public/modules/app-header.js +7 -4
  292. package/lib/public/modules/app-loop-ui.js +2 -0
  293. package/lib/public/modules/app-message-router.js +22 -1
  294. package/lib/public/modules/app-messages.js +119 -17
  295. package/lib/public/modules/app-misc.js +3 -1
  296. package/lib/public/modules/app-notifications.js +11 -5
  297. package/lib/public/modules/app-panels.js +61 -123
  298. package/lib/public/modules/app-projects.js +13 -0
  299. package/lib/public/modules/app-rate-limit.js +7 -27
  300. package/lib/public/modules/app-rendering.js +4 -3
  301. package/lib/public/modules/avatar.js +15 -41
  302. package/lib/public/modules/chat-render-runtime.js +20 -0
  303. package/lib/public/modules/clay-browser-links.js +47 -0
  304. package/lib/public/modules/clay-control-activity.js +214 -0
  305. package/lib/public/modules/clay-control-copy.js +36 -0
  306. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  307. package/lib/public/modules/clay-control-object-targets.js +52 -0
  308. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  309. package/lib/public/modules/clay-control-targets.js +44 -0
  310. package/lib/public/modules/clay-log-links.js +23 -0
  311. package/lib/public/modules/clay-navigation-render.js +52 -0
  312. package/lib/public/modules/clay-owner-navigation.js +33 -0
  313. package/lib/public/modules/clay-session-links.js +31 -0
  314. package/lib/public/modules/clay-studio-bridge.js +20 -0
  315. package/lib/public/modules/clay-studio-document.js +67 -0
  316. package/lib/public/modules/clay-studio-render.js +146 -0
  317. package/lib/public/modules/clay-tool-activity.js +140 -0
  318. package/lib/public/modules/clay-tool-presentation.js +342 -0
  319. package/lib/public/modules/command-palette.js +162 -40
  320. package/lib/public/modules/contextual-ask-session.js +26 -0
  321. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  322. package/lib/public/modules/contextual-clay-session.js +130 -0
  323. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  324. package/lib/public/modules/contextual-clay.js +250 -0
  325. package/lib/public/modules/contextual-composer.js +91 -0
  326. package/lib/public/modules/contextual-mate-context.js +117 -0
  327. package/lib/public/modules/contextual-mate-hint.js +40 -0
  328. package/lib/public/modules/contextual-mate-identity.js +23 -0
  329. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  330. package/lib/public/modules/contextual-search.js +137 -0
  331. package/lib/public/modules/contextual-session-citations.js +58 -0
  332. package/lib/public/modules/debate.js +1 -0
  333. package/lib/public/modules/default-ai.js +11 -3
  334. package/lib/public/modules/elicitation-form.js +5 -0
  335. package/lib/public/modules/filebrowser.js +20 -1
  336. package/lib/public/modules/generation-stop.js +8 -5
  337. package/lib/public/modules/git-panel.js +3 -1
  338. package/lib/public/modules/history-replay-batch.js +13 -1
  339. package/lib/public/modules/home-debate-live.js +2 -0
  340. package/lib/public/modules/home-debate-planning.js +7 -7
  341. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  342. package/lib/public/modules/home-mate-chat.js +8 -6
  343. package/lib/public/modules/home-mate-creation.js +73 -1
  344. package/lib/public/modules/home-mate-settings.js +19 -12
  345. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  346. package/lib/public/modules/input.js +88 -10
  347. package/lib/public/modules/issues-render.js +3 -2
  348. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  349. package/lib/public/modules/markdown.js +6 -34
  350. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  351. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  352. package/lib/public/modules/mate-management.js +40 -7
  353. package/lib/public/modules/mcp-connection-view.js +31 -13
  354. package/lib/public/modules/mcp-discovery-view.js +31 -0
  355. package/lib/public/modules/mcp-ui.js +23 -4
  356. package/lib/public/modules/mention.js +3 -0
  357. package/lib/public/modules/message-delivery.js +20 -2
  358. package/lib/public/modules/model-picker.js +2 -0
  359. package/lib/public/modules/pane-activation.js +214 -0
  360. package/lib/public/modules/pane-binding.js +82 -0
  361. package/lib/public/modules/pane-bridge.js +7 -4
  362. package/lib/public/modules/pane-browser-bridge.js +22 -0
  363. package/lib/public/modules/pane-file-bridge.js +4 -0
  364. package/lib/public/modules/pane-issue-bridge.js +4 -1
  365. package/lib/public/modules/passkey-browser.js +69 -0
  366. package/lib/public/modules/passkey-server-settings.js +57 -0
  367. package/lib/public/modules/pending-message-queue.js +1 -0
  368. package/lib/public/modules/permission-control.js +5 -4
  369. package/lib/public/modules/personal-settings-dialog.js +7 -1
  370. package/lib/public/modules/product-review.js +26 -0
  371. package/lib/public/modules/profile.js +1 -238
  372. package/lib/public/modules/project-access-recovery.js +17 -0
  373. package/lib/public/modules/project-admin-overview.js +21 -0
  374. package/lib/public/modules/project-chat-identity.js +13 -4
  375. package/lib/public/modules/project-logs-render.js +6 -2
  376. package/lib/public/modules/project-mate-navigation.js +144 -22
  377. package/lib/public/modules/rewind.js +5 -0
  378. package/lib/public/modules/scheduled-tasks.js +2 -0
  379. package/lib/public/modules/scheduler.js +2 -0
  380. package/lib/public/modules/search-clay-chat.js +5 -440
  381. package/lib/public/modules/server-settings-controls.js +10 -0
  382. package/lib/public/modules/server-settings.js +7 -2
  383. package/lib/public/modules/session-actions.js +5 -2
  384. package/lib/public/modules/session-context-menu.js +5 -0
  385. package/lib/public/modules/session-create-form.js +10 -10
  386. package/lib/public/modules/session-folder-layout.js +1 -1
  387. package/lib/public/modules/session-folder-view-menu.js +9 -0
  388. package/lib/public/modules/session-github.js +85 -14
  389. package/lib/public/modules/session-rich-drafts.js +21 -0
  390. package/lib/public/modules/session-switch-defer.js +67 -0
  391. package/lib/public/modules/session-work-primary.js +51 -0
  392. package/lib/public/modules/settings-defaults.js +27 -28
  393. package/lib/public/modules/shared-browser-settings.js +112 -0
  394. package/lib/public/modules/shared-browser-tabs.js +13 -3
  395. package/lib/public/modules/shared-browser.js +29 -6
  396. package/lib/public/modules/sidebar-mobile.js +4 -3
  397. package/lib/public/modules/sidebar-projects.js +1 -0
  398. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  399. package/lib/public/modules/sidebar-sessions.js +1 -0
  400. package/lib/public/modules/split-group-restore.js +68 -0
  401. package/lib/public/modules/split-pair-ui.js +1 -0
  402. package/lib/public/modules/split-pane-reconciler.js +15 -0
  403. package/lib/public/modules/split-pane-renderer.js +87 -6
  404. package/lib/public/modules/split-session-boundary.js +1 -1
  405. package/lib/public/modules/split-view.js +60 -68
  406. package/lib/public/modules/sticky-note-markdown.js +72 -6
  407. package/lib/public/modules/sticky-notes-actions.js +30 -0
  408. package/lib/public/modules/sticky-notes-browser.js +9 -2
  409. package/lib/public/modules/sticky-notes-card.js +23 -7
  410. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  411. package/lib/public/modules/sticky-notes-editor.js +108 -44
  412. package/lib/public/modules/sticky-notes-shared.js +50 -2
  413. package/lib/public/modules/sticky-notes-state.js +66 -0
  414. package/lib/public/modules/sticky-notes.js +34 -51
  415. package/lib/public/modules/stt-controller.js +4 -1
  416. package/lib/public/modules/stt-recording.js +1 -1
  417. package/lib/public/modules/stt.js +7 -2
  418. package/lib/public/modules/terminal.js +9 -0
  419. package/lib/public/modules/theme.js +8 -1
  420. package/lib/public/modules/thinking-lifecycle.js +33 -3
  421. package/lib/public/modules/thinking-view.js +23 -1
  422. package/lib/public/modules/tools.js +60 -11
  423. package/lib/public/modules/tui-grab.js +1 -2
  424. package/lib/public/modules/user-settings-account.js +14 -1
  425. package/lib/public/modules/user-settings-appearance.js +10 -3
  426. package/lib/public/modules/user-settings-editors.js +1 -1
  427. package/lib/public/modules/user-settings-layout.js +11 -2
  428. package/lib/public/modules/user-settings-preferences.js +6 -2
  429. package/lib/public/modules/user-settings-profile.js +12 -2
  430. package/lib/public/modules/user-settings-sessions.js +120 -0
  431. package/lib/public/modules/user-settings.js +6 -2
  432. package/lib/public/modules/vendor-login-browser.js +5 -3
  433. package/lib/public/modules/vendor-login.js +2 -2
  434. package/lib/public/modules/vendor-priority.js +15 -1
  435. package/lib/public/modules/wireframe-workbench.js +5 -2
  436. package/lib/public/modules/you-activity.js +3 -1
  437. package/lib/public/modules/you.js +91 -6
  438. package/lib/public/muse-avatar.svg +4 -0
  439. package/lib/public/style.css +6 -0
  440. package/lib/public/sw.js +3 -1
  441. package/lib/safe-bash-commands.js +3 -45
  442. package/lib/scheduled-task-records.js +3 -1
  443. package/lib/scheduler.js +2 -0
  444. package/lib/sdk-bridge.js +342 -401
  445. package/lib/sdk-foreground-admission.js +16 -0
  446. package/lib/sdk-mcp-descriptors.js +2 -37
  447. package/lib/sdk-message-processor.js +52 -17
  448. package/lib/sdk-quota-snapshot.js +1 -1
  449. package/lib/sdk-response-recovery.js +1 -0
  450. package/lib/sdk-worker.js +2 -677
  451. package/lib/server-account-passkeys.js +186 -0
  452. package/lib/server-account-passwords.js +127 -0
  453. package/lib/server-account-security.js +53 -0
  454. package/lib/server-admin.js +63 -16
  455. package/lib/server-appearance-settings.js +13 -1
  456. package/lib/server-auth.js +107 -79
  457. package/lib/server-contextual-clay-settings.js +40 -0
  458. package/lib/server-contextual-mate-sessions.js +70 -0
  459. package/lib/server-dm.js +2 -1
  460. package/lib/server-global-ws.js +10 -20
  461. package/lib/server-home-chat-events.js +18 -4
  462. package/lib/server-home-chat.js +22 -20
  463. package/lib/server-home-clay-entry.js +23 -4
  464. package/lib/server-home-clay-session-links.js +29 -9
  465. package/lib/server-home-mate-creation.js +1 -0
  466. package/lib/server-home-mcp-consent.js +14 -0
  467. package/lib/server-mates.js +25 -62
  468. package/lib/server-owner-ui.js +118 -0
  469. package/lib/server-path-access.js +38 -0
  470. package/lib/server-project-removal.js +22 -0
  471. package/lib/server-settings.js +8 -2
  472. package/lib/server.js +165 -43
  473. package/lib/session-config-transition.js +45 -0
  474. package/lib/session-folders.js +7 -2
  475. package/lib/session-fork-history.js +21 -0
  476. package/lib/session-github.js +9 -2
  477. package/lib/session-hygiene.js +3 -35
  478. package/lib/session-permission-mode.js +4 -3
  479. package/lib/session-skill-scope.js +11 -0
  480. package/lib/session-visibility.js +5 -2
  481. package/lib/session-work-primary.js +50 -0
  482. package/lib/sessions.js +64 -99
  483. package/lib/shared-browser-cookie-sync.js +32 -0
  484. package/lib/shared-browser-cookies.js +79 -0
  485. package/lib/shared-browser-runtime.js +25 -9
  486. package/lib/shared-browser-storage-sync.js +43 -0
  487. package/lib/shared-browser-storage.js +101 -0
  488. package/lib/shared-browser-tools.js +2 -1
  489. package/lib/shared-browser-worker.js +46 -10
  490. package/lib/terminal-manager.js +65 -6
  491. package/lib/tool-llm.js +1 -1
  492. package/lib/tui-transcript-index.js +1 -132
  493. package/lib/user-knowledge-service.js +23 -1
  494. package/lib/users-auth.js +38 -3
  495. package/lib/users-contextual-clay-preferences.js +31 -0
  496. package/lib/users-create.js +97 -0
  497. package/lib/users-permissions.js +2 -8
  498. package/lib/users-server-pin.js +37 -0
  499. package/lib/users.js +18 -84
  500. package/lib/vendor-login-browser.js +1 -11
  501. package/lib/workspace-assignment-service.js +25 -0
  502. package/lib/workspace-query-access.js +4 -1
  503. package/lib/workspace-query-mcp-server.js +1 -1
  504. package/lib/workspace-query-service.js +13 -2
  505. package/lib/ws-request.js +1 -0
  506. package/lib/ws-schema.js +18 -2
  507. package/lib/yoke/acp-agent-profiles.js +7 -5
  508. package/lib/yoke/adapters/antigravity.js +3 -14
  509. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  510. package/lib/yoke/adapters/claude.js +54 -50
  511. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  512. package/lib/yoke/adapters/codex.js +53 -111
  513. package/lib/yoke/adapters/kiro.js +3 -1
  514. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  515. package/lib/yoke/adapters/muse.js +122 -0
  516. package/lib/yoke/auth-events.js +17 -0
  517. package/lib/yoke/claude-hook-installer.js +271 -0
  518. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  519. package/lib/yoke/claude-maintenance.js +55 -0
  520. package/lib/yoke/claude-permission-patterns.js +53 -0
  521. package/lib/yoke/claude-response-recovery.js +155 -0
  522. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  523. package/lib/yoke/claude-worker-startup.js +28 -0
  524. package/lib/yoke/clay-skill-install.js +33 -0
  525. package/lib/yoke/cli-sessions.js +300 -0
  526. package/lib/yoke/codex-app-server.js +7 -12
  527. package/lib/yoke/codex-idle-recovery.js +81 -1
  528. package/lib/yoke/codex-recovery-admission.js +164 -0
  529. package/lib/yoke/configuration.js +13 -0
  530. package/lib/yoke/discovery.js +70 -0
  531. package/lib/yoke/errors.js +8 -0
  532. package/lib/yoke/host-environment.js +7 -0
  533. package/lib/yoke/index.js +9 -51
  534. package/lib/yoke/interface.js +116 -0
  535. package/lib/yoke/kiro-acp-server.js +5 -5
  536. package/lib/yoke/legacy-sessions.js +89 -0
  537. package/lib/yoke/login-protocol.js +25 -0
  538. package/lib/yoke/maintenance.js +12 -0
  539. package/lib/yoke/mcp-proxy.js +32 -0
  540. package/lib/yoke/mcp-source-adapters.js +91 -0
  541. package/lib/yoke/mcp-source-context.js +42 -0
  542. package/lib/yoke/mcp-source-discovery.js +169 -0
  543. package/lib/yoke/mcp-source-plugins.js +68 -0
  544. package/lib/yoke/mcp-source-restrictions.js +47 -0
  545. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  546. package/lib/yoke/model-preferences.js +6 -0
  547. package/lib/yoke/muse-artifacts.js +36 -0
  548. package/lib/yoke/muse-controls.js +50 -0
  549. package/lib/yoke/muse-input.js +64 -0
  550. package/lib/yoke/muse-items.js +157 -0
  551. package/lib/yoke/muse-policy.js +52 -0
  552. package/lib/yoke/muse-query.js +428 -0
  553. package/lib/yoke/muse-runtime.js +211 -0
  554. package/lib/yoke/muse-services.js +79 -0
  555. package/lib/yoke/muse-skills.js +79 -0
  556. package/lib/yoke/muse-turns.js +71 -0
  557. package/lib/yoke/options/acp.js +2 -0
  558. package/lib/yoke/options/antigravity.js +2 -0
  559. package/lib/yoke/options/claude.js +21 -0
  560. package/lib/yoke/options/codex-defaults.js +29 -0
  561. package/lib/yoke/options/codex-settings.js +21 -0
  562. package/lib/yoke/options/codex.js +6 -0
  563. package/lib/yoke/options/kiro-defaults.js +22 -0
  564. package/lib/yoke/options/kiro.js +5 -0
  565. package/lib/yoke/options/muse.js +5 -0
  566. package/lib/yoke/provider-contract.js +5 -0
  567. package/lib/yoke/providers/antigravity-executable.js +8 -0
  568. package/lib/yoke/providers/claude-executable.js +40 -0
  569. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  570. package/lib/yoke/providers/claude-process.js +97 -0
  571. package/lib/yoke/providers/claude-provision.js +75 -0
  572. package/lib/yoke/providers/codex-errors.js +8 -0
  573. package/lib/yoke/providers/muse-executable.js +17 -0
  574. package/lib/yoke/provisioning.js +6 -0
  575. package/lib/yoke/query-options.js +10 -0
  576. package/lib/yoke/response-recovery.js +41 -0
  577. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  578. package/lib/yoke/sdk-server-factory.js +7 -0
  579. package/lib/yoke/session-history.js +8 -0
  580. package/lib/yoke/session-tool-transport.js +34 -13
  581. package/lib/yoke/settings.js +23 -0
  582. package/lib/yoke/source-locations.js +4 -0
  583. package/lib/yoke/title-query.js +18 -7
  584. package/lib/yoke/tui-transcript-index.js +132 -0
  585. package/lib/yoke/usage.js +48 -0
  586. package/lib/yoke/user-input.js +13 -0
  587. package/lib/yoke/vendor-registry.js +81 -1
  588. package/package.json +11 -4
@@ -1,10 +1,13 @@
1
+ import { forwardContextualSessionCitation, validContextualCitation, contextualCitationLink } from './contextual-session-citations.js';
1
2
  import { mateAvatarUrl } from './avatar.js';
2
3
  import { escapeHtml } from './utils.js';
3
4
  import { refreshIcons } from './icons.js';
4
5
  import { openSearch as openSessionSearch } from './session-search.js';
5
- import { startSearchClayChat, attachSearchClayChat, detachSearchClayChat, getSearchClayChatSummary } from './search-clay-chat.js';
6
+ import { startSearchClayChat, retrySearchClayAsk } from './search-clay-chat.js';
6
7
  import { getWs } from './ws-ref.js';
7
8
  import { openProjectLog } from './project-logs.js';
9
+ import { store } from './store.js';
10
+ import { disarmStickyBottom } from './chat-render-runtime.js';
8
11
 
9
12
  function formatRelativeDate(ts) {
10
13
  if (!ts) return "";
@@ -27,7 +30,7 @@ var paletteEl = null, inputEl = null, resultsEl = null, footerEl = null;
27
30
  var activeIndex = -1, items = [], debounceTimer = null, abortCtrl = null;
28
31
  var pendingNav = null, cachedHomeData = [], cachedVersion = null;
29
32
  var pendingLogNav = null;
30
- var searchResults = [], searchQuery = "", searchPending = false, chatMode = false;
33
+ var searchResults = [], searchQuery = "", searchPending = false;
31
34
 
32
35
  export function initCommandPalette(value) {
33
36
  ctx = value;
@@ -60,6 +63,10 @@ function handleClaySessionLinkClick(event) {
60
63
  openProjectLog(link.dataset.logRef);
61
64
  return;
62
65
  }
66
+ if (link.classList.contains('clayos-session-link') && forwardContextualSessionCitation(link)) return;
67
+ requestClayRecordLink(link);
68
+ }
69
+ export function requestClayRecordLink(link, citation) {
63
70
  var ws = getWs();
64
71
  if (!ws || ws.readyState !== 1) {
65
72
  link.classList.add("is-error");
@@ -70,6 +77,10 @@ function handleClaySessionLinkClick(event) {
70
77
  var requestId = "clayos-" + (isLog ? "log-" : "session-") + Date.now() + "-" + Math.random().toString(36).slice(2, 9);
71
78
  if (isLog) link.dataset.logRequest = requestId;
72
79
  else link.dataset.sessionRequest = requestId;
80
+ if (!isLog) store.set({ sessionNavigationRequestId: requestId, sessionNavigationRequestContext: {
81
+ projectSlug: store.get('currentSlug'),
82
+ sessionId: store.get('activeSessionId'), citation: citation || null
83
+ } });
73
84
  link.classList.remove("is-error");
74
85
  link.classList.add("is-loading");
75
86
  var request = { requestId: requestId, surface: link.closest(".search-clay-chat") ? "search" : "home" };
@@ -79,24 +90,50 @@ function handleClaySessionLinkClick(event) {
79
90
  } else {
80
91
  request.type = "home_clay_session_resolve";
81
92
  request.sessionRef = link.dataset.sessionRef;
93
+ if (citation) request.contextualSource = { mateId: citation.mateId, sessionId: citation.sessionId, sessionOriginId: citation.originId, mateStamp: citation.stamp };
94
+ if (link.dataset.sessionEntryIndex !== undefined) request.entryIndex = Number(link.dataset.sessionEntryIndex);
82
95
  }
83
96
  ws.send(JSON.stringify(request));
97
+ return true;
84
98
  }
85
99
 
86
100
  export function handleClaySessionTarget(msg) {
87
101
  if (!msg || (msg.type !== "home_clay_session_target" && msg.type !== "home_clay_log_target")) return false;
88
102
  var isLog = msg.type === "home_clay_log_target";
89
103
  var links = document.querySelectorAll(isLog ? ".clayos-log-link[data-log-request]" : ".clayos-session-link[data-session-request]");
90
- var link = null;
104
+ var sourceContext = store.get('sessionNavigationRequestContext');
105
+ var citation = !isLog && sourceContext && sourceContext.citation;
106
+ var link = !isLog ? contextualCitationLink(citation, msg.requestId) : null;
91
107
  for (var i = 0; i < links.length; i++) {
92
108
  if ((isLog ? links[i].dataset.logRequest : links[i].dataset.sessionRequest) === msg.requestId) link = links[i];
93
109
  }
110
+ if (!isLog && link && link.ownerDocument !== document && !citation) { link.classList.remove('is-loading'); link.classList.add('is-error'); link.title = 'The view changed. Click again from the current conversation.'; delete link.dataset.sessionRequest; return true; }
111
+ if (!isLog && store.get('sessionNavigationRequestId') !== msg.requestId) {
112
+ if (link) {
113
+ link.classList.remove("is-loading");
114
+ delete link.dataset.sessionRequest;
115
+ }
116
+ return true;
117
+ }
118
+ if (!isLog) {
119
+ var requestContext = store.get('sessionNavigationRequestContext');
120
+ if (citation && (!validContextualCitation(citation) || msg.sessionRef !== citation.ref)) { if (link) { link.classList.remove('is-loading'); link.classList.add('is-error'); link.title = 'The view changed. Click again from the current conversation.'; delete link.dataset.sessionRequest; } store.set({ pendingSessionEntryNavigation: null, sessionNavigationRequestContext: null }); return true; }
121
+ if (requestContext && (String(store.get('currentSlug')) !== String(requestContext.projectSlug) || String(store.get('activeSessionId')) !== String(requestContext.sessionId))) {
122
+ if (link) {
123
+ link.classList.remove("is-loading");
124
+ delete link.dataset.sessionRequest;
125
+ }
126
+ store.set({ pendingSessionEntryNavigation: null, sessionNavigationRequestContext: null });
127
+ return true;
128
+ }
129
+ }
94
130
  if (link) {
95
131
  link.classList.remove("is-loading");
96
132
  if (isLog) delete link.dataset.logRequest;
97
133
  else delete link.dataset.sessionRequest;
98
134
  }
99
135
  if (msg.status !== "ready" || !msg.target) {
136
+ if (!isLog) store.set({ pendingSessionEntryNavigation: null });
100
137
  if (link) {
101
138
  link.classList.add("is-error");
102
139
  link.title = msg.error || "Item not available";
@@ -108,7 +145,7 @@ export function handleClaySessionTarget(msg) {
108
145
  navigateToLog(msg.target);
109
146
  return true;
110
147
  }
111
- navigateToSession({ projectSlug: msg.target.projectSlug, sessionId: msg.target.sessionId }, null);
148
+ navigateToSession({ projectSlug: msg.target.projectSlug, sessionId: msg.target.sessionId }, null, msg.target.entryIndex);
112
149
  return true;
113
150
  }
114
151
 
@@ -120,11 +157,6 @@ export function openCommandPalette() {
120
157
  var trigger = document.getElementById("cmd-palette-btn");
121
158
  if (trigger) trigger.style.visibility = "hidden";
122
159
  updateFooter();
123
- if (attachSearchClayChat(resultsEl, showSearch, closeCommandPalette)) {
124
- chatMode = true;
125
- paletteEl.classList.add("is-chatting");
126
- return;
127
- }
128
160
  showSearch();
129
161
  fetchHomeData();
130
162
  }
@@ -136,24 +168,114 @@ export function closeCommandPalette() {
136
168
  if (trigger) trigger.style.visibility = "";
137
169
  if (debounceTimer) { clearTimeout(debounceTimer); debounceTimer = null; }
138
170
  if (abortCtrl) { abortCtrl.abort(); abortCtrl = null; }
139
- detachSearchClayChat();
140
171
  }
141
172
 
142
173
  export function setPaletteVersion(version) { cachedVersion = version; }
143
174
 
144
- export function handlePaletteSessionSwitch() {
175
+ export function handlePaletteSessionSwitch(authoritative) {
145
176
  if (pendingLogNav && ctx.currentSlug && ctx.currentSlug() === pendingLogNav.projectSlug) {
146
177
  var logNav = pendingLogNav;
147
178
  pendingLogNav = null;
148
179
  openProjectLog(logNav.ref);
149
180
  }
150
- if (!pendingNav) return;
151
- var nav = pendingNav;
152
- pendingNav = null;
153
- if (ctx.currentSlug && ctx.currentSlug() === nav.slug) {
154
- ctx.selectSession(nav.sessionId);
155
- if (nav.query) setTimeout(function () { openSessionSearch(nav.query); }, 400);
181
+ // session_list precedes the connection's authoritative session_switched.
182
+ // Wait for that identity instead of requesting a duplicate initial replay.
183
+ if (authoritative === true && pendingNav && store.get('activeSessionId')) {
184
+ var nav = pendingNav;
185
+ pendingNav = null;
186
+ if (ctx.currentSlug && ctx.currentSlug() === nav.slug) {
187
+ navigateToSession({ projectSlug: nav.slug, sessionId: nav.sessionId }, nav.query, nav.entryIndex);
188
+ }
156
189
  }
190
+ var pending = store.get('pendingSessionEntryNavigation');
191
+ if (pending && isActiveEntryNavigation(pending)) pending.awaitingTarget = false;
192
+ var highlight = store.get('sessionEntryHighlight');
193
+ if (highlight && !isCurrentEntryHighlight(highlight)) store.set({ sessionEntryHighlight: null });
194
+ }
195
+
196
+ export function handlePaletteHistoryDone() {
197
+ var pending = store.get('pendingSessionEntryNavigation');
198
+ if (!pending) {
199
+ var highlight = store.get('sessionEntryHighlight');
200
+ if (highlight && isCurrentEntryHighlight(highlight)) jumpToSessionEntry(highlight.entryIndex, highlight);
201
+ return;
202
+ }
203
+ if (!isActiveEntryNavigation(pending)) {
204
+ if (pending.awaitingTarget) return;
205
+ store.set({ pendingSessionEntryNavigation: null });
206
+ return;
207
+ }
208
+ var historyFrom = store.get('historyFrom') || 0;
209
+ if (pending.entryIndex < historyFrom) {
210
+ var ws = getWs();
211
+ if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: "load_more_history", before: historyFrom, target: pending.entryIndex }));
212
+ return;
213
+ }
214
+ jumpToSessionEntry(pending.entryIndex, pending);
215
+ }
216
+
217
+ export function handlePaletteHistoryPrepended() {
218
+ var pending = store.get('pendingSessionEntryNavigation');
219
+ if (!pending) return;
220
+ if (!isActiveEntryNavigation(pending)) {
221
+ if (pending.awaitingTarget) return;
222
+ store.set({ pendingSessionEntryNavigation: null });
223
+ return;
224
+ }
225
+ requestAnimationFrame(function () {
226
+ if (store.get('pendingSessionEntryNavigation') !== pending) return;
227
+ // This frame was scheduled for an already active target. A later
228
+ // navigation cancels it even if its initial awaiting flag was retained.
229
+ if (!isActiveEntryNavigation(pending)) {
230
+ store.set({ pendingSessionEntryNavigation: null });
231
+ return;
232
+ }
233
+ handlePaletteHistoryDone();
234
+ });
235
+ }
236
+
237
+ function isActiveEntryNavigation(pending) {
238
+ return String(store.get('currentSlug') || (ctx && ctx.currentSlug ? ctx.currentSlug() : "")) === String(pending.projectSlug) && String(store.get('activeSessionId')) === String(pending.sessionId);
239
+ }
240
+
241
+ function isCurrentEntryHighlight(highlight) {
242
+ return highlight.expiresAt > Date.now() && isActiveEntryNavigation(highlight)
243
+ && highlight.sessionOriginId === (store.get('sessionOriginId') || null);
244
+ }
245
+
246
+ function jumpToSessionEntry(entryIndex, pending) {
247
+ if (pending && !isActiveEntryNavigation(pending)) return;
248
+ var messages = document.querySelectorAll("#messages [data-history-index], #messages [data-history-indexes]");
249
+ var target = null;
250
+ for (var i = 0; i < messages.length; i++) {
251
+ var indexes = (messages[i].dataset.historyIndexes || messages[i].dataset.historyIndex || "").split(",");
252
+ if (indexes.indexOf(String(entryIndex)) !== -1) { target = messages[i]; break; }
253
+ }
254
+ if (!target) return;
255
+ store.set({ pendingSessionEntryNavigation: null });
256
+ disarmStickyBottom();
257
+ var oldTargets = document.querySelectorAll("#messages .session-entry-target");
258
+ for (var oldIndex = 0; oldIndex < oldTargets.length; oldIndex++) oldTargets[oldIndex].classList.remove("session-entry-target");
259
+ var reducedMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
260
+ // A repeated authoritative replay replaces the DOM after the initial jump.
261
+ // Retain only this exact origin for the original feedback lifetime.
262
+ var highlight = pending && pending.expiresAt ? pending : {
263
+ projectSlug: store.get('currentSlug'), sessionId: store.get('activeSessionId'),
264
+ sessionOriginId: store.get('sessionOriginId') || null, entryIndex: entryIndex,
265
+ expiresAt: Date.now() + (reducedMotion ? 700 : 1800),
266
+ };
267
+ store.set({ sessionEntryHighlight: highlight });
268
+ target.scrollIntoView({ behavior: reducedMotion ? "auto" : "smooth", block: "center" });
269
+ target.classList.remove("session-entry-target");
270
+ void target.offsetWidth;
271
+ target.classList.add("session-entry-target");
272
+ target.sessionEntryHighlight = highlight;
273
+ setTimeout(function () {
274
+ if (target.sessionEntryHighlight !== highlight) return;
275
+ target.classList.remove("session-entry-target");
276
+ delete target.sessionEntryHighlight;
277
+ if (store.get('sessionEntryHighlight') === highlight) store.set({ sessionEntryHighlight: null });
278
+ }, Math.max(0, highlight.expiresAt - Date.now()));
157
279
  }
158
280
 
159
281
  function navigateToLog(target) {
@@ -211,8 +333,6 @@ function buildDOM() {
211
333
  }
212
334
 
213
335
  function showSearch() {
214
- chatMode = false;
215
- paletteEl.classList.remove("is-chatting");
216
336
  inputEl.value = searchQuery;
217
337
  inputEl.disabled = false;
218
338
  inputEl.focus({ preventScroll: true });
@@ -276,7 +396,6 @@ function sessionIcon(session) {
276
396
  }
277
397
 
278
398
  function renderSearch() {
279
- if (chatMode) return;
280
399
  var query = searchQuery.toLowerCase();
281
400
  var sessions = query ? cachedHomeData.filter(function (item) {
282
401
  return (item.sessionTitle || "").toLowerCase().indexOf(query) !== -1 || (item.projectTitle || "").toLowerCase().indexOf(query) !== -1;
@@ -286,11 +405,10 @@ function renderSearch() {
286
405
  for (var r = 0; r < searchResults.length; r++) if (!seen[sessionKey(searchResults[r])]) { sessions.push(searchResults[r]); seen[sessionKey(searchResults[r])] = true; }
287
406
  items = [];
288
407
  var html = "", index = 0;
289
- var clayChat = getSearchClayChatSummary();
290
- if (clayChat) {
291
- items.push({ type: "resume-clay" });
292
- html += '<div class="cmd-palette-group-label">Current Clay chat</div>';
293
- html += renderItem(index++, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', "Return to Clay", escapeHtml(clayChat.processing ? "Clay is responding" : "Continue your current conversation"), clayChat.preview ? escapeHtml(clayChat.preview) : null, clayChat.updatedAt, " is-resume-clay");
408
+ var pendingAsk = store.get('contextualSearchAsk');
409
+ if (!query && pendingAsk && pendingAsk.ownerId === store.get('myUserId') && !pendingAsk.clientMessageId && /^(error|stopped)$/.test(pendingAsk.status)) {
410
+ items.push({ type: 'retry-clay-ask' });
411
+ html += renderItem(index++, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', 'Retry previous question', escapeHtml(pendingAsk.text), null, null, ' is-retry-clay-ask');
294
412
  }
295
413
  if (sessions.length) {
296
414
  html += '<div class="cmd-palette-group-label">' + (query ? "Conversations" : "Recent conversations") + '</div>';
@@ -305,8 +423,8 @@ function renderSearch() {
305
423
  if (query) {
306
424
  items.push({ type: "ask-clay", query: searchQuery });
307
425
  if (!sessions.length && !searchPending) html += '<div class="cmd-palette-exact-empty">No exact matches. Clay can search by meaning.</div>';
308
- html += '<div class="cmd-palette-group-label">' + (clayChat ? "New Clay chat" : "Ask Clay") + '</div>';
309
- html += renderItem(index, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', (clayChat ? 'Start a new Clay chat about “' : 'Ask Clay about “') + escapeHtml(searchQuery) + '”', "Search by meaning across your projects and conversations", null, null, " is-ask-clay");
426
+ html += '<div class="cmd-palette-group-label">Ask Clay</div>';
427
+ html += renderItem(index, '<img src="/clay-studio-symbol.png" width="22" height="22" alt="">', 'Ask Clay about “' + escapeHtml(searchQuery) + '”', "Start a new Clay conversation", null, null, " is-ask-clay");
310
428
  }
311
429
  if (!html) html = '<div class="cmd-palette-empty">No conversations yet.</div>';
312
430
  resultsEl.innerHTML = html;
@@ -339,31 +457,35 @@ function setActive(index, skipScroll) {
339
457
  }
340
458
 
341
459
  function beginClayChat(query) {
342
- if (chatMode) return;
343
- chatMode = true;
344
- paletteEl.classList.add("is-chatting");
345
- startSearchClayChat(query, resultsEl, showSearch, closeCommandPalette);
346
- }
347
-
348
- function resumeClayChat() {
349
- if (!attachSearchClayChat(resultsEl, showSearch, closeCommandPalette)) return;
350
- chatMode = true;
351
- paletteEl.classList.add("is-chatting");
460
+ if (!isCommandPaletteOpen()) return;
461
+ if (startSearchClayChat(query)) closeCommandPalette();
352
462
  }
353
463
 
354
464
  function activateItem(entry) {
355
- if (entry.type === "resume-clay") { resumeClayChat(); return; }
465
+ if (entry.type === 'retry-clay-ask') { if (retrySearchClayAsk()) closeCommandPalette(); return; }
356
466
  if (entry.type === "ask-clay") { beginClayChat(entry.query); return; }
357
467
  if (entry.type === "mate-session" || entry.type === "session") navigateToSession(entry.data, entry.query);
358
468
  }
359
469
 
360
- function navigateToSession(item, query) {
470
+ export function navigateToSession(item, query, entryIndex) {
361
471
  closeCommandPalette();
472
+ pendingNav = null;
473
+ store.set({ sessionEntryHighlight: null });
474
+ var hasEntry = entryIndex !== null && entryIndex !== undefined && Number.isSafeInteger(Number(entryIndex)) && Number(entryIndex) >= 0;
475
+ store.set({ pendingSessionEntryNavigation: hasEntry ? { projectSlug: item.projectSlug, sessionId: item.sessionId, entryIndex: Number(entryIndex), awaitingTarget: true } : null });
362
476
  if (ctx.currentSlug && ctx.currentSlug() === item.projectSlug) {
477
+ var alreadyActive = String(store.get('activeSessionId')) === String(item.sessionId);
478
+ if (alreadyActive) {
479
+ if (query) setTimeout(function () { openSessionSearch(query); }, 400);
480
+ if (hasEntry) requestAnimationFrame(function () {
481
+ if (!store.get('replayingHistory')) handlePaletteHistoryDone();
482
+ });
483
+ return;
484
+ }
363
485
  ctx.selectSession(item.sessionId);
364
486
  if (query) setTimeout(function () { openSessionSearch(query); }, 400);
365
487
  } else {
366
- pendingNav = { slug: item.projectSlug, sessionId: item.sessionId, query: query };
488
+ pendingNav = { slug: item.projectSlug, sessionId: item.sessionId, query: query, entryIndex: hasEntry ? Number(entryIndex) : null };
367
489
  ctx.switchProject(item.projectSlug);
368
490
  }
369
491
  }
@@ -0,0 +1,26 @@
1
+ import { store } from './store.js';
2
+ import { sendTextMessage } from './input.js';
3
+ import { pausePendingMessage } from './message-delivery.js';
4
+ import { stopGeneration } from './generation-stop.js';
5
+
6
+ export function submitContextualAsk(request) {
7
+ if (!request || typeof request.requestId !== 'string' || typeof request.text !== 'string') return null;
8
+ var current = store.get('contextualAskSubmission');
9
+ if (current && current.requestId === request.requestId) return current;
10
+ if (!request || request.ownerId !== store.get('myUserId') || request.sessionId !== store.get('paneSessionId') || request.sessionOriginId !== store.get('sessionOriginId') || !store.get('contextualSessionReady') || !store.get('connected') || store.get('contextualWriterSuspended') || !window.frameElement || window.frameElement.dataset.canonical !== 'true') return null;
11
+ // A fresh session has no user draft to replace. Refuse any ambiguous target.
12
+ if (document.getElementById('input').value || (store.get('pendingOutboundMessages') || []).length) return null;
13
+ store.set({ contextualAskSubmission: { requestId: request.requestId, status: 'sending' } });
14
+ sendTextMessage(request.text);
15
+ var outbound = (store.get('pendingOutboundMessages') || []).find(function (item) { return item.payload.text === request.text && item.sessionId === request.sessionId; });
16
+ var submission = { requestId: request.requestId, status: outbound ? 'sent' : 'unconfirmed', clientMessageId: outbound && outbound.payload.clientMessageId };
17
+ store.set({ contextualAskSubmission: submission });
18
+ return submission;
19
+ }
20
+
21
+ export function pauseContextualAsk() {
22
+ var current = store.get('contextualAskSubmission');
23
+ if (current && current.clientMessageId) pausePendingMessage(current.clientMessageId);
24
+ if (current) store.set({ contextualAskSubmission: Object.assign({}, current, { status: 'stopped' }) });
25
+ }
26
+ export function stopContextualAsk() { pauseContextualAsk(); return stopGeneration(); }
@@ -0,0 +1,155 @@
1
+ import { contextualTrigger } from './contextual-mate-identity.js';
2
+ import { renderContextualMateHint } from './contextual-mate-hint.js';
3
+ import { store } from './store.js';
4
+ import { showToast } from './utils.js';
5
+
6
+ var endpoint = '/api/user/contextual-clay-geometry';
7
+ function state() { return store.get('contextualClayGeometry') || {}; }
8
+ function surface() { return document.getElementById('contextual-clay'); }
9
+ function narrow() { return window.matchMedia('(max-width: 768px)').matches; }
10
+ function rectValue(rect) { return { left: rect.left, top: rect.top, width: rect.width, height: rect.height }; }
11
+ function bounded(value) {
12
+ return { left: Math.round(Math.max(0, Math.min(16384, value.left))), top: Math.round(Math.max(0, Math.min(16384, value.top))), width: Math.round(Math.max(340, Math.min(2560, value.width))), height: Math.round(Math.max(360, Math.min(2160, value.height))) };
13
+ }
14
+ function setState(patch) { store.set({ contextualClayGeometry: Object.assign({}, state(), patch) }); }
15
+ function defaultGeometry() {
16
+ var trigger = contextualTrigger();
17
+ var anchor = trigger && trigger.getBoundingClientRect();
18
+ return { left: anchor ? anchor.right + 8 : 64, top: anchor ? anchor.top : 38, width: 480, height: 640 };
19
+ }
20
+ export function positionContextualClay() {
21
+ var element = surface();
22
+ var hint = renderContextualMateHint();
23
+ if (!element || narrow() || (store.get('contextualClay') || {}).mode === 'opening') return;
24
+ var desired = state().preview || state().desired || defaultGeometry();
25
+ var width = Math.min(desired.width, window.innerWidth - 16);
26
+ var height = Math.min(desired.height, window.innerHeight - 16);
27
+ var left = Math.max(8, Math.min(desired.left, window.innerWidth - width - 8));
28
+ var top = Math.max(8, Math.min(desired.top, window.innerHeight - height - 8));
29
+ if (hint && left < hint.right + 8 && left + width > hint.left && top < hint.bottom + 8 && top + height > hint.top) {
30
+ left = hint.right + 8; width = Math.min(width, window.innerWidth - left - 8);
31
+ }
32
+ element.style.setProperty('--contextual-left', left + 'px');
33
+ element.style.setProperty('--contextual-top', top + 'px');
34
+ element.style.setProperty('--contextual-width', width + 'px');
35
+ element.style.setProperty('--contextual-height', height + 'px');
36
+ }
37
+ async function flushSave() {
38
+ var current = state();
39
+ if (current.saving || !current.pending) return;
40
+ var owner = store.get('myUserId'); var value = current.pending;
41
+ setState({ saving: true, pending: null });
42
+ try {
43
+ var response = await fetch(endpoint, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Clay-Settings': '1' }, body: JSON.stringify(value) });
44
+ if (!response.ok) throw new Error('Could not save popover position and size.');
45
+ if (store.get('myUserId') === owner) setState({ saved: value });
46
+ } catch (error) {
47
+ if (store.get('myUserId') === owner) showToast('Popover position and size could not be saved. Adjust again to retry.', 'error');
48
+ } finally {
49
+ if (store.get('myUserId') === owner) { setState({ saving: false }); flushSave(); }
50
+ }
51
+ }
52
+ function commit(value) {
53
+ var next = bounded(value);
54
+ setState({ desired: next, pending: next, revision: (state().revision || 0) + 1 });
55
+ positionContextualClay(); flushSave();
56
+ }
57
+ function finish(cancel) {
58
+ var drag = state().interaction;
59
+ if (!drag) return;
60
+ var value = state().preview;
61
+ setState({ interaction: null, preview: null });
62
+ var element = surface();
63
+ if (element) {
64
+ element.classList.remove('contextual-clay-manipulating');
65
+ var handle = drag.edge ? element.querySelector('[data-clay-resize="' + drag.edge + '"]') : element.querySelector('header');
66
+ if (handle && handle.hasPointerCapture(drag.pointerId)) handle.releasePointerCapture(drag.pointerId);
67
+ }
68
+ if (!cancel && value) {
69
+ if (!drag.edge && drag.desired) { value.width = drag.desired.width; value.height = drag.desired.height; }
70
+ commit(value);
71
+ }
72
+ else positionContextualClay();
73
+ }
74
+ function move(event) {
75
+ var drag = state().interaction;
76
+ if (!drag || event.pointerId !== drag.pointerId) return;
77
+ var dx = event.clientX - drag.x; var dy = event.clientY - drag.y;
78
+ if (!state().preview && Math.hypot(dx, dy) < 3) return;
79
+ var value = Object.assign({}, drag.start);
80
+ if (drag.edge) {
81
+ if (drag.edge.indexOf('e') >= 0) value.width = Math.max(340, Math.min(2560, window.innerWidth - value.left - 8, value.width + dx));
82
+ if (drag.edge.indexOf('s') >= 0) value.height = Math.max(360, Math.min(2160, window.innerHeight - value.top - 8, value.height + dy));
83
+ } else {
84
+ value.left = Math.max(8, Math.min(window.innerWidth - value.width - 8, value.left + dx));
85
+ value.top = Math.max(8, Math.min(window.innerHeight - value.height - 8, value.top + dy));
86
+ }
87
+ setState({ preview: value }); positionContextualClay();
88
+ }
89
+ async function loadPreference(owner) {
90
+ setState({ owner: owner, desired: null, revision: 0, pending: null, saving: false });
91
+ try {
92
+ var response = await fetch(endpoint);
93
+ if (!response.ok) throw new Error('Preference unavailable');
94
+ var data = await response.json();
95
+ if (store.get('myUserId') === owner && !state().revision && !state().interaction) {
96
+ setState({ desired: data.geometry, saved: data.geometry }); positionContextualClay();
97
+ }
98
+ } catch (error) { /* Keep the usable anchored default when preferences are unavailable. */ }
99
+ }
100
+ export function attachContextualGeometry(element) {
101
+ var header = element.querySelector('header');
102
+ header.tabIndex = 0;
103
+ header.setAttribute('aria-label', 'Move Clay conversation. Use arrow keys to move; hold Shift for larger steps.');
104
+ header.title = 'Drag to move · Arrow keys when focused';
105
+ ['e', 's', 'se'].forEach(function (edge) {
106
+ var handle = document.createElement('button');
107
+ handle.type = 'button'; handle.dataset.clayResize = edge;
108
+ handle.setAttribute('aria-label', 'Resize Clay conversation' + (edge === 'e' ? ' width' : edge === 's' ? ' height' : '') + '. Use arrow keys; hold Shift for larger steps.');
109
+ handle.title = 'Drag to resize · Arrow keys when focused';
110
+ element.appendChild(handle);
111
+ });
112
+ element.addEventListener('pointerdown', function (event) {
113
+ var handle = event.target.closest('[data-clay-resize]');
114
+ var heading = event.target.closest('header');
115
+ if (narrow() || event.button !== 0 || (!handle && (!heading || event.target.closest('button, details, a, input')))) return;
116
+ if ((store.get('contextualClay') || {}).mode !== 'popover') return;
117
+ event.preventDefault();
118
+ var target = handle || header;
119
+ setState({ interaction: { pointerId: event.pointerId, x: event.clientX, y: event.clientY, start: rectValue(element.getBoundingClientRect()), desired: state().desired, edge: handle ? handle.dataset.clayResize : null } });
120
+ element.classList.add('contextual-clay-manipulating');
121
+ target.setPointerCapture(event.pointerId);
122
+ });
123
+ element.addEventListener('pointermove', move);
124
+ element.addEventListener('pointerup', function (event) { if (state().interaction && event.pointerId === state().interaction.pointerId) { move(event); finish(false); } });
125
+ element.addEventListener('pointercancel', function () { finish(true); });
126
+ element.addEventListener('lostpointercapture', function () { finish(true); });
127
+ element.addEventListener('keydown', function (event) {
128
+ if (narrow() || ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].indexOf(event.key) < 0) return;
129
+ var edge = event.target.dataset.clayResize;
130
+ if (event.target !== header && !edge) return;
131
+ event.preventDefault();
132
+ var value = rectValue(element.getBoundingClientRect()); var step = event.shiftKey ? 32 : 8;
133
+ var horizontal = event.key === 'ArrowLeft' || event.key === 'ArrowRight';
134
+ var delta = event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -step : step;
135
+ if (edge) {
136
+ if (horizontal && edge.indexOf('e') >= 0) value.width = Math.min(window.innerWidth - value.left - 8, value.width + delta);
137
+ if (!horizontal && edge.indexOf('s') >= 0) value.height = Math.min(window.innerHeight - value.top - 8, value.height + delta);
138
+ } else if (horizontal) value.left = Math.max(8, Math.min(window.innerWidth - value.width - 8, value.left + delta));
139
+ else value.top = Math.max(8, Math.min(window.innerHeight - value.height - 8, value.top + delta));
140
+ if (!edge && state().desired) { value.width = state().desired.width; value.height = state().desired.height; }
141
+ commit(value);
142
+ });
143
+ }
144
+ export function initContextualGeometry() {
145
+ store.subscribe(function (value, previous) {
146
+ if (value.myUserId && value.myUserId !== previous.myUserId) { finish(true); loadPreference(value.myUserId); }
147
+ if ((value.contextualClay || {}).mode !== (previous.contextualClay || {}).mode) finish(true);
148
+ });
149
+ document.addEventListener('keydown', function (event) {
150
+ if (event.key === 'Escape' && state().interaction) { event.preventDefault(); event.stopImmediatePropagation(); finish(true); }
151
+ }, true);
152
+ window.addEventListener('blur', function () { finish(true); });
153
+ window.addEventListener('resize', function () { finish(true); positionContextualClay(); });
154
+ if (store.get('myUserId')) loadPreference(store.get('myUserId'));
155
+ }
@@ -0,0 +1,130 @@
1
+ // Session identity remains pinned across transport recovery and presentation.
2
+ import { autoResize, takeComposerDraft, restoreComposerDraft } from './input.js';
3
+ import { store } from './store.js';
4
+ import { withdrawPaneControlActivity } from './clay-control-activity.js';
5
+ import { initContextualComposer } from './contextual-composer.js';
6
+ import { submitContextualAsk, pauseContextualAsk, stopContextualAsk } from './contextual-ask-session.js';
7
+
8
+ // Session replay and authenticated account bootstrap complete independently.
9
+ function submissionReady() { var expected = window.frameElement && window.frameElement.dataset.expectedSessionOrigin; return (!expected || expected === store.get('sessionOriginId')) && !!(store.get('contextualSessionReady') && store.get('connected') && store.get('myUserId') && store.get('sessionOriginId') && store.get('activeSessionId') === store.get('paneSessionId')); }
10
+ function enabled() { return store.get('paneMode') && new URLSearchParams(location.search).get('contextual') === '1'; }
11
+ function renderSessionAvailability() {
12
+ var input = document.getElementById('input');
13
+ var frame = window.frameElement;
14
+ var mate = frame && (store.get('cachedMatesList') || []).find(function (item) { return item.id === frame.dataset.mateId; });
15
+ var name = mate && ((mate.profile || {}).displayName || mate.displayName || mate.name);
16
+ if (input && name) { input.setAttribute('aria-label', 'Message ' + name); if (name.length > 32) input.placeholder = 'Message this Mate…'; }
17
+ var wrapper = document.getElementById('input-wrapper');
18
+ if (wrapper) wrapper.inert = !submissionReady();
19
+ try {
20
+ var surface = window.parent.document.getElementById('contextual-clay');
21
+ var anchor = window.parent.document.querySelector('[aria-describedby="contextual-mate-hint"]') || window.parent.document.querySelector('.icon-strip-brand');
22
+ if (submissionReady() && surface && surface.dataset.focusEntry === 'true' && !window.frameElement.hidden && !window.frameElement.inert) {
23
+ delete surface.dataset.focusEntry;
24
+ if (surface.dataset.mode === 'popover' && window.parent.document.activeElement === anchor) document.getElementById('input').focus({ preventScroll: true });
25
+ }
26
+ } catch (error) { /* Cross-origin authentication owns focus. */ }
27
+ if (store.get('contextualSessionReady') && window.frameElement && !window.frameElement.hidden) {
28
+ window.frameElement.dataset.sessionId = String(store.get('paneSessionId'));
29
+ var parentSurface = window.parent.document.getElementById('contextual-clay');
30
+ if (parentSurface) parentSurface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-ready'));
31
+ }
32
+ var warning = document.getElementById('contextual-session-warning');
33
+ if (!warning && store.get('contextualSessionUnavailable')) {
34
+ warning = document.createElement('p');
35
+ warning.id = 'contextual-session-warning'; warning.setAttribute('role', 'status');
36
+ warning.textContent = 'This Mate conversation is no longer available. Your draft is still here.';
37
+ document.getElementById('input-area').prepend(warning);
38
+ }
39
+ if (warning) warning.hidden = !store.get('contextualSessionUnavailable');
40
+ }
41
+ export function handleContextualSessionMessage(msg) {
42
+ if (!enabled()) return;
43
+ if (msg.type === 'session_list' && store.get('paneSessionId') && !(msg.sessions || []).some(function (session) { return session.id === store.get('paneSessionId'); })) {
44
+ store.set({ contextualSessionReady: false, contextualSessionUnavailable: true });
45
+ }
46
+ if (msg.type === 'session_switched') {
47
+ var pin = store.get('paneSessionId');
48
+ if (pin && msg.id !== pin) return true;
49
+ var path = store.get('wsPath').replace(/&session=\d+/g, '');
50
+ store.set({ contextualSessionReady: false, contextualSessionReceived: true, contextualSessionUnavailable: false, paneSessionId: msg.id, wsPath: path + '&session=' + msg.id });
51
+ }
52
+ if (msg.type === 'history_done' && store.get('contextualSessionReceived')) store.set({ contextualSessionReady: true });
53
+ renderSessionAvailability();
54
+ return false;
55
+ }
56
+ export function initContextualSession() {
57
+ if (!enabled()) return;
58
+ document.body.classList.add('contextual-chat-pane');
59
+ initContextualComposer();
60
+ // Bind at app readiness rather than iframe load: slow assets must not leave
61
+ // an already usable composer without its presentation keyboard handling.
62
+ document.addEventListener('keydown', function (event) {
63
+ if (event.key !== 'Escape') return;
64
+ try {
65
+ var surface = window.parent.document.getElementById('contextual-clay');
66
+ if (surface && window.frameElement && surface.contains(window.frameElement)) surface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-keydown', { detail: { source: window, keyboardEvent: event } }));
67
+ } catch (error) { /* Authentication navigation owns its document. */ }
68
+ });
69
+ var surfaceBridge = window.parent.document.getElementById('contextual-clay');
70
+ if (surfaceBridge && window.frameElement && surfaceBridge.contains(window.frameElement)) window.frameElement.conversation = {
71
+ source: window, document: document,
72
+ submitAsk: submitContextualAsk,
73
+ pauseAsk: pauseContextualAsk,
74
+ stopAsk: stopContextualAsk,
75
+ identity: function () { return { mateId: store.get('activeProjectMateId'), viewerRef: store.get('clayControlViewerRef'), sessionId: store.get('paneSessionId'), sessionOriginId: store.get('sessionOriginId'), ownerId: store.get('myUserId'), connected: store.get('connected'), available: !store.get('contextualSessionUnavailable'), ready: submissionReady() }; },
76
+ suspend: function (value) { store.set({ contextualWriterSuspended: value }); document.getElementById('input').readOnly = value; },
77
+ checkDraft: function () { var draft = takeComposerDraft(); restoreComposerDraft(draft); },
78
+ take: function () { var draft = takeComposerDraft(); var drafts = Object.assign({}, store.get('sessionDrafts')); delete drafts[store.get('paneSessionId')]; store.set({ sessionDrafts: drafts }); return draft; },
79
+ restore: restoreComposerDraft
80
+ };
81
+ document.addEventListener('click', function (event) {
82
+ if (event.target.closest('#generation-stop, #autonomous-run-stop, #send-btn.stop')) {
83
+ pauseContextualAsk();
84
+ var askHost = window.parent.document.getElementById('contextual-clay');
85
+ if (askHost) askHost.dispatchEvent(new window.parent.CustomEvent('contextual-ask-stopped', { detail: { source: window } }));
86
+ }
87
+ if (store.get('contextualWriterSuspended') && event.target.closest('#send-btn, #attach-wrap, #contextual-attach-btn, #config-chip-wrap, .ask-user-container')) { event.preventDefault(); event.stopImmediatePropagation(); }
88
+ }, true);
89
+ store.set({ contextualSessionReady: false, contextualSessionUnavailable: false });
90
+ var width = 0;
91
+ new ResizeObserver(function (entries) {
92
+ var next = entries[0].contentRect.width;
93
+ if (next === width || next === 0) return;
94
+ width = next;
95
+ autoResize();
96
+ }).observe(document.getElementById('input-textarea-wrap'));
97
+ function guardPendingReview(event) {
98
+ if ((!store.get('contextualSessionReady') || store.get('contextualWriterSuspended')) && event.target.closest('.ask-user-submit, .ask-user-other input') && (event.type === 'click' || event.key === 'Enter')) { event.preventDefault(); event.stopImmediatePropagation(); }
99
+ }
100
+ document.addEventListener('click', guardPendingReview, true);
101
+ document.addEventListener('keydown', guardPendingReview, true);
102
+ store.subscribe(function (value, previous) {
103
+ if (value.connected !== previous.connected || value.contextualSessionReady !== previous.contextualSessionReady || value.contextualSessionUnavailable !== previous.contextualSessionUnavailable) {
104
+ var parentSurface = window.parent.document.getElementById('contextual-clay');
105
+ if (parentSurface && window.frameElement && !window.frameElement.hidden && parentSurface.contains(window.frameElement)) parentSurface.dispatchEvent(new window.parent.CustomEvent('contextual-clay-availability'));
106
+ }
107
+ if (!value.connected && previous.connected) {
108
+ withdrawPaneControlActivity();
109
+ var input = document.getElementById('input');
110
+ var drafts = Object.assign({}, value.sessionDrafts);
111
+ if (value.paneSessionId && input) drafts[value.paneSessionId] = input.value;
112
+ store.set({ contextualSessionReady: false, contextualSessionReceived: false, sessionDrafts: drafts });
113
+ }
114
+ renderSessionAvailability();
115
+ });
116
+ renderSessionAvailability();
117
+ }
118
+
119
+ // Capture bounded metadata separately from user attachments. This is
120
+ // untrusted reference data, never approval or a target for an existing action.
121
+ export function contextualScreenReference() {
122
+ if (!enabled() || window.parent === window) return null;
123
+ try {
124
+ var surface = window.parent.document.getElementById('contextual-clay');
125
+ if (!surface || !window.frameElement || window.frameElement.hidden || window.frameElement.dataset.canonical !== 'true' || !surface.contains(window.frameElement)) return null;
126
+ var reference = JSON.parse(surface.dataset.screenReference || 'null');
127
+ if (!reference || reference.ownerId !== (store.get('myUserId') || null)) return null;
128
+ return { version: 1, viewId: typeof reference.viewId === 'string' ? reference.viewId.slice(0, 100) : null, projectTitle: typeof reference.projectTitle === 'string' ? reference.projectTitle.slice(0, 160) : null, conversationTitle: typeof reference.conversationTitle === 'string' ? reference.conversationTitle.slice(0, 160) : null, projectSlug: typeof reference.projectSlug === 'string' ? reference.projectSlug.slice(0, 160) : null, sessionId: Number.isSafeInteger(reference.sessionId) ? reference.sessionId : null, screen: String(reference.screen || '').slice(0, 40) };
129
+ } catch (error) { return null; }
130
+ }