clay-server 5.2.0-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 (552) hide show
  1. package/lib/account-auth-socket.js +1 -0
  2. package/lib/builtin-mates.js +19 -16
  3. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  4. package/lib/canonical-clay-record-authority.js +15 -0
  5. package/lib/canonical-clay-scheduling-authority.js +19 -0
  6. package/lib/claude-hook-installer.js +1 -239
  7. package/lib/claude-jsonl-watcher.js +1 -204
  8. package/lib/clay-control-presentation-binding.js +96 -0
  9. package/lib/clay-control-presentation.js +128 -0
  10. package/lib/clay-control-target-projection.js +26 -0
  11. package/lib/clay-mate-chat-receipts.js +26 -0
  12. package/lib/clay-mate-chat.js +88 -0
  13. package/lib/clay-mate-knowledge-input.js +26 -0
  14. package/lib/clay-mate-knowledge.js +95 -0
  15. package/lib/clay-mate-lifecycle.js +95 -0
  16. package/lib/clay-product-control-input.js +33 -0
  17. package/lib/clay-product-control-tools.js +51 -0
  18. package/lib/clay-product-control.js +247 -0
  19. package/lib/clay-project-lifecycle.js +154 -0
  20. package/lib/clay-project-record-input.js +44 -0
  21. package/lib/clay-project-records.js +84 -0
  22. package/lib/clay-scheduling-input.js +21 -0
  23. package/lib/clay-scheduling-receipts.js +26 -0
  24. package/lib/clay-scheduling.js +119 -0
  25. package/lib/clay-screen-controls.js +104 -0
  26. package/lib/clay-skill-install.js +1 -33
  27. package/lib/clay-workspace-controls.js +84 -0
  28. package/lib/clay-workspace-input.js +17 -0
  29. package/lib/clay-workspace-receipts.js +26 -0
  30. package/lib/cli-sessions.js +1 -300
  31. package/lib/codex-defaults.js +1 -28
  32. package/lib/context-usage.js +3 -2
  33. package/lib/contextual-screen-snapshot.js +38 -0
  34. package/lib/daemon-project-access.js +11 -0
  35. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  36. package/lib/daemon-project-lifecycle.js +262 -0
  37. package/lib/daemon-projects.js +1 -1
  38. package/lib/daemon.js +78 -276
  39. package/lib/default-ai-runtime.js +4 -8
  40. package/lib/dm-digest-cursor.js +120 -0
  41. package/lib/email-mcp-server.js +1 -1
  42. package/lib/issues-service.js +29 -15
  43. package/lib/kiro-defaults.js +1 -22
  44. package/lib/knowledge-db-import-validation.js +46 -0
  45. package/lib/knowledge-db-import.js +99 -0
  46. package/lib/knowledge-db-service.js +24 -33
  47. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  48. package/lib/knowledge-db-storage-nedb.js +66 -0
  49. package/lib/knowledge-db-storage.js +72 -0
  50. package/lib/knowledge-db-validation.js +0 -0
  51. package/lib/knowledge-document-index.js +2 -1
  52. package/lib/knowledge-file-store.js +7 -1
  53. package/lib/knowledge-product-operations.js +46 -0
  54. package/lib/mate-avatar-catalog.js +12 -0
  55. package/lib/mate-avatar-migration.js +41 -0
  56. package/lib/mate-context-service.js +138 -0
  57. package/lib/mate-context-tools.js +21 -0
  58. package/lib/mate-creation-mcp-server.js +2 -0
  59. package/lib/mate-knowledge-canonical-access.js +10 -0
  60. package/lib/mate-knowledge-mate-bound.js +53 -0
  61. package/lib/mate-knowledge-mcp-server.js +55 -8
  62. package/lib/mate-knowledge-service.js +16 -34
  63. package/lib/mate-knowledge-text-tools.js +106 -0
  64. package/lib/mate-lifecycle-service.js +94 -0
  65. package/lib/mate-message-delivery.js +43 -0
  66. package/lib/mate-ready-creation.js +9 -1
  67. package/lib/mate-schedule-input.js +29 -0
  68. package/lib/mate-schedule-lifecycle.js +151 -0
  69. package/lib/mate-scheduling.js +103 -0
  70. package/lib/mates.js +18 -6
  71. package/lib/mcp-agent-tools.js +117 -0
  72. package/lib/mcp-connection-store.js +119 -15
  73. package/lib/mcp-import-credentials.js +31 -0
  74. package/lib/mcp-local-transport.js +13 -0
  75. package/lib/mcp-oauth.js +8 -6
  76. package/lib/mcp-proxy.js +2 -32
  77. package/lib/mcp-query-bridge.js +30 -0
  78. package/lib/mcp-remote-connections.js +74 -20
  79. package/lib/mcp-source-adapters.js +1 -0
  80. package/lib/mcp-source-context.js +1 -0
  81. package/lib/mcp-source-discovery.js +1 -0
  82. package/lib/mcp-source-plugins.js +1 -0
  83. package/lib/mcp-source-restrictions.js +1 -0
  84. package/lib/mcp-tool-policy.js +9 -0
  85. package/lib/notes-checklist.js +50 -0
  86. package/lib/notes.js +49 -3
  87. package/lib/os-user-diagnostics.js +2 -4
  88. package/lib/os-users.js +24 -70
  89. package/lib/pane-pending-interactions.js +20 -0
  90. package/lib/pane-session-activation.js +114 -0
  91. package/lib/pane-session-transport.js +26 -0
  92. package/lib/project-admin-overview.js +51 -0
  93. package/lib/project-ask-user.js +8 -4
  94. package/lib/project-connection.js +14 -10
  95. package/lib/project-control-git-view.js +12 -0
  96. package/lib/project-debate.js +1 -0
  97. package/lib/project-delegated-follow-up.js +2 -1
  98. package/lib/project-directory-claim.js +65 -0
  99. package/lib/project-file-operations.js +61 -0
  100. package/lib/project-filesystem.js +15 -85
  101. package/lib/project-full-access.js +23 -2
  102. package/lib/project-http.js +7 -4
  103. package/lib/project-knowledge.js +32 -18
  104. package/lib/project-lifecycle-operations.js +98 -0
  105. package/lib/project-lifecycle-process-witness.js +32 -0
  106. package/lib/project-lifecycle-runtime.js +50 -0
  107. package/lib/project-linux-access.js +22 -0
  108. package/lib/project-logs-canonical-clay.js +27 -0
  109. package/lib/project-logs-clay-query.js +16 -0
  110. package/lib/project-logs-schema.js +4 -2
  111. package/lib/project-logs-service.js +8 -7
  112. package/lib/project-logs.js +1 -0
  113. package/lib/project-loop.js +1 -0
  114. package/lib/project-mate-chat-control.js +55 -0
  115. package/lib/project-mate-creation-proposal.js +18 -3
  116. package/lib/project-mate-interaction.js +40 -62
  117. package/lib/project-mcp.js +54 -16
  118. package/lib/project-models.js +14 -31
  119. package/lib/project-notifications.js +76 -17
  120. package/lib/project-ownership.js +77 -0
  121. package/lib/project-pair-result-delivery.js +14 -3
  122. package/lib/project-pair-usage.js +12 -13
  123. package/lib/project-pending-message-queue.js +4 -1
  124. package/lib/project-product-control.js +89 -0
  125. package/lib/project-product-session-queue.js +46 -0
  126. package/lib/project-push-access.js +28 -0
  127. package/lib/project-scheduled-message-queue.js +30 -0
  128. package/lib/project-scheduled-messages.js +67 -68
  129. package/lib/project-scheduled-task-control.js +83 -0
  130. package/lib/project-scheduled-tasks.js +13 -2
  131. package/lib/project-scheduling-access.js +10 -0
  132. package/lib/project-session-actions.js +65 -0
  133. package/lib/project-session-delete.js +8 -1
  134. package/lib/project-session-document.js +27 -7
  135. package/lib/project-session-github.js +63 -19
  136. package/lib/project-session-history-actions.js +167 -0
  137. package/lib/project-session-linear.js +14 -6
  138. package/lib/project-session-notes.js +7 -3
  139. package/lib/project-session-pair.js +1 -1
  140. package/lib/project-session-runtime-actions.js +64 -0
  141. package/lib/project-session-spawn.js +2 -3
  142. package/lib/project-session-vendor.js +55 -0
  143. package/lib/project-sessions.js +103 -272
  144. package/lib/project-shared-browser.js +78 -17
  145. package/lib/project-studio-presentation.js +58 -0
  146. package/lib/project-user-message.js +67 -1
  147. package/lib/project-vendor-login.js +6 -36
  148. package/lib/project-workspace-operations.js +126 -0
  149. package/lib/project-workspace-query.js +19 -2
  150. package/lib/project.js +178 -45
  151. package/lib/public/app.js +46 -0
  152. package/lib/public/appearance-bootstrap.js +16 -0
  153. package/lib/public/css/clay-tool-activity.css +51 -0
  154. package/lib/public/css/clay-workspace.css +29 -0
  155. package/lib/public/css/command-palette.css +12 -33
  156. package/lib/public/css/contextual-clay.css +240 -0
  157. package/lib/public/css/home-debate-planning.css +2 -0
  158. package/lib/public/css/home-mate-creation.css +5 -0
  159. package/lib/public/css/input.css +6 -0
  160. package/lib/public/css/mate-avatar-gallery.css +12 -0
  161. package/lib/public/css/mate-conversation.css +10 -5
  162. package/lib/public/css/messages.css +6 -2
  163. package/lib/public/css/overlays.css +4 -2
  164. package/lib/public/css/project-admin-overview.css +13 -0
  165. package/lib/public/css/session-folders.css +11 -0
  166. package/lib/public/css/session-github.css +46 -1
  167. package/lib/public/css/shared-browser.css +35 -1
  168. package/lib/public/css/sticky-notes.css +87 -1
  169. package/lib/public/index.html +11 -5
  170. package/lib/public/mate-avatars/B01.png +0 -0
  171. package/lib/public/mate-avatars/B02.png +0 -0
  172. package/lib/public/mate-avatars/B03.png +0 -0
  173. package/lib/public/mate-avatars/B04.png +0 -0
  174. package/lib/public/mate-avatars/B05.png +0 -0
  175. package/lib/public/mate-avatars/B06.png +0 -0
  176. package/lib/public/mate-avatars/B07.png +0 -0
  177. package/lib/public/mate-avatars/B08.png +0 -0
  178. package/lib/public/mate-avatars/B09.png +0 -0
  179. package/lib/public/mate-avatars/B10.png +0 -0
  180. package/lib/public/mate-avatars/B11.png +0 -0
  181. package/lib/public/mate-avatars/B12.png +0 -0
  182. package/lib/public/mate-avatars/B13.png +0 -0
  183. package/lib/public/mate-avatars/B14.png +0 -0
  184. package/lib/public/mate-avatars/B15.png +0 -0
  185. package/lib/public/mate-avatars/B16.png +0 -0
  186. package/lib/public/mate-avatars/B17.png +0 -0
  187. package/lib/public/mate-avatars/B18.png +0 -0
  188. package/lib/public/mate-avatars/B19.png +0 -0
  189. package/lib/public/mate-avatars/B20.png +0 -0
  190. package/lib/public/mate-avatars/B21.png +0 -0
  191. package/lib/public/mate-avatars/B22.png +0 -0
  192. package/lib/public/mate-avatars/B23.png +0 -0
  193. package/lib/public/mate-avatars/B24.png +0 -0
  194. package/lib/public/mate-avatars/B25.png +0 -0
  195. package/lib/public/mate-avatars/B26.png +0 -0
  196. package/lib/public/mate-avatars/B27.png +0 -0
  197. package/lib/public/mate-avatars/B28.png +0 -0
  198. package/lib/public/mate-avatars/B29.png +0 -0
  199. package/lib/public/mate-avatars/B30.png +0 -0
  200. package/lib/public/mate-avatars/B31.png +0 -0
  201. package/lib/public/mate-avatars/B32.png +0 -0
  202. package/lib/public/mate-avatars/B33.png +0 -0
  203. package/lib/public/mate-avatars/B34.png +0 -0
  204. package/lib/public/mate-avatars/B35.png +0 -0
  205. package/lib/public/mate-avatars/B36.png +0 -0
  206. package/lib/public/mate-avatars/B37.png +0 -0
  207. package/lib/public/mate-avatars/B38.png +0 -0
  208. package/lib/public/mate-avatars/B39.png +0 -0
  209. package/lib/public/mate-avatars/B40.png +0 -0
  210. package/lib/public/mate-avatars/B41.png +0 -0
  211. package/lib/public/mate-avatars/B42.png +0 -0
  212. package/lib/public/mate-avatars/B43.png +0 -0
  213. package/lib/public/mate-avatars/B44.png +0 -0
  214. package/lib/public/mate-avatars/B45.png +0 -0
  215. package/lib/public/mate-avatars/B46.png +0 -0
  216. package/lib/public/mate-avatars/B47.png +0 -0
  217. package/lib/public/mate-avatars/B48.png +0 -0
  218. package/lib/public/mate-avatars/C01.png +0 -0
  219. package/lib/public/mate-avatars/C02.png +0 -0
  220. package/lib/public/mate-avatars/C03.png +0 -0
  221. package/lib/public/mate-avatars/C04.png +0 -0
  222. package/lib/public/mate-avatars/C05.png +0 -0
  223. package/lib/public/mate-avatars/C06.png +0 -0
  224. package/lib/public/mate-avatars/C07.png +0 -0
  225. package/lib/public/mate-avatars/C08.png +0 -0
  226. package/lib/public/mate-avatars/C09.png +0 -0
  227. package/lib/public/mate-avatars/C10.png +0 -0
  228. package/lib/public/mate-avatars/C11.png +0 -0
  229. package/lib/public/mate-avatars/C12.png +0 -0
  230. package/lib/public/mate-avatars/C13.png +0 -0
  231. package/lib/public/mate-avatars/C14.png +0 -0
  232. package/lib/public/mate-avatars/C15.png +0 -0
  233. package/lib/public/mate-avatars/C16.png +0 -0
  234. package/lib/public/mate-avatars/C17.png +0 -0
  235. package/lib/public/mate-avatars/C18.png +0 -0
  236. package/lib/public/mate-avatars/C19.png +0 -0
  237. package/lib/public/mate-avatars/C20.png +0 -0
  238. package/lib/public/mate-avatars/C21.png +0 -0
  239. package/lib/public/mate-avatars/C22.png +0 -0
  240. package/lib/public/mate-avatars/C23.png +0 -0
  241. package/lib/public/mate-avatars/C24.png +0 -0
  242. package/lib/public/mate-avatars/C25.png +0 -0
  243. package/lib/public/mate-avatars/C26.png +0 -0
  244. package/lib/public/mate-avatars/C27.png +0 -0
  245. package/lib/public/mate-avatars/C28.png +0 -0
  246. package/lib/public/mate-avatars/C29.png +0 -0
  247. package/lib/public/mate-avatars/C30.png +0 -0
  248. package/lib/public/mate-avatars/C31.png +0 -0
  249. package/lib/public/mate-avatars/C32.png +0 -0
  250. package/lib/public/mate-avatars/C33.png +0 -0
  251. package/lib/public/mate-avatars/C34.png +0 -0
  252. package/lib/public/mate-avatars/C35.png +0 -0
  253. package/lib/public/mate-avatars/C36.png +0 -0
  254. package/lib/public/mate-avatars/C37.png +0 -0
  255. package/lib/public/mate-avatars/C38.png +0 -0
  256. package/lib/public/mate-avatars/C39.png +0 -0
  257. package/lib/public/mate-avatars/C40.png +0 -0
  258. package/lib/public/mate-avatars/C41.png +0 -0
  259. package/lib/public/mate-avatars/C42.png +0 -0
  260. package/lib/public/mate-avatars/C43.png +0 -0
  261. package/lib/public/mate-avatars/C44.png +0 -0
  262. package/lib/public/mate-avatars/C45.png +0 -0
  263. package/lib/public/mate-avatars/C46.png +0 -0
  264. package/lib/public/mate-avatars/C47.png +0 -0
  265. package/lib/public/mate-avatars/C48.png +0 -0
  266. package/lib/public/mate-avatars/catalog.json +482 -0
  267. package/lib/public/mate-avatars/lead-clay.png +0 -0
  268. package/lib/public/modules/admin-settings-projects.js +6 -2
  269. package/lib/public/modules/app-connection.js +11 -1
  270. package/lib/public/modules/app-favicon.js +18 -9
  271. package/lib/public/modules/app-header.js +7 -4
  272. package/lib/public/modules/app-loop-ui.js +2 -0
  273. package/lib/public/modules/app-message-router.js +22 -1
  274. package/lib/public/modules/app-messages.js +115 -17
  275. package/lib/public/modules/app-misc.js +3 -1
  276. package/lib/public/modules/app-notifications.js +11 -5
  277. package/lib/public/modules/app-panels.js +61 -123
  278. package/lib/public/modules/app-projects.js +13 -0
  279. package/lib/public/modules/app-rate-limit.js +7 -27
  280. package/lib/public/modules/app-rendering.js +4 -3
  281. package/lib/public/modules/avatar.js +15 -41
  282. package/lib/public/modules/chat-render-runtime.js +20 -0
  283. package/lib/public/modules/clay-browser-links.js +47 -0
  284. package/lib/public/modules/clay-control-activity.js +214 -0
  285. package/lib/public/modules/clay-control-copy.js +36 -0
  286. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  287. package/lib/public/modules/clay-control-object-targets.js +52 -0
  288. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  289. package/lib/public/modules/clay-control-targets.js +44 -0
  290. package/lib/public/modules/clay-log-links.js +23 -0
  291. package/lib/public/modules/clay-navigation-render.js +52 -0
  292. package/lib/public/modules/clay-owner-navigation.js +33 -0
  293. package/lib/public/modules/clay-session-links.js +31 -0
  294. package/lib/public/modules/clay-studio-bridge.js +20 -0
  295. package/lib/public/modules/clay-studio-document.js +67 -0
  296. package/lib/public/modules/clay-studio-render.js +146 -0
  297. package/lib/public/modules/clay-tool-activity.js +140 -0
  298. package/lib/public/modules/clay-tool-presentation.js +342 -0
  299. package/lib/public/modules/command-palette.js +162 -40
  300. package/lib/public/modules/contextual-ask-session.js +26 -0
  301. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  302. package/lib/public/modules/contextual-clay-session.js +130 -0
  303. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  304. package/lib/public/modules/contextual-clay.js +250 -0
  305. package/lib/public/modules/contextual-composer.js +91 -0
  306. package/lib/public/modules/contextual-mate-context.js +117 -0
  307. package/lib/public/modules/contextual-mate-hint.js +40 -0
  308. package/lib/public/modules/contextual-mate-identity.js +23 -0
  309. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  310. package/lib/public/modules/contextual-search.js +137 -0
  311. package/lib/public/modules/contextual-session-citations.js +58 -0
  312. package/lib/public/modules/debate.js +1 -0
  313. package/lib/public/modules/default-ai.js +11 -3
  314. package/lib/public/modules/elicitation-form.js +5 -0
  315. package/lib/public/modules/filebrowser.js +20 -1
  316. package/lib/public/modules/generation-stop.js +8 -5
  317. package/lib/public/modules/git-panel.js +3 -1
  318. package/lib/public/modules/history-replay-batch.js +13 -1
  319. package/lib/public/modules/home-debate-live.js +2 -0
  320. package/lib/public/modules/home-debate-planning.js +7 -7
  321. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  322. package/lib/public/modules/home-mate-chat.js +8 -6
  323. package/lib/public/modules/home-mate-creation.js +73 -1
  324. package/lib/public/modules/home-mate-settings.js +19 -12
  325. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  326. package/lib/public/modules/input.js +88 -10
  327. package/lib/public/modules/issues-render.js +3 -2
  328. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  329. package/lib/public/modules/markdown.js +6 -34
  330. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  331. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  332. package/lib/public/modules/mate-management.js +40 -7
  333. package/lib/public/modules/mcp-connection-view.js +31 -13
  334. package/lib/public/modules/mcp-discovery-view.js +31 -0
  335. package/lib/public/modules/mcp-ui.js +23 -4
  336. package/lib/public/modules/mention.js +3 -0
  337. package/lib/public/modules/message-delivery.js +20 -2
  338. package/lib/public/modules/model-picker.js +2 -0
  339. package/lib/public/modules/pane-activation.js +214 -0
  340. package/lib/public/modules/pane-binding.js +82 -0
  341. package/lib/public/modules/pane-bridge.js +7 -4
  342. package/lib/public/modules/pane-browser-bridge.js +22 -0
  343. package/lib/public/modules/pane-file-bridge.js +4 -0
  344. package/lib/public/modules/pane-issue-bridge.js +4 -1
  345. package/lib/public/modules/pending-message-queue.js +1 -0
  346. package/lib/public/modules/permission-control.js +5 -4
  347. package/lib/public/modules/personal-settings-dialog.js +7 -1
  348. package/lib/public/modules/product-review.js +26 -0
  349. package/lib/public/modules/profile.js +1 -238
  350. package/lib/public/modules/project-access-recovery.js +17 -0
  351. package/lib/public/modules/project-admin-overview.js +21 -0
  352. package/lib/public/modules/project-chat-identity.js +13 -4
  353. package/lib/public/modules/project-logs-render.js +3 -0
  354. package/lib/public/modules/project-mate-navigation.js +144 -22
  355. package/lib/public/modules/rewind.js +5 -0
  356. package/lib/public/modules/scheduled-tasks.js +2 -0
  357. package/lib/public/modules/scheduler.js +2 -0
  358. package/lib/public/modules/search-clay-chat.js +5 -440
  359. package/lib/public/modules/session-actions.js +5 -2
  360. package/lib/public/modules/session-context-menu.js +5 -0
  361. package/lib/public/modules/session-create-form.js +10 -10
  362. package/lib/public/modules/session-folder-layout.js +1 -1
  363. package/lib/public/modules/session-folder-view-menu.js +9 -0
  364. package/lib/public/modules/session-github.js +85 -14
  365. package/lib/public/modules/session-rich-drafts.js +21 -0
  366. package/lib/public/modules/session-switch-defer.js +67 -0
  367. package/lib/public/modules/session-work-primary.js +51 -0
  368. package/lib/public/modules/settings-defaults.js +27 -28
  369. package/lib/public/modules/shared-browser-settings.js +112 -0
  370. package/lib/public/modules/shared-browser-tabs.js +13 -3
  371. package/lib/public/modules/shared-browser.js +29 -6
  372. package/lib/public/modules/sidebar-mobile.js +4 -3
  373. package/lib/public/modules/sidebar-projects.js +1 -0
  374. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  375. package/lib/public/modules/sidebar-sessions.js +1 -0
  376. package/lib/public/modules/split-group-restore.js +68 -0
  377. package/lib/public/modules/split-pair-ui.js +1 -0
  378. package/lib/public/modules/split-pane-reconciler.js +15 -0
  379. package/lib/public/modules/split-pane-renderer.js +87 -6
  380. package/lib/public/modules/split-session-boundary.js +1 -1
  381. package/lib/public/modules/split-view.js +60 -68
  382. package/lib/public/modules/sticky-note-markdown.js +72 -6
  383. package/lib/public/modules/sticky-notes-actions.js +30 -0
  384. package/lib/public/modules/sticky-notes-browser.js +9 -2
  385. package/lib/public/modules/sticky-notes-card.js +23 -7
  386. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  387. package/lib/public/modules/sticky-notes-editor.js +108 -44
  388. package/lib/public/modules/sticky-notes-shared.js +50 -2
  389. package/lib/public/modules/sticky-notes-state.js +66 -0
  390. package/lib/public/modules/sticky-notes.js +34 -51
  391. package/lib/public/modules/stt-controller.js +4 -1
  392. package/lib/public/modules/stt-recording.js +1 -1
  393. package/lib/public/modules/stt.js +7 -2
  394. package/lib/public/modules/terminal.js +9 -0
  395. package/lib/public/modules/theme.js +8 -1
  396. package/lib/public/modules/thinking-lifecycle.js +33 -3
  397. package/lib/public/modules/thinking-view.js +23 -1
  398. package/lib/public/modules/tools.js +60 -11
  399. package/lib/public/modules/tui-grab.js +1 -2
  400. package/lib/public/modules/user-settings-appearance.js +10 -3
  401. package/lib/public/modules/user-settings-editors.js +1 -1
  402. package/lib/public/modules/user-settings-layout.js +11 -2
  403. package/lib/public/modules/user-settings-preferences.js +6 -2
  404. package/lib/public/modules/user-settings-profile.js +12 -2
  405. package/lib/public/modules/user-settings.js +3 -2
  406. package/lib/public/modules/vendor-login-browser.js +5 -3
  407. package/lib/public/modules/vendor-login.js +2 -2
  408. package/lib/public/modules/vendor-priority.js +15 -1
  409. package/lib/public/modules/wireframe-workbench.js +5 -2
  410. package/lib/public/muse-avatar.svg +4 -0
  411. package/lib/public/style.css +5 -0
  412. package/lib/public/sw.js +3 -1
  413. package/lib/safe-bash-commands.js +3 -45
  414. package/lib/scheduled-task-records.js +3 -1
  415. package/lib/scheduler.js +2 -0
  416. package/lib/sdk-bridge.js +342 -401
  417. package/lib/sdk-foreground-admission.js +16 -0
  418. package/lib/sdk-mcp-descriptors.js +2 -37
  419. package/lib/sdk-message-processor.js +52 -17
  420. package/lib/sdk-quota-snapshot.js +1 -1
  421. package/lib/sdk-response-recovery.js +1 -0
  422. package/lib/sdk-worker.js +2 -677
  423. package/lib/server-admin.js +63 -16
  424. package/lib/server-appearance-settings.js +13 -1
  425. package/lib/server-contextual-clay-settings.js +40 -0
  426. package/lib/server-contextual-mate-sessions.js +70 -0
  427. package/lib/server-dm.js +2 -1
  428. package/lib/server-global-ws.js +10 -20
  429. package/lib/server-home-chat-events.js +18 -4
  430. package/lib/server-home-chat.js +22 -20
  431. package/lib/server-home-clay-entry.js +23 -4
  432. package/lib/server-home-clay-session-links.js +29 -9
  433. package/lib/server-home-mate-creation.js +1 -0
  434. package/lib/server-home-mcp-consent.js +14 -0
  435. package/lib/server-mates.js +25 -62
  436. package/lib/server-owner-ui.js +118 -0
  437. package/lib/server-path-access.js +38 -0
  438. package/lib/server-project-removal.js +22 -0
  439. package/lib/server-settings.js +6 -1
  440. package/lib/server.js +163 -43
  441. package/lib/session-config-transition.js +45 -0
  442. package/lib/session-folders.js +7 -2
  443. package/lib/session-fork-history.js +21 -0
  444. package/lib/session-github.js +9 -2
  445. package/lib/session-hygiene.js +3 -35
  446. package/lib/session-permission-mode.js +4 -3
  447. package/lib/session-skill-scope.js +11 -0
  448. package/lib/session-visibility.js +5 -2
  449. package/lib/session-work-primary.js +50 -0
  450. package/lib/sessions.js +64 -99
  451. package/lib/shared-browser-cookie-sync.js +32 -0
  452. package/lib/shared-browser-cookies.js +79 -0
  453. package/lib/shared-browser-runtime.js +25 -9
  454. package/lib/shared-browser-storage-sync.js +43 -0
  455. package/lib/shared-browser-storage.js +101 -0
  456. package/lib/shared-browser-tools.js +2 -1
  457. package/lib/shared-browser-worker.js +46 -10
  458. package/lib/terminal-manager.js +65 -6
  459. package/lib/tool-llm.js +1 -1
  460. package/lib/tui-transcript-index.js +1 -132
  461. package/lib/users-contextual-clay-preferences.js +31 -0
  462. package/lib/users-permissions.js +2 -8
  463. package/lib/users.js +7 -0
  464. package/lib/vendor-login-browser.js +1 -11
  465. package/lib/workspace-assignment-service.js +25 -0
  466. package/lib/workspace-query-access.js +4 -1
  467. package/lib/workspace-query-mcp-server.js +1 -1
  468. package/lib/workspace-query-service.js +13 -2
  469. package/lib/ws-request.js +1 -0
  470. package/lib/ws-schema.js +18 -2
  471. package/lib/yoke/acp-agent-profiles.js +7 -5
  472. package/lib/yoke/adapters/antigravity.js +3 -14
  473. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  474. package/lib/yoke/adapters/claude.js +54 -50
  475. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  476. package/lib/yoke/adapters/codex.js +53 -111
  477. package/lib/yoke/adapters/kiro.js +3 -1
  478. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  479. package/lib/yoke/adapters/muse.js +122 -0
  480. package/lib/yoke/auth-events.js +17 -0
  481. package/lib/yoke/claude-hook-installer.js +271 -0
  482. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  483. package/lib/yoke/claude-maintenance.js +55 -0
  484. package/lib/yoke/claude-permission-patterns.js +53 -0
  485. package/lib/yoke/claude-response-recovery.js +155 -0
  486. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  487. package/lib/yoke/claude-worker-startup.js +28 -0
  488. package/lib/yoke/clay-skill-install.js +33 -0
  489. package/lib/yoke/cli-sessions.js +300 -0
  490. package/lib/yoke/codex-app-server.js +7 -12
  491. package/lib/yoke/codex-idle-recovery.js +81 -1
  492. package/lib/yoke/codex-recovery-admission.js +164 -0
  493. package/lib/yoke/configuration.js +13 -0
  494. package/lib/yoke/discovery.js +70 -0
  495. package/lib/yoke/errors.js +8 -0
  496. package/lib/yoke/host-environment.js +7 -0
  497. package/lib/yoke/index.js +9 -51
  498. package/lib/yoke/interface.js +116 -0
  499. package/lib/yoke/kiro-acp-server.js +5 -5
  500. package/lib/yoke/legacy-sessions.js +89 -0
  501. package/lib/yoke/login-protocol.js +25 -0
  502. package/lib/yoke/maintenance.js +12 -0
  503. package/lib/yoke/mcp-proxy.js +32 -0
  504. package/lib/yoke/mcp-source-adapters.js +91 -0
  505. package/lib/yoke/mcp-source-context.js +42 -0
  506. package/lib/yoke/mcp-source-discovery.js +169 -0
  507. package/lib/yoke/mcp-source-plugins.js +68 -0
  508. package/lib/yoke/mcp-source-restrictions.js +47 -0
  509. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  510. package/lib/yoke/model-preferences.js +6 -0
  511. package/lib/yoke/muse-artifacts.js +36 -0
  512. package/lib/yoke/muse-controls.js +50 -0
  513. package/lib/yoke/muse-input.js +64 -0
  514. package/lib/yoke/muse-items.js +157 -0
  515. package/lib/yoke/muse-policy.js +52 -0
  516. package/lib/yoke/muse-query.js +428 -0
  517. package/lib/yoke/muse-runtime.js +211 -0
  518. package/lib/yoke/muse-services.js +79 -0
  519. package/lib/yoke/muse-skills.js +79 -0
  520. package/lib/yoke/muse-turns.js +71 -0
  521. package/lib/yoke/options/acp.js +2 -0
  522. package/lib/yoke/options/antigravity.js +2 -0
  523. package/lib/yoke/options/claude.js +21 -0
  524. package/lib/yoke/options/codex-defaults.js +29 -0
  525. package/lib/yoke/options/codex-settings.js +21 -0
  526. package/lib/yoke/options/codex.js +6 -0
  527. package/lib/yoke/options/kiro-defaults.js +22 -0
  528. package/lib/yoke/options/kiro.js +5 -0
  529. package/lib/yoke/options/muse.js +5 -0
  530. package/lib/yoke/provider-contract.js +5 -0
  531. package/lib/yoke/providers/antigravity-executable.js +8 -0
  532. package/lib/yoke/providers/claude-executable.js +40 -0
  533. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  534. package/lib/yoke/providers/claude-process.js +97 -0
  535. package/lib/yoke/providers/claude-provision.js +75 -0
  536. package/lib/yoke/providers/codex-errors.js +8 -0
  537. package/lib/yoke/providers/muse-executable.js +17 -0
  538. package/lib/yoke/provisioning.js +6 -0
  539. package/lib/yoke/query-options.js +10 -0
  540. package/lib/yoke/response-recovery.js +41 -0
  541. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  542. package/lib/yoke/sdk-server-factory.js +7 -0
  543. package/lib/yoke/session-history.js +8 -0
  544. package/lib/yoke/session-tool-transport.js +34 -13
  545. package/lib/yoke/settings.js +23 -0
  546. package/lib/yoke/source-locations.js +4 -0
  547. package/lib/yoke/title-query.js +18 -7
  548. package/lib/yoke/tui-transcript-index.js +132 -0
  549. package/lib/yoke/usage.js +48 -0
  550. package/lib/yoke/user-input.js +13 -0
  551. package/lib/yoke/vendor-registry.js +81 -1
  552. package/package.json +10 -4
