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
@@ -18,6 +18,13 @@ function attachAdmin(ctx) {
18
18
  var onGetProjectAccess = ctx.onGetProjectAccess;
19
19
  var onProjectOwnerChanged = ctx.onProjectOwnerChanged;
20
20
 
21
+ function verifyCurrentOwner(req, route) {
22
+ if (!route || req.method === "GET" || !users.isMultiUser()) return;
23
+ var actor = getMultiUserFromReq(req);
24
+ var access = onGetProjectAccess && onGetProjectAccess(route[1]);
25
+ if (!actor || !access || access.ownerId !== actor.id || !users.findUserById(access.ownerId)) throw new Error("Project owner access required");
26
+ }
27
+
21
28
  function handleRequest(req, res, fullUrl) {
22
29
  var mateAccessRoute = /^\/api\/admin\/projects\/([^/]+)\/(visibility|owner|users|access)$/.exec(fullUrl);
23
30
  if (mateAccessRoute) {
@@ -31,6 +38,25 @@ function attachAdmin(ctx) {
31
38
  }
32
39
 
33
40
 
41
+ // Project content authority belongs to the valid owner, never the role.
42
+ if (mateAccessRoute && users.isMultiUser()) {
43
+ var actor = getMultiUserFromReq(req);
44
+ var governing = onGetProjectAccess && onGetProjectAccess(mateAccessRoute[1]);
45
+ var validOwner = governing && governing.ownerId && users.findUserById(governing.ownerId);
46
+ var owns = actor && validOwner && actor.id === validOwner.id;
47
+ if (req.method !== "GET" && !owns) {
48
+ res.writeHead(403, { "Content-Type": "application/json" });
49
+ res.end(JSON.stringify({ error: "Only the valid project owner can change access." }));
50
+ return true;
51
+ }
52
+ if (req.method === "GET" && !owns && actor && actor.role === "admin") {
53
+ var overview = require("./project-admin-overview").metadataFor(actor, target && target.getStatus(), governing, users);
54
+ res.writeHead(overview ? 200 : 404, { "Content-Type": "application/json", "Cache-Control": "no-store" });
55
+ res.end(JSON.stringify(overview || { error: "Project not found" }));
56
+ return true;
57
+ }
58
+ }
59
+
34
60
  // --- Admin API endpoints (multi-user mode only) ---
35
61
 
36
62
  // List all users (admin only)
@@ -83,6 +109,16 @@ function attachAdmin(ctx) {
83
109
  // Look up the user before deletion to get linuxUser for deactivation
84
110
  var targetUser = users.findUserById(targetUserId);
85
111
  var targetLinuxUser = targetUser ? targetUser.linuxUser : null;
112
+ var owned = false;
113
+ projects.forEach(function (project, slug) {
114
+ var access = onGetProjectAccess && onGetProjectAccess(slug);
115
+ if (access && !access.isMate && access.ownerId === targetUserId) owned = true;
116
+ });
117
+ if (owned) {
118
+ res.writeHead(409, { "Content-Type": "application/json" });
119
+ res.end(JSON.stringify({ error: "The owner must transfer ordinary projects before account deletion." }));
120
+ return true;
121
+ }
86
122
  var result = users.removeUser(targetUserId);
87
123
  if (result.error) {
88
124
  res.writeHead(404, { "Content-Type": "application/json" });
@@ -118,6 +154,7 @@ function attachAdmin(ctx) {
118
154
  req.on("end", function () {
119
155
  try {
120
156
  var data = JSON.parse(body);
157
+ verifyCurrentOwner(req, mateAccessRoute);
121
158
  if (!data.username || typeof data.username !== "string" || data.username.trim().length < 1) {
122
159
  res.writeHead(400, { "Content-Type": "application/json" });
123
160
  res.end('{"error":"Username is required"}');
@@ -182,6 +219,11 @@ function attachAdmin(ctx) {
182
219
  res.end('{"error":"User not found"}');
183
220
  return true;
184
221
  }
222
+ if (mu.id !== targetUserId) {
223
+ res.writeHead(403, { "Content-Type": "application/json" });
224
+ res.end(JSON.stringify({ error: "Use account-owner credential recovery. Administrators cannot impersonate another account." }));
225
+ return true;
226
+ }
185
227
  var newPin = users.generatePin();
186
228
  var pinResult = users.updateUserPin(targetUserId, newPin);
187
229
  if (pinResult.error) {
@@ -222,15 +264,10 @@ function attachAdmin(ctx) {
222
264
  req.on("data", function(chunk) { body += chunk; });
223
265
  req.on("end", function() {
224
266
  try {
225
- var parsed = JSON.parse(body);
226
- var result = users.updateLinuxUser(targetUserId, parsed.linuxUser || null);
227
- if (result.error) {
228
- res.writeHead(400, { "Content-Type": "application/json" });
229
- res.end(JSON.stringify({ error: result.error }));
230
- } else {
231
- res.writeHead(200, { "Content-Type": "application/json" });
232
- res.end('{"ok":true}');
233
- }
267
+ JSON.parse(body);
268
+ res.writeHead(403, { "Content-Type": "application/json" });
269
+ res.end(JSON.stringify({ error: "OS identity mapping requires server-side verified provisioning." }));
270
+ return;
234
271
  } catch (e) {
235
272
  res.writeHead(400, { "Content-Type": "application/json" });
236
273
  res.end('{"error":"Invalid request body"}');
@@ -363,6 +400,7 @@ function attachAdmin(ctx) {
363
400
  req.on("end", function () {
364
401
  try {
365
402
  var data = JSON.parse(body);
403
+ verifyCurrentOwner(req, mateAccessRoute);
366
404
  if (!data.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
367
405
  res.writeHead(400, { "Content-Type": "application/json" });
368
406
  res.end('{"error":"Valid email is required"}');
@@ -429,6 +467,7 @@ function attachAdmin(ctx) {
429
467
  req.on("end", function () {
430
468
  try {
431
469
  var data = JSON.parse(body);
470
+ verifyCurrentOwner(req, mateAccessRoute);
432
471
  // Allow clearing SMTP config by sending empty fields
433
472
  if (!data.host && !data.user && !data.pass && !data.from) {
434
473
  smtp.saveSmtpConfig(null);
@@ -484,6 +523,7 @@ function attachAdmin(ctx) {
484
523
  req.on("end", function () {
485
524
  try {
486
525
  var data = JSON.parse(body);
526
+ verifyCurrentOwner(req, mateAccessRoute);
487
527
  // Use provided config or fall back to saved
488
528
  var existingCfg = smtp.getSmtpConfig();
489
529
  var pass = data.pass;
@@ -548,6 +588,7 @@ function attachAdmin(ctx) {
548
588
  req.on("end", function () {
549
589
  try {
550
590
  var data = JSON.parse(body);
591
+ verifyCurrentOwner(req, mateAccessRoute);
551
592
  if (data.visibility !== "public" && data.visibility !== "private") {
552
593
  res.writeHead(400, { "Content-Type": "application/json" });
553
594
  res.end('{"error":"Visibility must be public or private"}');
@@ -582,9 +623,10 @@ function attachAdmin(ctx) {
582
623
  return true;
583
624
  }
584
625
  var mu = getMultiUserFromReq(req);
585
- if (!mu || mu.role !== "admin") {
626
+ var ownerAccess = onGetProjectAccess && onGetProjectAccess(fullUrl.split("/")[4]);
627
+ if (!mu || !ownerAccess || mu.id !== ownerAccess.ownerId) {
586
628
  res.writeHead(403, { "Content-Type": "application/json" });
587
- res.end('{"error":"Admin access required"}');
629
+ res.end('{"error":"Project owner access required"}');
588
630
  return true;
589
631
  }
590
632
  var projSlug = fullUrl.split("/")[4];
@@ -598,17 +640,21 @@ function attachAdmin(ctx) {
598
640
  req.on("end", function () {
599
641
  try {
600
642
  var data = JSON.parse(body);
643
+ verifyCurrentOwner(req, mateAccessRoute);
601
644
  var targetCtx = projects.get(projSlug);
602
645
  if (!targetCtx) {
603
646
  res.writeHead(404, { "Content-Type": "application/json" });
604
647
  res.end('{"error":"Project not found"}');
605
648
  return;
606
649
  }
607
- var ownerId = data.userId || null;
650
+ var ownerId = data.userId;
651
+ if (typeof ownerId !== "string" || !users.findUserById(ownerId)) throw new Error("A valid owner is required");
652
+ var currentAccess = onGetProjectAccess && onGetProjectAccess(projSlug);
653
+ if (!currentAccess || currentAccess.ownerId !== mu.id) throw new Error("Project owner access required");
654
+ if (!onProjectOwnerChanged) throw new Error("Ownership persistence is unavailable");
655
+ var saved = onProjectOwnerChanged(projSlug, ownerId);
656
+ if (saved && saved.error) throw new Error(saved.error);
608
657
  targetCtx.setProjectOwner(ownerId);
609
- if (onProjectOwnerChanged) {
610
- onProjectOwnerChanged(projSlug, ownerId);
611
- }
612
658
  // Broadcast to project clients
613
659
  var ownerName = null;
614
660
  if (ownerId) {
@@ -653,7 +699,8 @@ function attachAdmin(ctx) {
653
699
  req.on("end", function () {
654
700
  try {
655
701
  var data = JSON.parse(body);
656
- if (!Array.isArray(data.allowedUsers)) {
702
+ verifyCurrentOwner(req, mateAccessRoute);
703
+ if (!Array.isArray(data.allowedUsers) || data.allowedUsers.some(function (id) { return typeof id !== "string" || !users.findUserById(id); })) {
657
704
  res.writeHead(400, { "Content-Type": "application/json" });
658
705
  res.end('{"error":"allowedUsers must be an array"}');
659
706
  return;
@@ -34,6 +34,18 @@ function attachAppearanceSettings(ctx) {
34
34
  fs.renameSync(defaultPath + '.tmp', defaultPath);
35
35
  }
36
36
  }
37
+ function getInitialAppearance(req) {
38
+ var user = identity(req);
39
+ if (!user) return null;
40
+ var saved = read(user);
41
+ return {
42
+ configured: saved.configured,
43
+ theme: saved.theme,
44
+ mode: saved.mode,
45
+ lightTheme: saved.lightTheme || null,
46
+ darkTheme: saved.darkTheme || null
47
+ };
48
+ }
37
49
  function handleRequest(req, res, url) {
38
50
  if (url !== '/api/user/appearance') return false;
39
51
  var user = identity(req);
@@ -66,6 +78,6 @@ function attachAppearanceSettings(ctx) {
66
78
  });
67
79
  return true;
68
80
  }
69
- return { handleRequest: handleRequest };
81
+ return { handleRequest: handleRequest, getInitialAppearance: getInitialAppearance };
70
82
  }
71
83
  module.exports = { attachAppearanceSettings: attachAppearanceSettings };
@@ -0,0 +1,40 @@
1
+ // Authenticated personal preferences, using the shared users/config persistence.
2
+ function attachContextualClaySettings(ctx) {
3
+ function reply(res, status, data) {
4
+ res.writeHead(status, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' });
5
+ res.end(JSON.stringify(data));
6
+ }
7
+ function identity(req) {
8
+ if (!ctx.isRequestAuthed(req)) return null;
9
+ return ctx.users.isMultiUser() ? ctx.getMultiUserFromReq(req) : { id: 'default' };
10
+ }
11
+ function handleRequest(req, res, url) {
12
+ if (url !== '/api/user/contextual-clay-geometry') return false;
13
+ var user = identity(req);
14
+ if (!user) { reply(res, 401, { error: 'Sign in to manage popover preferences.' }); return true; }
15
+ if (req.method === 'GET') {
16
+ try { reply(res, 200, { geometry: ctx.users.getContextualClayGeometry(user.id) }); }
17
+ catch (error) { reply(res, 500, { error: 'Could not read popover preference.' }); }
18
+ return true;
19
+ }
20
+ if (req.method !== 'PUT') { reply(res, 405, { error: 'Method not allowed.' }); return true; }
21
+ if (req.headers['x-clay-settings'] !== '1' || (req.headers['sec-fetch-site'] && ['same-origin', 'none'].indexOf(req.headers['sec-fetch-site']) < 0)) {
22
+ reply(res, 403, { error: 'Save preferences from Clay.' }); return true;
23
+ }
24
+ var body = ''; var tooLarge = false;
25
+ req.setEncoding('utf8');
26
+ req.on('data', function (chunk) { body += chunk; if (body.length > 1024 && !tooLarge) { tooLarge = true; reply(res, 413, { error: 'Request too large.' }); } });
27
+ req.on('end', function () {
28
+ if (tooLarge) return;
29
+ var live = identity(req);
30
+ if (!live || live.id !== user.id) { reply(res, 401, { error: 'Sign in again.' }); return; }
31
+ try {
32
+ var result = ctx.users.setContextualClayGeometry(live.id, JSON.parse(body));
33
+ reply(res, result.error ? 400 : 200, result);
34
+ } catch (error) { reply(res, 400, { error: 'Could not save popover preference.' }); }
35
+ });
36
+ return true;
37
+ }
38
+ return { handleRequest: handleRequest };
39
+ }
40
+ module.exports = { attachContextualClaySettings: attachContextualClaySettings };
@@ -0,0 +1,70 @@
1
+ // Presentation-only session operations share Home's authoritative permissions,
2
+ // model policy, saved-session projection and session manager. No transcript tap.
3
+ function attachContextualMateSessions(ctx) {
4
+ var receipts = new Map();
5
+ var lifetime = 30 * 60 * 1000;
6
+ function stamp(mate) { return JSON.stringify([mate.id, mate.createdBy || null, mate.createdAt || null, mate.builtinKey || null]); }
7
+ function live(ws, userId, msg, original) {
8
+ if (!ctx.isActorLive(ws, userId)) throw new Error('Your account is no longer available.');
9
+ var found = ctx.findMateProject(userId, msg.mateId, true);
10
+ if (!found || found.mate.archived || found.mate.lifecycleDeletion || found.mate.createdBy && found.mate.createdBy !== userId || stamp(found.mate) !== msg.mateStamp) throw new Error('This Mate is no longer available.');
11
+ var status = found.ctx.getStatus();
12
+ if (!status || !status.isMate || status.mateId !== found.mate.id || userId && status.projectOwnerId !== userId) throw new Error('This private Mate workspace is unavailable.');
13
+ found.contextualManager = found.ctx.getSessionManager();
14
+ found.contextualRevision = JSON.stringify([status.path, status.projectOwnerId, status.mateId, stamp(found.mate)]);
15
+ if (original && (found.ctx !== original.ctx || found.contextualRevision !== original.contextualRevision || found.contextualManager !== original.contextualManager)) throw new Error('This Mate conversation changed.');
16
+ return found;
17
+ }
18
+ function reply(ws, msg, data) { ctx.sendMessage(ws, Object.assign({ type: 'contextual_mate_sessions_result', requestId: msg.requestId, mateId: msg.mateId, mateStamp: msg.mateStamp }, data)); }
19
+ async function perform(ws, userId, msg) {
20
+ try {
21
+ if (typeof msg.requestId !== 'string' || !/^mate-conversations-[a-z0-9-]{36}$/.test(msg.requestId)) throw new Error('Invalid conversation request.');
22
+ var found = live(ws, userId, msg), manager = found.ctx.getSessionManager();
23
+ if (!manager) throw new Error('Conversation history is unavailable.');
24
+ if (msg.type === 'home_mate_sessions_list') {
25
+ var list = ctx.listHomeSessions(found, userId);
26
+ reply(ws, msg, { ok: true, sessions: list.slice(0, 500), truncated: list.length > 500 }); return;
27
+ }
28
+ var session;
29
+ if (msg.type === 'home_mate_session_open') {
30
+ session = ctx.resolveHomeSession(found, userId, msg.sessionId);
31
+ if (!session || typeof msg.sessionOriginId !== 'string' || msg.sessionOriginId !== session.sessionOriginId) throw new Error('This conversation is no longer available.');
32
+ } else {
33
+ var now = Date.now();
34
+ receipts.forEach(function (entry, key) { if (now - entry.at > lifetime) receipts.delete(key); });
35
+ var key = JSON.stringify([userId, msg.mateId, msg.requestId]);
36
+ var receipt = receipts.get(key);
37
+ manager.sessions.forEach(function (candidate) { if (candidate.contextualCreationRequestId === msg.requestId && ctx.ownsSession(candidate, userId)) session = candidate; });
38
+ if (session && session.contextualCreationMateStamp !== msg.mateStamp) throw new Error('This request belongs to a replaced Mate.');
39
+ if (receipt && (!session || receipt.origin !== session.sessionOriginId || receipt.stamp !== msg.mateStamp)) throw new Error('The previously created conversation is no longer available.');
40
+ if (!session && msg.lookupOnly) throw new Error('Creation was not confirmed. Start a new chat explicitly if you still want one.');
41
+ if (!session) {
42
+ if (receipts.size >= 1024) throw new Error('Please try starting a conversation later.');
43
+ var resolved = await ctx.homeModels.resolveMateModel(ws, found, userId);
44
+ found = live(ws, userId, msg, found);
45
+ // Recheck after model resolution: concurrent retries select one exact session.
46
+ manager.sessions.forEach(function (candidate) { if (candidate.contextualCreationRequestId === msg.requestId && ctx.ownsSession(candidate, userId)) session = candidate; });
47
+ receipt = receipts.get(key);
48
+ if (receipt && (!session || receipt.origin !== session.sessionOriginId || receipt.stamp !== msg.mateStamp)) throw new Error('The previously created conversation is no longer available.');
49
+ if (session && session.contextualCreationMateStamp !== msg.mateStamp) throw new Error('This request belongs to a replaced Mate.');
50
+ if (!session) {
51
+ if (receipts.size >= 1024) throw new Error('Please try starting a conversation later.');
52
+ session = manager.createSessionRaw({ ownerId: userId, vendor: resolved.vendor, model: resolved.model, effort: resolved.effort || null });
53
+ session.contextualCreationRequestId = msg.requestId;
54
+ session.contextualCreationMateStamp = msg.mateStamp;
55
+ manager.saveSessionFile(session);
56
+ }
57
+ }
58
+ if (!ctx.ownsSession(session, userId)) throw new Error('This conversation is no longer available.');
59
+ receipts.set(key, { at: now, origin: session.sessionOriginId, stamp: msg.mateStamp });
60
+ }
61
+ live(ws, userId, msg, found);
62
+ reply(ws, msg, { ok: true, sessionId: session.localId, sessionOriginId: session.sessionOriginId });
63
+ } catch (error) { reply(ws, msg, { ok: false, error: error.message || 'Conversation unavailable.' }); }
64
+ }
65
+ return { handle: function (ws, userId, msg) {
66
+ if (msg.presentation !== 'contextual' || !/^home_mate_(sessions_list|session_open|new_session)$/.test(msg.type)) return false;
67
+ perform(ws, userId, msg); return true;
68
+ } };
69
+ }
70
+ module.exports = { attachContextualMateSessions: attachContextualMateSessions };
package/lib/server-dm.js CHANGED
@@ -49,7 +49,7 @@ function attachDm(ctx) {
49
49
  var mateCtx2 = mates.buildMateCtx(userId);
50
50
  if (mates.isMate(mateCtx2, msg.targetUserId)) {
51
51
  var mate = mates.getMate(mateCtx2, msg.targetUserId);
52
- if (!mate) return true;
52
+ if (!mate || mate.lifecycleDeletion) return true;
53
53
  // Ensure mate project is registered (survives server restarts)
54
54
  var mateSlug2 = "mate-" + mate.id;
55
55
  if (!projects.has(mateSlug2)) {
@@ -69,6 +69,7 @@ function attachDm(ctx) {
69
69
  id: mate.id,
70
70
  displayName: mp.displayName || mate.name || "New Mate",
71
71
  username: mate.id,
72
+ avatarCatalogId: mp.avatarCatalogId || "",
72
73
  avatarStyle: mp.avatarStyle || "imprint",
73
74
  avatarSeed: mp.avatarSeed || mate.id,
74
75
  avatarColor: mp.avatarColor || "#5857fc",
@@ -0,0 +1,39 @@
1
+ // server-github-stars.js - GET /api/github-stars for the top-bar Star link.
2
+ //
3
+ // Read-only. Returns the cached public star count of the fixed Clay
4
+ // repository (null when not yet known). No request input reaches GitHub, and
5
+ // nothing about the caller is sent or stored.
6
+
7
+ var githubStarCount = require("./github-star-count");
8
+
9
+ function attachGithubStars(ctx) {
10
+ var cache = ctx.cache || githubStarCount.createGithubStarCount();
11
+
12
+ function json(res, status, body) {
13
+ res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
14
+ res.end(JSON.stringify(body));
15
+ }
16
+
17
+ function handleRequest(req, res, url) {
18
+ if (url !== "/api/github-stars") return false;
19
+ if (req.method !== "GET") {
20
+ res.writeHead(405, { "Content-Type": "application/json", "Allow": "GET" });
21
+ res.end(JSON.stringify({ error: "Method not allowed." }));
22
+ return true;
23
+ }
24
+ if (!ctx.isRequestAuthed(req)) {
25
+ json(res, 401, { error: "Sign in to continue." });
26
+ return true;
27
+ }
28
+ cache.get().then(function (snapshot) {
29
+ json(res, 200, snapshot);
30
+ }, function () {
31
+ json(res, 200, { repo: githubStarCount.REPO, stars: null, fetchedAt: null });
32
+ });
33
+ return true;
34
+ }
35
+
36
+ return { handleRequest: handleRequest };
37
+ }
38
+
39
+ module.exports = { attachGithubStars: attachGithubStars };
@@ -19,6 +19,9 @@
19
19
  var fs = require("fs");
20
20
  var path = require("path");
21
21
  var config = require("./config");
22
+ var startProtocol = require("./project-start-protocol");
23
+ var startReply = startProtocol.withRequestId;
24
+ var browseMeta = startProtocol.browseMeta;
22
25
 
23
26
  // Mirrored from lib/project.js — keep in sync if entries change there.
24
27
  var IGNORED_DIRS = new Set([
@@ -63,14 +66,6 @@ function attachGlobalWs(opts) {
63
66
  if (msg.type === "browse_dir") {
64
67
  var rawPath = (msg.path || "").replace(/^~/, config.REAL_HOME);
65
68
  var absTarget = path.resolve(rawPath);
66
- // Multi-user mode: non-admins can only browse their home directory.
67
- if (osUsers && ws._clayUser && ws._clayUser.role !== "admin") {
68
- var browseHome = ws._clayUser.linuxUser ? "/home/" + ws._clayUser.linuxUser : null;
69
- if (!browseHome || (absTarget !== browseHome && (absTarget + "/").indexOf(browseHome + "/") !== 0)) {
70
- sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: [], error: "Access restricted to your home directory" });
71
- return;
72
- }
73
- }
74
69
  var parentDir, prefix;
75
70
  try {
76
71
  var stat = fs.statSync(absTarget);
@@ -87,21 +82,27 @@ function attachGlobalWs(opts) {
87
82
  parentDir = path.dirname(absTarget);
88
83
  prefix = path.basename(absTarget).toLowerCase();
89
84
  }
85
+ var canList = function (candidate) { return !opts.canUsePath || opts.canUsePath(ws._clayUser && ws._clayUser.id, candidate); };
86
+ if (!canList(parentDir)) {
87
+ sendTo(ws, startReply(msg, { type: "browse_dir_result", path: msg.path, entries: [], error: "Directory access is not permitted" }));
88
+ return;
89
+ }
90
90
  try {
91
91
  var dirItems = fs.readdirSync(parentDir, { withFileTypes: true });
92
92
  var dirEntries = [];
93
93
  for (var di = 0; di < dirItems.length; di++) {
94
94
  var d = dirItems[di];
95
95
  if (!d.isDirectory()) continue;
96
+ if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, path.join(parentDir, d.name))) continue;
96
97
  if (d.name.charAt(0) === ".") continue;
97
98
  if (IGNORED_DIRS.has(d.name)) continue;
98
99
  if (prefix && !d.name.toLowerCase().startsWith(prefix)) continue;
99
100
  dirEntries.push({ name: d.name, path: path.join(parentDir, d.name) });
100
101
  }
101
102
  dirEntries.sort(function (a, b) { return a.name.localeCompare(b.name); });
102
- sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: dirEntries });
103
+ sendTo(ws, Object.assign(browseMeta(msg, parentDir, prefix, canList), { type: "browse_dir_result", path: msg.path, entries: dirEntries }));
103
104
  } catch (e) {
104
- sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: [], error: e.message });
105
+ sendTo(ws, startReply(msg, { type: "browse_dir_result", path: msg.path, entries: [], error: e.message }));
105
106
  }
106
107
  return;
107
108
  }
@@ -110,32 +111,25 @@ function attachGlobalWs(opts) {
110
111
  if (msg.type === "add_project") {
111
112
  var addPath = (msg.path || "").replace(/^~/, config.REAL_HOME);
112
113
  var addAbs = path.resolve(addPath);
113
- if (osUsers && ws._clayUser && ws._clayUser.role !== "admin") {
114
- if (!ws._clayUser.linuxUser) {
115
- sendTo(ws, { type: "add_project_result", ok: false, error: "No Linux user assigned" });
116
- return;
117
- }
118
- var userHome = "/home/" + ws._clayUser.linuxUser;
119
- if (addAbs !== userHome && (addAbs + "/").indexOf(userHome + "/") !== 0) {
120
- sendTo(ws, { type: "add_project_result", ok: false, error: "Path not allowed. You can only add directories under " + userHome });
121
- return;
122
- }
114
+ if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, addAbs)) {
115
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Directory access is not permitted" }));
116
+ return;
123
117
  }
124
118
  try {
125
119
  var addStat = fs.statSync(addAbs);
126
120
  if (!addStat.isDirectory()) {
127
- sendTo(ws, { type: "add_project_result", ok: false, error: "Not a directory" });
121
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not a directory" }));
128
122
  return;
129
123
  }
130
124
  } catch (e) {
131
- sendTo(ws, { type: "add_project_result", ok: false, error: "Directory not found" });
125
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Directory not found" }));
132
126
  return;
133
127
  }
134
128
  if (typeof onAddProject === "function") {
135
129
  var result = onAddProject(addAbs, ws._clayUser);
136
- sendTo(ws, { type: "add_project_result", ok: result.ok, slug: result.slug, error: result.error, existing: result.existing });
130
+ sendTo(ws, startReply(msg, Object.assign({}, result, { type: "add_project_result" })));
137
131
  } else {
138
- sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
132
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
139
133
  }
140
134
  return;
141
135
  }
@@ -145,7 +139,7 @@ function attachGlobalWs(opts) {
145
139
  if (ws._clayUser && usersModule) {
146
140
  var cpPerms = usersModule.getEffectivePermissions(ws._clayUser, osUsers);
147
141
  if (!cpPerms.createProject) {
148
- sendTo(ws, { type: "add_project_result", ok: false, error: "You do not have permission to create projects" });
142
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "You do not have permission to create projects" }));
149
143
  return;
150
144
  }
151
145
  }
@@ -154,14 +148,14 @@ function attachGlobalWs(opts) {
154
148
  if (msg.type === "create_project") {
155
149
  var createName = (msg.name || "").trim();
156
150
  if (!createName || !/^[a-zA-Z0-9_-]+$/.test(createName)) {
157
- sendTo(ws, { type: "add_project_result", ok: false, error: "Invalid name. Use only letters, numbers, dashes, and underscores." });
151
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Invalid name. Use only letters, numbers, dashes, and underscores." }));
158
152
  return;
159
153
  }
160
154
  if (typeof onCreateProject === "function") {
161
155
  var createResult = onCreateProject(createName, ws._clayUser);
162
- sendTo(ws, { type: "add_project_result", ok: createResult.ok, slug: createResult.slug, error: createResult.error });
156
+ sendTo(ws, startReply(msg, Object.assign({}, createResult, { type: "add_project_result" })));
163
157
  } else {
164
- sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
158
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
165
159
  }
166
160
  return;
167
161
  }
@@ -169,16 +163,16 @@ function attachGlobalWs(opts) {
169
163
  if (msg.type === "clone_project") {
170
164
  var cloneUrl = (msg.url || "").trim();
171
165
  if (!cloneUrl || (!/^https?:\/\//.test(cloneUrl) && !/^git@/.test(cloneUrl))) {
172
- sendTo(ws, { type: "add_project_result", ok: false, error: "Invalid URL. Use https:// or git@ format." });
166
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Invalid URL. Use https:// or git@ format." }));
173
167
  return;
174
168
  }
175
- sendTo(ws, { type: "clone_project_progress", status: "cloning" });
169
+ sendTo(ws, startReply(msg, { type: "clone_project_progress", status: "cloning" }));
176
170
  if (typeof onCloneProject === "function") {
177
171
  onCloneProject(cloneUrl, ws._clayUser, function (cloneResult) {
178
- sendTo(ws, { type: "add_project_result", ok: cloneResult.ok, slug: cloneResult.slug, error: cloneResult.error });
172
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: cloneResult.ok, slug: cloneResult.slug, error: cloneResult.error }));
179
173
  });
180
174
  } else {
181
- sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
175
+ sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
182
176
  }
183
177
  return;
184
178
  }
@@ -3,7 +3,7 @@
3
3
  function homeDebateQuestions(input) {
4
4
  var source = input && Array.isArray(input.questions) && input.questions[0] ? input.questions[0] : null;
5
5
  if (!source) return [];
6
- var question = { header: source.header || "", question: source.question || "", multiSelect: false, options: [] };
6
+ var question = { header: source.header || "", question: source.question || "", multiSelect: false, allowOther: source.allowOther !== false, options: [] };
7
7
  var options = Array.isArray(source.options) ? source.options.slice(0, 6) : [];
8
8
  for (var i = 0; i < options.length; i++) question.options.push({ label: options[i].label || "Option", description: options[i].description || "" });
9
9
  return [question];
@@ -36,6 +36,7 @@ function findDebateTurn(messages, event) {
36
36
  function debateIdentity(source, fallback) {
37
37
  var prior = fallback || {};
38
38
  return {
39
+ avatarCatalogId: source.avatarCatalogId || prior.avatarCatalogId || "",
39
40
  avatarStyle: source.avatarStyle || prior.avatarStyle || "imprint",
40
41
  avatarSeed: source.avatarSeed || prior.avatarSeed || source.mateId || "mate",
41
42
  avatarColor: source.avatarColor || prior.avatarColor || "",
@@ -112,7 +113,7 @@ function applyAssignmentHistoryEvent(messages, event) {
112
113
  messages.push({ role: "assignment", assignment: assignment });
113
114
  }
114
115
 
115
- function historyToHomeChat(history, debateSetupMode, mateCreationMode) {
116
+ function historyToHomeChat(history, debateSetupMode, mateCreationMode, pendingAskUser) {
116
117
  var messages = [];
117
118
  var pending = "";
118
119
  var interviewMode = debateSetupMode === true || mateCreationMode === true;
@@ -124,6 +125,12 @@ function historyToHomeChat(history, debateSetupMode, mateCreationMode) {
124
125
  for (var i = 0; i < history.length; i++) {
125
126
  var event = history[i];
126
127
  if (!event) continue;
128
+ if (event.type === 'tool_executing' && event.name === 'AskUserQuestion' && ['mcp-import', 'mate-schedule', 'mcp_fallback', 'product-control'].indexOf(event.source) >= 0) {
129
+ flushAssistant();
130
+ var activeConsent = pendingAskUser === undefined || !!(pendingAskUser && pendingAskUser[event.id]);
131
+ messages.push({ role: 'question', flow: event.source === 'mcp-import' ? 'mcp_import' : 'mate_question', toolId: event.id, questions: homeDebateQuestions(event.input), status: activeConsent ? 'pending' : 'expired', error: activeConsent ? '' : 'This question is no longer active. Ask for a new review.' });
132
+ continue;
133
+ }
127
134
  if (event.type === "project_assignment_proposal" || event.type === "project_assignment_status") {
128
135
  flushAssistant();
129
136
  applyAssignmentHistoryEvent(messages, event);
@@ -185,7 +192,7 @@ function historyToHomeChat(history, debateSetupMode, mateCreationMode) {
185
192
  } else if (interviewMode && event.type === "tool_executing" && event.name === "AskUserQuestion" && event.id && event.input) {
186
193
  flushAssistant();
187
194
  messages.push({ role: "question", flow: mateCreationMode === true ? "mate_creation" : "debate", toolId: event.id, questions: homeDebateQuestions(event.input), status: "pending", error: "" });
188
- } else if ((event.type === "ask_user_answered" || event.type === "home_debate_question_expired" || event.type === "home_mate_creation_question_expired") && event.toolId) {
195
+ } else if ((event.type === "ask_user_answered" || event.type === "home_debate_question_expired" || event.type === "home_mate_creation_question_expired" || event.type === "mcp_import_consent_expired" || event.type === "mate_schedule_question_expired") && event.toolId) {
189
196
  for (var k = messages.length - 1; k >= 0; k--) {
190
197
  if (messages[k].role === "question" && messages[k].toolId === event.toolId) {
191
198
  messages[k].status = event.type === "ask_user_answered" ? "answered" : "expired";
@@ -273,7 +280,7 @@ function transformEvent(event, mateId, session, requestId, stableSessionId) {
273
280
  }
274
281
  if (session && session.homeDebatePlanning === true && HOME_DEBATE_EVENT_TYPES[event.type]) {
275
282
  var live = { type: "home_debate_event", eventType: event.type };
276
- var fields = ["turnId", "decisionId", "decision", "toolName", "command", "commandTruncated", "topic", "format", "moderatorId", "moderatorName", "panelists", "mateName", "role", "round", "activity", "delta", "text", "reason", "action", "avatarStyle", "avatarSeed", "avatarColor", "avatarCustom"];
283
+ var fields = ["turnId", "decisionId", "decision", "toolName", "command", "commandTruncated", "topic", "format", "moderatorId", "moderatorName", "panelists", "mateName", "role", "round", "activity", "delta", "text", "reason", "action", "avatarCatalogId", "avatarStyle", "avatarSeed", "avatarColor", "avatarCustom"];
277
284
  for (var fi = 0; fi < fields.length; fi++) if (Object.prototype.hasOwnProperty.call(event, fields[fi])) live[fields[fi]] = event[fields[fi]];
278
285
  if (event.mateId) live.speakerMateId = event.mateId;
279
286
  return Object.assign(live, metadata);
@@ -298,6 +305,13 @@ function transformEvent(event, mateId, session, requestId, stableSessionId) {
298
305
  if (event.type === "debate_proposal_resolved" && event.proposalId) return Object.assign({ type: "home_debate_proposal_resolved", proposalId: event.proposalId, action: event.action || "cancel", error: event.error || "" }, metadata);
299
306
  if (session && session.mateCreationMode === true && event.type === "mate_creation_proposal" && event.proposal) return Object.assign({ type: "home_mate_creation_proposal", proposal: event.proposal }, metadata);
300
307
  if (session && session.mateCreationMode === true && event.type === "mate_creation_proposal_resolved" && event.proposalId) return Object.assign({ type: "home_mate_creation_proposal_resolved", proposalId: event.proposalId, action: event.action || "cancel", createdMateId: event.mateId || null, mateName: event.mateName || null, error: event.error || "" }, metadata);
308
+ if (!(session && (session.debateSetupMode === true || session.mateCreationMode === true)) && event.type === 'tool_executing' && event.name === 'AskUserQuestion' && ['mate-schedule', 'mcp_fallback', 'product-control'].indexOf(event.source) >= 0) return Object.assign({ type: 'home_mate_question', toolId: event.id, questions: homeDebateQuestions(event.input) }, metadata);
309
+ if (session && session.debateSetupMode !== true && session.mateCreationMode !== true && event.type === 'ask_user_answered' && event.toolId && (session.history || []).some(function (item) { return item.id === event.toolId && ['mate-schedule', 'mcp_fallback', 'product-control'].indexOf(item.source) >= 0; })) return Object.assign({ type: 'home_mate_question_resolved', toolId: event.toolId, status: 'answered', answers: event.answers }, metadata);
310
+ if (event.type === 'tool_executing' && event.name === 'AskUserQuestion' && event.source === 'mcp-import') return Object.assign({ type: 'home_mcp_import_question', toolId: event.id, questions: homeDebateQuestions(event.input) }, metadata);
311
+ if (event.type === 'product_control_question_expired') return Object.assign({ type: 'home_mate_question_resolved', toolId: event.toolId, status: 'expired', error: event.error }, metadata);
312
+ if (event.type === 'mate_schedule_question_expired') return Object.assign({ type: 'home_mate_question_resolved', toolId: event.toolId, status: 'expired', error: event.error }, metadata);
313
+ if (event.type === 'mcp_import_consent_expired') return Object.assign({ type: 'home_mcp_import_question_resolved', toolId: event.toolId, status: 'expired', error: event.error }, metadata);
314
+ if (session && event.type === 'ask_user_answered' && event.toolId && (session.history || []).some(function (item) { return item.id === event.toolId && item.source === 'mcp-import'; })) return Object.assign({ type: 'home_mcp_import_question_resolved', toolId: event.toolId, status: 'answered', answers: event.answers }, metadata);
301
315
  if (session && session.debateSetupMode === true && event.type === "tool_executing" && event.name === "AskUserQuestion" && event.id && event.input) {
302
316
  return Object.assign({ type: "home_debate_question", toolId: event.id, questions: homeDebateQuestions(event.input) }, metadata);
303
317
  }