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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (608) hide show
  1. package/README.md +0 -4
  2. package/lib/account-auth-socket.js +1 -0
  3. package/lib/builtin-mates.js +19 -16
  4. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  5. package/lib/canonical-clay-record-authority.js +15 -0
  6. package/lib/canonical-clay-scheduling-authority.js +19 -0
  7. package/lib/claude-hook-installer.js +1 -239
  8. package/lib/claude-jsonl-watcher.js +1 -204
  9. package/lib/clay-control-presentation-binding.js +96 -0
  10. package/lib/clay-control-presentation.js +128 -0
  11. package/lib/clay-control-target-projection.js +26 -0
  12. package/lib/clay-mate-chat-receipts.js +26 -0
  13. package/lib/clay-mate-chat.js +88 -0
  14. package/lib/clay-mate-knowledge-input.js +26 -0
  15. package/lib/clay-mate-knowledge.js +95 -0
  16. package/lib/clay-mate-lifecycle.js +95 -0
  17. package/lib/clay-product-control-input.js +33 -0
  18. package/lib/clay-product-control-tools.js +52 -0
  19. package/lib/clay-product-control.js +250 -0
  20. package/lib/clay-project-lifecycle.js +154 -0
  21. package/lib/clay-project-record-input.js +44 -0
  22. package/lib/clay-project-records.js +84 -0
  23. package/lib/clay-scheduling-input.js +21 -0
  24. package/lib/clay-scheduling-receipts.js +26 -0
  25. package/lib/clay-scheduling.js +119 -0
  26. package/lib/clay-screen-controls.js +104 -0
  27. package/lib/clay-skill-install.js +1 -33
  28. package/lib/clay-vendor-usage.js +44 -0
  29. package/lib/clay-workspace-controls.js +84 -0
  30. package/lib/clay-workspace-input.js +17 -0
  31. package/lib/clay-workspace-receipts.js +26 -0
  32. package/lib/cli-sessions.js +1 -300
  33. package/lib/codex-defaults.js +1 -28
  34. package/lib/context-usage.js +3 -2
  35. package/lib/contextual-screen-snapshot.js +38 -0
  36. package/lib/daemon-project-access.js +11 -0
  37. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  38. package/lib/daemon-project-lifecycle.js +262 -0
  39. package/lib/daemon-projects.js +1 -1
  40. package/lib/daemon.js +78 -276
  41. package/lib/default-ai-runtime.js +4 -8
  42. package/lib/dm-digest-cursor.js +120 -0
  43. package/lib/email-mcp-server.js +1 -1
  44. package/lib/github-star-count.js +147 -0
  45. package/lib/issues-service.js +29 -15
  46. package/lib/kiro-defaults.js +1 -22
  47. package/lib/knowledge-db-import-validation.js +46 -0
  48. package/lib/knowledge-db-import.js +99 -0
  49. package/lib/knowledge-db-service.js +24 -33
  50. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  51. package/lib/knowledge-db-storage-nedb.js +66 -0
  52. package/lib/knowledge-db-storage.js +72 -0
  53. package/lib/knowledge-db-validation.js +0 -0
  54. package/lib/knowledge-document-index.js +2 -1
  55. package/lib/knowledge-file-store.js +7 -1
  56. package/lib/knowledge-product-operations.js +46 -0
  57. package/lib/mate-avatar-catalog.js +12 -0
  58. package/lib/mate-avatar-migration.js +41 -0
  59. package/lib/mate-context-service.js +138 -0
  60. package/lib/mate-context-tools.js +21 -0
  61. package/lib/mate-creation-mcp-server.js +2 -0
  62. package/lib/mate-knowledge-canonical-access.js +10 -0
  63. package/lib/mate-knowledge-mate-bound.js +53 -0
  64. package/lib/mate-knowledge-mcp-server.js +55 -8
  65. package/lib/mate-knowledge-service.js +16 -34
  66. package/lib/mate-knowledge-text-tools.js +106 -0
  67. package/lib/mate-lifecycle-service.js +94 -0
  68. package/lib/mate-message-delivery.js +43 -0
  69. package/lib/mate-ready-creation.js +9 -1
  70. package/lib/mate-schedule-input.js +29 -0
  71. package/lib/mate-schedule-lifecycle.js +151 -0
  72. package/lib/mate-scheduling.js +103 -0
  73. package/lib/mates.js +18 -6
  74. package/lib/mcp-agent-tools.js +117 -0
  75. package/lib/mcp-connection-store.js +119 -15
  76. package/lib/mcp-import-credentials.js +31 -0
  77. package/lib/mcp-local-transport.js +13 -0
  78. package/lib/mcp-oauth.js +8 -6
  79. package/lib/mcp-proxy.js +2 -32
  80. package/lib/mcp-query-bridge.js +30 -0
  81. package/lib/mcp-remote-connections.js +74 -20
  82. package/lib/mcp-source-adapters.js +1 -0
  83. package/lib/mcp-source-context.js +1 -0
  84. package/lib/mcp-source-discovery.js +1 -0
  85. package/lib/mcp-source-plugins.js +1 -0
  86. package/lib/mcp-source-restrictions.js +1 -0
  87. package/lib/mcp-tool-policy.js +9 -0
  88. package/lib/notes-checklist.js +92 -0
  89. package/lib/notes.js +51 -4
  90. package/lib/os-user-diagnostics.js +2 -4
  91. package/lib/os-users.js +24 -70
  92. package/lib/pane-pending-interactions.js +20 -0
  93. package/lib/pane-session-activation.js +114 -0
  94. package/lib/pane-session-transport.js +26 -0
  95. package/lib/project-admin-overview.js +51 -0
  96. package/lib/project-ask-user.js +8 -4
  97. package/lib/project-connection.js +14 -10
  98. package/lib/project-control-git-view.js +12 -0
  99. package/lib/project-debate.js +1 -0
  100. package/lib/project-delegated-follow-up.js +2 -1
  101. package/lib/project-directory-claim.js +65 -0
  102. package/lib/project-file-operations.js +61 -0
  103. package/lib/project-filesystem.js +15 -85
  104. package/lib/project-full-access.js +23 -2
  105. package/lib/project-http.js +7 -4
  106. package/lib/project-knowledge.js +32 -18
  107. package/lib/project-lifecycle-operations.js +98 -0
  108. package/lib/project-lifecycle-process-witness.js +32 -0
  109. package/lib/project-lifecycle-runtime.js +50 -0
  110. package/lib/project-linux-access.js +22 -0
  111. package/lib/project-logs-canonical-clay.js +27 -0
  112. package/lib/project-logs-clay-query.js +16 -0
  113. package/lib/project-logs-schema.js +4 -2
  114. package/lib/project-logs-service.js +8 -7
  115. package/lib/project-logs.js +1 -0
  116. package/lib/project-loop.js +1 -0
  117. package/lib/project-mate-chat-control.js +55 -0
  118. package/lib/project-mate-creation-proposal.js +18 -3
  119. package/lib/project-mate-interaction.js +40 -62
  120. package/lib/project-mcp.js +54 -16
  121. package/lib/project-models.js +14 -31
  122. package/lib/project-notifications.js +76 -17
  123. package/lib/project-ownership.js +77 -0
  124. package/lib/project-pair-result-delivery.js +14 -3
  125. package/lib/project-pair-usage.js +12 -13
  126. package/lib/project-pending-message-queue.js +4 -1
  127. package/lib/project-product-control.js +89 -0
  128. package/lib/project-product-session-queue.js +46 -0
  129. package/lib/project-push-access.js +28 -0
  130. package/lib/project-scheduled-message-queue.js +30 -0
  131. package/lib/project-scheduled-messages.js +67 -68
  132. package/lib/project-scheduled-task-control.js +83 -0
  133. package/lib/project-scheduled-tasks.js +13 -2
  134. package/lib/project-scheduling-access.js +10 -0
  135. package/lib/project-session-actions.js +65 -0
  136. package/lib/project-session-delete.js +8 -1
  137. package/lib/project-session-document.js +27 -7
  138. package/lib/project-session-github.js +63 -19
  139. package/lib/project-session-history-actions.js +167 -0
  140. package/lib/project-session-linear.js +14 -6
  141. package/lib/project-session-notes.js +40 -11
  142. package/lib/project-session-pair.js +1 -1
  143. package/lib/project-session-runtime-actions.js +64 -0
  144. package/lib/project-session-spawn.js +2 -3
  145. package/lib/project-session-vendor.js +55 -0
  146. package/lib/project-sessions.js +160 -290
  147. package/lib/project-shared-browser.js +78 -17
  148. package/lib/project-start-protocol.js +29 -0
  149. package/lib/project-studio-presentation.js +58 -0
  150. package/lib/project-user-message.js +67 -1
  151. package/lib/project-vendor-login.js +8 -36
  152. package/lib/project-workspace-operations.js +126 -0
  153. package/lib/project-workspace-query.js +19 -2
  154. package/lib/project.js +181 -45
  155. package/lib/public/app.js +71 -17
  156. package/lib/public/appearance-bootstrap.js +16 -0
  157. package/lib/public/css/clay-tool-activity.css +51 -0
  158. package/lib/public/css/clay-workspace.css +29 -0
  159. package/lib/public/css/command-palette.css +12 -33
  160. package/lib/public/css/contextual-clay.css +240 -0
  161. package/lib/public/css/filebrowser.css +1 -1
  162. package/lib/public/css/home-debate-planning.css +2 -0
  163. package/lib/public/css/home-mate-creation.css +5 -0
  164. package/lib/public/css/input.css +6 -0
  165. package/lib/public/css/mate-avatar-gallery.css +12 -0
  166. package/lib/public/css/mate-conversation.css +10 -5
  167. package/lib/public/css/mate-loading-scene.css +21 -0
  168. package/lib/public/css/messages.css +6 -2
  169. package/lib/public/css/overlays.css +68 -258
  170. package/lib/public/css/project-admin-overview.css +13 -0
  171. package/lib/public/css/project-mate-creation.css +5 -6
  172. package/lib/public/css/project-start.css +108 -0
  173. package/lib/public/css/projects-hub.css +53 -14
  174. package/lib/public/css/session-folders.css +11 -0
  175. package/lib/public/css/session-github.css +46 -1
  176. package/lib/public/css/settings-shell.css +103 -0
  177. package/lib/public/css/shared-browser.css +35 -1
  178. package/lib/public/css/sidebar.css +7 -0
  179. package/lib/public/css/sticky-notes.css +87 -1
  180. package/lib/public/css/title-bar.css +79 -0
  181. package/lib/public/index.html +61 -68
  182. package/lib/public/mate-avatars/B01.png +0 -0
  183. package/lib/public/mate-avatars/B02.png +0 -0
  184. package/lib/public/mate-avatars/B03.png +0 -0
  185. package/lib/public/mate-avatars/B04.png +0 -0
  186. package/lib/public/mate-avatars/B05.png +0 -0
  187. package/lib/public/mate-avatars/B06.png +0 -0
  188. package/lib/public/mate-avatars/B07.png +0 -0
  189. package/lib/public/mate-avatars/B08.png +0 -0
  190. package/lib/public/mate-avatars/B09.png +0 -0
  191. package/lib/public/mate-avatars/B10.png +0 -0
  192. package/lib/public/mate-avatars/B11.png +0 -0
  193. package/lib/public/mate-avatars/B12.png +0 -0
  194. package/lib/public/mate-avatars/B13.png +0 -0
  195. package/lib/public/mate-avatars/B14.png +0 -0
  196. package/lib/public/mate-avatars/B15.png +0 -0
  197. package/lib/public/mate-avatars/B16.png +0 -0
  198. package/lib/public/mate-avatars/B17.png +0 -0
  199. package/lib/public/mate-avatars/B18.png +0 -0
  200. package/lib/public/mate-avatars/B19.png +0 -0
  201. package/lib/public/mate-avatars/B20.png +0 -0
  202. package/lib/public/mate-avatars/B21.png +0 -0
  203. package/lib/public/mate-avatars/B22.png +0 -0
  204. package/lib/public/mate-avatars/B23.png +0 -0
  205. package/lib/public/mate-avatars/B24.png +0 -0
  206. package/lib/public/mate-avatars/B25.png +0 -0
  207. package/lib/public/mate-avatars/B26.png +0 -0
  208. package/lib/public/mate-avatars/B27.png +0 -0
  209. package/lib/public/mate-avatars/B28.png +0 -0
  210. package/lib/public/mate-avatars/B29.png +0 -0
  211. package/lib/public/mate-avatars/B30.png +0 -0
  212. package/lib/public/mate-avatars/B31.png +0 -0
  213. package/lib/public/mate-avatars/B32.png +0 -0
  214. package/lib/public/mate-avatars/B33.png +0 -0
  215. package/lib/public/mate-avatars/B34.png +0 -0
  216. package/lib/public/mate-avatars/B35.png +0 -0
  217. package/lib/public/mate-avatars/B36.png +0 -0
  218. package/lib/public/mate-avatars/B37.png +0 -0
  219. package/lib/public/mate-avatars/B38.png +0 -0
  220. package/lib/public/mate-avatars/B39.png +0 -0
  221. package/lib/public/mate-avatars/B40.png +0 -0
  222. package/lib/public/mate-avatars/B41.png +0 -0
  223. package/lib/public/mate-avatars/B42.png +0 -0
  224. package/lib/public/mate-avatars/B43.png +0 -0
  225. package/lib/public/mate-avatars/B44.png +0 -0
  226. package/lib/public/mate-avatars/B45.png +0 -0
  227. package/lib/public/mate-avatars/B46.png +0 -0
  228. package/lib/public/mate-avatars/B47.png +0 -0
  229. package/lib/public/mate-avatars/B48.png +0 -0
  230. package/lib/public/mate-avatars/C01.png +0 -0
  231. package/lib/public/mate-avatars/C02.png +0 -0
  232. package/lib/public/mate-avatars/C03.png +0 -0
  233. package/lib/public/mate-avatars/C04.png +0 -0
  234. package/lib/public/mate-avatars/C05.png +0 -0
  235. package/lib/public/mate-avatars/C06.png +0 -0
  236. package/lib/public/mate-avatars/C07.png +0 -0
  237. package/lib/public/mate-avatars/C08.png +0 -0
  238. package/lib/public/mate-avatars/C09.png +0 -0
  239. package/lib/public/mate-avatars/C10.png +0 -0
  240. package/lib/public/mate-avatars/C11.png +0 -0
  241. package/lib/public/mate-avatars/C12.png +0 -0
  242. package/lib/public/mate-avatars/C13.png +0 -0
  243. package/lib/public/mate-avatars/C14.png +0 -0
  244. package/lib/public/mate-avatars/C15.png +0 -0
  245. package/lib/public/mate-avatars/C16.png +0 -0
  246. package/lib/public/mate-avatars/C17.png +0 -0
  247. package/lib/public/mate-avatars/C18.png +0 -0
  248. package/lib/public/mate-avatars/C19.png +0 -0
  249. package/lib/public/mate-avatars/C20.png +0 -0
  250. package/lib/public/mate-avatars/C21.png +0 -0
  251. package/lib/public/mate-avatars/C22.png +0 -0
  252. package/lib/public/mate-avatars/C23.png +0 -0
  253. package/lib/public/mate-avatars/C24.png +0 -0
  254. package/lib/public/mate-avatars/C25.png +0 -0
  255. package/lib/public/mate-avatars/C26.png +0 -0
  256. package/lib/public/mate-avatars/C27.png +0 -0
  257. package/lib/public/mate-avatars/C28.png +0 -0
  258. package/lib/public/mate-avatars/C29.png +0 -0
  259. package/lib/public/mate-avatars/C30.png +0 -0
  260. package/lib/public/mate-avatars/C31.png +0 -0
  261. package/lib/public/mate-avatars/C32.png +0 -0
  262. package/lib/public/mate-avatars/C33.png +0 -0
  263. package/lib/public/mate-avatars/C34.png +0 -0
  264. package/lib/public/mate-avatars/C35.png +0 -0
  265. package/lib/public/mate-avatars/C36.png +0 -0
  266. package/lib/public/mate-avatars/C37.png +0 -0
  267. package/lib/public/mate-avatars/C38.png +0 -0
  268. package/lib/public/mate-avatars/C39.png +0 -0
  269. package/lib/public/mate-avatars/C40.png +0 -0
  270. package/lib/public/mate-avatars/C41.png +0 -0
  271. package/lib/public/mate-avatars/C42.png +0 -0
  272. package/lib/public/mate-avatars/C43.png +0 -0
  273. package/lib/public/mate-avatars/C44.png +0 -0
  274. package/lib/public/mate-avatars/C45.png +0 -0
  275. package/lib/public/mate-avatars/C46.png +0 -0
  276. package/lib/public/mate-avatars/C47.png +0 -0
  277. package/lib/public/mate-avatars/C48.png +0 -0
  278. package/lib/public/mate-avatars/catalog.json +482 -0
  279. package/lib/public/mate-avatars/lead-clay.png +0 -0
  280. package/lib/public/modules/admin-settings-invitations.js +2 -2
  281. package/lib/public/modules/admin-settings-projects.js +8 -4
  282. package/lib/public/modules/admin-settings-ui.js +20 -4
  283. package/lib/public/modules/admin-settings-users.js +4 -4
  284. package/lib/public/modules/app-connection.js +11 -1
  285. package/lib/public/modules/app-favicon.js +18 -9
  286. package/lib/public/modules/app-header.js +7 -4
  287. package/lib/public/modules/app-home-hub.js +2 -1
  288. package/lib/public/modules/app-loop-ui.js +2 -0
  289. package/lib/public/modules/app-message-router.js +22 -1
  290. package/lib/public/modules/app-messages.js +125 -19
  291. package/lib/public/modules/app-misc.js +3 -1
  292. package/lib/public/modules/app-notifications.js +11 -5
  293. package/lib/public/modules/app-panels.js +61 -123
  294. package/lib/public/modules/app-projects.js +14 -407
  295. package/lib/public/modules/app-rate-limit.js +19 -28
  296. package/lib/public/modules/app-rendering.js +4 -3
  297. package/lib/public/modules/avatar.js +15 -41
  298. package/lib/public/modules/chat-render-runtime.js +20 -0
  299. package/lib/public/modules/clay-browser-links.js +47 -0
  300. package/lib/public/modules/clay-control-activity.js +214 -0
  301. package/lib/public/modules/clay-control-copy.js +36 -0
  302. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  303. package/lib/public/modules/clay-control-object-targets.js +52 -0
  304. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  305. package/lib/public/modules/clay-control-targets.js +44 -0
  306. package/lib/public/modules/clay-log-links.js +23 -0
  307. package/lib/public/modules/clay-navigation-render.js +52 -0
  308. package/lib/public/modules/clay-owner-navigation.js +33 -0
  309. package/lib/public/modules/clay-session-links.js +31 -0
  310. package/lib/public/modules/clay-studio-bridge.js +20 -0
  311. package/lib/public/modules/clay-studio-document.js +67 -0
  312. package/lib/public/modules/clay-studio-render.js +146 -0
  313. package/lib/public/modules/clay-tool-activity.js +140 -0
  314. package/lib/public/modules/clay-tool-presentation.js +343 -0
  315. package/lib/public/modules/command-palette.js +162 -40
  316. package/lib/public/modules/contextual-ask-session.js +26 -0
  317. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  318. package/lib/public/modules/contextual-clay-session.js +130 -0
  319. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  320. package/lib/public/modules/contextual-clay.js +252 -0
  321. package/lib/public/modules/contextual-composer.js +91 -0
  322. package/lib/public/modules/contextual-mate-context.js +117 -0
  323. package/lib/public/modules/contextual-mate-hint.js +40 -0
  324. package/lib/public/modules/contextual-mate-identity.js +23 -0
  325. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  326. package/lib/public/modules/contextual-search.js +137 -0
  327. package/lib/public/modules/contextual-session-citations.js +58 -0
  328. package/lib/public/modules/debate.js +1 -0
  329. package/lib/public/modules/default-ai.js +11 -3
  330. package/lib/public/modules/elicitation-form.js +5 -0
  331. package/lib/public/modules/filebrowser.js +20 -1
  332. package/lib/public/modules/generation-stop.js +8 -5
  333. package/lib/public/modules/git-panel.js +3 -1
  334. package/lib/public/modules/github-star.js +66 -0
  335. package/lib/public/modules/history-replay-batch.js +13 -1
  336. package/lib/public/modules/home-debate-live.js +2 -0
  337. package/lib/public/modules/home-debate-planning.js +7 -7
  338. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  339. package/lib/public/modules/home-mate-chat.js +8 -6
  340. package/lib/public/modules/home-mate-creation.js +73 -1
  341. package/lib/public/modules/home-mate-settings.js +19 -12
  342. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  343. package/lib/public/modules/input.js +88 -10
  344. package/lib/public/modules/issues-render.js +3 -2
  345. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  346. package/lib/public/modules/markdown.js +6 -34
  347. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  348. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  349. package/lib/public/modules/mate-loading-scene.js +17 -0
  350. package/lib/public/modules/mate-management.js +40 -7
  351. package/lib/public/modules/mcp-connection-view.js +31 -13
  352. package/lib/public/modules/mcp-discovery-view.js +31 -0
  353. package/lib/public/modules/mcp-ui.js +23 -4
  354. package/lib/public/modules/mention.js +3 -0
  355. package/lib/public/modules/message-delivery.js +20 -2
  356. package/lib/public/modules/model-picker.js +2 -0
  357. package/lib/public/modules/pane-activation.js +214 -0
  358. package/lib/public/modules/pane-binding.js +82 -0
  359. package/lib/public/modules/pane-bridge.js +7 -4
  360. package/lib/public/modules/pane-browser-bridge.js +22 -0
  361. package/lib/public/modules/pane-file-bridge.js +4 -0
  362. package/lib/public/modules/pane-issue-bridge.js +4 -1
  363. package/lib/public/modules/pending-message-queue.js +1 -0
  364. package/lib/public/modules/permission-control.js +5 -4
  365. package/lib/public/modules/personal-settings-dialog.js +7 -1
  366. package/lib/public/modules/product-review.js +26 -0
  367. package/lib/public/modules/profile.js +12 -241
  368. package/lib/public/modules/project-access-recovery.js +17 -0
  369. package/lib/public/modules/project-admin-overview.js +21 -0
  370. package/lib/public/modules/project-chat-identity.js +13 -4
  371. package/lib/public/modules/project-logs-render.js +3 -0
  372. package/lib/public/modules/project-mate-creation-workspace.js +13 -4
  373. package/lib/public/modules/project-mate-navigation.js +144 -22
  374. package/lib/public/modules/project-session-visibility-settings.js +19 -16
  375. package/lib/public/modules/project-settings.js +119 -129
  376. package/lib/public/modules/project-start-dialog.js +130 -0
  377. package/lib/public/modules/project-start-folder-state.js +78 -0
  378. package/lib/public/modules/project-start-folder-view.js +190 -0
  379. package/lib/public/modules/project-start-forms.js +66 -0
  380. package/lib/public/modules/project-start-path.js +60 -0
  381. package/lib/public/modules/project-start-state.js +54 -0
  382. package/lib/public/modules/project-start-submit.js +67 -0
  383. package/lib/public/modules/projects-hub-view.js +33 -14
  384. package/lib/public/modules/projects-hub.js +10 -6
  385. package/lib/public/modules/rewind.js +5 -0
  386. package/lib/public/modules/scheduled-tasks.js +2 -0
  387. package/lib/public/modules/scheduler.js +2 -0
  388. package/lib/public/modules/search-clay-chat.js +5 -440
  389. package/lib/public/modules/server-settings.js +36 -91
  390. package/lib/public/modules/session-actions.js +5 -2
  391. package/lib/public/modules/session-context-menu.js +5 -0
  392. package/lib/public/modules/session-create-form.js +10 -10
  393. package/lib/public/modules/session-folder-layout.js +1 -1
  394. package/lib/public/modules/session-folder-view-menu.js +9 -0
  395. package/lib/public/modules/session-github.js +85 -14
  396. package/lib/public/modules/session-rich-drafts.js +21 -0
  397. package/lib/public/modules/session-switch-defer.js +67 -0
  398. package/lib/public/modules/session-work-primary.js +51 -0
  399. package/lib/public/modules/settings-defaults.js +27 -28
  400. package/lib/public/modules/settings-project-target.js +56 -0
  401. package/lib/public/modules/settings-select.js +1 -1
  402. package/lib/public/modules/settings-shell-registry.js +88 -0
  403. package/lib/public/modules/settings-shell-view.js +104 -0
  404. package/lib/public/modules/settings-shell.js +342 -0
  405. package/lib/public/modules/shared-browser-settings.js +112 -0
  406. package/lib/public/modules/shared-browser-tabs.js +13 -3
  407. package/lib/public/modules/shared-browser.js +29 -6
  408. package/lib/public/modules/sidebar-mobile.js +12 -33
  409. package/lib/public/modules/sidebar-projects.js +3 -1
  410. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  411. package/lib/public/modules/sidebar-sessions.js +1 -0
  412. package/lib/public/modules/split-group-restore.js +68 -0
  413. package/lib/public/modules/split-pair-ui.js +1 -0
  414. package/lib/public/modules/split-pane-reconciler.js +15 -0
  415. package/lib/public/modules/split-pane-renderer.js +87 -6
  416. package/lib/public/modules/split-session-boundary.js +1 -1
  417. package/lib/public/modules/split-view.js +60 -68
  418. package/lib/public/modules/sticky-note-markdown.js +72 -6
  419. package/lib/public/modules/sticky-notes-actions.js +30 -0
  420. package/lib/public/modules/sticky-notes-browser.js +9 -2
  421. package/lib/public/modules/sticky-notes-card.js +23 -7
  422. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  423. package/lib/public/modules/sticky-notes-editor.js +108 -44
  424. package/lib/public/modules/sticky-notes-shared.js +50 -2
  425. package/lib/public/modules/sticky-notes-state.js +66 -0
  426. package/lib/public/modules/sticky-notes.js +34 -51
  427. package/lib/public/modules/stt-controller.js +4 -1
  428. package/lib/public/modules/stt-recording.js +1 -1
  429. package/lib/public/modules/stt.js +7 -2
  430. package/lib/public/modules/terminal.js +9 -0
  431. package/lib/public/modules/theme.js +18 -3
  432. package/lib/public/modules/thinking-lifecycle.js +33 -3
  433. package/lib/public/modules/thinking-view.js +23 -1
  434. package/lib/public/modules/tools.js +60 -11
  435. package/lib/public/modules/tui-grab.js +1 -2
  436. package/lib/public/modules/user-settings-appearance.js +10 -3
  437. package/lib/public/modules/user-settings-editors.js +1 -1
  438. package/lib/public/modules/user-settings-layout.js +14 -30
  439. package/lib/public/modules/user-settings-preferences.js +6 -2
  440. package/lib/public/modules/user-settings-profile.js +13 -3
  441. package/lib/public/modules/user-settings.js +18 -84
  442. package/lib/public/modules/vendor-login-browser.js +5 -3
  443. package/lib/public/modules/vendor-login.js +2 -2
  444. package/lib/public/modules/vendor-priority.js +15 -1
  445. package/lib/public/modules/vendor-usage-format.js +93 -0
  446. package/lib/public/modules/vendor-usage-list.js +45 -0
  447. package/lib/public/modules/vendor-usage-model.js +215 -0
  448. package/lib/public/modules/vendor-usage-overview.js +312 -0
  449. package/lib/public/modules/wireframe-workbench.js +5 -2
  450. package/lib/public/muse-avatar.svg +4 -0
  451. package/lib/public/style.css +14 -6
  452. package/lib/public/sw.js +3 -1
  453. package/lib/public/welcome-art/conversation-desk.png +0 -0
  454. package/lib/public/welcome-art/mate-clay.png +0 -0
  455. package/lib/public/welcome-art/project-clay.png +0 -0
  456. package/lib/safe-bash-commands.js +3 -45
  457. package/lib/scheduled-task-records.js +3 -1
  458. package/lib/scheduler.js +2 -0
  459. package/lib/sdk-bridge.js +348 -402
  460. package/lib/sdk-foreground-admission.js +16 -0
  461. package/lib/sdk-mcp-descriptors.js +2 -37
  462. package/lib/sdk-message-processor.js +61 -18
  463. package/lib/sdk-quota-snapshot.js +21 -3
  464. package/lib/sdk-response-recovery.js +1 -0
  465. package/lib/sdk-worker.js +2 -677
  466. package/lib/server-admin.js +63 -16
  467. package/lib/server-appearance-settings.js +13 -1
  468. package/lib/server-contextual-clay-settings.js +40 -0
  469. package/lib/server-contextual-mate-sessions.js +70 -0
  470. package/lib/server-dm.js +2 -1
  471. package/lib/server-github-stars.js +39 -0
  472. package/lib/server-global-ws.js +26 -32
  473. package/lib/server-home-chat-events.js +18 -4
  474. package/lib/server-home-chat.js +22 -20
  475. package/lib/server-home-clay-entry.js +23 -4
  476. package/lib/server-home-clay-session-links.js +29 -9
  477. package/lib/server-home-mate-creation.js +1 -0
  478. package/lib/server-home-mcp-consent.js +14 -0
  479. package/lib/server-mates.js +25 -62
  480. package/lib/server-owner-ui.js +118 -0
  481. package/lib/server-path-access.js +38 -0
  482. package/lib/server-project-removal.js +22 -0
  483. package/lib/server-settings.js +6 -1
  484. package/lib/server.js +167 -43
  485. package/lib/session-config-transition.js +45 -0
  486. package/lib/session-folders.js +7 -2
  487. package/lib/session-fork-history.js +21 -0
  488. package/lib/session-github.js +9 -2
  489. package/lib/session-hygiene.js +3 -35
  490. package/lib/session-notes-mcp-server.js +26 -4
  491. package/lib/session-notes-writes.js +88 -0
  492. package/lib/session-permission-mode.js +4 -3
  493. package/lib/session-skill-scope.js +11 -0
  494. package/lib/session-visibility.js +25 -10
  495. package/lib/session-work-primary.js +50 -0
  496. package/lib/sessions.js +66 -99
  497. package/lib/shared-browser-cookie-sync.js +32 -0
  498. package/lib/shared-browser-cookies.js +79 -0
  499. package/lib/shared-browser-runtime.js +25 -9
  500. package/lib/shared-browser-storage-sync.js +43 -0
  501. package/lib/shared-browser-storage.js +101 -0
  502. package/lib/shared-browser-tools.js +2 -1
  503. package/lib/shared-browser-worker.js +46 -10
  504. package/lib/terminal-manager.js +65 -6
  505. package/lib/tool-llm.js +1 -1
  506. package/lib/tui-transcript-index.js +1 -132
  507. package/lib/users-contextual-clay-preferences.js +31 -0
  508. package/lib/users-permissions.js +2 -8
  509. package/lib/users.js +7 -0
  510. package/lib/vendor-login-browser.js +1 -11
  511. package/lib/vendor-usage-acp-readers.js +97 -0
  512. package/lib/vendor-usage-capabilities.js +88 -0
  513. package/lib/vendor-usage-http-readers.js +214 -0
  514. package/lib/vendor-usage-metrics.js +47 -0
  515. package/lib/vendor-usage-native-readers.js +106 -0
  516. package/lib/vendor-usage-overview.js +406 -0
  517. package/lib/vendor-usage-service.js +281 -0
  518. package/lib/workspace-assignment-service.js +25 -0
  519. package/lib/workspace-query-access.js +4 -1
  520. package/lib/workspace-query-mcp-server.js +1 -1
  521. package/lib/workspace-query-service.js +13 -2
  522. package/lib/ws-request.js +1 -0
  523. package/lib/ws-schema.js +22 -4
  524. package/lib/yoke/acp-agent-profiles.js +7 -5
  525. package/lib/yoke/adapters/antigravity.js +3 -14
  526. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  527. package/lib/yoke/adapters/claude.js +66 -50
  528. package/lib/yoke/adapters/codex-query-contract.js +25 -0
  529. package/lib/yoke/adapters/codex.js +98 -123
  530. package/lib/yoke/adapters/kiro.js +3 -1
  531. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  532. package/lib/yoke/adapters/muse.js +122 -0
  533. package/lib/yoke/auth-events.js +17 -0
  534. package/lib/yoke/claude-hook-installer.js +272 -0
  535. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  536. package/lib/yoke/claude-maintenance.js +55 -0
  537. package/lib/yoke/claude-permission-patterns.js +53 -0
  538. package/lib/yoke/claude-response-recovery.js +155 -0
  539. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  540. package/lib/yoke/claude-worker-startup.js +28 -0
  541. package/lib/yoke/clay-skill-install.js +33 -0
  542. package/lib/yoke/cli-sessions.js +300 -0
  543. package/lib/yoke/codex-app-server.js +7 -12
  544. package/lib/yoke/codex-dynamic-tool-names.js +80 -0
  545. package/lib/yoke/codex-idle-recovery.js +81 -1
  546. package/lib/yoke/codex-model-catalog.js +37 -3
  547. package/lib/yoke/codex-recovery-admission.js +164 -0
  548. package/lib/yoke/configuration.js +13 -0
  549. package/lib/yoke/discovery.js +70 -0
  550. package/lib/yoke/errors.js +8 -0
  551. package/lib/yoke/host-environment.js +7 -0
  552. package/lib/yoke/index.js +9 -51
  553. package/lib/yoke/interface.js +116 -0
  554. package/lib/yoke/kiro-acp-server.js +5 -5
  555. package/lib/yoke/legacy-sessions.js +89 -0
  556. package/lib/yoke/login-protocol.js +25 -0
  557. package/lib/yoke/maintenance.js +12 -0
  558. package/lib/yoke/mcp-proxy.js +32 -0
  559. package/lib/yoke/mcp-source-adapters.js +91 -0
  560. package/lib/yoke/mcp-source-context.js +42 -0
  561. package/lib/yoke/mcp-source-discovery.js +169 -0
  562. package/lib/yoke/mcp-source-plugins.js +68 -0
  563. package/lib/yoke/mcp-source-restrictions.js +47 -0
  564. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  565. package/lib/yoke/model-preferences.js +6 -0
  566. package/lib/yoke/muse-artifacts.js +36 -0
  567. package/lib/yoke/muse-controls.js +50 -0
  568. package/lib/yoke/muse-input.js +64 -0
  569. package/lib/yoke/muse-items.js +157 -0
  570. package/lib/yoke/muse-policy.js +52 -0
  571. package/lib/yoke/muse-query.js +428 -0
  572. package/lib/yoke/muse-runtime.js +211 -0
  573. package/lib/yoke/muse-services.js +92 -0
  574. package/lib/yoke/muse-skills.js +79 -0
  575. package/lib/yoke/muse-turns.js +71 -0
  576. package/lib/yoke/options/acp.js +2 -0
  577. package/lib/yoke/options/antigravity.js +2 -0
  578. package/lib/yoke/options/claude.js +21 -0
  579. package/lib/yoke/options/codex-defaults.js +29 -0
  580. package/lib/yoke/options/codex-settings.js +21 -0
  581. package/lib/yoke/options/codex.js +6 -0
  582. package/lib/yoke/options/kiro-defaults.js +22 -0
  583. package/lib/yoke/options/kiro.js +5 -0
  584. package/lib/yoke/options/muse.js +5 -0
  585. package/lib/yoke/provider-contract.js +5 -0
  586. package/lib/yoke/providers/antigravity-executable.js +8 -0
  587. package/lib/yoke/providers/claude-executable.js +40 -0
  588. package/lib/yoke/providers/claude-model-descriptions.js +34 -0
  589. package/lib/yoke/providers/claude-process.js +97 -0
  590. package/lib/yoke/providers/claude-provision.js +75 -0
  591. package/lib/yoke/providers/codex-errors.js +8 -0
  592. package/lib/yoke/providers/muse-executable.js +17 -0
  593. package/lib/yoke/provisioning.js +6 -0
  594. package/lib/yoke/query-options.js +10 -0
  595. package/lib/yoke/response-recovery.js +41 -0
  596. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  597. package/lib/yoke/sdk-server-factory.js +7 -0
  598. package/lib/yoke/session-history.js +8 -0
  599. package/lib/yoke/session-tool-transport.js +34 -13
  600. package/lib/yoke/settings.js +23 -0
  601. package/lib/yoke/source-locations.js +4 -0
  602. package/lib/yoke/title-query.js +18 -7
  603. package/lib/yoke/tui-transcript-index.js +132 -0
  604. package/lib/yoke/usage.js +48 -0
  605. package/lib/yoke/user-input.js +13 -0
  606. package/lib/yoke/vendor-registry.js +87 -3
  607. package/package.json +11 -4
  608. package/lib/public/modules/server-settings-navigation.js +0 -39
