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
@@ -12,7 +12,8 @@ export function speechContext() {
12
12
  var s = store.snap();
13
13
  return JSON.stringify([s.currentSlug, s.activeSessionId, s.dmMode, s.dmKey,
14
14
  s.dmTargetUser && s.dmTargetUser.id, s.homePrimarySurface, s.homeSubSurface,
15
- s.homeChatMateId, s.homeChatSessionId]);
15
+ s.homeChatMateId, s.homeChatSessionId, s.sessionOriginId, s.myUserId, s.sessionActionEpoch || 0,
16
+ s.paneCommittedBinding && s.paneCommittedBinding.generation]);
16
17
  }
17
18
 
18
19
  export function setSpeechStatus(id, message, isError) {
@@ -76,6 +77,7 @@ export function claimSpeech(id, input, recognition) {
76
77
  var active = { id: id, input: input, recognition: recognition, context: speechContext(),
77
78
  before: input.value, lastValue: input.value, writing: false, started: false, timeout: null };
78
79
  active.traceId = Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 7);
80
+ active.paneBinding = store.get('paneCommittedBinding') || null;
79
81
  active.traceStarted = Date.now();
80
82
  store.set({ speechActive: active, speechRetry: null });
81
83
  return active;
@@ -113,6 +115,7 @@ export function startSTT(id, input) {
113
115
  var active = { id: id, input: input, recognition: recognition, context: speechContext(),
114
116
  before: input.value, lastValue: input.value, writing: false, started: false, timeout: null };
115
117
  recognition.lang = store.get('speechLang') || 'en-US';
118
+ active.paneBinding = store.get('paneCommittedBinding') || null;
116
119
  recognition.continuous = true;
117
120
  recognition.interimResults = true;
118
121
  recognition.onstart = function () {
@@ -26,7 +26,7 @@ async function upload(active, blob) {
26
26
  model: active.model, language: active.language, blob: blob };
27
27
  failSTT(error.name === 'AbortError' ? 'Transcription timed out. Please try again.' : error.message);
28
28
  store.set({ speechRetry: retry });
29
- setTimeout(function () { if (store.get('speechRetry') === retry) store.set({ speechRetry: null }); }, 300000);
29
+ setTimeout(function () { if (store.get('speechRetry') === retry && !store.get('deferredSessionSwitch')) store.set({ speechRetry: null }); }, 300000);
30
30
  return false;
31
31
  }
32
32
  }
@@ -25,6 +25,7 @@ function bindComposer(id, inputId, wrapperId) {
25
25
  if (!button || !input || !wrapper || button.dataset.speechBound) return;
26
26
  var composer = document.getElementById(id === 'stt-btn' ? 'input-row' : 'home-mate-chat-composer') || wrapper;
27
27
  var toolbar = document.getElementById(id === 'stt-btn' ? 'input-bottom' : 'home-mate-chat-composer') || composer;
28
+ button.addEventListener('click', refreshSpeechBrowser);
28
29
  button.dataset.speechBound = 'true'; button.classList.add('stt-button');
29
30
  var group = document.createElement('span'); group.className = 'stt-controls';
30
31
  button.before(group); group.appendChild(button);
@@ -32,7 +33,7 @@ function bindComposer(id, inputId, wrapperId) {
32
33
  picker.className = 'stt-picker-toggle'; picker.innerHTML = iconHtml('chevron-down');
33
34
  picker.setAttribute('aria-label', 'Choose voice model'); picker.setAttribute('aria-haspopup', 'dialog'); picker.setAttribute('aria-expanded', 'false');
34
35
  picker.title = 'Choose voice model'; group.appendChild(picker);
35
- picker.addEventListener('click', function () { openSpeechPicker(picker); });
36
+ picker.addEventListener('click', function () { refreshSpeechBrowser(); openSpeechPicker(picker); });
36
37
  var row = document.createElement('div'); row.className = 'stt-progress'; row.hidden = true;
37
38
  var status = document.createElement('span'); status.id = id + '-status'; status.className = 'stt-status'; status.setAttribute('role', 'status');
38
39
  var timer = document.createElement('span'); timer.className = 'stt-timer'; timer.setAttribute('aria-hidden', 'true');
@@ -70,7 +71,7 @@ function bindComposer(id, inputId, wrapperId) {
70
71
  function render() {
71
72
  var active = store.get('speechActive'); var own = !!active && active.id === id;
72
73
  var model = voiceModel(); var provider = voiceProvider(model.provider);
73
- var browser = model.provider === 'browser' ? browserSpeechInfo() : null;
74
+ var browser = model.provider === 'browser' ? store.get('speechBrowserIdentity') : null;
74
75
  var pending = own && active.model && active.phase !== 'recording';
75
76
  var autoSend = own && !!active.autoSend;
76
77
  composer.classList.toggle('stt-recording', own);
@@ -117,7 +118,11 @@ function bindComposer(id, inputId, wrapperId) {
117
118
  observer.observe(input, { attributes: true, attributeFilter: ['disabled', 'readonly'] });
118
119
  render();
119
120
  }
121
+ // Browser identity may read layout; refresh on entry and interaction, not transcript updates.
122
+ function refreshSpeechBrowser() { store.set({ speechBrowserIdentity: browserSpeechInfo() }); }
120
123
  export function initSTT() {
124
+ refreshSpeechBrowser();
125
+ window.addEventListener('focus', refreshSpeechBrowser);
121
126
  initSpeechLifecycle(); initSpeechPicker();
122
127
  bindComposer('stt-btn', 'input', 'input-wrapper');
123
128
  bindComposer('home-stt-btn', 'home-mate-chat-input', 'home-mate-chat-composer-frame');
@@ -1,3 +1,4 @@
1
+ import { store } from './store.js';
1
2
  import { iconHtml, refreshIcons } from './icons.js';
2
3
  import { closeSidebar } from './sidebar.js';
3
4
  import { claimRightWorkbench, registerRightWorkbench, releaseRightWorkbench } from './right-workbench.js';
@@ -538,6 +539,8 @@ function renderTabBar() {
538
539
  (function (t) {
539
540
  var el = document.createElement("div");
540
541
  el.className = "terminal-tab";
542
+ el.dataset.controlTerminalId = String(t.id);
543
+ el.dataset.controlRuntime = store.get("controlRuntimeId") || "";
541
544
  if (t.id === activeTabId) el.classList.add("active");
542
545
  if (t.exited) el.classList.add("exited");
543
546
 
@@ -696,6 +699,7 @@ function updateTerminalBadge() {
696
699
  // --- Handle server messages ---
697
700
 
698
701
  export function handleTermList(msg) {
702
+ store.set({ clayControlTerminalViews: (msg.terminals || []).map(function (item) { return { id: item.id, identity: item.controlIdentity, revision: item.controlRevision, runtimeId: store.get('controlRuntimeId') }; }) });
699
703
  // TUI session terminals are owned by session-tui-view.js and must not
700
704
  // appear in the bottom terminal panel. Filter them out before any tab
701
705
  // bookkeeping so the panel never tries to render or auto-attach them.
@@ -762,7 +766,11 @@ export function handleTermCreated(msg) {
762
766
  }
763
767
  }
764
768
 
769
+ export function handleTerminalProjection(msg) {
770
+ if (msg.controlIdentity && msg.controlRevision) store.set({ clayControlTerminalViews: (store.get('clayControlTerminalViews') || []).map(function (item) { return item.id === msg.id && item.identity === msg.controlIdentity ? Object.assign({}, item, { revision: msg.controlRevision }) : item; }) });
771
+ }
765
772
  export function handleTermOutput(msg) {
773
+ handleTerminalProjection(msg);
766
774
  if (!msg.id) return;
767
775
  var tab = tabs.get(msg.id);
768
776
  if (tab && tab.xterm && msg.data) {
@@ -771,6 +779,7 @@ export function handleTermOutput(msg) {
771
779
  }
772
780
 
773
781
  export function handleTermResized(msg) {
782
+ handleTerminalProjection(msg);
774
783
  if (!msg.id) return;
775
784
  var tab = tabs.get(msg.id);
776
785
  if (tab && tab.xterm && msg.cols > 0 && msg.rows > 0) {
@@ -482,8 +482,13 @@ function updateToggleIcon() {
482
482
  // User settings toggle
483
483
  var usToggle = document.getElementById("us-theme-toggle");
484
484
  if (usToggle) usToggle.checked = isLight;
485
- // User island button is now a static "skins / themes" trigger; no
486
- // icon swap on mode change.
485
+ var quickToggle = document.getElementById("appearance-mode-toggle");
486
+ if (quickToggle) {
487
+ var label = isLight ? "Switch to dark mode" : "Switch to light mode";
488
+ quickToggle.setAttribute("aria-label", label);
489
+ quickToggle.title = label;
490
+ quickToggle.innerHTML = '<i data-lucide="' + (isLight ? "moon" : "sun") + '" class="cursor-share-icon" aria-hidden="true"></i>';
491
+ }
487
492
  refreshIcons();
488
493
  }
489
494
 
@@ -614,7 +619,14 @@ function rebuildPicker() {
614
619
 
615
620
  // --- Init ---
616
621
  export function initTheme() {
617
- currentThemeId = getSystemMode() === 'light' ? DEFAULT_LIGHT_THEME_ID : DEFAULT_DARK_THEME_ID;
622
+ var seed = window.__clayAppearanceSeed;
623
+ if (seed && seed.configured) store.set({ appearancePreference: seed });
624
+ var initialMode = seed && seed.configured && (seed.mode === 'light' || seed.mode === 'dark')
625
+ ? seed.mode
626
+ : getSystemMode();
627
+ currentThemeId = seed && seed.configured && seed[initialMode + 'Theme']
628
+ ? seed[initialMode + 'Theme']
629
+ : (initialMode === 'light' ? DEFAULT_LIGHT_THEME_ID : DEFAULT_DARK_THEME_ID);
618
630
  document.body.classList.toggle('wide-view', isWideView());
619
631
 
620
632
  // Load all themes from server, then apply properly
@@ -642,6 +654,9 @@ export function initTheme() {
642
654
  }
643
655
  }
644
656
 
657
+ var quickToggle = document.getElementById("appearance-mode-toggle");
658
+ if (quickToggle) quickToggle.addEventListener("click", toggleDarkMode);
659
+
645
660
  // Set initial toggle icon
646
661
  updateToggleIcon();
647
662
 
@@ -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
 
@@ -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
  }