@@ -4,7 +4,7 @@ import { setChatLayout } from './theme.js';
4
4
  // Generated identities use deterministic local pixel identicons.
5
5
 
6
6
  import { iconHtml, refreshIcons } from './icons.js';
7
- import { avatarUrl, mateAvatarUrl, mateMarkUrl, userAvatarSeed } from './avatar.js';
7
+ import { avatarUrl, userAvatarSeed } from './avatar.js';
8
8
  import { store } from './store.js';
9
9
  import { applyTerminalFont } from './terminal-prefs.js';
10
10
 
@@ -586,240 +586,3 @@ export function getProfile() {
586
586
  export function getProfileLang() {
587
587
  return profile.lang;
588
588
  }
589
-
590
- // --- Mate profile popover (reuses same UI minus language) ---
591
- var matePopoverEl = null;
592
- var mateSaveTimer = null;
593
-
594
- export function showMateProfilePopover(anchorEl, mateData, onUpdate) {
595
- if (matePopoverEl) {
596
- hideMatePopover();
597
- return;
598
- }
599
-
600
- var mp = mateData.profile || {};
601
- var mateName = mp.displayName || mateData.name || '';
602
- var mateColor = mp.avatarColor || '#5857fc';
603
- var mateStyle = mp.avatarStyle || 'imprint';
604
- var mateSeed = mp.avatarSeed || mateData.id || 'mate';
605
- var mateCustom = mp.avatarCustom || '';
606
-
607
- matePopoverEl = document.createElement('div');
608
- matePopoverEl.className = 'profile-popover mate-profile-popover';
609
-
610
- var html = '';
611
-
612
- // Banner + close
613
- html += '<div class="profile-banner">';
614
- html += '<button class="profile-close-btn">&times;</button>';
615
- html += '</div>';
616
-
617
- // Avatar row
618
- var mateAvatarSrc = mateCustom ? mateCustom : mateMarkUrl(mateName || 'Mate', 80);
619
- html += '<div class="profile-avatar-row">';
620
- html += '<div class="profile-popover-avatar">';
621
- html += '<img class="profile-popover-avatar-img" src="' + mateAvatarSrc + '" alt="' + escapeAttr(mateName || 'Clay Mate') + '">';
622
- html += '</div>';
623
- html += '<div class="profile-name-display">' + escapeAttr(mateName || 'New Mate') + '</div>';
624
- html += '</div>';
625
-
626
- // Body
627
- html += '<div class="profile-popover-body">';
628
-
629
- // Name
630
- html += '<div class="profile-field">';
631
- html += '<label class="profile-field-label">Display Name</label>';
632
- html += '<input type="text" class="profile-field-input" id="mate-profile-name" value="' + escapeAttr(mateName) + '" placeholder="Name your mate..." maxlength="50" spellcheck="false" autocomplete="off">';
633
- html += '</div>';
634
-
635
- // Avatar picker (hidden if avatar is locked)
636
- var mateAvatarLocked = mp.avatarLocked || false;
637
- if (!mateAvatarLocked) {
638
- html += '<div class="profile-field">';
639
- html += '<label class="profile-field-label">Identity</label>';
640
- html += '<div class="profile-imprint-panel">';
641
- html += '<div class="profile-imprint-preview"><img src="' + mateMarkUrl(mateName || 'Mate', 72) + '" alt="Clay Mate initial"><span><strong>Mate initial</strong><small>Based on display name</small></span></div>';
642
- html += '<div class="profile-imprint-actions profile-mate-mark-actions">';
643
- html += '<button class="profile-use-imprint' + (!mateCustom ? ' is-active' : '') + '" type="button">Use initial</button>';
644
- html += '<button class="profile-avatar-upload' + (mateCustom ? ' is-active' : '') + '" type="button">Upload image</button>';
645
- html += '</div>';
646
- html += '</div>';
647
- html += '<input type="file" id="mate-profile-avatar-file" accept="image/*" style="display:none">';
648
- html += '</div>';
649
- }
650
-
651
- html += '</div>'; // close body
652
-
653
- matePopoverEl.innerHTML = html;
654
-
655
- // State tracker
656
- var mateProfile = {
657
- displayName: mateName,
658
- avatarStyle: mateStyle,
659
- avatarSeed: mateSeed,
660
- avatarColor: mateColor,
661
- avatarCustom: mateCustom,
662
- };
663
-
664
- function refreshChatAvatars() {
665
- var newUrl = mateAvatarUrl({ profile: mateProfile, id: mateData.id }, 64);
666
- // Update all mate avatars in the chat area
667
- var bubbles = document.querySelectorAll('.dm-bubble-avatar-mate');
668
- for (var i = 0; i < bubbles.length; i++) {
669
- bubbles[i].src = newUrl;
670
- }
671
- // Update body dataset so new messages use the updated URL
672
- if (document.body.dataset.mateAvatarUrl) {
673
- document.body.dataset.mateAvatarUrl = newUrl;
674
- }
675
- // Update mate sidebar avatar
676
- var sidebarAvatar = document.querySelector('.mate-sidebar-avatar');
677
- if (sidebarAvatar) sidebarAvatar.src = newUrl;
678
- }
679
-
680
- function debouncedMateUpdate() {
681
- if (mateSaveTimer) clearTimeout(mateSaveTimer);
682
- mateSaveTimer = setTimeout(function() {
683
- if (onUpdate) onUpdate({
684
- name: mateProfile.displayName,
685
- profile: {
686
- displayName: mateProfile.displayName,
687
- avatarStyle: mateProfile.avatarStyle,
688
- avatarSeed: mateProfile.avatarSeed,
689
- avatarColor: mateProfile.avatarColor,
690
- avatarCustom: mateProfile.avatarCustom,
691
- },
692
- });
693
- refreshChatAvatars();
694
- mateSaveTimer = null;
695
- }, 400);
696
- }
697
-
698
- function updateMatePopoverHeader() {
699
- if (!matePopoverEl) return;
700
- var img = matePopoverEl.querySelector('.profile-popover-avatar-img');
701
- var nd = matePopoverEl.querySelector('.profile-name-display');
702
- if (img) img.src = mateProfile.avatarCustom
703
- ? mateProfile.avatarCustom
704
- : mateMarkUrl(mateProfile.displayName || 'Mate', 80);
705
- var preview = matePopoverEl.querySelector('.profile-imprint-preview img');
706
- if (preview) preview.src = mateMarkUrl(mateProfile.displayName || 'Mate', 72);
707
- if (nd) nd.textContent = mateProfile.displayName || 'New Mate';
708
- }
709
-
710
- // Events
711
- matePopoverEl.querySelector('.profile-close-btn').addEventListener('click', function(e) {
712
- e.stopPropagation();
713
- hideMatePopover();
714
- });
715
-
716
- var nameInput = matePopoverEl.querySelector('#mate-profile-name');
717
- nameInput.addEventListener('input', function() {
718
- mateProfile.displayName = nameInput.value.trim();
719
- updateMatePopoverHeader();
720
- debouncedMateUpdate();
721
- });
722
- nameInput.addEventListener('keydown', function(e) {
723
- if (e.key === 'Enter') { e.preventDefault(); hideMatePopover(); }
724
- e.stopPropagation();
725
- });
726
- nameInput.addEventListener('keyup', function(e) { e.stopPropagation(); });
727
- nameInput.addEventListener('keypress', function(e) { e.stopPropagation(); });
728
-
729
- // Avatar upload button
730
- var mateUploadBtn = matePopoverEl.querySelector('.profile-avatar-upload');
731
- var mateFileInput = matePopoverEl.querySelector('#mate-profile-avatar-file');
732
- if (mateUploadBtn && mateFileInput) {
733
- mateUploadBtn.addEventListener('click', function() {
734
- mateFileInput.click();
735
- });
736
- mateFileInput.addEventListener('change', function() {
737
- var file = mateFileInput.files[0];
738
- if (!file) return;
739
-
740
- function uploadMateBlob(blob) {
741
- blob.arrayBuffer().then(function(ab) {
742
- var buf = new Uint8Array(ab);
743
- fetch('/api/mate-avatar/' + encodeURIComponent(mateData.id), {
744
- method: 'POST',
745
- headers: { 'Content-Type': 'application/octet-stream' },
746
- body: buf,
747
- }).then(function(r) { return r.json(); }).then(function(data) {
748
- if (data.ok) {
749
- mateProfile.avatarCustom = data.avatar;
750
- updateMatePopoverHeader();
751
- if (mateUploadBtn) {
752
- mateUploadBtn.classList.add('is-active');
753
- }
754
- var imprintButton = matePopoverEl && matePopoverEl.querySelector('.profile-use-imprint');
755
- if (imprintButton) imprintButton.classList.remove('is-active');
756
- debouncedMateUpdate();
757
- }
758
- });
759
- });
760
- }
761
-
762
- // Load image and open position picker
763
- var img = new Image();
764
- var objectUrl = URL.createObjectURL(file);
765
- img.onload = function() {
766
- showAvatarPositioner(img, objectUrl, function(croppedBlob) {
767
- URL.revokeObjectURL(objectUrl);
768
- uploadMateBlob(croppedBlob);
769
- });
770
- };
771
- img.src = objectUrl;
772
- });
773
- }
774
-
775
- if (!mateAvatarLocked) {
776
- matePopoverEl.querySelector('.profile-use-imprint').addEventListener('click', function() {
777
- mateProfile.avatarCustom = '';
778
- updateMatePopoverHeader();
779
- matePopoverEl.querySelector('.profile-use-imprint').classList.add('is-active');
780
- matePopoverEl.querySelector('.profile-avatar-upload').classList.remove('is-active');
781
- debouncedMateUpdate();
782
- });
783
- }
784
-
785
- matePopoverEl.addEventListener('click', function(e) { e.stopPropagation(); });
786
-
787
- // Position near anchor
788
- document.body.appendChild(matePopoverEl);
789
- refreshIcons();
790
-
791
- var rect = anchorEl.getBoundingClientRect();
792
- matePopoverEl.style.position = 'fixed';
793
- matePopoverEl.style.left = (rect.right + 8) + 'px';
794
- matePopoverEl.style.zIndex = '9999';
795
- // Align bottom of popover with bottom of anchor icon
796
- var popHeight = matePopoverEl.offsetHeight;
797
- var bottomAligned = rect.bottom - popHeight;
798
- matePopoverEl.style.top = Math.max(8, bottomAligned) + 'px';
799
-
800
- setTimeout(function() {
801
- document.addEventListener('click', closeMateOnOutside);
802
- document.addEventListener('keydown', closeMateOnEscape);
803
- }, 0);
804
- }
805
-
806
- function closeMateOnOutside(e) {
807
- if (matePopoverEl && !matePopoverEl.contains(e.target)) {
808
- hideMatePopover();
809
- }
810
- }
811
-
812
- function closeMateOnEscape(e) {
813
- if (e.key === 'Escape' && matePopoverEl) {
814
- hideMatePopover();
815
- }
816
- }
817
-
818
- function hideMatePopover() {
819
- if (matePopoverEl) {
820
- matePopoverEl.remove();
821
- matePopoverEl = null;
822
- }
823
- document.removeEventListener('click', closeMateOnOutside);
824
- document.removeEventListener('keydown', closeMateOnEscape);
825
- }
@@ -0,0 +1,17 @@
1
+ import { store } from './store.js';
2
+
3
+ // Hard navigation destroys detached panels, cached transcripts and sockets.
4
+ // Clear the rendered document first so revoked content cannot linger while the
5
+ // replacement page is loading or when that request fails.
6
+ export function leaveRevokedProject(url) {
7
+ store.set({ activeSessionId: null, activeProjectSlug: null, sessionActivatedProjectSlug: null, sessions: [], splitPanes: null });
8
+ document.body.replaceChildren();
9
+ window.location.replace(url || "/");
10
+ }
11
+
12
+ export function reconnectDestination(info, slug) {
13
+ if (!slug || !info || !Array.isArray(info.projects)) return null;
14
+ var project = info.projects.find(function (item) { return item.slug === slug; });
15
+ if (!project) return "/";
16
+ return project.contentAccess === false ? "/p/" + encodeURIComponent(slug) + "/" : null;
17
+ }
@@ -0,0 +1,21 @@
1
+ // This page never opens a project socket or loads project content modules.
2
+ var tabs = Array.from(document.querySelectorAll('[role="tab"]'));
3
+ function select(tab) {
4
+ tabs.forEach(function (item) {
5
+ var active = item === tab;
6
+ item.setAttribute("aria-selected", String(active));
7
+ item.tabIndex = active ? 0 : -1;
8
+ document.getElementById(item.getAttribute("aria-controls")).hidden = !active;
9
+ });
10
+ }
11
+ tabs.forEach(function (tab, index) {
12
+ tab.addEventListener("click", function () { select(tab); });
13
+ tab.addEventListener("keydown", function (event) {
14
+ if (["ArrowLeft", "ArrowRight", "Home", "End"].indexOf(event.key) === -1) return;
15
+ event.preventDefault();
16
+ var target = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs[tabs.length - 1] : tabs[(index + (event.key === "ArrowRight" ? 1 : tabs.length - 1)) % tabs.length];
17
+ select(target);
18
+ target.focus();
19
+ });
20
+ });
21
+ select(tabs[0]);
@@ -4,6 +4,9 @@ import { store } from './store.js';
4
4
  import { mateAvatarUrl } from './avatar.js';
5
5
  import { VENDOR_AVATARS, VENDOR_NAMES } from './chat-render-runtime.js';
6
6
 
7
+ // A missing or failed profile image must never borrow another speaker's identity.
8
+ var NEUTRAL_AVATAR = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#888" fill-opacity=".14"/><circle cx="16" cy="12" r="5" fill="#888"/><path d="M6 29a10 10 0 0 1 20 0" fill="#888"/></svg>');
9
+
7
10
  function mateById(state, mateId) {
8
11
  var mates = state.cachedMatesList || [];
9
12
  for (var i = 0; i < mates.length; i++) {
@@ -24,12 +27,11 @@ export function resolveProjectAssistantIdentity(state, vendor) {
24
27
  if (mateId) {
25
28
  var mate = mateById(state, mateId) || dmTarget;
26
29
  var fallbackName = dmTarget && dmTarget.displayName || state.activeSessionMateName || 'Mate';
27
- var avatarMate = mate || { id: mateId, name: fallbackName, profile: { displayName: fallbackName } };
28
30
  return {
29
31
  kind: 'mate',
30
32
  mateId: mateId,
31
33
  name: mateName(mate, fallbackName),
32
- avatarUrl: mateAvatarUrl(avatarMate, 34),
34
+ avatarUrl: mate ? mateAvatarUrl(mate, 34) : NEUTRAL_AVATAR,
33
35
  };
34
36
  }
35
37
  var vendorId = vendor || state.currentVendor || 'claude';
@@ -47,9 +49,16 @@ export function getProjectAssistantPlaceholder(state, vendor) {
47
49
 
48
50
  export function applyProjectAssistantIdentity(element, identity) {
49
51
  if (!element || !identity) return element;
50
- var avatar = element.querySelector('.dm-bubble-avatar');
52
+ var avatar = element.querySelector('.dm-bubble-avatar') || element.querySelector('.activity-inline-avatar');
51
53
  var name = element.querySelector('.dm-bubble-name');
52
- if (avatar) avatar.src = identity.avatarUrl;
54
+ if (avatar) {
55
+ avatar.onerror = identity.kind === 'mate' ? function () { avatar.onerror = null; avatar.src = NEUTRAL_AVATAR; } : null;
56
+ avatar.src = identity.avatarUrl;
57
+ }
58
+ if (element.className.indexOf('activity-inline') >= 0) {
59
+ var activityLabel = element.querySelector('.activity-state-label');
60
+ element.setAttribute('aria-label', identity.name + ' · ' + (activityLabel ? activityLabel.textContent : 'Responding'));
61
+ }
53
62
  if (name) name.textContent = identity.name;
54
63
  if (identity.kind === 'mate') {
55
64
  element.dataset.sessionMateId = identity.mateId;
@@ -1,3 +1,4 @@
1
+ import { store } from './store.js';
1
2
  // Project Logs rendering — ledger rows, entry detail, and discussion.
2
3
  //
3
4
  // Split from project-logs.js so both stay well inside the module size limit.
@@ -142,6 +143,8 @@ function renderRow(entry, onOpen) {
142
143
  row.type = "button";
143
144
  row.className = "project-log-row";
144
145
  row.dataset.ref = entry.ref;
146
+ row.dataset.controlRuntime = store.get("controlRuntimeId") || "";
147
+ row.dataset.controlRevision = String(entry.revisions);
145
148
  row.setAttribute("role", "listitem");
146
149
 
147
150
  var head = document.createElement("div");
@@ -1,3 +1,6 @@
1
+ import { contextualMateStamp, contextualMate } from './contextual-mate-identity.js';
2
+ import { finishContextualWorkspace } from './contextual-clay-workspace.js';
3
+ import { initContextualClay, cycleContextualClay, contextualClayMode } from './contextual-clay.js';
1
4
  // Existing Mates share the project rail while retaining their conversations.
2
5
  import { store } from './store.js';
3
6
  import { applyWorkspaceColor } from './mate-workspace-color.js';
@@ -8,6 +11,9 @@ import { switchProject } from './app-projects.js';
8
11
  import { closeTerminal } from './terminal.js';
9
12
  import { closeFileViewer } from './filebrowser.js';
10
13
  import { getActiveMentionMateIds, onMentionActiveChange, bindIconTooltip, hideIconTooltip, showMateCtxMenu } from './sidebar-mates.js';
14
+ import { chooseProjectActivationTarget } from './project-activation.js';
15
+ import { showProjectsHub } from './projects-hub.js';
16
+ import { openProjectSession } from './project-session-navigation.js';
11
17
 
12
18
  var FILTER_MODES = ['all', 'projects', 'mates'];
13
19
  var FILTER_LABELS = { all: 'All', projects: 'Projects', mates: 'Mates' };
@@ -98,14 +104,109 @@ function renderMateHeaderDefault(state) {
98
104
  renderMateProjectHeader(state, mate);
99
105
  }
100
106
 
101
- export function openMateWorkspace(mateId) {
107
+ function ordinaryProjects(state) {
108
+ return (state.projectsHubList || []).filter(function (project) {
109
+ return project && project.slug && project.isMate !== true && project.contentAccess !== false;
110
+ });
111
+ }
112
+
113
+ function clayIsActive(state, clay) {
114
+ return !!clay && !state.homeShellVisible && !state.dmMode && state.currentSlug === 'mate-' + clay.id;
115
+ }
116
+
117
+ export function clayReturnTargetForState(state) {
118
+ var target = state && state.clayReturnTarget;
119
+ var recordedSlug = target && target.projectSlug;
120
+ var candidates = recordedSlug ? [recordedSlug] : [];
121
+ var slug = chooseProjectActivationTarget(ordinaryProjects(state), candidates);
122
+ if (!slug) return null;
123
+ var sameProject = slug === recordedSlug;
124
+ return {
125
+ projectSlug: slug,
126
+ sessionId: sameProject && target && Number.isSafeInteger(Number(target.sessionId)) && Number(target.sessionId) > 0 ? Number(target.sessionId) : null,
127
+ };
128
+ }
129
+
130
+ export function rememberClayReturnTarget(state) {
131
+ if (!state || state.homeShellVisible || state.dmMode || isMateWorkspace(state) || !state.currentSlug ||
132
+ state.activeProjectSlug !== state.currentSlug || state.sessionActivatedProjectSlug !== state.currentSlug) return;
133
+ var projects = ordinaryProjects(state);
134
+ var found = projects.some(function (project) { return project.slug === state.currentSlug; });
135
+ if (!found) return;
136
+ var target = { projectSlug: state.currentSlug, sessionId: Number.isSafeInteger(Number(state.activeSessionId)) && Number(state.activeSessionId) > 0 ? Number(state.activeSessionId) : null };
137
+ store.set({ clayReturnTarget: target });
138
+ return target;
139
+ }
140
+
141
+ export function returnFromClay() {
142
+ var handoff = store.get('contextualWorkspace');
143
+ var originalMate = handoff && handoff.returnSlug && handoff.returnSlug.indexOf('mate-') === 0 && contextualMate(handoff.returnSlug.slice(5));
144
+ if (finishContextualWorkspace() === false) return false;
145
+ var state = store.snap();
146
+ var target = originalMate ? { projectSlug: handoff.returnSlug, sessionId: handoff.returnSessionId } : clayReturnTargetForState(state);
147
+ if (!target) {
148
+ store.set({ pendingProjectSessionNavigation: null, clayReturnPendingProjectSlug: null, clayReturnTarget: null });
149
+ showProjectsHub();
150
+ return false;
151
+ }
152
+ store.set({ clayReturnTarget: originalMate ? state.clayReturnTarget : null, clayReturnPendingProjectSlug: target.sessionId ? target.projectSlug : null });
153
+ if (target.sessionId) openProjectSession(target.projectSlug, target.sessionId);
154
+ else {
155
+ store.set({ pendingProjectSessionNavigation: null });
156
+ switchProject(target.projectSlug);
157
+ }
158
+ return true;
159
+ }
160
+
161
+ function updateClayBrand(state) {
162
+ var entry = document.querySelector('.icon-strip-brand');
163
+ if (!entry) return;
164
+ var clay = navigationMates(state.cachedMatesList).find(function (mate) { return mate.builtinKey === 'clay'; });
165
+ var ownPopover = (state.contextualClay || {}).mateId === (clay && clay.id) && contextualClayMode() !== 'closed';
166
+ var active = clayIsActive(state, clay) || ownPopover;
167
+ var speaking = !!(state.youActivity && state.youActivity.active);
168
+ entry.dataset.clayMode = active ? 'mate' : 'project';
169
+ entry.classList.toggle('clay-speaking', speaking);
170
+ var avatar = entry.querySelector('.clay-brand-avatar');
171
+ var logo = entry.querySelector('.clay-brand-logo');
172
+ if (avatar && clay) avatar.src = mateAvatarUrl(clay, 38);
173
+ if (logo) logo.src = 'clay-studio-symbol.png';
174
+ entry.disabled = !clay;
175
+ entry.classList.toggle('active', active);
176
+ entry.setAttribute('aria-label', clay ? (ownPopover && contextualClayMode() === 'popover' ? 'Open Clay workspace' : active ? 'Return to project' : 'Open Clay') : 'Clay is unavailable');
177
+ entry.setAttribute('aria-expanded', String(ownPopover));
178
+ entry.setAttribute('aria-controls', 'contextual-clay');
179
+ if (clayIsActive(state, clay)) entry.setAttribute('aria-current', 'page');
180
+ else entry.removeAttribute('aria-current');
181
+ }
182
+
183
+ export function openMateWorkspace(mateId, sessionId) {
102
184
  var mate = navigationMates(store.get('cachedMatesList')).find(function (item) { return item.id === mateId; });
103
- if (!mate) return;
185
+ if (!mate || !contextualMate(mateId)) return;
186
+ if (mate.builtinKey === 'clay' && store.snap) rememberClayReturnTarget(store.snap());
104
187
  if (store.get('currentSlug') !== 'mate-' + mateId) {
105
188
  closeTerminal();
106
189
  closeFileViewer();
107
190
  }
108
- switchProject('mate-' + mateId);
191
+ if (Number.isSafeInteger(sessionId) && sessionId > 0) openProjectSession('mate-' + mateId, sessionId);
192
+ else switchProject('mate-' + mateId);
193
+ }
194
+
195
+ export function activateContextualMate(mateId) {
196
+ var mate = contextualMate(mateId);
197
+ if (!mate) return;
198
+ var handoff = store.get('contextualWorkspace');
199
+ if (handoff && handoff.stage !== 'returning') {
200
+ if (handoff.stage !== 'workspace') return;
201
+ var popup = store.get('contextualClay') || {};
202
+ var otherSession = popup.mode === 'popover' && popup.mateId === mateId && popup.sessionId && popup.sessionId !== handoff.sessionId;
203
+ if (handoff.slug === 'mate-' + mateId && !otherSession && !(popup.mode === 'popover' && popup.mateId === mateId)) return returnFromClay();
204
+ cycleContextualClay(mate);
205
+ return;
206
+ }
207
+ if (handoff) { store.set({ contextualMatePending: mateId }); return; }
208
+ rememberClayReturnTarget(store.snap());
209
+ cycleContextualClay(mate);
109
210
  }
110
211
 
111
212
  function createMateIcon(mateId) {
@@ -116,9 +217,10 @@ function createMateIcon(mateId) {
116
217
  button.innerHTML = '<img class="icon-strip-mate-avatar" alt="" draggable="false"><span class="icon-strip-pill"></span><span class="icon-strip-status"></span><span class="icon-strip-project-badge"></span>';
117
218
  button.addEventListener('click', function () {
118
219
  hideIconTooltip();
119
- openMateWorkspace(mateId);
220
+ activateContextualMate(mateId);
120
221
  });
121
222
  bindIconTooltip(button, function () {
223
+ if ((store.get('contextualClay') || {}).mode === 'popover' && (store.get('contextualClay') || {}).mateId === mateId) return { text: '' };
122
224
  var mate = navigationMates(store.get('cachedMatesList')).find(function (item) { return item.id === mateId; });
123
225
  return {
124
226
  text: mate ? getHomeMateName(mate) : 'Mate',
@@ -126,10 +228,14 @@ function createMateIcon(mateId) {
126
228
  avatarUrl: mate ? mateAvatarUrl(mate, 24) : '',
127
229
  };
128
230
  });
129
- button.addEventListener('contextmenu', function (event) {
130
- event.preventDefault();
231
+ function openContextMenu(event) {
232
+ event.preventDefault(); event.stopPropagation(); hideIconTooltip();
131
233
  var mate = navigationMates(store.get('cachedMatesList')).find(function (item) { return item.id === mateId; });
132
234
  if (mate) showMateCtxMenu(button, mate);
235
+ }
236
+ button.addEventListener('contextmenu', openContextMenu);
237
+ button.addEventListener('keydown', function (event) {
238
+ if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) openContextMenu(event);
133
239
  });
134
240
  return button;
135
241
  }
@@ -142,33 +248,30 @@ export function renderProjectMates() {
142
248
  var clay = navigationMates(state.cachedMatesList).find(function (mate) { return mate.builtinKey === 'clay'; });
143
249
  var clayActive = !!clay && !state.homeShellVisible && !state.dmMode && state.currentSlug === 'mate-' + clay.id;
144
250
  document.body.classList.toggle('clay-workspace-active', clayActive);
145
- var clayEntry = document.querySelector('.icon-strip-brand');
146
- if (clayEntry) {
147
- clayEntry.disabled = !clay;
148
- clayEntry.classList.toggle('active', clayActive);
149
- clayEntry.setAttribute('aria-label', clay ? 'Open Clay' : 'Clay is unavailable');
150
- if (clayActive) clayEntry.setAttribute('aria-current', 'page');
151
- else clayEntry.removeAttribute('aria-current');
152
- }
251
+ updateClayBrand(state);
153
252
  document.body.classList.toggle('mate-workspace-active', !state.homeShellVisible && isMateWorkspace(state));
154
253
  applyWorkspaceColor(mateForWorkspace(state));
155
254
  renderMateHeaderDefault(state);
156
255
  var mates = navigationMates(state.cachedMatesList).filter(function (mate) {
157
- return mate.builtinKey !== 'clay';
256
+ return mate.builtinKey !== 'clay' && contextualMate(mate.id);
158
257
  });
159
258
  var mentionActive = getActiveMentionMateIds();
160
259
  var projects = state.projectsHubList || [];
161
260
  var unread = state.dmUnread || {};
162
261
  var icons = {};
163
- rail.querySelectorAll('[data-mate-id]').forEach(function (button) { icons[button.dataset.mateId] = button; });
262
+ document.querySelectorAll('.icon-strip-project-mate[data-mate-id]').forEach(function (button) { icons[button.dataset.mateId] = button; });
164
263
  mates.forEach(function (mate) {
165
264
  var button = icons[mate.id] || createMateIcon(mate.id);
166
265
  delete icons[mate.id];
266
+ button.dataset.controlMateStamp = contextualMateStamp(mate);
167
267
  var active = !state.homeShellVisible && !state.dmMode && state.currentSlug === 'mate-' + mate.id;
168
268
  var project = projects.find(function (item) { return item.slug === 'mate-' + mate.id; });
169
269
  var busy = !!(project && project.isProcessing) || !!mentionActive[mate.id];
170
270
  var count = active ? 0 : (unread[mate.id] || 0);
171
- button.classList.toggle('active', !!active);
271
+ var popover = (state.contextualClay || {}).mateId === mate.id && contextualClayMode() === 'popover';
272
+ button.classList.toggle('active', !!active || popover);
273
+ button.setAttribute('aria-expanded', String(popover));
274
+ button.setAttribute('aria-controls', 'contextual-clay');
172
275
  button.setAttribute('aria-label', getHomeMateName(mate) + ', Mate' + (busy ? ', working' : '') + (count ? ', ' + count + ' unread' : ''));
173
276
  if (active) button.setAttribute('aria-current', 'page');
174
277
  else button.removeAttribute('aria-current');
@@ -186,6 +289,7 @@ export function renderProjectMates() {
186
289
  Object.keys(icons).forEach(function (id) { icons[id].remove(); });
187
290
  var ordered = Array.from(rail.querySelectorAll('[data-mate-id]'));
188
291
  mates.forEach(function (mate, index) {
292
+ if (document.querySelector('.contextual-mate-mobile-trigger[data-mate-id="' + CSS.escape(mate.id) + '"]')) return;
189
293
  var button = ordered.find(function (item) { return item.dataset.mateId === mate.id; });
190
294
  if (ordered[index] === button) return;
191
295
  rail.insertBefore(button, ordered[index] || null);
@@ -213,22 +317,40 @@ export function renderProjectMates() {
213
317
  }
214
318
 
215
319
  export function initProjectMateNavigation() {
320
+ initContextualClay();
216
321
  var clayEntry = document.querySelector('.icon-strip-brand');
217
322
  if (clayEntry) {
218
- clayEntry.addEventListener('click', function () {
219
- var clay = navigationMates(store.get('cachedMatesList')).find(function (mate) { return mate.builtinKey === 'clay'; });
323
+ clayEntry.addEventListener('click', function (event) {
324
+ var state = store.snap();
325
+ var clay = navigationMates(state.cachedMatesList).find(function (mate) { return mate.builtinKey === 'clay'; });
220
326
  hideIconTooltip();
221
- if (clay) openMateWorkspace(clay.id);
327
+ if (!clay) return;
328
+ var popup = state.contextualClay || {};
329
+ if (clayIsActive(state, clay) && !(popup.mode === 'popover' && popup.mateId === clay.id)) returnFromClay();
330
+ else {
331
+ activateContextualMate(clay.id);
332
+ }
333
+ });
334
+ bindIconTooltip(clayEntry, function () {
335
+ var state = store.snap();
336
+ var clay = navigationMates(state.cachedMatesList).find(function (mate) { return mate.builtinKey === 'clay'; });
337
+ if ((state.contextualClay || {}).mateId === (clay && clay.id) && contextualClayMode() === 'popover') return { text: '' };
338
+ return { text: (state.contextualClay || {}).mateId === (clay && clay.id) && contextualClayMode() === 'popover' ? 'Open Clay workspace' : clayIsActive(state, clay) ? 'Return to project' : 'Open Clay', kind: 'mate', avatarUrl: 'clay-studio-symbol.png' };
222
339
  });
223
- bindIconTooltip(clayEntry, { text: 'Clay', kind: 'mate', avatarUrl: 'clay-studio-symbol.png' });
224
340
  }
225
341
  var knob = document.getElementById('icon-strip-filter-knob');
226
342
  if (knob) knob.addEventListener('click', activateProjectMateFilter);
227
343
  store.subscribe(function (state, previous) {
344
+ if (state.clayReturnPendingProjectSlug && state.currentSlug !== previous.currentSlug &&
345
+ state.currentSlug !== state.clayReturnPendingProjectSlug) {
346
+ store.set({ pendingProjectSessionNavigation: null, clayReturnPendingProjectSlug: null });
347
+ } else if (state.clayReturnPendingProjectSlug && !state.pendingProjectSessionNavigation && previous.pendingProjectSessionNavigation) {
348
+ store.set({ clayReturnPendingProjectSlug: null });
349
+ }
228
350
  if (state.cachedMatesList !== previous.cachedMatesList || state.homeChatMateId !== previous.homeChatMateId ||
229
351
  state.homeShellVisible !== previous.homeShellVisible || state.projectsHubList !== previous.projectsHubList ||
230
352
  state.dmUnread !== previous.dmUnread || state.currentSlug !== previous.currentSlug ||
231
- state.dmMode !== previous.dmMode || state.connected !== previous.connected) renderProjectMates();
353
+ state.contextualClay !== previous.contextualClay || state.dmMode !== previous.dmMode || state.connected !== previous.connected || state.activeSessionId !== previous.activeSessionId || state.youActivity !== previous.youActivity) renderProjectMates();
232
354
  if (state.projectMateFilterMode !== previous.projectMateFilterMode ||
233
355
  state.projectMateFilterTurns !== previous.projectMateFilterTurns) applyProjectMateFilter();
234
356
  });
@@ -1,5 +1,7 @@
1
1
  import { escapeHtml } from './utils.js';
2
2
  import { iconHtml, refreshIcons } from './icons.js';
3
+ import { store } from './store.js';
4
+ import { captureSessionAction, sessionActionCurrent } from './pane-binding.js';
3
5
 
4
6
  var ctx;
5
7
  var rewindMode = false;
@@ -81,6 +83,7 @@ function initiateRewind(uuid) {
81
83
  return;
82
84
  }
83
85
  pendingRewindUuid = uuid;
86
+ store.set({ rewindAction: captureSessionAction() });
84
87
  rewindPreviewInFlight = true;
85
88
  if (ctx.ws && ctx.connected) {
86
89
  ctx.ws.send(JSON.stringify({ type: "rewind_preview", uuid: uuid }));
@@ -120,6 +123,7 @@ function updateSummaryForMode() {
120
123
  }
121
124
 
122
125
  export function showRewindModal(data) {
126
+ if (!sessionActionCurrent(store.get('rewindAction'))) return;
123
127
  rewindPreviewInFlight = false;
124
128
 
125
129
  // Ignore stale preview results that don't match current pending UUID
@@ -367,6 +371,7 @@ export function initRewind(_ctx) {
367
371
  });
368
372
 
369
373
  rewindConfirmBtn.addEventListener("click", function() {
374
+ if (!sessionActionCurrent(store.get('rewindAction'))) { hideRewindModal(); return; }
370
375
  if (rewindExecuting) return;
371
376
  if (pendingRewindUuid && ctx.ws && ctx.connected) {
372
377
  rewindExecuting = true;
@@ -170,6 +170,8 @@ function buildRow(record) {
170
170
  var row = document.createElement("article");
171
171
  row.className = "scheduled-task-row" + (record.enabled === false ? " paused" : "");
172
172
  row.dataset.taskId = record.id;
173
+ row.dataset.controlRuntime = store.get("controlRuntimeId") || "";
174
+ row.dataset.controlRevision = String(record.updatedAt);
173
175
  row.setAttribute("role", "listitem");
174
176
  var stateLabel = scheduledTaskExecutionLabel(record);
175
177
  row.innerHTML =
@@ -784,6 +784,8 @@ function renderModelTab(bodyEl, rec) {
784
784
  }
785
785
 
786
786
  var opts = {
787
+ effortLevels: ((store.get("vendorInfo") || {})[store.get("currentVendor")] || {}).effortLevels || [],
788
+ configuration: ((store.get("vendorInfo") || {})[store.get("currentVendor")] || {}).configuration || {},
787
789
  models: store.get('currentModels') || [],
788
790
  currentModel: settings.model || "",
789
791
  currentMode: settings.permissionMode || "default",