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
@@ -15,10 +15,12 @@ function attachHomeClayEntry(ctx) {
15
15
  }
16
16
 
17
17
  async function start(ws, userId, msg) {
18
+ var contextual = msg.presentation === 'contextual';
18
19
  var text = typeof msg.text === "string" ? msg.text.replace(/[\u0000-\u001f\u007f]/g, " ").trim().slice(0, 12000) : "";
19
20
  var requestId = typeof msg.requestId === "string" ? msg.requestId.slice(0, 240) : null;
21
+ if (ctx.isActorLive && !ctx.isActorLive(ws, userId)) { ctx.sendError(ws, null, 'Your account is no longer available.', requestId, null, 'actor_unavailable'); return; }
20
22
  var found = ctx.findMateProject(userId, null, true);
21
- if (!found || found.mate.builtinKey !== "clay") {
23
+ if (!found || found.mate.builtinKey !== "clay" || found.mate.archived || ctx.isActorLive && !ctx.isActorLive(ws, userId)) {
22
24
  ctx.sendError(ws, null, "Clay is not available.", requestId, null, "mate_unavailable");
23
25
  return;
24
26
  }
@@ -27,26 +29,43 @@ function attachHomeClayEntry(ctx) {
27
29
  return;
28
30
  }
29
31
  var manager = found.ctx.getSessionManager();
32
+ var mateStamp = JSON.stringify([found.mate.id, found.mate.createdAt || null, found.mate.createdBy || null]);
30
33
  if (!manager || typeof manager.sendAndRecord !== "function") {
31
34
  ctx.sendError(ws, found.mate.id, "Conversation history is unavailable.", requestId, null, "session_unavailable");
32
35
  return;
33
36
  }
34
37
  var existing = findExisting(manager, userId, requestId);
35
38
  if (existing) {
39
+ if (contextual) {
40
+ if (existing.homeClayEntryMode !== 'contextual' || existing.homeClayEntryText !== text || msg.sessionOriginId && msg.sessionOriginId !== existing.sessionOriginId) { ctx.sendError(ws, found.mate.id, 'This request belongs to a different conversation.', requestId, null, 'request_mismatch'); return; }
41
+ ctx.sendMessage(ws, { type: 'home_clay_contextual_session', requestId: requestId, mateId: found.mate.id, sessionId: existing.localId, sessionOriginId: existing.sessionOriginId }); return;
42
+ }
36
43
  ctx.setupSearchTap(ws, found, existing.localId, requestId);
37
44
  ctx.sendHistory(ws, found, existing, requestId);
38
45
  ctx.sendSessionList(ws, found, userId);
39
46
  return;
40
47
  }
48
+ if (contextual && msg.sessionOriginId) { ctx.sendError(ws, found.mate.id, 'This new conversation is no longer available. Start a new Ask.', requestId, null, 'session_unavailable'); return; }
41
49
  var session = null;
42
50
  try {
43
51
  var resolved = await ctx.homeModels.resolveMateModel(ws, found, userId);
44
52
  if (ctx.isActorLive && !ctx.isActorLive(ws, userId)) throw new Error("Your account is no longer available.");
45
53
  var liveFound = ctx.findMateProject(userId, null, true);
46
- if (!liveFound || liveFound.ctx !== found.ctx || !liveFound.mate || liveFound.mate.builtinKey !== "clay") throw new Error("Clay is no longer available.");
47
- session = manager.createSession({ ownerId: userId, vendor: resolved.vendor, model: resolved.model, effort: resolved.effort || null }, null);
54
+ if (!liveFound || liveFound.ctx !== found.ctx || !liveFound.mate || liveFound.ctx.getSessionManager() !== manager || liveFound.mate.builtinKey !== "clay" || JSON.stringify([liveFound.mate.id, liveFound.mate.createdAt || null, liveFound.mate.createdBy || null]) !== mateStamp || liveFound.mate.archived) throw new Error("Clay is no longer available.");
55
+ // Another request may have completed while model resolution was awaiting.
56
+ if (findExisting(manager, userId, requestId)) return start(ws, userId, msg);
57
+ var options = { ownerId: userId, vendor: resolved.vendor, model: resolved.model, effort: resolved.effort || null };
58
+ // Background creation must not switch any existing pane/native writer.
59
+ session = contextual ? manager.createSessionRaw(options) : manager.createSession(options, null);
48
60
  session.homeClayEntryRequestId = requestId;
49
- session.homeClayEntryMode = "search";
61
+ session.homeClayEntryMode = contextual ? 'contextual' : 'search';
62
+ if (contextual) {
63
+ session.homeClayEntryText = text;
64
+ session.title = text.slice(0, 80);
65
+ manager.saveSessionFile(session);
66
+ ctx.sendMessage(ws, { type: 'home_clay_contextual_session', requestId: requestId, mateId: found.mate.id, sessionId: session.localId, sessionOriginId: session.sessionOriginId });
67
+ return;
68
+ }
50
69
  manager.sendAndRecord(session, { type: "user_message", text: text });
51
70
  session.isProcessing = true;
52
71
  session.sentToolResults = {};
@@ -2,23 +2,43 @@
2
2
  // owner-bound source session.
3
3
 
4
4
  function attachHomeClaySessionLinks(ctx) {
5
- function source(ws, msg) {
5
+ function source(ws, msg, routedProjectSlug) {
6
+ if (Object.prototype.hasOwnProperty.call(msg, "contextualSource")) {
7
+ var hint = msg.contextualSource, userId = ws && ws._clayUser && ws._clayUser.id;
8
+ if (!hint || typeof hint.mateId !== "string" || !Number.isSafeInteger(hint.sessionId) || typeof hint.sessionOriginId !== "string" || typeof hint.mateStamp !== "string" || !ctx.isActorLive || !ctx.isActorLive(ws, userId)) return {};
9
+ var found = ctx.findMateProject && ctx.findMateProject(userId, hint.mateId, false);
10
+ if (!found || found.mate.archived || found.mate.lifecycleDeletion || found.mate.createdBy && found.mate.createdBy !== userId) return {};
11
+ var stamp = JSON.stringify([found.mate.id, found.mate.createdBy || null, found.mate.createdAt || null, found.mate.builtinKey || null]);
12
+ if (stamp !== hint.mateStamp || ctx.projects.get(found.slug) !== found.ctx) return {};
13
+ var manager = found.ctx.getSessionManager && found.ctx.getSessionManager();
14
+ var session = manager && manager.sessions.get(hint.sessionId);
15
+ if (!ctx.ownsSession(session, userId) || session.sessionOriginId !== hint.sessionOriginId) return {};
16
+ return { tap: { mateSlug: found.slug, mateId: found.mate.id, sessionId: hint.sessionId }, project: found.ctx, session: session };
17
+ }
6
18
  var tap = msg.surface === "search" ? ws._searchClayTap : ws._homeChatTap;
19
+ if (!tap && routedProjectSlug) {
20
+ var routedProject = ctx.projects.get(routedProjectSlug);
21
+ var routedManager = routedProject && routedProject.getSessionManager ? routedProject.getSessionManager() : null;
22
+ var routedSession = routedManager && ws._clayActiveSession ? routedManager.sessions.get(ws._clayActiveSession) : null;
23
+ return { tap: { mateSlug: routedProjectSlug, sessionId: ws._clayActiveSession }, project: routedProject, session: routedSession };
24
+ }
7
25
  var sourceProject = tap && tap.mateSlug ? ctx.projects.get(tap.mateSlug) : null;
8
26
  var sourceManager = sourceProject && sourceProject.getSessionManager ? sourceProject.getSessionManager() : null;
9
27
  var sourceSession = sourceManager && tap ? sourceManager.sessions.get(tap.sessionId) : null;
10
28
  return { tap: tap, project: sourceProject, session: sourceSession };
11
29
  }
12
30
 
13
- function resolve(ws, msg) {
14
- var selected = source(ws, msg);
15
- var bound = ctx.workspaceQueryService && selected.session
16
- ? ctx.workspaceQueryService.bindProjectSession({ projectSlug: selected.tap.mateSlug, session: selected.session })
17
- : null;
31
+ function resolve(ws, msg, routedProjectSlug) {
32
+ var selected = source(ws, msg, routedProjectSlug);
18
33
  var payload = { type: "home_clay_session_target", requestId: msg.requestId || null, sessionRef: msg.sessionRef || null, status: "error" };
19
34
  try {
35
+ var binding = selected.session ? { projectSlug: selected.tap.mateSlug, session: selected.session } : null;
36
+ if (binding && ws && ws._clayUser) binding.viewerId = ws._clayUser.id;
37
+ var bound = ctx.workspaceQueryService && binding
38
+ ? ctx.workspaceQueryService.bindProjectSession(binding)
39
+ : null;
20
40
  if (!bound) throw new Error("The source conversation is no longer available.");
21
- payload.target = bound.resolveSessionNavigation({ sessionRef: msg.sessionRef });
41
+ payload.target = bound.resolveSessionNavigation({ sessionRef: msg.sessionRef, entryIndex: msg.entryIndex });
22
42
  payload.status = "ready";
23
43
  } catch (error) {
24
44
  payload.error = error.message || "Session not available.";
@@ -26,8 +46,8 @@ function attachHomeClaySessionLinks(ctx) {
26
46
  ctx.sendMessage(ws, payload);
27
47
  }
28
48
 
29
- function resolveLog(ws, msg) {
30
- var selected = source(ws, msg);
49
+ function resolveLog(ws, msg, routedProjectSlug) {
50
+ var selected = source(ws, msg, routedProjectSlug);
31
51
  var status = selected.project && selected.project.getStatus ? selected.project.getStatus() : null;
32
52
  var bound = ctx.projectLogsService && selected.session && status
33
53
  ? ctx.projectLogsService.bindMate({
@@ -18,6 +18,7 @@ var INITIATION_PROMPT = [
18
18
  "Before the user answers again, your first and only action must be the next most useful AskUserQuestion. Before presenting it, do not use Bash, Read, Glob, Grep, workspace history, general knowledge, or any other inspection tool, and do not add a preface.",
19
19
  "When that tool returns the user's answer, continue the interview normally. Inspect only bounded context that is directly relevant to what the user supplied, and do not bulk-read knowledge files.",
20
20
  "Then explore the working relationship, recurring activities and context, communication preferences, autonomy, boundaries, and escalation behavior. Use grounded choices only when helpful. Every three to five exchanges, briefly summarize what you understand inside the next question and let the user correct it.",
21
+ "If the user explicitly asks the future Mate to send a scheduled message, collect the message and exact local date/time, timezone, and repetition only through one focused structured question at a time. Treat it as optional schedule intent: never create or register a job during this interview; include it only in propose_mate after reviewing it with the user.",
21
22
  "Choose the Mate's name last. Do not write files and do not create or update a Mate directly.",
22
23
  "When the identity is complete, end only by calling propose_mate with a concise public bio, structured preferences, and a complete first-person identityMarkdown. Do not emit a normal assistant preface or conclusion.",
23
24
  ].join("\n");
@@ -0,0 +1,14 @@
1
+ // Home transcript responses retain the project's server-owned consent request.
2
+ function attachHomeMcpConsent(ctx) {
3
+ function respond(ws, userId, msg) {
4
+ var found = ctx.findMateProject(userId, msg.mateId || null, false);
5
+ var session = found && ctx.resolveHomeSession(found, userId, msg.sessionId);
6
+ var tap = ctx.messageTap(ws, msg), pending = session && session.pendingAskUser && session.pendingAskUser[msg.toolId];
7
+ if (!ctx.isActorLive(ws, userId) || !found || !session || !tap || tap.mateSlug !== found.slug || tap.sessionId !== session.localId || (tap.requestId || null) !== (msg.requestId || null) || !pending || !pending.request || ['mcp-import', 'mate-schedule', 'mcp_fallback', 'product-control'].indexOf(pending.request.source) < 0) {
8
+ ctx.sendError(ws, found && found.mate.id, 'This owner question is unavailable or expired.', msg.requestId || null, msg.sessionId || null, 'question_expired', { toolId: msg.toolId }); return;
9
+ }
10
+ if (!found.ctx.handleHomeAskUserResponse({ type: 'ask_user_response', toolId: msg.toolId, answers: msg.answers || {} }, session, ws)) ctx.sendError(ws, found.mate.id, 'This question could not be submitted.', msg.requestId || null, msg.sessionId, 'question_refused', { toolId: msg.toolId });
11
+ }
12
+ return { respond: respond };
13
+ }
14
+ module.exports = { attachHomeMcpConsent: attachHomeMcpConsent };
@@ -74,12 +74,26 @@ function attachMates(ctx) {
74
74
  var mateSlug = "mate-" + mate.id;
75
75
  var mateName = (mate.profile && mate.profile.displayName) || mate.name || "Mate";
76
76
  var registered = false;
77
+ var boundScheduleJob = null;
77
78
  var favorites;
78
79
  try {
79
80
  registered = addProject(mateDir, mateSlug, mateName, null, mate.createdBy || effectiveUserId, null, { isMate: true, mateDisplayName: mateName }) !== false;
80
81
  if (!registered) throw new Error("The Mate project could not be registered.");
82
+ var intent = mate.seedData && mate.seedData.scheduleIntent;
83
+ if (intent && intent.message && intent.scheduleRule) {
84
+ var targetProject = projects.get(mateSlug);
85
+ var targetManager = targetProject && targetProject.getSessionManager();
86
+ if (!targetProject || !targetManager || typeof targetProject.bindMateSchedule !== "function") throw new Error("The Mate schedule could not be bound to the new Mate.");
87
+ var targetSession = targetManager.createSessionRaw({ ownerId: users.isMultiUser() ? effectiveUserId : null, vendor: mate.vendor, model: mate.model });
88
+ boundScheduleJob = targetProject.bindMateSchedule(targetSession, intent, "creation-" + mate.id);
89
+ if (!boundScheduleJob) throw new Error("The Mate schedule could not be persisted.");
90
+ mates.updateMate(mateCtx, mate.id, { seedData: Object.assign({}, mate.seedData, { scheduleIntent: null }) });
91
+ }
81
92
  favorites = users.addDmFavorite(effectiveUserId, mate.id);
82
93
  } catch (error) {
94
+ if (targetSession && targetSession.mateSchedules && targetProject && typeof targetProject.cancelMateSchedule === "function") {
95
+ try { targetSession.mateSchedules.forEach(function (record) { targetProject.cancelMateSchedule(targetSession, record); }); } catch (cancelError) {}
96
+ }
83
97
  if (registered) try { removeProject(mateSlug); } catch (removeError) {}
84
98
  try { mates.deleteMate(mateCtx, mate.id); } catch (deleteError) {}
85
99
  throw error;
@@ -97,6 +111,10 @@ function attachMates(ctx) {
97
111
  return mate;
98
112
  }
99
113
 
114
+ var lifecycle = require("./mate-lifecycle-service").attachMateLifecycleService({
115
+ users: users, mates: mates, projects: projects, removeProject: removeProject, refresh: refreshTeamSections,
116
+ });
117
+
100
118
  // --- Mate message handlers ---
101
119
 
102
120
  function handleMessage(ws, msg) {
@@ -168,7 +186,7 @@ function attachMates(ctx) {
168
186
  for (var mi = 0; mi < mateList.length; mi++) {
169
187
  var m = mateList[mi];
170
188
  var mSlug = "mate-" + m.id;
171
- if (!projects.has(mSlug)) {
189
+ if (!m.lifecycleDeletion && !projects.has(mSlug)) {
172
190
  var mDir = mates.getMateDir(mateCtx5, m.id);
173
191
  fs.mkdirSync(mDir, { recursive: true });
174
192
  var mName = (m.profile && m.profile.displayName) || m.name || "New Mate";
@@ -200,45 +218,9 @@ function attachMates(ctx) {
200
218
 
201
219
  if (msg.type === "mate_delete") {
202
220
  if (!msg.mateId) return true;
203
- var mateCtx6 = mates.buildMateCtx(userId);
204
- // Track deleted built-in mate key so it doesn't auto-recreate
205
- var mateToDelete = mates.getMate(mateCtx6, msg.mateId);
206
- if (mateToDelete && mateToDelete.builtinKey) {
207
- users.addDeletedBuiltinKey(userId, mateToDelete.builtinKey);
208
- }
209
- var result = mates.deleteMate(mateCtx6, msg.mateId);
210
- if (result.error) {
211
- ws.send(JSON.stringify({ type: "mate_error", error: result.error }));
212
- } else {
213
- removeProject("mate-" + msg.mateId);
214
- // Build updated available builtins list
215
- var builtinDefs3 = require("./builtin-mates");
216
- var missingKeys3 = mates.getMissingBuiltinKeys(mateCtx6);
217
- var availableBuiltins3 = [];
218
- for (var abk3 = 0; abk3 < missingKeys3.length; abk3++) {
219
- var bDef3 = builtinDefs3.getBuiltinByKey(missingKeys3[abk3]);
220
- if (bDef3) {
221
- availableBuiltins3.push({
222
- key: bDef3.key,
223
- displayName: bDef3.displayName,
224
- bio: bDef3.bio,
225
- avatarCustom: bDef3.avatarCustom || "",
226
- avatarStyle: bDef3.avatarStyle || "imprint",
227
- avatarColor: bDef3.avatarColor || "",
228
- });
229
- }
230
- }
231
- ws.send(JSON.stringify({ type: "mate_deleted", mateId: msg.mateId, availableBuiltins: availableBuiltins3 }));
232
- // Broadcast to all clients so strips update
233
- projects.forEach(function (pCtx) {
234
- pCtx.forEachClient(function (otherWs) {
235
- if (otherWs === ws) return;
236
- if (users.isMultiUser() && (!otherWs._clayUser || otherWs._clayUser.id !== userId)) return;
237
- if (otherWs.readyState !== 1) return;
238
- otherWs.send(JSON.stringify({ type: "mate_deleted", mateId: msg.mateId, availableBuiltins: availableBuiltins3 }));
239
- });
240
- });
241
- }
221
+ lifecycle.remove(userId, msg.mateId, null, ws).then(function () {}, function (error) {
222
+ ws.send(JSON.stringify({ type: "mate_error", mateId: msg.mateId, error: error.message }));
223
+ });
242
224
  return true;
243
225
  }
244
226
 
@@ -303,28 +285,8 @@ function attachMates(ctx) {
303
285
  ws.send(JSON.stringify({ type: "mate_error", mateId: msg.mateId, error: "Use the Mate model selector to change this setting." }));
304
286
  return true;
305
287
  }
306
- var mateCtx7 = mates.buildMateCtx(userId);
307
- var updated = mates.updateMate(mateCtx7, msg.mateId, msg.updates);
308
- if (updated && updated.error) {
309
- ws.send(JSON.stringify({ type: "mate_error", mateId: msg.mateId, requestId: msg.requestId, error: updated.error }));
310
- return true;
311
- }
312
- if (updated) {
313
- ws.send(JSON.stringify({ type: "mate_updated", mate: updated, requestId: msg.requestId }));
314
- // Broadcast update
315
- projects.forEach(function (pCtx) {
316
- pCtx.forEachClient(function (otherWs) {
317
- if (otherWs === ws) return;
318
- if (users.isMultiUser() && (!otherWs._clayUser || otherWs._clayUser.id !== userId)) return;
319
- if (otherWs.readyState !== 1) return;
320
- otherWs.send(JSON.stringify({ type: "mate_updated", mate: updated }));
321
- });
322
- });
323
- // Re-enforce team sections across all mate projects so roster stays current
324
- refreshTeamSections(mateCtx7);
325
- } else {
326
- ws.send(JSON.stringify({ type: "mate_error", mateId: msg.mateId, requestId: msg.requestId, error: "Mate not found" }));
327
- }
288
+ try { lifecycle.update(userId, msg.mateId, msg.updates, ws, msg.requestId); }
289
+ catch (error) { ws.send(JSON.stringify({ type: "mate_error", mateId: msg.mateId, requestId: msg.requestId, error: error.message })); }
328
290
  return true;
329
291
  }
330
292
 
@@ -333,6 +295,7 @@ function attachMates(ctx) {
333
295
 
334
296
  return {
335
297
  handleMessage: handleMessage,
298
+ lifecycle: lifecycle,
336
299
  scheduleRegistryRefresh: scheduleRegistryRefresh,
337
300
  createReadyMateFromInterview: createReadyMateFromInterview,
338
301
  };
@@ -0,0 +1,118 @@
1
+ var crypto = require('crypto');
2
+ // Only authenticated application sockets enumerated by the server are targets.
3
+ function attachOwnerUi(ctx) {
4
+ var identities = new WeakMap(), capabilities = new WeakMap(), deliveries = new Map();
5
+ var activityOrder = 0;
6
+ function activity(owner, slug, sessionId, mateId, selected, source, validateSource, navigationTarget) {
7
+ var order = ++activityOrder;
8
+ var viewers = selected ? [check(owner, selected)] : sockets(owner).filter(function (viewer) {
9
+ var tap = viewer.ws._homeChatTap;
10
+ return viewer.slug === slug && viewer.sessionId === sessionId || tap && tap.mateSlug === slug && tap.sessionId === sessionId;
11
+ });
12
+ function send(message, receiptViewer) {
13
+ viewers.forEach(function (viewer) {
14
+ try {
15
+ if (receiptViewer && viewer.ws !== receiptViewer || !alive(viewer.ws, owner)) return;
16
+ if (message.phase !== 'clear' && validateSource) validateSource();
17
+ var live = inspect(owner, viewer.ref), tap = live.ws._homeChatTap;
18
+ if (message.phase !== 'clear' && (selected ? (live.slug !== viewer.slug || live.sessionId !== viewer.sessionId) && !(message.phase === 'rendered' && navigationTarget && live.slug === navigationTarget.projectSlug && live.sessionId === navigationTarget.sessionId) : !(live.slug === slug && live.sessionId === sessionId || tap && tap.mateSlug === slug && tap.sessionId === sessionId))) return;
19
+ live.ws.send(JSON.stringify(Object.assign({ type: 'clay_control_activity', ownerId: owner, mateId: mateId,
20
+ sourceSlug: slug, sourceSessionId: sessionId, order: order, recipientViewerRef: live.ref }, source, message)));
21
+ } catch (error) { /* Presentation cannot alter the authoritative effect. */ }
22
+ });
23
+ }
24
+ return { send: send, clear: function (id, sequence) { send({ version: 1, id: id, sequence: sequence, phase: 'clear' }); } };
25
+ }
26
+ function alive(ws, owner) {
27
+ return ws && ws.readyState === 1 && (!ws._clayAuthCheck || ws._clayAuthCheck()) &&
28
+ (ctx.isMultiUser() ? !!owner && ws._clayUser && ws._clayUser.id === owner && !!ctx.findUser(owner) : !ws._clayUser);
29
+ }
30
+ function sockets(owner) {
31
+ var all = new Map();
32
+ ctx.forEachClient(function (ws, slug) {
33
+ if (!alive(ws, owner) || all.has(ws)) return;
34
+ if (!identities.has(ws)) identities.set(ws, 'viewer:' + crypto.randomUUID());
35
+ all.set(ws, { ws: ws, ref: identities.get(ws), slug: slug || null, sessionId: ws._clayActiveSession || null,
36
+ supported: capabilities.get(ws) === 1 && !ws._clayPane });
37
+ });
38
+ return Array.from(all.values());
39
+ }
40
+ function get(owner, ref) { return sockets(owner).find(function (item) { return item.ref === ref; }); }
41
+ function inspect(owner, ref) {
42
+ var viewer = get(owner, ref);
43
+ if (!viewer) throw new Error('The exact owner UI connection is absent or revoked.');
44
+ return viewer;
45
+ }
46
+ function check(owner, original) {
47
+ var live = inspect(owner, original.ref);
48
+ if (live.ws !== original.ws || live.slug !== original.slug || live.sessionId !== original.sessionId || live.supported !== original.supported) throw new Error('The selected viewer context changed. Inspect again.');
49
+ return live;
50
+ }
51
+ function deliver(owner, original, target, revalidate, activity) {
52
+ revalidate(); var viewer = check(owner, original);
53
+ if (!viewer.supported) return { status: 'unsupported', delivered: false, acknowledged: false, visible: 'unknown' };
54
+ if (deliveries.size >= 100) {
55
+ deliveries.forEach(function (item, key) { if (Date.now() - item.created > 300000) deliveries.delete(key); });
56
+ if (deliveries.size >= 100) throw new Error('UI delivery capacity is full; wait for earlier attempts to expire.');
57
+ }
58
+ var id = 'navigation:' + crypto.randomUUID();
59
+ var renderToken = crypto.randomUUID();
60
+ var record = { owner: owner, viewer: viewer, target: target, revalidate: revalidate, activity: activity, created: Date.now(), claimed: false, renderToken: renderToken, renderClosed: false,
61
+ result: { status: 'delivered', deliveryId: id, delivered: false, acknowledged: false, visible: 'unknown' } };
62
+ deliveries.set(id, record);
63
+ record.renderTimer = setTimeout(function () {
64
+ if (record.renderClosed) return;
65
+ record.renderClosed = true; record.result.renderStatus = 'unknown';
66
+ if (record.activity) record.activity.navigation('unknown');
67
+ }, ctx.renderTimeoutMs || 5000); record.renderTimer.unref();
68
+ try {
69
+ viewer.ws.send(JSON.stringify({ type: 'clay_navigation_offer', deliveryId: id }));
70
+ if (!alive(viewer.ws, owner)) throw new Error('Viewer authorization or connection ended during delivery.');
71
+ record.result.delivered = true;
72
+ } catch (error) { record.result.status = 'failed'; record.result.error = error.message; record.result.retrySafe = false; }
73
+ return Object.assign({}, record.result);
74
+ }
75
+ function read(owner, id) {
76
+ var record = deliveries.get(id);
77
+ if (!record || record.owner !== owner) throw new Error('No delivery exists for this owner.');
78
+ if (Date.now() - record.created > 300000) { deliveries.delete(id); throw new Error('The five-minute navigation receipt expired. Inspect the current view before any new reviewed request.'); }
79
+ record.revalidate();
80
+ return Object.assign({}, record.result);
81
+ }
82
+ function handleMessage(ws, msg) {
83
+ if (['clay_ui_ready', 'clay_navigation_claim', 'clay_navigation_ack', 'clay_navigation_rendered'].indexOf(msg.type) < 0) return false;
84
+ var owner = ctx.isMultiUser() ? ws._clayUser && ws._clayUser.id : null;
85
+ if (!sockets(owner).some(function (item) { return item.ws === ws; })) return true;
86
+ if (msg.type === 'clay_ui_ready') {
87
+ if (msg.version === 1) { capabilities.set(ws, 1); ws.send(JSON.stringify({ type: 'clay_control_viewer', viewerRef: identities.get(ws) })); }
88
+ return true;
89
+ }
90
+ var record = deliveries.get(msg.deliveryId);
91
+ if (!record || record.viewer.ws !== ws || record.owner !== owner || Date.now() - record.created > 30000) return true;
92
+ try {
93
+ record.revalidate();
94
+ if (msg.type === 'clay_navigation_rendered') {
95
+ if (!record.renderClosed && Date.now() > record.created + (ctx.renderTimeoutMs || 5000)) { record.renderClosed = true; clearTimeout(record.renderTimer); record.result.renderStatus = 'unknown'; if (record.activity) record.activity.navigation('unknown'); }
96
+ if (record.renderClosed || !record.claimed || !record.result.acknowledged || record.result.clientStatus !== 'accepted' || msg.renderToken !== record.renderToken) return true;
97
+ var current = inspect(owner, record.viewer.ref);
98
+ if (current.ws !== ws || msg.sessionOriginId !== record.target.sessionOriginId || !record.target.sessionOriginId || msg.projectSlug !== record.target.projectSlug || msg.sessionId !== record.target.sessionId || msg.surface !== 'conversation' || msg.entryIndex !== record.target.entryIndex || current.slug !== record.target.projectSlug || current.sessionId !== record.target.sessionId) throw new Error('Rendered target or authenticated viewer changed.');
99
+ record.renderClosed = true; clearTimeout(record.renderTimer);
100
+ record.result.renderStatus = msg.visible === true ? 'rendered' : 'unknown'; record.result.visible = msg.visible === true ? true : 'unknown';
101
+ if (record.activity) record.activity.navigation(msg.visible === true ? 'rendered' : 'unknown');
102
+ } else if (msg.type === 'clay_navigation_claim') {
103
+ if (record.claimed) return true;
104
+ check(owner, record.viewer); record.claimed = true;
105
+ ws.send(JSON.stringify({ type: 'clay_navigation_apply', deliveryId: msg.deliveryId, target: record.target, renderToken: record.renderToken, renderDeadline: record.created + (ctx.renderTimeoutMs || 5000) }));
106
+ } else if (record.claimed && !record.result.acknowledged && ['accepted', 'refused', 'failed'].indexOf(msg.status) >= 0) {
107
+ record.result.acknowledged = true;
108
+ // Accepted only confirms invocation of the existing navigator, never rendering.
109
+ record.result.clientStatus = msg.status;
110
+ if (msg.status !== 'accepted') { record.renderClosed = true; clearTimeout(record.renderTimer); }
111
+ if (record.activity) record.activity.navigation(msg.status === 'accepted' ? 'acknowledged' : msg.status === 'refused' ? 'cancelled' : 'failed');
112
+ }
113
+ } catch (error) { record.renderClosed = true; clearTimeout(record.renderTimer); record.result.visible = 'unknown'; record.result.status = 'failed'; record.result.error = error.message; record.result.retrySafe = false; if (record.activity) record.activity.cancel(); }
114
+ return true;
115
+ }
116
+ return { list: sockets, inspect: inspect, check: check, deliver: deliver, read: read, handleMessage: handleMessage, activity: activity };
117
+ }
118
+ module.exports = { attachOwnerUi: attachOwnerUi };
@@ -0,0 +1,38 @@
1
+ // Directory pickers and project registration must not become content-access
2
+ // bypasses through another spelling, symlink or nested directory.
3
+ var fs = require("fs");
4
+ var path = require("path");
5
+ function inside(root, target) {
6
+ var relative = path.relative(root, target);
7
+ return relative !== ".." && relative.indexOf(".." + path.sep) !== 0 && !path.isAbsolute(relative);
8
+ }
9
+ function attachPathAccess(ctx) {
10
+ return function (userId, requested) {
11
+ if (!ctx.users.isMultiUser()) return true;
12
+ var user = userId && ctx.users.findUserById(userId);
13
+ if (!user) return false;
14
+ var target;
15
+ try { target = fs.realpathSync(requested); } catch (error) { return false; }
16
+ var allowed = false;
17
+ var denied = false;
18
+ ctx.projects.forEach(function (project, slug) {
19
+ var status = project.getStatus();
20
+ var root;
21
+ try { root = fs.realpathSync(status.path); } catch (error) { return; }
22
+ if (inside(root, target) || inside(target, root)) {
23
+ if (!ctx.canAccess(userId, slug)) denied = true;
24
+ else if (inside(root, target)) allowed = true;
25
+ }
26
+ });
27
+ if (denied) return false;
28
+ if (ctx.osUsers) {
29
+ if (!user.linuxUser) return false;
30
+ try {
31
+ var identity = ctx.resolveIdentity(user.linuxUser);
32
+ return inside(fs.realpathSync(identity.home), target);
33
+ } catch (error) { return false; }
34
+ }
35
+ return allowed || ctx.users.getAllUsers().length === 1;
36
+ };
37
+ }
38
+ module.exports = { attachPathAccess: attachPathAccess };
@@ -0,0 +1,22 @@
1
+ // Shared runtime removal used by the server callback and lifecycle controls.
2
+ function removeProjectRuntime(projects, slug, awaitCompletion, registryRefresh) {
3
+ var project = projects.get(slug);
4
+ if (!project) return false;
5
+ var wasMate = project.getStatus().isMate;
6
+ var shutdownResult = project.destroy();
7
+ if (!awaitCompletion) projects.delete(slug);
8
+ if (shutdownResult && typeof shutdownResult.catch === 'function') {
9
+ shutdownResult.catch(function (error) {
10
+ console.error('[server] Project destroy failed for ' + slug + ':', error && error.message ? error.message : error);
11
+ });
12
+ }
13
+ if (!wasMate && registryRefresh) registryRefresh();
14
+ if (awaitCompletion) return Promise.resolve(shutdownResult).then(function (result) {
15
+ if (result !== true) throw new Error('Project runtime shutdown did not complete successfully: ' + slug);
16
+ if (projects.get(slug) !== project) throw new Error('Project runtime was replaced during shutdown: ' + slug);
17
+ projects.delete(slug);
18
+ return true;
19
+ });
20
+ return true;
21
+ }
22
+ module.exports = { removeProjectRuntime: removeProjectRuntime };
@@ -12,11 +12,13 @@ function attachSettings(ctx) {
12
12
  var CONFIG_DIR = ctx.CONFIG_DIR;
13
13
 
14
14
  var profilePath = path.join(CONFIG_DIR, "profile.json");
15
+ var contextualClaySettings = require('./server-contextual-clay-settings').attachContextualClaySettings(ctx);
15
16
  var appearanceSettings = require('./server-appearance-settings').attachAppearanceSettings(ctx);
16
17
  var notificationSettings = require('./server-notification-settings').attachNotificationSettings(ctx);
17
18
  var experimentalSettings = attachExperimentalSettings(ctx);
18
19
 
19
20
  function handleRequest(req, res, fullUrl) {
21
+ if (contextualClaySettings.handleRequest(req, res, fullUrl)) return true;
20
22
  if (appearanceSettings.handleRequest(req, res, fullUrl)) return true;
21
23
  if (notificationSettings.handleRequest(req, res, fullUrl)) return true;
22
24
  if (experimentalSettings.handleRequest(req, res, fullUrl)) return true;
@@ -755,7 +757,10 @@ function attachSettings(ctx) {
755
757
  return false;
756
758
  }
757
759
 
758
- return { handleRequest: handleRequest };
760
+ return {
761
+ handleRequest: handleRequest,
762
+ getInitialAppearance: appearanceSettings.getInitialAppearance
763
+ };
759
764
  }
760
765
 
761
766
  module.exports = { attachSettings: attachSettings };