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
@@ -614,7 +614,14 @@ function rebuildPicker() {
614
614
 
615
615
  // --- Init ---
616
616
  export function initTheme() {
617
- currentThemeId = getSystemMode() === 'light' ? DEFAULT_LIGHT_THEME_ID : DEFAULT_DARK_THEME_ID;
617
+ var seed = window.__clayAppearanceSeed;
618
+ if (seed && seed.configured) store.set({ appearancePreference: seed });
619
+ var initialMode = seed && seed.configured && (seed.mode === 'light' || seed.mode === 'dark')
620
+ ? seed.mode
621
+ : getSystemMode();
622
+ currentThemeId = seed && seed.configured && seed[initialMode + 'Theme']
623
+ ? seed[initialMode + 'Theme']
624
+ : (initialMode === 'light' ? DEFAULT_LIGHT_THEME_ID : DEFAULT_DARK_THEME_ID);
618
625
  document.body.classList.toggle('wide-view', isWideView());
619
626
 
620
627
  // Load all themes from server, then apply properly
@@ -27,6 +27,32 @@ function maybeScrollToBottom() {
27
27
  if (!store.get('replayingHistory')) scrollToBottom();
28
28
  }
29
29
 
30
+ function cancelThinkingRender() {
31
+ var frame = store.get('thinkingRenderFrame');
32
+ if (frame == null) return;
33
+ cancelAnimationFrame(frame);
34
+ store.set({ thinkingRenderFrame: null });
35
+ }
36
+
37
+ function flushThinkingRender() {
38
+ cancelThinkingRender();
39
+ var state = getThinkingState();
40
+ if (!state) return;
41
+ updateThinkingView(state.el, state.segmentText || state.latestText, state.detailsText);
42
+ }
43
+
44
+ function scheduleThinkingRender() {
45
+ if (store.get('replayingHistory') || store.get('thinkingRenderFrame') != null) return;
46
+ store.set({ thinkingRenderFrame: requestAnimationFrame(function () {
47
+ store.set({ thinkingRenderFrame: null });
48
+ var state = getThinkingState();
49
+ if (!state || !state.active) return;
50
+ keepActiveThinkingAtTail();
51
+ updateThinkingView(state.el, state.segmentText || state.latestText, state.detailsText);
52
+ maybeScrollToBottom();
53
+ }) });
54
+ }
55
+
30
56
  function createThinkingElement() {
31
57
  var el = document.createElement("div");
32
58
  el.className = "thinking-item";
@@ -111,14 +137,13 @@ export function appendThinkingText(text) {
111
137
  detailsText: thinkingState.detailsText + separator + text,
112
138
  latestText: segmentText.trim() ? segmentText : thinkingState.latestText,
113
139
  });
114
- if (!store.get('replayingHistory')) keepActiveThinkingAtTail();
115
- updateThinkingView(thinkingState.el, thinkingState.segmentText || thinkingState.latestText, thinkingState.detailsText);
116
- maybeScrollToBottom();
140
+ scheduleThinkingRender();
117
141
  }
118
142
 
119
143
  export function stopThinkingSegment(duration) {
120
144
  var thinkingState = getThinkingState();
121
145
  if (!thinkingState || !thinkingState.active) return;
146
+ cancelThinkingRender();
122
147
  var seconds = typeof duration === "number" ? duration : (Date.now() - thinkingState.startTime) / 1000;
123
148
  thinkingState = updateThinkingState(thinkingState, {
124
149
  totalDuration: thinkingState.totalDuration + seconds,
@@ -145,20 +170,25 @@ export function resetThinkingTurn() {
145
170
  }
146
171
 
147
172
  export function clearThinkingState() {
173
+ cancelThinkingRender();
148
174
  setThinkingState(null);
149
175
  }
150
176
 
151
177
  export function saveThinkingState() {
178
+ flushThinkingRender();
152
179
  return getThinkingState();
153
180
  }
154
181
 
155
182
  export function restoreThinkingState(saved) {
183
+ cancelThinkingRender();
156
184
  setThinkingState(saved || null);
185
+ if (saved && saved.active) scheduleThinkingRender();
157
186
  }
158
187
 
159
188
  export function resumeThinkingAfterReplay(processing) {
160
189
  var thinkingState = getThinkingState();
161
190
  if (!thinkingState || !thinkingState.active || !processing) return;
191
+ flushThinkingRender();
162
192
  keepActiveThinkingAtTail();
163
193
  setThinkingViewLive(thinkingState.el, !isMateThinking());
164
194
  showMateActivity(thinkingState.el, true, !!thinkingState.detailsText.trim());
@@ -1,7 +1,26 @@
1
1
  import { thinkingSummary } from './thinking-summary.js';
2
2
  import { renderMarkdown } from './markdown.js';
3
+ import { store } from './store.js';
4
+
5
+ // Retain complete source for each historical entry; parse only on disclosure.
6
+ function thinkingDetailsCache() {
7
+ var cache = store.get('thinkingDetailsCache');
8
+ if (!cache) {
9
+ cache = new WeakMap();
10
+ store.set({ thinkingDetailsCache: cache });
11
+ }
12
+ return cache;
13
+ }
14
+
15
+ function renderThinkingDetails(el) {
16
+ var details = thinkingDetailsCache().get(el);
17
+ if (!details || details.rendered === details.text) return;
18
+ el.querySelector(".thinking-content").innerHTML = details.text.trim() ? renderMarkdown(details.text) : "";
19
+ details.rendered = details.text;
20
+ }
3
21
 
4
22
  export function prepareThinkingView(el) {
23
+ thinkingDetailsCache().set(el, { text: "", rendered: "" });
5
24
  el.hidden = false;
6
25
  el.classList.remove("empty", "done", "expanded", "thinking-live");
7
26
  var header = el.querySelector(".thinking-header");
@@ -21,6 +40,7 @@ export function bindThinkingView(el) {
21
40
  var header = el.querySelector(".thinking-header");
22
41
  function toggle() {
23
42
  if (header.getAttribute("aria-disabled") === "true") return;
43
+ if (!el.classList.contains("expanded")) renderThinkingDetails(el);
24
44
  el.classList.toggle("expanded");
25
45
  header.setAttribute("aria-expanded", el.classList.contains("expanded") ? "true" : "false");
26
46
  }
@@ -37,7 +57,9 @@ export function updateThinkingView(el, summaryText, detailsText) {
37
57
  var label = el.querySelector(".thinking-label");
38
58
  label.textContent = summary;
39
59
  label.title = summary;
40
- el.querySelector(".thinking-content").innerHTML = detailsText.trim() ? renderMarkdown(detailsText) : "";
60
+ var details = thinkingDetailsCache().get(el);
61
+ if (details) details.text = detailsText;
62
+ if (el.classList.contains("expanded")) renderThinkingDetails(el);
41
63
  }
42
64
 
43
65
  export function setThinkingViewLive(el, live) {
@@ -1,3 +1,6 @@
1
+ import { renderProductReview } from './product-review.js';
2
+ import { clayToolGroupSummary } from './clay-tool-presentation.js';
3
+ import { applyClayToolItem, applyClayToolResult, finishClayToolItem, findEndedClayTool, clayToolResultGroup, bindToolGroupDisclosure, syncToolGroupDisclosure, syncClayToolGroup } from './clay-tool-activity.js';
1
4
  import { escapeHtml, copyToClipboard } from './utils.js';
2
5
  import { iconHtml, refreshIcons } from './icons.js';
3
6
  import { renderMarkdown, highlightCodeBlocks, renderMermaidBlocks } from './markdown.js';
@@ -6,6 +9,7 @@ import { openFile } from './filebrowser.js';
6
9
  import { mateAvatarUrl } from './avatar.js';
7
10
  import { getChatLayout } from './theme.js';
8
11
  import { store } from './store.js';
12
+ import { currentPaneReview } from './pane-binding.js';
9
13
  import { applyPermissionHints } from './permission-hints.js';
10
14
  import { VENDOR_NAMES } from './app-rendering.js';
11
15
  import { startThinkingSegment, appendThinkingText, stopThinkingSegment, resetThinkingTurn, clearThinkingState, saveThinkingState, restoreThinkingState, updateThinkingTokenEstimate } from './thinking-lifecycle.js';
@@ -76,6 +80,8 @@ function findToolGroup(groupId) {
76
80
  }
77
81
 
78
82
  function toolGroupSummary(group) {
83
+ var claySummary = clayToolGroupSummary(group, tools);
84
+ if (claySummary) return claySummary;
79
85
  var names = group.toolNames;
80
86
  var count = names.length;
81
87
  var allDone = group.doneCount >= count;
@@ -167,10 +173,13 @@ function updateToolGroupHeader(group) {
167
173
  header.style.display = "none";
168
174
  group.el.classList.remove("collapsed");
169
175
  }
176
+ syncToolGroupDisclosure(group.el);
177
+ syncClayToolGroup(group);
170
178
  }
171
179
 
172
180
  function isPlanFile(filePath) {
173
- return filePath && filePath.indexOf(".claude/plans/") !== -1;
181
+ var info = (store.get('vendorInfo') || {})[store.get('currentVendor')] || {};
182
+ return !!filePath && (info.planPathSegments || []).some(function (segment) { return filePath.indexOf(segment) !== -1; });
174
183
  }
175
184
 
176
185
  export function toolSummary(name, input) {
@@ -244,6 +253,7 @@ export function renderAskUserQuestion(toolId, input) {
244
253
 
245
254
  var container = document.createElement("div");
246
255
  container.className = "ask-user-container";
256
+ if (input.source === "mcp-import") container.classList.add("mcp-import-consent");
247
257
  container.dataset.toolId = toolId;
248
258
  var requestKey = getAskUserRequestKey(toolId);
249
259
  container.dataset.askUserRequestKey = requestKey;
@@ -290,6 +300,7 @@ export function renderAskUserQuestion(toolId, input) {
290
300
  var qText = document.createElement("div");
291
301
  qText.className = "ask-user-question-text";
292
302
  qText.textContent = q.question || "";
303
+ if (renderProductReview(qText, q)) qDiv.dataset.answerLabel = q.review.action;
293
304
  qDiv.appendChild(qText);
294
305
 
295
306
  var optionsDiv = document.createElement("div");
@@ -364,7 +375,7 @@ export function renderAskUserQuestion(toolId, input) {
364
375
  }
365
376
  });
366
377
  otherDiv.appendChild(otherInput);
367
- qDiv.appendChild(otherDiv);
378
+ if (q.allowOther !== false || !(q.options || []).length) qDiv.appendChild(otherDiv);
368
379
  container.appendChild(qDiv);
369
380
  });
370
381
 
@@ -384,12 +395,13 @@ export function renderAskUserQuestion(toolId, input) {
384
395
  skipBtn.className = "ask-user-skip";
385
396
  skipBtn.textContent = "Skip";
386
397
  skipBtn.addEventListener("click", function () {
398
+ if (!currentPaneReview(container)) return;
387
399
  if (container.classList.contains("answered")) return;
388
400
  container.classList.add("answered");
389
401
  markAskUserRequestAnswered(toolId);
390
402
  enableMainInput();
391
403
  if (ctx.ws && ctx.connected) {
392
- ctx.ws.send(JSON.stringify({ type: "stop" }));
404
+ ctx.ws.send(JSON.stringify({ type: "stop", paneBinding: container.paneBinding || undefined }));
393
405
  }
394
406
  });
395
407
  actions.appendChild(skipBtn);
@@ -409,6 +421,7 @@ export function renderAskUserQuestion(toolId, input) {
409
421
  container.appendChild(mateContentWrap);
410
422
  }
411
423
 
424
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
412
425
  ctx.addToMessages(container);
413
426
  disableMainInput();
414
427
  ctx.setActivity(null);
@@ -426,6 +439,7 @@ export function enableMainInput() {
426
439
  }
427
440
 
428
441
  function submitAskUserAnswer(container, toolId, questions, answers, multiSelections) {
442
+ if (!currentPaneReview(container)) return;
429
443
  if (container.classList.contains("answered") || container.dataset.askUserSubmitted === "true") return;
430
444
 
431
445
  var result = {};
@@ -451,6 +465,7 @@ function submitAskUserAnswer(container, toolId, questions, answers, multiSelecti
451
465
  if (ctx.ws && ctx.connected) {
452
466
  ctx.ws.send(JSON.stringify({
453
467
  type: "ask_user_response",
468
+ paneBinding: container.paneBinding || undefined,
454
469
  toolId: toolId,
455
470
  answers: result,
456
471
  }));
@@ -468,7 +483,8 @@ function showAnswerSummary(container, questions, answers) {
468
483
  var row = document.createElement("div");
469
484
  row.className = "ask-user-answer-row";
470
485
  var qi = parseInt(key, 10);
471
- var label = (questions && questions[qi] && questions[qi].question) ? questions[qi].question : "Answer";
486
+ var questionNode = container.querySelectorAll(".ask-user-question")[qi];
487
+ var label = questionNode && questionNode.dataset.answerLabel || (questions && questions[qi] && (questions[qi].header || questions[qi].question)) || "Answer";
472
488
  row.innerHTML = '<span class="ask-user-answer-label">' + escapeHtml(label) + '</span>' +
473
489
  '<span class="ask-user-answer-value">' + escapeHtml(String(answers[key])) + '</span>';
474
490
  summary.appendChild(row);
@@ -644,6 +660,7 @@ function renderFormalPermission(requestId, toolName, toolInput, decisionReason)
644
660
  container.appendChild(header);
645
661
  container.appendChild(body);
646
662
  container.appendChild(actions);
663
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
647
664
  ctx.addToMessages(container);
648
665
 
649
666
  pendingPermissions[requestId] = container;
@@ -751,6 +768,7 @@ function renderPlanPermission(requestId) {
751
768
  container.appendChild(body);
752
769
  container.appendChild(actions);
753
770
  container.appendChild(feedbackRow);
771
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
754
772
  ctx.addToMessages(container);
755
773
 
756
774
  pendingPermissions[requestId] = container;
@@ -758,10 +776,11 @@ function renderPlanPermission(requestId) {
758
776
  ctx.setActivity(null);
759
777
  maybeScrollToBottom();
760
778
  // Focus the feedback input after render
761
- setTimeout(function () { feedbackInput.focus(); }, 50);
779
+ setTimeout(function () { if (currentPaneReview(container)) feedbackInput.focus(); }, 50);
762
780
  }
763
781
 
764
782
  function sendPlanResponse(container, requestId, decision, feedback) {
783
+ if (!currentPaneReview(container)) return;
765
784
  if (container.classList.contains("resolved")) return;
766
785
  container.classList.add("resolved");
767
786
  if (ctx.stopUrgentBlink) ctx.stopUrgentBlink();
@@ -789,6 +808,7 @@ function sendPlanResponse(container, requestId, decision, feedback) {
789
808
  if (ctx.ws && ctx.connected) {
790
809
  var payload = {
791
810
  type: "permission_response",
811
+ paneBinding: container.paneBinding || undefined,
792
812
  requestId: requestId,
793
813
  decision: decision,
794
814
  };
@@ -943,6 +963,7 @@ function renderConversationalPermission(requestId, toolName, toolInput, mateId,
943
963
 
944
964
  container.appendChild(content);
945
965
 
966
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
946
967
  ctx.addToMessages(container);
947
968
  pendingPermissions[requestId] = container;
948
969
  refreshIcons();
@@ -951,6 +972,7 @@ function renderConversationalPermission(requestId, toolName, toolInput, mateId,
951
972
  }
952
973
 
953
974
  function sendPermissionResponse(container, requestId, decision) {
975
+ if (!currentPaneReview(container)) return;
954
976
  if (container.classList.contains("resolved")) return;
955
977
  container.classList.add("resolved");
956
978
  if (ctx.stopUrgentBlink) ctx.stopUrgentBlink();
@@ -968,6 +990,7 @@ function sendPermissionResponse(container, requestId, decision) {
968
990
  if (ctx.ws && ctx.connected) {
969
991
  ctx.ws.send(JSON.stringify({
970
992
  type: "permission_response",
993
+ paneBinding: container.paneBinding || undefined,
971
994
  requestId: requestId,
972
995
  decision: decision,
973
996
  }));
@@ -1042,6 +1065,7 @@ export function renderElicitationRequest(msg) {
1042
1065
  var container = buildElicitationCard(msg, function () {
1043
1066
  if (ctx.stopUrgentBlink) ctx.stopUrgentBlink();
1044
1067
  });
1068
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
1045
1069
  ctx.addToMessages(container);
1046
1070
  pendingElicitations[msg.requestId] = container;
1047
1071
  refreshIcons();
@@ -1068,6 +1092,7 @@ export function markElicitationError(requestId, error, expired) {
1068
1092
  var pendingUserDialogs = {};
1069
1093
 
1070
1094
  function sendUserDialogResponse(container, requestId, behavior, result) {
1095
+ if (!currentPaneReview(container)) return;
1071
1096
  if (container.classList.contains("resolved")) return;
1072
1097
  container.classList.add("resolved");
1073
1098
  if (ctx.stopUrgentBlink) ctx.stopUrgentBlink();
@@ -1083,6 +1108,7 @@ function sendUserDialogResponse(container, requestId, behavior, result) {
1083
1108
  if (ctx.ws && ctx.connected) {
1084
1109
  var msg = {
1085
1110
  type: "user_dialog_response",
1111
+ paneBinding: container.paneBinding || undefined,
1086
1112
  requestId: requestId,
1087
1113
  behavior: isCancel ? "cancelled" : "completed",
1088
1114
  };
@@ -1174,6 +1200,7 @@ export function renderUserDialogRequest(msg) {
1174
1200
  container.appendChild(header);
1175
1201
  container.appendChild(body);
1176
1202
  container.appendChild(actions);
1203
+ container.paneBinding = store.get("panePendingBinding") || store.get("paneCommittedBinding") || null;
1177
1204
  ctx.addToMessages(container);
1178
1205
 
1179
1206
  pendingUserDialogs[msg.requestId] = container;
@@ -1627,9 +1654,9 @@ export function createToolItem(id, name) {
1627
1654
  }
1628
1655
 
1629
1656
  applyProjectAssistantIdentity(groupEl, identity);
1630
- groupEl.querySelector(".tool-group-header").addEventListener("click", function () {
1631
- groupEl.classList.toggle("collapsed");
1632
- if (currentToolGroup) currentToolGroup.userToggled = true;
1657
+ bindToolGroupDisclosure(groupEl, function () {
1658
+ var group = findToolGroup(groupEl.dataset.groupId);
1659
+ if (group) group.userToggled = true;
1633
1660
  });
1634
1661
 
1635
1662
  ctx.addToMessages(groupEl);
@@ -1639,6 +1666,8 @@ export function createToolItem(id, name) {
1639
1666
  el: groupEl,
1640
1667
  id: "g" + toolGroupCounter,
1641
1668
  toolNames: [],
1669
+ toolIds: [],
1670
+ toolRecords: {},
1642
1671
  toolCount: 0,
1643
1672
  doneCount: 0,
1644
1673
  errorCount: 0,
@@ -1665,17 +1694,21 @@ export function createToolItem(id, name) {
1665
1694
 
1666
1695
  el.querySelector(".tool-name").textContent = name;
1667
1696
 
1697
+ tools[id] = { el: el, name: name, input: null, done: false, groupId: currentToolGroup.id };
1698
+ applyClayToolItem(tools[id]);
1699
+
1668
1700
  // Append to group instead of messages directly
1669
1701
  currentToolGroup.el.querySelector(".tool-group-items").appendChild(el);
1670
1702
  currentToolGroup.toolNames.push(name);
1703
+ currentToolGroup.toolIds.push(id);
1704
+ currentToolGroup.toolRecords[id] = tools[id];
1671
1705
  currentToolGroup.toolCount++;
1672
1706
  updateToolGroupHeader(currentToolGroup);
1673
1707
 
1674
1708
  refreshIcons();
1675
1709
  maybeScrollToBottom();
1676
1710
 
1677
- tools[id] = { el: el, name: name, input: null, done: false, groupId: currentToolGroup.id };
1678
- ctx.setActivity("Running " + name + "...");
1711
+ ctx.setActivity(tools[id].clayActivity ? tools[id].clayActivity.label : "Running " + name + "...");
1679
1712
  }
1680
1713
 
1681
1714
  export function updateToolExecuting(id, name, input) {
@@ -1683,6 +1716,12 @@ export function updateToolExecuting(id, name, input) {
1683
1716
  if (!tool) return;
1684
1717
 
1685
1718
  tool.input = input;
1719
+ if (applyClayToolItem(tool)) {
1720
+ ctx.setActivity(tool.clayActivity.label);
1721
+ updateToolGroupHeader(findToolGroup(tool.groupId));
1722
+ maybeScrollToBottom();
1723
+ return;
1724
+ }
1686
1725
  var descEl = tool.el.querySelector(".tool-desc");
1687
1726
  descEl.textContent = toolSummary(name, input);
1688
1727
 
@@ -1892,9 +1931,17 @@ function isImagePath(filePath) {
1892
1931
  }
1893
1932
 
1894
1933
  export function updateToolResult(id, content, isError, images) {
1895
- var tool = tools[id];
1934
+ var tool = tools[id] || findEndedClayTool(ctx.messagesEl, id);
1896
1935
  if (!tool) return;
1897
1936
 
1937
+ if (applyClayToolResult(tool, content, isError)) {
1938
+ markToolDone(id, tool.clayActivity.phase === "error" || tool.clayActivity.phase === "cancelled");
1939
+ applyClayToolItem(tool);
1940
+ updateToolGroupHeader(clayToolResultGroup(tool, findToolGroup(tool.groupId)));
1941
+ maybeScrollToBottom();
1942
+ return;
1943
+ }
1944
+
1898
1945
  // Re-render the sublabel from the now-complete input (streaming can have
1899
1946
  // built it from a partial one), but in its terminal form: a result has
1900
1947
  // arrived, so this call is no longer running.
@@ -2025,6 +2072,7 @@ export function markToolDone(id, isError) {
2025
2072
  icon.innerHTML = '<span class="check">' + iconHtml("check") + '</span>';
2026
2073
  }
2027
2074
  refreshIcons();
2075
+ finishClayToolItem(tool, findToolGroup(tool.groupId));
2028
2076
 
2029
2077
  // Update group state
2030
2078
  if (tool.groupId) {
@@ -2243,6 +2291,7 @@ export function removeToolFromGroup(toolId) {
2243
2291
  var group = findToolGroup(tool.groupId);
2244
2292
  if (!group) return;
2245
2293
  group.toolCount--;
2294
+ if (group.toolIds) group.toolIds = group.toolIds.filter(function (id) { return id !== toolId; });
2246
2295
  // Remove tool name from the names array (remove first occurrence)
2247
2296
  var idx = group.toolNames.indexOf(tool.name);
2248
2297
  if (idx !== -1) group.toolNames.splice(idx, 1);
@@ -635,10 +635,9 @@ export function attachTuiGrab(xterm, containerEl, localId, opts) {
635
635
  if (opts && opts.vendor) {
636
636
  var vendors = store.get('vendorInfo') || {};
637
637
  var info = vendors[opts.vendor];
638
- var legacyTuiVendors = ["claude"];
639
638
  var supportsTui = info
640
639
  ? Array.isArray(info.sessionModes) && info.sessionModes.indexOf("tui") !== -1
641
- : legacyTuiVendors.indexOf(opts.vendor) !== -1;
640
+ : false;
642
641
  if (!supportsTui) return;
643
642
  }
644
643
 
@@ -1,4 +1,5 @@
1
1
  import { refreshIcons } from './icons.js';
2
+ import { resetAccountSessions } from './user-settings-sessions.js';
2
3
  import { confirmSettingsAction as showConfirmDialog } from './server-settings-state.js';
3
4
  import { store } from './store.js';
4
5
  import { getWs } from './ws-ref.js';
@@ -10,6 +11,7 @@ import { syncCapsulePreference } from './capsule-preference.js';
10
11
  import { getEmailAccountListCache } from './context-sources.js';
11
12
  function applyProjectMateDmsClass(enabled) { document.body.classList.toggle('project-mate-dms-disabled', !enabled); }
12
13
  export function showPinForm() {
14
+ if (store.get('userPasswordEnabled')) { window.location.href = '/account/password'; return; }
13
15
  var pinForm = document.getElementById('us-pin-form');
14
16
  if (!pinForm) return;
15
17
  if(!pinForm.classList.contains('hidden'))return;
@@ -76,6 +78,7 @@ export function hidePinForm(force) {
76
78
  // --- Account population ---
77
79
 
78
80
  export function populateAccount() {
81
+ resetAccountSessions();
79
82
  fetch('/api/profile').then(function (r) {
80
83
  if (!r.ok) return null;
81
84
  return r.json();
@@ -98,9 +101,19 @@ export function populateAccount() {
98
101
  if (data.role) parts.push(data.role.charAt(0).toUpperCase() + data.role.slice(1));
99
102
  accountSubline.textContent = parts.length ? parts.join(' · ') : 'Local profile';
100
103
  }
101
- store.set({userPinEnabled:!!data.pinEnabled});
104
+ store.set({userPinEnabled:!!data.pinEnabled, userPasswordEnabled:!!data.passwordEnabled});
105
+ var passkeyRow = document.getElementById('us-passkey-row');
106
+ if (passkeyRow) passkeyRow.hidden = !data.passwordEnabled;
107
+ var sessionsRow = document.getElementById('us-sessions-row');
108
+ if (sessionsRow) sessionsRow.hidden = !data.passwordEnabled && !data.pinEnabled;
102
109
  if (pinSetBtnEl) {
103
110
  pinSetBtnEl.textContent = store.get('userPinEnabled') ? 'Change PIN' : 'Set PIN';
111
+ if (data.passwordEnabled) pinSetBtnEl.textContent = 'Change password';
112
+ var row = pinSetBtnEl.closest('.settings-field-row');
113
+ if (row) {
114
+ row.querySelector('.settings-label').textContent = data.passwordEnabled ? 'Password' : 'Account PIN';
115
+ row.querySelector('.settings-hint').textContent = data.passwordEnabled ? 'Change your account password or passphrase.' : 'Manage your account PIN.';
116
+ }
104
117
  }
105
118
  if (pinFormTitle) {
106
119
  pinFormTitle.textContent = store.get('userPinEnabled') ? 'Change PIN' : 'Set PIN';
@@ -31,7 +31,11 @@ function addTerminalTypography(section) {
31
31
  var option = document.createElement('option'); option.value = font.family; option.textContent = font.label; family.appendChild(option);
32
32
  });
33
33
  function sync() {
34
- if (store.get('userTerminalDirty')) return;
34
+ if (store.get('userTerminalDirty')) {
35
+ var dirty = family.value !== getTerminalFontFamily() || size.value !== String(getTerminalFontSize());
36
+ store.set({userTerminalDirty:dirty});
37
+ if (dirty) return;
38
+ }
35
39
  var value = getTerminalFontFamily();
36
40
  if (!Array.from(family.options).some(function (option) { return option.value === value; })) {
37
41
  var option = document.createElement('option'); option.value = value; option.textContent = 'Custom font'; family.appendChild(option);
@@ -41,7 +45,10 @@ function addTerminalTypography(section) {
41
45
  family.dispatchEvent(new Event('settings-sync'));
42
46
  }
43
47
  async function save() {
44
- var value = Number(size.value); store.set({ userTerminalDirty: true });
48
+ var dirty = family.value !== getTerminalFontFamily() || size.value !== String(getTerminalFontSize());
49
+ store.set({userTerminalDirty:dirty});
50
+ if (!dirty) {retry.hidden = true;status.textContent = '';status.dataset.state = '';return;}
51
+ var value = Number(size.value);
45
52
  if (!Number.isInteger(value) || value < 9 || value > 32) { status.textContent = 'Choose a whole size from 9 to 32.'; status.dataset.state = 'error'; return; }
46
53
  family.disabled = true; size.disabled = true; retry.hidden = true; status.textContent = 'Saving…'; status.dataset.state = '';
47
54
  try {
@@ -50,6 +57,6 @@ function addTerminalTypography(section) {
50
57
  finally { family.disabled = false; size.disabled = false; family.dispatchEvent(new Event('settings-sync')); }
51
58
  }
52
59
  family.onchange = save; size.onchange = save; retry.onclick = save;
53
- size.oninput = function () { store.set({ userTerminalDirty: true }); };
60
+ size.oninput = function () { store.set({ userTerminalDirty: family.value !== getTerminalFontFamily() || size.value !== String(getTerminalFontSize()) }); };
54
61
  onTerminalFontChange(sync); sync(); enhanceSettingsSelects(content);
55
62
  }
@@ -19,6 +19,6 @@ function wrapEditor(content, title, summary) {
19
19
  }
20
20
  export function initPersonalEditors() {
21
21
  var allow=document.getElementById('us-claude-allow-list');var permission=wrapEditor(allow.closest('.settings-card'),'Personal allow rules',function(){var count=(store.get('userAllowSaved') || []).length;return count+' personal rules. Managed defaults apply separately.';});
22
- permission.done.textContent='Cancel';permission.done.onclick=function(){function cancel(){allow.value=(store.get('userAllowSaved') || []).join('\n');store.set({userAllowDirty:false});permission.content.hidden=true;permission.state.hidden=false;permission.edit.hidden=false;permission.edit.focus();}if(store.get('userAllowDirty'))showConfirmDialog('Discard unsaved command rules?', 'Discard',cancel);else cancel();};
22
+ permission.done.textContent='Cancel';permission.done.onclick=function(){function cancel(){allow.value=(store.get('userAllowSaved') || []).join('\n');store.set({userAllowDirty:false,userAllowNeedsRetry:false});permission.content.hidden=true;permission.state.hidden=false;permission.edit.hidden=false;permission.edit.focus();}if(store.get('userAllowDirty'))showConfirmDialog('Discard unsaved command rules?', 'Discard',cancel);else cancel();};
23
23
  store.subscribe(function(state,previous){if(state.userAllowSaved!==previous.userAllowSaved){permission.state.textContent=(state.userAllowSaved || []).length+' personal rules. Managed defaults apply separately.';if(previous.userAllowDirty && !state.userAllowDirty){permission.content.hidden=true;permission.state.hidden=false;permission.edit.hidden=false;permission.edit.focus();}}});
24
24
  }
@@ -69,12 +69,21 @@ export function loadUserSettingsExtras(page) {
69
69
  if (page === 'us-ai') { mountDefaultAi(document.getElementById('us-default-ai')); requestDefaultAi(); var ws=getWs();if(ws && ws.readyState===1)ws.send(JSON.stringify({type:'get_claude_allow_list'})); }
70
70
  }
71
71
  export function finishUserSettingsExtras() {closeSpeechPicker();unmountDefaultAi(document.getElementById('us-default-ai'));}
72
- export function guardUserSettingsLeave(done) {
72
+ export function guardUserSettingsLeave(done, destination) {
73
+ var active = document.querySelector('#user-settings .us-section.active');
74
+ var page = active && active.dataset.section;
75
+ if (destination && resolveUserSettingsPage(destination) === page) {done();return;}
76
+ function leaving(id) {return !destination || page === id;}
73
77
  var pin = document.getElementById('us-pin-form');
74
78
  var pinDirty = pin && !pin.classList.contains('hidden') && Array.from(pin.querySelectorAll('input')).some(function (input) {return !!input.value;});
75
79
  var key = document.getElementById('us-linear-key');
76
80
  if(store.get('speechPopup'))return;
77
- var dirty = store.get('personalEmailDirty') || store.get('personalLinearDirty') || store.get('userVoiceDirty') || store.get('notificationDraft') || store.get('appearanceSaveError') || store.get('userProfileDirty') || store.get('userTerminalDirty') || pinDirty || key && key.value || store.get('defaultAiDraftDirty') || store.get('userAllowDirty');
81
+ var dirty = leaving('us-integrations') && (store.get('personalEmailDirty') || store.get('personalLinearDirty') || key && key.value) ||
82
+ leaving('us-chat') && store.get('userVoiceDirty') ||
83
+ leaving('us-notifications') && store.get('notificationDraft') ||
84
+ leaving('us-appearance') && (store.get('appearanceDraft') || store.get('userTerminalDirty')) ||
85
+ leaving('us-account') && (store.get('userProfileDirty') || pinDirty) ||
86
+ leaving('us-ai') && (store.get('defaultAiDraftDirty') || store.get('userAllowDirty'));
78
87
  if (!dirty) {done();return;}
79
88
  showConfirmDialog('Your unsaved changes will remain in this tab. Leave this editor and keep the draft?', 'Keep draft and leave', done);
80
89
  }
@@ -27,7 +27,10 @@ export function initPersonalPreferences() {
27
27
  catch(error){preferenceStatus('us-layout-switcher',error.message+' Try again.',true);}
28
28
  finally{controls.forEach(function(el){el.disabled=false;});}
29
29
  };});
30
- var textarea=document.getElementById('us-claude-allow-list');textarea.oninput=function(){store.set({userAllowDirty:true});};
30
+ var textarea=document.getElementById('us-claude-allow-list');textarea.oninput=function(){
31
+ var patterns=textarea.value.split('\n').map(function(line){return line.trim();}).filter(Boolean);
32
+ store.set({userAllowDirty:!!store.get('userAllowNeedsRetry') || JSON.stringify(patterns)!==JSON.stringify(store.get('userAllowSaved') || [])});
33
+ };
31
34
  document.getElementById('us-claude-allow-save').onclick=function(){
32
35
  var ws=getWs();if(!ws || ws.readyState!==1){preferenceStatus('us-claude-allow-list','Disconnected. Your draft is retained.',true);return;}
33
36
  this.disabled=true;preferenceStatus('us-claude-allow-list','Saving…');ws.send(JSON.stringify({type:'set_claude_user_allow_list',patterns:textarea.value.split('\n').map(function(line){return line.trim();}).filter(Boolean)}));
@@ -37,11 +40,12 @@ export function initPersonalPreferences() {
37
40
  export function handlePersonalSettingsMessage(msg) {
38
41
  if(msg.type==='claude_allow_list') {
39
42
  store.set({userAllowSaved:msg.user || []});
43
+ if(store.get('userAllowDirty'))document.getElementById('us-claude-allow-list').oninput();
40
44
  if(store.get('userAllowDirty'))return;
41
45
  }
42
46
  if(msg.type==='set_claude_user_allow_list_result') {
43
47
  document.getElementById('us-claude-allow-save').disabled=false;
44
- if(msg.ok)store.set({userAllowDirty:msg.effective===false,userAllowSaved:msg.patterns || []});
48
+ if(msg.ok)store.set({userAllowDirty:msg.effective===false,userAllowNeedsRetry:msg.effective===false,userAllowSaved:msg.patterns || []});
45
49
  var message=msg.ok ? (msg.effective===false ? 'Saved to your account, but not installed in Claude. Check filesystem access, then Save to retry.' : 'Saved. Applies on the next Claude invocation.') : msg.error || 'Save failed. Your draft is retained.';
46
50
  preferenceStatus('us-claude-allow-list',message,!msg.ok || msg.effective===false);
47
51
  }
@@ -13,10 +13,20 @@ export function initPersonalProfile() {
13
13
  name.after(form); var input = form.querySelector('input');
14
14
  function close() { form.hidden = true; name.hidden = false; edit.hidden = false; edit.focus(); }
15
15
  edit.onclick = function () {
16
- if (!store.get('userProfileDirty')) input.value = getProfile().name || name.textContent;
16
+ if (!store.get('userProfileDirty')) {
17
+ input.value = name.textContent || getProfile().name;
18
+ store.set({userProfileSavedName:input.value.trim()});
19
+ }
17
20
  form.hidden = false; name.hidden = true; edit.hidden = true; input.focus(); input.select();
18
21
  };
19
- input.oninput = function () { store.set({ userProfileDirty: true }); };
22
+ input.oninput = function () { store.set({ userProfileDirty: input.value.trim() !== store.get('userProfileSavedName') }); };
23
+ store.subscribe(function (state, previous) {
24
+ if (state.userSettingsProfile === previous.userSettingsProfile || !state.userSettingsProfile) return;
25
+ var data = state.userSettingsProfile;
26
+ var saved = data.name || data.displayName || data.username || 'Clay User';
27
+ if (!state.userProfileDirty) input.value = saved;
28
+ store.set({userProfileSavedName:saved.trim(), userProfileDirty:input.value.trim() !== saved.trim()});
29
+ });
20
30
  form.onsubmit = async function (event) {
21
31
  event.preventDefault(); var save = form.querySelector('[type=submit]'); var status = form.querySelector('[role=status]');
22
32
  if (!input.value.trim()) { status.textContent = 'Enter a display name.'; return; }