@@ -0,0 +1,82 @@
1
+ import { store } from './store.js';
2
+ import { getWs } from './ws-ref.js';
3
+
4
+ export function captureSessionAction() {
5
+ var state = store.snap();
6
+ return { projectSlug: state.currentSlug, ownerId: state.myUserId, sessionId: state.activeSessionId,
7
+ origin: state.sessionOriginId, socket: getWs(), binding: state.paneCommittedBinding || null,
8
+ epoch: state.sessionActionEpoch || 0 };
9
+ }
10
+
11
+ export function sessionActionCurrent(action, draftCompletion) {
12
+ var state = store.snap();
13
+ return !!action && action.socket === getWs() && state.connected &&
14
+ action.projectSlug === state.currentSlug && action.ownerId === state.myUserId &&
15
+ action.sessionId === state.activeSessionId && action.origin === state.sessionOriginId &&
16
+ action.epoch === (state.sessionActionEpoch || 0) &&
17
+ (draftCompletion || !state.deferredSessionSwitch) && !state.panePendingBinding && !state.paneSuspended &&
18
+ (action.binding ? state.paneReady && samePaneBinding(action.binding, state.paneCommittedBinding) : !state.paneCommittedBinding);
19
+ }
20
+
21
+ // Capture at callback creation, never when an old callback eventually sends.
22
+ export function sessionCallback(callback, draftCompletion) {
23
+ var action = captureSessionAction();
24
+ return function () {
25
+ if (!sessionActionCurrent(action, draftCompletion)) return;
26
+ var previous = store.get('paneCallbackBinding');
27
+ store.set({ paneCallbackBinding: action.binding });
28
+ try { return callback.apply(this, arguments); }
29
+ finally { store.set({ paneCallbackBinding: previous }); }
30
+ };
31
+ }
32
+
33
+ export function samePaneBinding(a, b) {
34
+ return !!a && !!b && ['requestId', 'generation', 'projectSlug', 'viewerId', 'ownerId', 'sessionId', 'sessionOriginId', 'role', 'workerGeneration', 'groupStamp', 'parentSessionOriginId'].every(function (key) { return a[key] === b[key]; });
35
+ }
36
+
37
+ export function samePaneTarget(a, b) {
38
+ return !!a && !!b && ['projectSlug', 'viewerId', 'ownerId', 'sessionId', 'sessionOriginId', 'role', 'workerGeneration', 'groupStamp', 'parentSessionOriginId'].every(function (key) { return a[key] === b[key]; });
39
+ }
40
+
41
+ export function paneTarget(state, sessions, id) {
42
+ var session = (sessions || []).find(function (item) { return item.id === id; });
43
+ if (!session || session.isMate || !session.sessionOriginId || (session.runtimeMode || session.mode || 'gui') !== 'gui' || session.tuiSuspended) return null;
44
+ var group = (state.splitGroups || []).find(function (item) { return item.members.indexOf(id) >= 0; });
45
+ var parent = session.sessionRole === 'worker' && sessions.find(function (item) { return item.id === session.parentSessionId; });
46
+ if (session.sessionRole === 'worker' && (!parent || !session.parentAvailable || !Number.isSafeInteger(session.workerGeneration) || !parent.sessionOriginId || parent.ownerId !== session.ownerId || !group || !group.pair || group.pair.driverId !== parent.id)) return null;
47
+ return {
48
+ projectSlug: state.currentSlug, viewerId: state.myUserId || null, ownerId: session.ownerId || null,
49
+ sessionId: session.id, sessionOriginId: session.sessionOriginId,
50
+ role: session.sessionRole === 'worker' ? 'worker' : 'driver', workerGeneration: session.workerGeneration || null,
51
+ parentSessionOriginId: parent ? parent.sessionOriginId : null,
52
+ groupStamp: group ? JSON.stringify({ id: group.id, members: group.members, pair: group.pair || null }) : null,
53
+ };
54
+ }
55
+
56
+ // Ordinary reusable panes have a live document binding; legacy/canonical frames
57
+ // retain their existing URL and receipt checks in their own bridge paths.
58
+ export function livePaneBinding(frame, message) {
59
+ if (!frame || !frame.clayPane) return false;
60
+ var api = frame.clayPane, live = api.identity();
61
+ var state = store.snap(), split = state.splitPanes;
62
+ var target = live && paneTarget(state, state.paneBindingSessions || [], live.sessionId);
63
+ return api.source === frame.contentWindow && api.document === frame.contentDocument && live && live.ready &&
64
+ samePaneTarget(target, live.binding) &&
65
+ live.ownerId === (state.myUserId || null) && live.projectSlug === state.currentSlug &&
66
+ split && split.panes.some(function (pane) { return pane.slug === live.projectSlug && pane.sessionId === live.sessionId; }) &&
67
+ (!message || samePaneBinding(live.binding, message.paneBinding));
68
+ }
69
+
70
+ export function paneMessageBinding() {
71
+ return store.get('paneReady') && !store.get('paneSuspended') ? store.get('paneCommittedBinding') : null;
72
+ }
73
+
74
+ export function currentPaneReview(container) {
75
+ if (!container || !container.paneBinding) return true;
76
+ return container.isConnected !== false && store.get('paneReady') && !store.get('paneSuspended') && samePaneBinding(container.paneBinding, store.get('paneCommittedBinding'));
77
+ }
78
+
79
+ export function paneCallbackCurrent(binding) {
80
+ var current = store.get('panePendingBinding') || store.get('paneCommittedBinding');
81
+ return current ? samePaneBinding(current, binding) : !binding;
82
+ }
@@ -1,9 +1,11 @@
1
+ import { forwardStudioPresentation } from './clay-studio-render.js';
1
2
  // Pane-side postMessage bridge for the split-view shell. A chrome-less pane
2
3
  // iframe reports its context usage up to the parent (which renders a chip in
3
4
  // the pane header) and honors panel-toggle requests coming back down.
4
5
  // Same-origin messages only, both directions.
5
6
 
6
7
  import { store } from './store.js';
8
+ import { paneMessageBinding, samePaneBinding } from './pane-binding.js';
7
9
  import { getEffectiveContextView } from './context-view-preference.js';
8
10
  import { forceExternalLinkToNewTab } from './pane-links.js';
9
11
 
@@ -11,6 +13,7 @@ export function reportPaneContext(data) {
11
13
  if (!store.get('paneMode') || window.parent === window) return;
12
14
  window.parent.postMessage({
13
15
  type: "clay-pane-context",
16
+ paneBinding: paneMessageBinding(),
14
17
  sessionId: store.get('activeSessionId'),
15
18
  pct: data.pct,
16
19
  used: data.used,
@@ -26,19 +29,18 @@ export function reportPaneContext(data) {
26
29
  // Hand the event to the parent shell, which owns the single flow.
27
30
  export function forwardPaneAuthRequired(message) {
28
31
  if (!store.get('paneMode') || window.parent === window) return false;
29
- window.parent.postMessage({ type: "clay-pane-auth-required", message: message }, window.location.origin);
32
+ window.parent.postMessage({ type: "clay-pane-auth-required", paneBinding: paneMessageBinding(), message: message }, window.location.origin);
30
33
  return true;
31
34
  }
32
35
 
33
36
  export function forwardPaneMarkdownPresentation(message) {
34
37
  if (!store.get('paneMode') || window.parent === window) return false;
35
- window.parent.postMessage({ type: "clay-pane-present-markdown", message: message }, window.location.origin);
36
- return true;
38
+ return forwardStudioPresentation(message, "clay-pane-present-markdown");
37
39
  }
38
40
 
39
41
  export function forwardPaneIssueReference(ref, projectSlug) {
40
42
  if (!store.get('paneMode') || window.parent === window) return false;
41
- window.parent.postMessage({ type: "clay-pane-open-issue", ref: ref, projectSlug: projectSlug || store.get('currentSlug') }, window.location.origin);
43
+ window.parent.postMessage({ type: "clay-pane-open-issue", paneBinding: paneMessageBinding(), ref: ref, projectSlug: projectSlug || store.get('currentSlug') }, window.location.origin);
42
44
  return true;
43
45
  }
44
46
 
@@ -70,6 +72,7 @@ export function initPaneBridge() {
70
72
  if (event.origin !== window.location.origin) return;
71
73
  var msg = event.data;
72
74
  if (!msg || msg.type !== "clay-pane-toggle-context") return;
75
+ if (event.source !== window.parent || store.get('paneCommittedBinding') && !samePaneBinding(paneMessageBinding(), msg.paneBinding)) return;
73
76
  togglePaneContextPanel();
74
77
  });
75
78
  }
@@ -0,0 +1,22 @@
1
+ import { store } from './store.js';
2
+ import { livePaneBinding, paneMessageBinding } from './pane-binding.js';
3
+ import { showToast } from './utils.js';
4
+
5
+ export function forwardPaneBrowserLink(url) {
6
+ if (!store.get('paneMode') || window.parent === window) return false;
7
+ window.parent.postMessage({ type: 'clay-pane-open-browser', paneBinding: paneMessageBinding(), url: url, projectSlug: store.get('currentSlug'), sessionId: String(store.get('activeSessionId')) }, window.location.origin);
8
+ return true;
9
+ }
10
+ export function handlePaneBrowserMessage(event, host) {
11
+ if (!event || event.origin !== window.location.origin || !host || !event.data || event.data.type !== 'clay-pane-open-browser') return false;
12
+ var msg = event.data, s = store.snap();
13
+ var frame = Array.from(host.querySelectorAll('.split-pane-frame')).find(function (item) { return item.contentWindow === event.source; });
14
+ var pane = frame && s.splitPanes && s.splitPanes.panes && s.splitPanes.panes.find(function (item) { return String(item.slug) === frame.dataset.projectSlug && String(item.sessionId) === frame.dataset.sessionId; });
15
+ if (!pane || msg.projectSlug !== s.currentSlug || msg.projectSlug !== frame.dataset.projectSlug || String(msg.sessionId) !== frame.dataset.sessionId) return true;
16
+ var expected = new URL('/p/' + encodeURIComponent(pane.slug) + '/?pane=1&session=' + encodeURIComponent(pane.sessionId), window.location.href).href;
17
+ if (frame.clayPane ? !livePaneBinding(frame, msg) : frame.src !== expected) return true;
18
+ // The authenticated host owns the browser; a live same-project pane supplies only a URL.
19
+ var binding = frame.clayPane && frame.clayPane.identity().binding;
20
+ import('./shared-browser.js').then(function (module) { if (binding && (!livePaneBinding(frame, msg) || frame.clayPane.identity().binding !== binding)) return; module.openSharedBrowserAt(msg.url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
21
+ return true;
22
+ }
@@ -1,4 +1,5 @@
1
1
  import { store } from './store.js';
2
+ import { livePaneBinding, paneMessageBinding } from './pane-binding.js';
2
3
 
3
4
  function paneFrame(host, source) {
4
5
  if (!host || !source) return null;
@@ -19,6 +20,7 @@ function matchingPane(frame, split) {
19
20
  }
20
21
 
21
22
  function hasLivePaneSource(frame, pane) {
23
+ if (frame && frame.clayPane) return livePaneBinding(frame);
22
24
  if (!frame || !pane || typeof frame.src !== "string") return false;
23
25
  var expected = "/p/" + encodeURIComponent(pane.slug) + "/?pane=1&session=" + encodeURIComponent(pane.sessionId);
24
26
  try { return new URL(expected, window.location.href).href === frame.src; } catch (e) { return false; }
@@ -41,6 +43,7 @@ export function forwardPaneFileReference(path, opts) {
41
43
  if (!store.get('paneMode') || window.parent === window || typeof path !== "string" || !path) return false;
42
44
  window.parent.postMessage({
43
45
  type: "clay-pane-open-file",
46
+ paneBinding: paneMessageBinding(),
44
47
  path: path,
45
48
  line: opts && opts.line != null ? opts.line : null,
46
49
  column: opts && opts.column != null ? opts.column : null,
@@ -57,6 +60,7 @@ export function handlePaneFileMessage(event, host, openFile, openFiles) {
57
60
  var frame = paneFrame(host, event.source);
58
61
  var state = store.snap();
59
62
  var pane = matchingPane(frame, state.splitPanes);
63
+ if (frame && frame.clayPane && !livePaneBinding(frame, msg)) return true;
60
64
  if (!pane || !hasLivePaneSource(frame, pane) || String(pane.slug) !== String(state.currentSlug) || msg.projectSlug !== frame.dataset.projectSlug || String(msg.sessionId) !== String(frame.dataset.sessionId) || !validLocation(msg.line) || !validLocation(msg.column)) return true;
61
65
  if (typeof msg.path !== "string" || !msg.path) return true;
62
66
  if (!state.connected || typeof openFile !== "function") return true;
@@ -1,4 +1,5 @@
1
1
  import { store } from './store.js';
2
+ import { livePaneBinding } from './pane-binding.js';
2
3
  import { openIssues } from './issues.js';
3
4
 
4
5
  function isIssueReference(ref) {
@@ -8,7 +9,7 @@ function isIssueReference(ref) {
8
9
  function isPaneSource(host, source) {
9
10
  var frames = host.querySelectorAll(".split-pane-frame");
10
11
  for (var i = 0; i < frames.length; i++) {
11
- if (frames[i].contentWindow === source) return true;
12
+ if (frames[i].contentWindow === source) return !frames[i].clayPane || livePaneBinding(frames[i]);
12
13
  }
13
14
  return false;
14
15
  }
@@ -18,6 +19,8 @@ export function handlePaneIssueMessage(event, host) {
18
19
  var msg = event.data;
19
20
  if (!msg || msg.type !== "clay-pane-open-issue") return false;
20
21
  if (!isIssueReference(msg.ref) || !isPaneSource(host, event.source)) return true;
22
+ var frame = Array.from(host.querySelectorAll('.split-pane-frame')).find(function (item) { return item.contentWindow === event.source; });
23
+ if (frame && frame.clayPane && !livePaneBinding(frame, msg)) return true;
21
24
 
22
25
  var issueTarget = store.get('issuesCache') && store.get('issuesCache')[msg.ref];
23
26
  var projectSlug = (issueTarget && issueTarget.projectSlug) || msg.projectSlug || store.get('currentSlug');
@@ -330,6 +330,7 @@ function renderItem(item, index) {
330
330
  var disabled = controlsDisabled ? ' disabled aria-disabled="true"' : '';
331
331
  var text = (item.message && item.message.text || "").trim() || "Attachment-only message";
332
332
  var html = '<div class="pending-message-chip' + (item.state === "claimed" ? ' is-claimed' : '') + (scheduled ? ' is-scheduled' : '') + (futureScheduled ? ' is-future' : '') + '" data-pending-id="' + escapeHtml(item.id) + '">';
333
+ if (item.schedule && item.schedule.logicalScheduleId) html = html.replace('data-pending-id=', 'data-control-schedule-id="' + escapeHtml(item.schedule.logicalScheduleId) + '" data-control-revision="' + escapeHtml(item.schedule.logicalRevision || '') + '" data-control-runtime="' + escapeHtml(store.get('controlRuntimeId') || '') + '" data-pending-id=');
333
334
  html += '<span class="pending-message-number" aria-hidden="true">' + (index + 1) + '</span>';
334
335
  if (own && item.state === "pending") html += '<button class="pending-message-drag" type="button" data-action="drag" aria-label="Reorder queued message ' + (index + 1) + '" title="Drag, or use arrow keys to reorder"' + disabled + '>' + '<i data-lucide="grip-vertical"></i></button>';
335
336
  else html += '<span class="pending-message-drag is-static"><i data-lucide="' + (item.state === "claimed" ? "loader-circle" : "lock-keyhole") + '"></i></span>';
@@ -66,7 +66,7 @@ export function permissionStatusText(state, pending, autoSupported, autoVisible)
66
66
  if (state.permissionMode === "plan") return "Plan workflow";
67
67
  if (state.permissionMode === "acceptEdits") return "Auto-accept edits workflow";
68
68
  if (state.permissionMode === "dontAsk") return "Don't ask workflow";
69
- if (autoVisible && !autoSupported) return "Auto unavailable for this Claude session";
69
+ if (autoVisible && !autoSupported) return "Auto unavailable for this session";
70
70
  if (state.permissionMode === "auto" && !state.effectivePermissionMode) return "Auto selected · waiting for runtime";
71
71
  if (state.permissionMode === "auto" && state.effectivePermissionMode !== "auto") {
72
72
  return "Auto unavailable at runtime · using " + modeLabel(state.effectivePermissionMode);
@@ -91,7 +91,8 @@ export function renderPermissionControl(control, state) {
91
91
  var projectSlug = state.projectSlug || "";
92
92
  var sessionId = state.sessionId || null;
93
93
  var pending = permissionPendingFor(projectSlug, sessionId);
94
- var autoVisible = state.vendor === "claude";
94
+ var description = ((store.get("vendorInfo") || {})[state.vendor] || {}).configuration || {};
95
+ var autoVisible = description.auto === true || !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
95
96
  var autoSupported = !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
96
97
  var globallyForced = state.globalPermissionModeForced === true;
97
98
  var connected = state.connected !== false && !!getWs() && getWs().readyState === 1;
@@ -114,7 +115,7 @@ export function renderPermissionControl(control, state) {
114
115
  buttons[i].classList.toggle("pending", requested);
115
116
  buttons[i].setAttribute("aria-pressed", selected ? "true" : "false");
116
117
  buttons[i].setAttribute("aria-busy", requested ? "true" : "false");
117
- buttons[i].title = unsupported ? "Auto permissions are unavailable for this Claude session." : buttonTitles[mode];
118
+ buttons[i].title = unsupported ? "Auto permissions are unavailable for this session." : buttonTitles[mode];
118
119
  }
119
120
  var status = control.querySelector(".session-permission-status");
120
121
  if (status) {
@@ -138,7 +139,7 @@ export function bindPermissionControl(control, getState) {
138
139
  var autoSupported = !!(state.permissionCapabilities && state.permissionCapabilities.auto === true);
139
140
  if (state.visible === false || state.locked === true || state.globalPermissionModeForced === true || state.connected === false || store.get('connected') === false) return;
140
141
  if (!state.projectSlug || state.projectSlug !== store.get('currentSlug') || !state.sessionId) return;
141
- if (mode === "auto" && (state.vendor !== "claude" || !autoSupported)) return;
142
+ if (mode === "auto" && !autoSupported) return;
142
143
  sendPermissionMode(state.projectSlug, state.sessionId, mode);
143
144
  });
144
145
  }
@@ -17,7 +17,13 @@ export function preparePersonalConnectionDialog(overlay, inline) {
17
17
  if (label && input) label.htmlFor = input.id;
18
18
  });
19
19
  enhanceSettingsSelects(overlay);
20
- function markDirty() { dirty = true; if (inline) store.set({personalEmailDirty:true}); }
20
+ var fields = Array.from(overlay.querySelectorAll('input,select,textarea'));
21
+ function value(field) {return field.type === 'checkbox' ? field.checked : field.value;}
22
+ var baseline = fields.map(value);
23
+ function markDirty() {
24
+ dirty = fields.some(function (field, index) {return value(field) !== baseline[index];});
25
+ if (inline) store.set({personalEmailDirty:dirty});
26
+ }
21
27
  overlay.addEventListener('input', markDirty);
22
28
  overlay.addEventListener('change', markDirty);
23
29
  var unsubscribe = inline ? store.subscribe(function (state, previousState) {
@@ -0,0 +1,26 @@
1
+ // Display-only metadata from a bound product service. The exact question and
2
+ // authenticated response remain unchanged; this renderer grants no authority.
3
+ export function renderProductReview(element, question) {
4
+ var review = question.review;
5
+ if (!review || review.kind !== 'product-control' || typeof review.action !== 'string' || typeof review.target !== 'string' || typeof review.context !== 'string' || typeof review.reason !== 'string') return false;
6
+ element.classList.add('product-review');
7
+ element.textContent = '';
8
+ function text(tag, className, value) {
9
+ var node = document.createElement(tag);
10
+ node.className = className;
11
+ node.textContent = value;
12
+ element.appendChild(node);
13
+ }
14
+ text('strong', 'product-review-action', review.action + ': ' + review.target);
15
+ text('p', 'product-review-context', review.context);
16
+ text('p', 'product-review-reason', review.reason);
17
+ var details = document.createElement('details');
18
+ var summary = document.createElement('summary');
19
+ summary.textContent = 'Exact request details';
20
+ var payload = document.createElement('pre');
21
+ payload.textContent = question.question;
22
+ details.appendChild(summary);
23
+ details.appendChild(payload);
24
+ element.appendChild(details);
25
+ return true;
26
+ }
@@ -4,7 +4,7 @@ import { setChatLayout } from './theme.js';
4
4
  // Generated identities use deterministic local pixel identicons.
5
5
 
6
6
  import { iconHtml, refreshIcons } from './icons.js';
7
- import { avatarUrl, mateAvatarUrl, mateMarkUrl, userAvatarSeed } from './avatar.js';
7
+ import { avatarUrl, userAvatarSeed } from './avatar.js';
8
8
  import { store } from './store.js';
9
9
  import { applyTerminalFont } from './terminal-prefs.js';
10
10
 
@@ -135,9 +135,12 @@ export function uploadAvatarBlob(blob) {
135
135
  }
136
136
 
137
137
  // --- Avatar position picker ---
138
- export function showAvatarPositioner(img, objectUrl, onDone) {
138
+ // With a host element the editor mounts inline as a settings subview instead
139
+ // of a page-level overlay.
140
+ export function showAvatarPositioner(img, objectUrl, onDone, host) {
139
141
  var outputSize = 256;
140
142
  var viewSize = 220;
143
+ var priorFocus = document.activeElement;
141
144
 
142
145
  // State
143
146
  var scale = 1;
@@ -169,7 +172,7 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
169
172
 
170
173
  // Build overlay
171
174
  var overlay = document.createElement('div');
172
- overlay.className = 'avatar-positioner-overlay';
175
+ overlay.className = host ? 'avatar-positioner-inline settings-subview' : 'avatar-positioner-overlay';
173
176
 
174
177
  var container = document.createElement('div');
175
178
  container.className = 'avatar-positioner-container';
@@ -225,8 +228,10 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
225
228
  container.appendChild(btnRow);
226
229
 
227
230
  overlay.appendChild(container);
228
- document.body.appendChild(overlay);
231
+ if (host) { host.classList.add('has-subview'); host.appendChild(overlay); overlay.setAttribute('role', 'region'); overlay.setAttribute('aria-label', 'Position your avatar'); }
232
+ else document.body.appendChild(overlay);
229
233
  updatePreview();
234
+ if (host) doneFocus();
230
235
 
231
236
  // Drag
232
237
  var dragging = false;
@@ -288,9 +293,12 @@ export function showAvatarPositioner(img, objectUrl, onDone) {
288
293
  updatePreview();
289
294
  }, { passive: false });
290
295
 
296
+ function doneFocus() { closeBtn.focus(); }
297
+
291
298
  function cleanup(revoke) {
292
299
  document.removeEventListener('keydown', onOverlayKeydown);
293
300
  overlay.remove();
301
+ if (host) { host.classList.remove('has-subview'); if (priorFocus && priorFocus.isConnected) priorFocus.focus(); }
294
302
  if (revoke) URL.revokeObjectURL(objectUrl);
295
303
  }
296
304
 
@@ -586,240 +594,3 @@ export function getProfile() {
586
594
  export function getProfileLang() {
587
595
  return profile.lang;
588
596
  }
589
-
590
- // --- Mate profile popover (reuses same UI minus language) ---
591
- var matePopoverEl = null;
592
- var mateSaveTimer = null;
593
-
594
- export function showMateProfilePopover(anchorEl, mateData, onUpdate) {
595
- if (matePopoverEl) {
596
- hideMatePopover();
597
- return;
598
- }
599
-
600
- var mp = mateData.profile || {};
601
- var mateName = mp.displayName || mateData.name || '';
602
- var mateColor = mp.avatarColor || '#5857fc';
603
- var mateStyle = mp.avatarStyle || 'imprint';
604
- var mateSeed = mp.avatarSeed || mateData.id || 'mate';
605
- var mateCustom = mp.avatarCustom || '';
606
-
607
- matePopoverEl = document.createElement('div');
608
- matePopoverEl.className = 'profile-popover mate-profile-popover';
609
-
610
- var html = '';
611
-
612
- // Banner + close
613
- html += '<div class="profile-banner">';
614
- html += '<button class="profile-close-btn">&times;</button>';
615
- html += '</div>';
616
-
617
- // Avatar row
618
- var mateAvatarSrc = mateCustom ? mateCustom : mateMarkUrl(mateName || 'Mate', 80);
619
- html += '<div class="profile-avatar-row">';
620
- html += '<div class="profile-popover-avatar">';
621
- html += '<img class="profile-popover-avatar-img" src="' + mateAvatarSrc + '" alt="' + escapeAttr(mateName || 'Clay Mate') + '">';
622
- html += '</div>';
623
- html += '<div class="profile-name-display">' + escapeAttr(mateName || 'New Mate') + '</div>';
624
- html += '</div>';
625
-
626
- // Body
627
- html += '<div class="profile-popover-body">';
628
-
629
- // Name
630
- html += '<div class="profile-field">';
631
- html += '<label class="profile-field-label">Display Name</label>';
632
- html += '<input type="text" class="profile-field-input" id="mate-profile-name" value="' + escapeAttr(mateName) + '" placeholder="Name your mate..." maxlength="50" spellcheck="false" autocomplete="off">';
633
- html += '</div>';
634
-
635
- // Avatar picker (hidden if avatar is locked)
636
- var mateAvatarLocked = mp.avatarLocked || false;
637
- if (!mateAvatarLocked) {
638
- html += '<div class="profile-field">';
639
- html += '<label class="profile-field-label">Identity</label>';
640
- html += '<div class="profile-imprint-panel">';
641
- html += '<div class="profile-imprint-preview"><img src="' + mateMarkUrl(mateName || 'Mate', 72) + '" alt="Clay Mate initial"><span><strong>Mate initial</strong><small>Based on display name</small></span></div>';
642
- html += '<div class="profile-imprint-actions profile-mate-mark-actions">';
643
- html += '<button class="profile-use-imprint' + (!mateCustom ? ' is-active' : '') + '" type="button">Use initial</button>';
644
- html += '<button class="profile-avatar-upload' + (mateCustom ? ' is-active' : '') + '" type="button">Upload image</button>';
645
- html += '</div>';
646
- html += '</div>';
647
- html += '<input type="file" id="mate-profile-avatar-file" accept="image/*" style="display:none">';
648
- html += '</div>';
649
- }
650
-
651
- html += '</div>'; // close body
652
-
653
- matePopoverEl.innerHTML = html;
654
-
655
- // State tracker
656
- var mateProfile = {
657
- displayName: mateName,
658
- avatarStyle: mateStyle,
659
- avatarSeed: mateSeed,
660
- avatarColor: mateColor,
661
- avatarCustom: mateCustom,
662
- };
663
-
664
- function refreshChatAvatars() {
665
- var newUrl = mateAvatarUrl({ profile: mateProfile, id: mateData.id }, 64);
666
- // Update all mate avatars in the chat area
667
- var bubbles = document.querySelectorAll('.dm-bubble-avatar-mate');
668
- for (var i = 0; i < bubbles.length; i++) {
669
- bubbles[i].src = newUrl;
670
- }
671
- // Update body dataset so new messages use the updated URL
672
- if (document.body.dataset.mateAvatarUrl) {
673
- document.body.dataset.mateAvatarUrl = newUrl;
674
- }
675
- // Update mate sidebar avatar
676
- var sidebarAvatar = document.querySelector('.mate-sidebar-avatar');
677
- if (sidebarAvatar) sidebarAvatar.src = newUrl;
678
- }
679
-
680
- function debouncedMateUpdate() {
681
- if (mateSaveTimer) clearTimeout(mateSaveTimer);
682
- mateSaveTimer = setTimeout(function() {
683
- if (onUpdate) onUpdate({
684
- name: mateProfile.displayName,
685
- profile: {
686
- displayName: mateProfile.displayName,
687
- avatarStyle: mateProfile.avatarStyle,
688
- avatarSeed: mateProfile.avatarSeed,
689
- avatarColor: mateProfile.avatarColor,
690
- avatarCustom: mateProfile.avatarCustom,
691
- },
692
- });
693
- refreshChatAvatars();
694
- mateSaveTimer = null;
695
- }, 400);
696
- }
697
-
698
- function updateMatePopoverHeader() {
699
- if (!matePopoverEl) return;
700
- var img = matePopoverEl.querySelector('.profile-popover-avatar-img');
701
- var nd = matePopoverEl.querySelector('.profile-name-display');
702
- if (img) img.src = mateProfile.avatarCustom
703
- ? mateProfile.avatarCustom
704
- : mateMarkUrl(mateProfile.displayName || 'Mate', 80);
705
- var preview = matePopoverEl.querySelector('.profile-imprint-preview img');
706
- if (preview) preview.src = mateMarkUrl(mateProfile.displayName || 'Mate', 72);
707
- if (nd) nd.textContent = mateProfile.displayName || 'New Mate';
708
- }
709
-
710
- // Events
711
- matePopoverEl.querySelector('.profile-close-btn').addEventListener('click', function(e) {
712
- e.stopPropagation();
713
- hideMatePopover();
714
- });
715
-
716
- var nameInput = matePopoverEl.querySelector('#mate-profile-name');
717
- nameInput.addEventListener('input', function() {
718
- mateProfile.displayName = nameInput.value.trim();
719
- updateMatePopoverHeader();
720
- debouncedMateUpdate();
721
- });
722
- nameInput.addEventListener('keydown', function(e) {
723
- if (e.key === 'Enter') { e.preventDefault(); hideMatePopover(); }
724
- e.stopPropagation();
725
- });
726
- nameInput.addEventListener('keyup', function(e) { e.stopPropagation(); });
727
- nameInput.addEventListener('keypress', function(e) { e.stopPropagation(); });
728
-
729
- // Avatar upload button
730
- var mateUploadBtn = matePopoverEl.querySelector('.profile-avatar-upload');
731
- var mateFileInput = matePopoverEl.querySelector('#mate-profile-avatar-file');
732
- if (mateUploadBtn && mateFileInput) {
733
- mateUploadBtn.addEventListener('click', function() {
734
- mateFileInput.click();
735
- });
736
- mateFileInput.addEventListener('change', function() {
737
- var file = mateFileInput.files[0];
738
- if (!file) return;
739
-
740
- function uploadMateBlob(blob) {
741
- blob.arrayBuffer().then(function(ab) {
742
- var buf = new Uint8Array(ab);
743
- fetch('/api/mate-avatar/' + encodeURIComponent(mateData.id), {
744
- method: 'POST',
745
- headers: { 'Content-Type': 'application/octet-stream' },
746
- body: buf,
747
- }).then(function(r) { return r.json(); }).then(function(data) {
748
- if (data.ok) {
749
- mateProfile.avatarCustom = data.avatar;
750
- updateMatePopoverHeader();
751
- if (mateUploadBtn) {
752
- mateUploadBtn.classList.add('is-active');
753
- }
754
- var imprintButton = matePopoverEl && matePopoverEl.querySelector('.profile-use-imprint');
755
- if (imprintButton) imprintButton.classList.remove('is-active');
756
- debouncedMateUpdate();
757
- }
758
- });
759
- });
760
- }
761
-
762
- // Load image and open position picker
763
- var img = new Image();
764
- var objectUrl = URL.createObjectURL(file);
765
- img.onload = function() {
766
- showAvatarPositioner(img, objectUrl, function(croppedBlob) {
767
- URL.revokeObjectURL(objectUrl);
768
- uploadMateBlob(croppedBlob);
769
- });
770
- };
771
- img.src = objectUrl;
772
- });
773
- }
774
-
775
- if (!mateAvatarLocked) {
776
- matePopoverEl.querySelector('.profile-use-imprint').addEventListener('click', function() {
777
- mateProfile.avatarCustom = '';
778
- updateMatePopoverHeader();
779
- matePopoverEl.querySelector('.profile-use-imprint').classList.add('is-active');
780
- matePopoverEl.querySelector('.profile-avatar-upload').classList.remove('is-active');
781
- debouncedMateUpdate();
782
- });
783
- }
784
-
785
- matePopoverEl.addEventListener('click', function(e) { e.stopPropagation(); });
786
-
787
- // Position near anchor
788
- document.body.appendChild(matePopoverEl);
789
- refreshIcons();
790
-
791
- var rect = anchorEl.getBoundingClientRect();
792
- matePopoverEl.style.position = 'fixed';
793
- matePopoverEl.style.left = (rect.right + 8) + 'px';
794
- matePopoverEl.style.zIndex = '9999';
795
- // Align bottom of popover with bottom of anchor icon
796
- var popHeight = matePopoverEl.offsetHeight;
797
- var bottomAligned = rect.bottom - popHeight;
798
- matePopoverEl.style.top = Math.max(8, bottomAligned) + 'px';
799
-
800
- setTimeout(function() {
801
- document.addEventListener('click', closeMateOnOutside);
802
- document.addEventListener('keydown', closeMateOnEscape);
803
- }, 0);
804
- }
805
-
806
- function closeMateOnOutside(e) {
807
- if (matePopoverEl && !matePopoverEl.contains(e.target)) {
808
- hideMatePopover();
809
- }
810
- }
811
-
812
- function closeMateOnEscape(e) {
813
- if (e.key === 'Escape' && matePopoverEl) {
814
- hideMatePopover();
815
- }
816
- }
817
-
818
- function hideMatePopover() {
819
- if (matePopoverEl) {
820
- matePopoverEl.remove();
821
- matePopoverEl = null;
822
- }
823
- document.removeEventListener('click', closeMateOnOutside);
824
- document.removeEventListener('keydown', closeMateOnEscape);
825
- }
@@ -0,0 +1,17 @@
1
+ import { store } from './store.js';
2
+
3
+ // Hard navigation destroys detached panels, cached transcripts and sockets.
4
+ // Clear the rendered document first so revoked content cannot linger while the
5
+ // replacement page is loading or when that request fails.
6
+ export function leaveRevokedProject(url) {
7
+ store.set({ activeSessionId: null, activeProjectSlug: null, sessionActivatedProjectSlug: null, sessions: [], splitPanes: null });
8
+ document.body.replaceChildren();
9
+ window.location.replace(url || "/");
10
+ }
11
+
12
+ export function reconnectDestination(info, slug) {
13
+ if (!slug || !info || !Array.isArray(info.projects)) return null;
14
+ var project = info.projects.find(function (item) { return item.slug === slug; });
15
+ if (!project) return "/";
16
+ return project.contentAccess === false ? "/p/" + encodeURIComponent(slug) + "/" : null;
17
+ }
@@ -0,0 +1,21 @@
1
+ // This page never opens a project socket or loads project content modules.
2
+ var tabs = Array.from(document.querySelectorAll('[role="tab"]'));
3
+ function select(tab) {
4
+ tabs.forEach(function (item) {
5
+ var active = item === tab;
6
+ item.setAttribute("aria-selected", String(active));
7
+ item.tabIndex = active ? 0 : -1;
8
+ document.getElementById(item.getAttribute("aria-controls")).hidden = !active;
9
+ });
10
+ }
11
+ tabs.forEach(function (tab, index) {
12
+ tab.addEventListener("click", function () { select(tab); });
13
+ tab.addEventListener("keydown", function (event) {
14
+ if (["ArrowLeft", "ArrowRight", "Home", "End"].indexOf(event.key) === -1) return;
15
+ event.preventDefault();
16
+ var target = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs[tabs.length - 1] : tabs[(index + (event.key === "ArrowRight" ? 1 : tabs.length - 1)) % tabs.length];
17
+ select(target);
18
+ target.focus();
19
+ });
20
+ });
21
+ select(tabs[0]);