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
package/lib/server.js CHANGED
@@ -10,7 +10,7 @@ var dm = require("./dm");
10
10
  var mates = require("./mates");
11
11
  var serverAuth = require("./server-auth");
12
12
  var serverSkills = require("./server-skills");
13
- var claudeHookInstaller = require("./claude-hook-installer");
13
+ var claudeHookInstaller = require("./yoke/claude-hook-installer");
14
14
  var serverDm = require("./server-dm");
15
15
  var serverMates = require("./server-mates");
16
16
  var serverHomeChat = require("./server-home-chat");
@@ -219,6 +219,14 @@ function createServer(opts) {
219
219
  var isRequestAuthed = auth.isRequestAuthed;
220
220
  var parseCookies = auth.parseCookies;
221
221
 
222
+ var projectAdminOverview = require("./project-admin-overview");
223
+
224
+ function administrativeMetadata(userId, slug) {
225
+ var user = userId && users.findUserById(userId);
226
+ var context = projects.get(slug);
227
+ return projectAdminOverview.metadataFor(user, context && context.getStatus(), onGetProjectAccess && onGetProjectAccess(slug), users);
228
+ }
229
+
222
230
  function canUserAccessSlug(userId, slug) {
223
231
  if (!userId || !slug) return false;
224
232
  var project = projects && projects.get(slug);
@@ -237,6 +245,13 @@ function createServer(opts) {
237
245
  return users.canAccessProject(userId, access) === true;
238
246
  }
239
247
 
248
+ var projects = new Map(); // slug → projectContext
249
+ var lifecycleRuntime = require("./project-lifecycle-runtime").attachLifecycleRuntime({ projects: projects });
250
+ var canUsePath = require("./server-path-access").attachPathAccess({
251
+ users: users, projects: projects, canAccess: canUserAccessSlug, osUsers: osUsers,
252
+ resolveIdentity: require("./os-users").resolveOsUserInfo,
253
+ });
254
+
240
255
  var realVersion = require("../package.json").version;
241
256
  var currentVersion = debug ? "0.0.9" : realVersion;
242
257
 
@@ -341,8 +356,13 @@ function createServer(opts) {
341
356
  var caContent = caPath ? (function () { try { return fs.readFileSync(caPath); } catch (e) { return null; } })() : null;
342
357
 
343
358
  // --- Project registry ---
344
- var projects = new Map(); // slug → projectContext
345
359
  var assignmentService = attachWorkspaceAssignmentService({
360
+ getPresentation: function (principal) {
361
+ var project = projects.get(principal.sourceProjectSlug), manager = project && project.getSessionManager(), status = project && project.getStatus();
362
+ var session = manager && manager.sessions.get(principal.sourceSessionId);
363
+ var bound = clayProductControl && session && clayProductControl.bind({ projectSlug: principal.sourceProjectSlug, projectOwnerId: status.projectOwnerId, isMate: status.isMate, mateId: status.mateId, session: session });
364
+ return bound && bound._presentation;
365
+ },
346
366
  storageDir: path.join(CONFIG_DIR, "workspace-assignments"),
347
367
  getProjects: function () { return projects; },
348
368
  isMultiUser: function () { return users.isMultiUser(); },
@@ -363,6 +383,36 @@ function createServer(opts) {
363
383
  },
364
384
  assignmentService: assignmentService,
365
385
  });
386
+ var ownerUiService = require('./server-owner-ui').attachOwnerUi({
387
+ isMultiUser: users.isMultiUser, findUser: users.findUserById,
388
+ forEachClient: function (visit) {
389
+ if (globalWs) globalWs.forEachClient(function (ws) { visit(ws, null); });
390
+ projects.forEach(function (project, slug) { project.forEachClient(function (ws) { visit(ws, slug); }); });
391
+ }
392
+ });
393
+ var mateContextService = require('./mate-context-service').attachMateContextService({
394
+ getOwnerUi: function () { return ownerUiService; }, workspace: workspaceQueryService,
395
+ getProjects: function () { return projects; }, isMultiUser: users.isMultiUser,
396
+ findUser: users.findUserById, onGetProjectAccess: onGetProjectAccess,
397
+ canAccessProject: users.canAccessProject,
398
+ resolveMate: function (owner, id) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? owner : null), id); }
399
+ });
400
+ var clayProductControl = require("./clay-product-control").attachClayProductControl({
401
+ getOwnerUi: function () { return ownerUiService; },
402
+ getNotifications: function () { return _globalNotifications; },
403
+ getRecordServices: function () { return { issues: issuesService, logs: projectLogsService }; },
404
+ projectLifecycle: opts.projectLifecycle || null,
405
+ getMateLifecycle: function () { return mateHandler && mateHandler.lifecycle; },
406
+ getMateDir: function (ownerId, mateId) { return mates.getMateDir(mates.buildMateCtx(users.isMultiUser() ? ownerId : null), mateId); },
407
+ lifecyclePermissions: function (user) { return users.getEffectivePermissions(user, osUsers); },
408
+ canUsePath: canUsePath,
409
+ getProjects: function () { return projects; },
410
+ isMultiUser: function () { return users.isMultiUser(); },
411
+ onGetProjectAccess: onGetProjectAccess,
412
+ canAccessProject: function (userId, access) { return users.canAccessProject(userId, access) === true; },
413
+ findUser: function (userId) { return users.findUserById(userId); },
414
+ resolveMate: function (userId, mateId) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? userId : null), mateId); },
415
+ });
366
416
  // Project access is resolved from the authoritative project record, not from
367
417
  // getStatus(), which carries no visibility or allowedUsers fields.
368
418
  var projectLogsService = attachProjectLogsService({
@@ -409,6 +459,7 @@ function createServer(opts) {
409
459
  // Mate Knowledge reads the synchronized Knowledge records. The Mate list is
410
460
  // derived from the owning user alone, so a binding can never span users.
411
461
  var mateKnowledgeService = attachMateKnowledgeService({
462
+ findUser: function (userId) { return users.findUserById(userId); },
412
463
  getProjects: function () { return projects; },
413
464
  isMultiUser: function () { return users.isMultiUser(); },
414
465
  resolveMate: function (userId, mateId) {
@@ -491,6 +542,41 @@ function createServer(opts) {
491
542
  },
492
543
  });
493
544
 
545
+ function injectAppearanceSeed(html, appearance) {
546
+ var validId = function (value) {
547
+ return typeof value === "string" && /^[a-zA-Z0-9_-]{1,120}$/.test(value) ? value : null;
548
+ };
549
+ var mode = appearance && ["light", "dark"].indexOf(appearance.mode) >= 0 ? appearance.mode : null;
550
+ var seed = appearance && appearance.configured === true ? {
551
+ configured: true,
552
+ theme: validId(appearance.theme),
553
+ mode: mode,
554
+ lightTheme: validId(appearance.lightTheme),
555
+ darkTheme: validId(appearance.darkTheme),
556
+ } : null;
557
+ var payload = JSON.stringify(seed).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
558
+ var script = '<script>window.__clayAppearanceSeed=' + payload + ';</script>';
559
+ return html.replace('<script src="appearance-bootstrap.js"></script>', script + '<script src="appearance-bootstrap.js"></script>');
560
+ }
561
+
562
+ function sendAppShell(req, res, slug) {
563
+ try {
564
+ var shell = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
565
+ if (slug) shell = injectRootProjectSlug(shell, slug);
566
+ var appearance = null;
567
+ try { appearance = settings.getInitialAppearance(req); } catch (e) {}
568
+ shell = injectAppearanceSeed(shell, appearance);
569
+ res.writeHead(200, {
570
+ "Content-Type": "text/html; charset=utf-8",
571
+ "Cache-Control": "private, no-store",
572
+ });
573
+ res.end(shell);
574
+ } catch (e) {
575
+ res.writeHead(500, { "Content-Type": "text/plain" });
576
+ res.end("App shell missing.");
577
+ }
578
+ }
579
+
494
580
  var palette = serverPalette.attachPalette({
495
581
  users: users,
496
582
  projects: projects,
@@ -512,7 +598,28 @@ function createServer(opts) {
512
598
  broadcastAll: function (msg) { broadcastAll(msg); },
513
599
  sendToUser: function (userId, msg) { sendToUser(userId, msg); },
514
600
  pushModule: pushModule,
601
+ forEachClient: forEachAppClient,
602
+ getUsers: function () { return users.getAllUsers(); },
603
+ canView: function (ws, notification) { return canViewNotification(ws && ws._clayUser && ws._clayUser.id, notification); },
604
+ canViewPrincipal: function (principal, notification) { return canViewNotification(principal.userId, notification); },
515
605
  });
606
+ function canViewNotification(userId, notification) {
607
+ if (!users.isMultiUser()) return true;
608
+ if (!userId || !users.findUserById(userId)) return false;
609
+ if (notification.targetUserId && notification.targetUserId !== userId) return false;
610
+ if (notification.slug) {
611
+ if (!canUserAccessSlug(userId, notification.slug)) return false;
612
+ if (notification.sessionId) {
613
+ var project = projects.get(notification.slug);
614
+ var session = project && project.getSessionManager().sessions.get(notification.sessionId);
615
+ var status = project && project.getStatus();
616
+ var access = status && status.isMate ? { isMate: true, visibility: "private", ownerId: status.projectOwnerId } : onGetProjectAccess(notification.slug);
617
+ if (!session || !users.canAccessSession(userId, session, access)) return false;
618
+ }
619
+ return !notification.ownerId || notification.ownerId === userId || !!notification.sessionId;
620
+ }
621
+ return notification.targetUserId === userId || notification.ownerId === userId;
622
+ }
516
623
 
517
624
  // --- Security headers ---
518
625
  var securityHeaders = {
@@ -910,15 +1017,7 @@ function createServer(opts) {
910
1017
  });
911
1018
  }
912
1019
  if (targetSlug) {
913
- try {
914
- var homeHtml = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
915
- homeHtml = injectRootProjectSlug(homeHtml, targetSlug);
916
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-cache" });
917
- res.end(homeHtml);
918
- } catch (e) {
919
- res.writeHead(500, { "Content-Type": "text/plain" });
920
- res.end("App shell missing.");
921
- }
1020
+ sendAppShell(req, res, targetSlug);
922
1021
  return;
923
1022
  }
924
1023
  }
@@ -936,9 +1035,7 @@ function createServer(opts) {
936
1035
  return;
937
1036
  }
938
1037
  }
939
- if (serveStatic("/index.html", res)) return;
940
- res.writeHead(500, { "Content-Type": "text/plain" });
941
- res.end("App shell missing.");
1038
+ sendAppShell(req, res, null);
942
1039
  return;
943
1040
  }
944
1041
 
@@ -955,8 +1052,8 @@ function createServer(opts) {
955
1052
  var projectList = [];
956
1053
  var infoUser = users.isMultiUser() ? getMultiUserFromReq(req) : null;
957
1054
  projects.forEach(function (ctx, slug) {
958
- if (users.isMultiUser() && (!infoUser || !canUserAccessSlug(infoUser.id, slug))) return;
959
- projectList.push({ slug: slug, project: ctx.project });
1055
+ if (users.isMultiUser() && (!infoUser || (!canUserAccessSlug(infoUser.id, slug) && !administrativeMetadata(infoUser.id, slug)))) return;
1056
+ projectList.push({ slug: slug, project: ctx.project, contentAccess: !users.isMultiUser() || canUserAccessSlug(infoUser.id, slug) });
960
1057
  });
961
1058
  res.writeHead(200, { "Content-Type": "application/json" });
962
1059
  res.end(JSON.stringify({ projects: projectList, version: currentVersion, authenticated: true }));
@@ -965,6 +1062,10 @@ function createServer(opts) {
965
1062
 
966
1063
  // Static files (favicon, manifest, icons, sw.js, mate avatars, etc.)
967
1064
  if (!fullUrl.includes("..") && !fullUrl.startsWith("/p/") && !fullUrl.startsWith("/api/")) {
1065
+ if (fullUrl === "/index.html") {
1066
+ sendAppShell(req, res, null);
1067
+ return;
1068
+ }
968
1069
  if (serveStatic(fullUrl, res)) return;
969
1070
  }
970
1071
 
@@ -1028,8 +1129,14 @@ function createServer(opts) {
1028
1129
  if (users.isMultiUser() && !isMcpBridgeAuthenticated) {
1029
1130
  var httpUser = getMultiUserFromReq(req);
1030
1131
  if (!httpUser || !canUserAccessSlug(httpUser.id, slug)) {
1031
- res.writeHead(302, { "Location": "/" });
1032
- res.end();
1132
+ var overview = httpUser && administrativeMetadata(httpUser.id, slug);
1133
+ if (overview && req.method === "GET" && (projectUrlForAuth === "/" || projectUrlForAuth === "/index.html")) {
1134
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
1135
+ res.end(projectAdminOverview.page(overview, getVisibleProjects(httpUser.id)));
1136
+ return;
1137
+ }
1138
+ res.writeHead(403, { "Content-Type": "application/json", "Cache-Control": "no-store" });
1139
+ res.end(JSON.stringify({ error: "Project content access is not permitted" }));
1033
1140
  return;
1034
1141
  }
1035
1142
  }
@@ -1054,6 +1161,10 @@ function createServer(opts) {
1054
1161
 
1055
1162
  // Static files (same assets for all projects)
1056
1163
  if (req.method === "GET") {
1164
+ if (projectUrl === "/" || projectUrl === "/index.html") {
1165
+ sendAppShell(req, res, slug);
1166
+ return;
1167
+ }
1057
1168
  if (serveStatic(projectUrl, res)) return;
1058
1169
  }
1059
1170
 
@@ -1134,6 +1245,7 @@ function createServer(opts) {
1134
1245
  var globalWs = serverGlobalWs.attachGlobalWs({
1135
1246
  osUsers: osUsers,
1136
1247
  usersModule: users,
1248
+ canUsePath: canUsePath,
1137
1249
  onAddProject: onAddProject,
1138
1250
  onCreateProject: onCreateProject,
1139
1251
  onCloneProject: onCloneProject,
@@ -1185,6 +1297,7 @@ function createServer(opts) {
1185
1297
  if (!require('./account-auth-socket').guardSocket(ws, req, isRequestAuthed, auth.touchSession)) return;
1186
1298
  ws._clayPane = wsRequest.pane;
1187
1299
  ws._clayPaneSession = wsRequest.paneSession;
1300
+ ws._clayContextual = wsRequest.contextual;
1188
1301
  globalWs.handleConnection(ws, globalUser);
1189
1302
  });
1190
1303
  return;
@@ -1230,6 +1343,7 @@ function createServer(opts) {
1230
1343
  ws._clayUser = wsUser; // attach user context
1231
1344
  ws._clayPane = wsRequest.pane;
1232
1345
  ws._clayPaneSession = wsRequest.paneSession;
1346
+ ws._clayContextual = wsRequest.contextual;
1233
1347
  var remoteAddr = req.socket.remoteAddress || "";
1234
1348
  ws._clayLocal = (remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1");
1235
1349
  // Clear cross-project unread for this project when client connects
@@ -1274,17 +1388,10 @@ function createServer(opts) {
1274
1388
  if (processingUpdateTimer) clearTimeout(processingUpdateTimer);
1275
1389
  processingUpdateTimer = setTimeout(function () {
1276
1390
  processingUpdateTimer = null;
1277
- var allProjectsList = getProjects();
1278
1391
  // Always send per-client to include cross-project unread counts
1279
1392
  projects.forEach(function (ctx, projSlug) {
1280
1393
  ctx.forEachClient(function (ws) {
1281
- var filtered = allProjectsList;
1282
- if (users.isMultiUser() && onGetProjectAccess) {
1283
- var wsUser = ws._clayUser;
1284
- filtered = wsUser ? allProjectsList.filter(function (p) {
1285
- return canUserAccessSlug(wsUser.id, p.slug);
1286
- }) : [];
1287
- }
1394
+ var filtered = getVisibleProjects(ws._clayUser ? ws._clayUser.id : null);
1288
1395
  // Attach per-project unread counts for this client
1289
1396
  var unreadMap = getCrossProjectUnread(ws);
1290
1397
  var projectsWithUnread = filtered.map(function (p) {
@@ -1334,6 +1441,10 @@ function createServer(opts) {
1334
1441
  function addProject(cwd, slug, title, icon, projectOwnerId, worktreeMeta, extraOpts) {
1335
1442
  if (projects.has(slug)) return false;
1336
1443
  var extra = extraOpts || {};
1444
+ if (extra.isMate) {
1445
+ var registeredMate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
1446
+ if (registeredMate && registeredMate.lifecycleDeletion) return false;
1447
+ }
1337
1448
  var ctx = createProjectContext({
1338
1449
  cwd: cwd,
1339
1450
  slug: slug,
@@ -1353,6 +1464,9 @@ function createServer(opts) {
1353
1464
  return mateHandler.createReadyMateFromInterview(ws, userId, definition);
1354
1465
  },
1355
1466
  workspaceQueryService: workspaceQueryService,
1467
+ clayProductControl: clayProductControl,
1468
+ mateContextService: mateContextService,
1469
+ resumeLifecycleProject: function (userId) { return opts.projectLifecycle ? opts.projectLifecycle.resumeRecovered(slug, userId) : true; },
1356
1470
  projectLogsService: projectLogsService,
1357
1471
  issuesService: issuesService,
1358
1472
  linearStorage: linear.storage,
@@ -1374,13 +1488,19 @@ function createServer(opts) {
1374
1488
  return !!(access && !access.error && users.canAccessProject(userId, access));
1375
1489
  },
1376
1490
  getProjectAccess: function () {
1377
- if (extra.isMate) return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [] };
1491
+ if (extra.isMate) {
1492
+ var mate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
1493
+ return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [], lifecycleExecutionPaused: !mate || !!mate.lifecycleDeletion };
1494
+ }
1378
1495
  return onGetProjectAccess ? onGetProjectAccess(slug) : { visibility: "public", ownerId: projectOwnerId || null };
1379
1496
  },
1380
1497
  shouldSuppressResponseNotification: function (session) {
1381
1498
  return shouldSuppressHomeResponse(projects, slug, session);
1382
1499
  },
1383
- pushModule: pushModule,
1500
+ pushModule: require("./project-push-access").scopedPush(pushModule, {
1501
+ slug: slug, users: users, getProject: function (target) { return projects.get(target); },
1502
+ canAccessProject: canUserAccessSlug, getAccess: onGetProjectAccess,
1503
+ }),
1384
1504
  debug: debug,
1385
1505
  dangerouslySkipPermissions: dangerouslySkipPermissions,
1386
1506
  osUsers: osUsers,
@@ -1412,6 +1532,7 @@ function createServer(opts) {
1412
1532
  var status = ctx.getStatus();
1413
1533
  var recs = ctx.getSchedules();
1414
1534
  for (var i = 0; i < recs.length; i++) {
1535
+ if (users.isMultiUser() && recs[i].ownerId !== userId) continue;
1415
1536
  // Shallow-copy full record and augment with project metadata
1416
1537
  var copy = {};
1417
1538
  var keys = Object.keys(recs[i]);
@@ -1469,6 +1590,7 @@ function createServer(opts) {
1469
1590
  return ctx.getSchedules().length;
1470
1591
  },
1471
1592
  canAccessProjectSlug: canUserAccessSlug,
1593
+ canUsePath: canUsePath,
1472
1594
  onPresenceChange: broadcastPresenceChange,
1473
1595
  onProcessingChanged: broadcastProcessingChange,
1474
1596
  onSessionDone: function () { onSessionDone(slug); },
@@ -1622,6 +1744,8 @@ function createServer(opts) {
1622
1744
  }
1623
1745
 
1624
1746
  function handleDmMessage(ws, msg, routedProjectSlug) {
1747
+ if (ownerUiService.handleMessage(ws, msg)) return true;
1748
+ if (mateContextService.handleMessage(ws, msg)) return true;
1625
1749
  if (cursorSharingService && cursorSharingService.handleMessage(ws, msg)) return true;
1626
1750
  if (defaultVendorService && defaultVendorService.handleMessage(ws, msg, routedProjectSlug)) return true;
1627
1751
  if (contextViewService && contextViewService.handleMessage(ws, msg)) return true;
@@ -1630,25 +1754,14 @@ function createServer(opts) {
1630
1754
  if (dmHandler.handleMessage(ws, msg)) return true;
1631
1755
  if (mateHandler && mateHandler.handleMessage(ws, msg)) return true;
1632
1756
  if (emailHandler.handleMessage(ws, msg)) return true;
1633
- if (homeChatHandler.handleMessage(ws, msg)) return true;
1757
+ if (homeChatHandler.handleMessage(ws, msg, routedProjectSlug)) return true;
1634
1758
  if (homePreferencesHandler.handleMessage(ws, msg)) return true;
1635
1759
  if (toolsHandler.handleMessage(ws, msg)) return true;
1636
1760
  return false;
1637
1761
  }
1638
1762
 
1639
- function removeProject(slug) {
1640
- var ctx = projects.get(slug);
1641
- if (!ctx) return false;
1642
- var wasMate = ctx.getStatus().isMate;
1643
- var shutdownResult = ctx.destroy();
1644
- projects.delete(slug);
1645
- if (shutdownResult && typeof shutdownResult.catch === "function") {
1646
- shutdownResult.catch(function(err) {
1647
- console.error("[server] Project destroy failed for " + slug + ":", err && err.message ? err.message : err);
1648
- });
1649
- }
1650
- if (!wasMate) scheduleRegistryRefresh();
1651
- return true;
1763
+ function removeProject(slug, awaitCompletion) {
1764
+ return require('./server-project-removal').removeProjectRuntime(projects, slug, awaitCompletion, scheduleRegistryRefresh);
1652
1765
  }
1653
1766
 
1654
1767
  // Now that addProject and removeProject are defined, initialize mateHandler
@@ -1734,7 +1847,11 @@ function createServer(opts) {
1734
1847
  function getVisibleProjects(userId) {
1735
1848
  var visible = [];
1736
1849
  projects.forEach(function (ctx, slug) {
1737
- if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) return;
1850
+ if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) {
1851
+ var metadata = administrativeMetadata(userId, slug);
1852
+ if (metadata) visible.push(metadata);
1853
+ return;
1854
+ }
1738
1855
  var status = ctx.getStatus();
1739
1856
  if (!status.isMate && onGetProjectAccess) {
1740
1857
  var access = onGetProjectAccess(slug);
@@ -1933,6 +2050,7 @@ function createServer(opts) {
1933
2050
  speech.destroy();
1934
2051
  var shutdowns = [];
1935
2052
  shutdowns.push(durableSchedulerLifecycle.shutdown());
2053
+ shutdowns.push(lifecycleRuntime.shutdown());
1936
2054
  projects.forEach(function (ctx, slug) {
1937
2055
  console.log("[server] Destroying project:", slug);
1938
2056
  var result = ctx.destroy();
@@ -2000,6 +2118,8 @@ function createServer(opts) {
2000
2118
  isTLS: !!tlsOptions,
2001
2119
  addProject: addProject,
2002
2120
  removeProject: removeProject,
2121
+ getProjectLifecycleTargets: lifecycleRuntime.targets,
2122
+ closeProjectLifecycle: lifecycleRuntime.close,
2003
2123
  getProjects: getProjects,
2004
2124
  reorderProjects: reorderProjects,
2005
2125
  setProjectTitle: setProjectTitle,
@@ -0,0 +1,45 @@
1
+ // Guarded configuration commit shared by SDK setters and permission transitions.
2
+ // Provider acknowledgement is distinct from local persistence. Once a request
3
+ // has crossed that boundary, failures never imply the provider was rolled back.
4
+ async function applySessionConfig(ctx) {
5
+ var session = ctx.session, sm = ctx.sm, handle = session.queryInstance;
6
+ var generation = Number(session._sdkQueryGeneration || 0), owner = session.ownerId;
7
+ var paused = !!session._pendingMessageDrainPaused, signal = session.abortController && session.abortController.signal;
8
+ var attempted = false, acknowledged = false, persisted = false, previous = {};
9
+ function current() {
10
+ ctx.revalidate();
11
+ if (sm.sessions.get(session.localId) !== session || session.ownerId !== owner || session.queryInstance !== handle ||
12
+ Number(session._sdkQueryGeneration || 0) !== generation || session.taskStopRequested ||
13
+ !!session._pendingMessageDrainPaused !== paused || signal && signal.aborted) throw new Error("Target ownership, runtime, or Stop state changed during the configuration request.");
14
+ }
15
+ try {
16
+ current();
17
+ if (handle) {
18
+ if (typeof handle[ctx.method] !== "function") throw new Error("This provider cannot apply this configuration to the active runtime.");
19
+ attempted = true;
20
+ var reply = await handle[ctx.method](ctx.nativeValue);
21
+ if (reply === false || reply && reply.ok === false) throw new Error(reply && reply.error || "The provider refused the configuration change.");
22
+ acknowledged = true;
23
+ current();
24
+ }
25
+ var changes = typeof ctx.changes === "function" ? ctx.changes() : ctx.changes;
26
+ Object.keys(changes).forEach(function (key) { previous[key] = { present: Object.prototype.hasOwnProperty.call(session, key), value: session[key] }; });
27
+ Object.assign(session, changes);
28
+ try {
29
+ if (sm.saveSessionFile(session) !== true) throw new Error("Could not persist the configuration change.");
30
+ persisted = true;
31
+ } catch (error) {
32
+ Object.keys(previous).forEach(function (key) { if (previous[key].present) session[key] = previous[key].value; else delete session[key]; });
33
+ throw error;
34
+ }
35
+ // There is no await between the last authorization check, disk commit and
36
+ // publication. Never broadcast a desired value before its save succeeds.
37
+ ctx.publish();
38
+ return Object.assign({ ok: true, status: "completed", persisted: true, runtimeEffect: acknowledged ? "applied" : "none" }, changes);
39
+ } catch (error) {
40
+ return { ok: false, status: "failed", outcome: persisted ? "partial" : attempted ? "uncertain" : "failed", persisted: persisted,
41
+ runtimeEffect: acknowledged ? "applied" : attempted ? "unknown" : "none", retrySafe: !attempted && !persisted,
42
+ error: (persisted ? "The configuration was saved, but publication did not complete. " : "") + (attempted ? "The provider may retain the requested change; no external rollback was attempted. " : "") + (error.message || String(error)) };
43
+ }
44
+ }
45
+ module.exports = { applySessionConfig: applySessionConfig };
@@ -9,7 +9,7 @@
9
9
  // also keeps its folder (or Unfiled) assignment
10
10
  // orders: { containerKey: [keys] } manual order per container ("unfiled", custom id, "all")
11
11
  // collapsed: { containerKey: true }
12
- // view: { group, sort, direction }
12
+ // view: { group, sort, direction, showDateHeadings }
13
13
  // sessionKey is the session's opaque, durable sessionOriginId.
14
14
 
15
15
  var crypto = require("crypto");
@@ -35,7 +35,7 @@ function defaultState() {
35
35
  favorites: [],
36
36
  orders: {},
37
37
  collapsed: {},
38
- view: { group: "folders", sort: "activity", direction: "desc" },
38
+ view: { group: "folders", sort: "activity", direction: "desc", showDateHeadings: true },
39
39
  legacyFavoritesMigrated: false,
40
40
  };
41
41
  }
@@ -147,6 +147,7 @@ function normalizeState(raw) {
147
147
  var view = isPlainObject(source.view) ? source.view : {};
148
148
  if (SORTS.indexOf(view.sort) !== -1) state.view.sort = view.sort;
149
149
  if (DIRECTIONS.indexOf(view.direction) !== -1) state.view.direction = view.direction;
150
+ if (typeof view.showDateHeadings === "boolean") state.view.showDateHeadings = view.showDateHeadings;
150
151
  state.legacyFavoritesMigrated = source.legacyFavoritesMigrated === true;
151
152
  return state;
152
153
  }
@@ -334,6 +335,10 @@ function applyRaw(input, op, env) {
334
335
  if (DIRECTIONS.indexOf(op.direction) === -1) return { error: "Invalid direction" };
335
336
  state.view.direction = op.direction;
336
337
  }
338
+ if (op.showDateHeadings !== undefined) {
339
+ if (typeof op.showDateHeadings !== "boolean") return { error: "Invalid date heading setting" };
340
+ state.view.showDateHeadings = op.showDateHeadings;
341
+ }
337
342
  return { state: state };
338
343
  }
339
344
 
@@ -0,0 +1,21 @@
1
+ // Product transcript slicing for providers that include a completed turn.
2
+ function endIndex(session, uuid, boundary) {
3
+ if (boundary === undefined) return undefined;
4
+ if (boundary !== "completed-turn-inclusive") throw new Error("Unsupported local fork history boundary");
5
+ var history = session.history || [];
6
+ var markers = (session.messageUUIDs || []).filter(function(marker) { return marker.uuid === uuid && marker.type === "user"; });
7
+ var marker = markers.length === 1 && markers[0];
8
+ var index = marker && marker.historyIndex;
9
+ var entry = Number.isInteger(index) && history[index];
10
+ if (!entry || entry.type !== "message_uuid" || entry.uuid !== uuid) throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
11
+ for (var i = index + 1; i < history.length; i++) {
12
+ entry = history[i];
13
+ if (entry.type === "user_message" || entry.type === "message_uuid" && entry.messageType === "user") break;
14
+ if (entry.type === "done") {
15
+ if (entry.code === 0) return i + 1;
16
+ break;
17
+ }
18
+ }
19
+ throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
20
+ }
21
+ module.exports = { endIndex: endIndex };
@@ -33,22 +33,29 @@ function runGh(cwd, args, identity, input) {
33
33
  }
34
34
  async function readReference(cwd, url, identity, run, statusOnly) {
35
35
  var ref = parseReference(url);
36
- var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
36
+ var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft,reviewDecision,reviewRequests" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
37
37
  var data = await (run || runGh)(cwd, [ref.kind === "pr" ? "pr" : "issue", "view", String(ref.number), "--repo", ref.repository, "--json", fields], identity);
38
38
  var verified = parseReference(data.url);
39
39
  if (verified.url.toLowerCase() !== ref.url.toLowerCase()) throw new Error("GitHub returned a different reference.");
40
40
  ref.title = String(data.title || "").slice(0, 200);
41
41
  ref.state = data.state === "MERGED" ? "merged" : data.state === "CLOSED" ? "closed" : data.state === "OPEN" ? (data.isDraft ? "draft" : "open") : "unknown";
42
42
  ref.checkedAt = Date.now();
43
+ if (ref.kind === "pr") {
44
+ ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
45
+ }
43
46
  if (ref.kind === "pr" && !statusOnly) {
44
47
  ref.branch = String(data.headRefName || "").slice(0, 200);
45
- ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
46
48
  ref.checks = (data.statusCheckRollup || []).slice(0, 30).map(function (check) {
47
49
  var target = check.detailsUrl || check.targetUrl || "";
48
50
  if (!/^https:\/\//i.test(target)) target = "";
49
51
  return { name: String(check.name || check.context || "Check").slice(0, 100), state: String(check.conclusion || check.state || check.status || "PENDING").slice(0, 40), url: target };
50
52
  });
51
53
  }
54
+ if (ref.kind === "pr" && statusOnly) {
55
+ ref.reviewRequests = Array.isArray(data.reviewRequests) ? data.reviewRequests.slice(0, 30).map(function (request) {
56
+ return String(request.login || "").trim().toLowerCase().slice(0, 100);
57
+ }).filter(Boolean) : [];
58
+ }
52
59
  return ref;
53
60
  }
54
61
  module.exports = { parseReference: parseReference, readReference: readReference, runGh: runGh };
@@ -5,7 +5,7 @@
5
5
  var sessionProvenance = require("./session-provenance");
6
6
 
7
7
  var BLANK_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
8
- var CLAUDE_INTERRUPTED_TEXT = "[Request interrupted by user]";
8
+ var transcriptHygiene = require("./yoke/claude-transcript-hygiene");
9
9
 
10
10
  // A session is "blank" when nothing has ever happened in it and nothing is
11
11
  // attached to it. Adopted external sessions are never blank (their transcript
@@ -61,43 +61,11 @@ function collectStaleBlankSessions(sessions, activeSessionId, now) {
61
61
  return stale;
62
62
  }
63
63
 
64
- function extractClaudeUserText(event) {
65
- var content = event && event.message && event.message.content;
66
- if (typeof content === "string") return content;
67
- if (!Array.isArray(content)) return "";
68
- var parts = [];
69
- for (var i = 0; i < content.length; i++) {
70
- if (content[i] && content[i].type === "text" && typeof content[i].text === "string") {
71
- parts.push(content[i].text);
72
- }
73
- }
74
- return parts.join("");
75
- }
76
-
77
- // SDK capability probes create a real Claude transcript with a single "hi"
78
- // prompt. Newer Claude Code versions append an interruption record when Clay
79
- // aborts the probe, so that bookkeeping record must not make the transcript
80
- // look like a real two-turn conversation.
81
- function isClaudeWarmupTranscript(events) {
82
- var promptCount = 0;
83
- for (var i = 0; i < events.length; i++) {
84
- var event = events[i];
85
- if (!event || typeof event !== "object") continue;
86
- if (event.type === "assistant") return false;
87
- if (event.type !== "user" || !event.message || event.message.role !== "user") continue;
88
- var text = extractClaudeUserText(event);
89
- if (text === CLAUDE_INTERRUPTED_TEXT) continue;
90
- if (text !== "hi") return false;
91
- promptCount++;
92
- }
93
- return promptCount === 1;
94
- }
95
-
96
64
  module.exports = {
97
65
  isBlankSession: isBlankSession,
98
66
  findReusableBlankSession: findReusableBlankSession,
99
67
  collectStaleBlankSessions: collectStaleBlankSessions,
100
- extractClaudeUserText: extractClaudeUserText,
101
- isClaudeWarmupTranscript: isClaudeWarmupTranscript,
68
+ extractClaudeUserText: transcriptHygiene.extractClaudeUserText,
69
+ isClaudeWarmupTranscript: transcriptHygiene.isClaudeWarmupTranscript,
102
70
  BLANK_SESSION_MAX_AGE_MS: BLANK_SESSION_MAX_AGE_MS,
103
71
  };
@@ -7,11 +7,12 @@ function normalize(mode) {
7
7
  return null;
8
8
  }
9
9
 
10
- function capabilities(session, defaultVendor) {
10
+ function capabilities(session, defaultVendor, provider) {
11
11
  var vendor = session && session.vendor || defaultVendor || "claude";
12
+ var contract = require("./yoke/session-tool-transport").contract(provider || vendor);
12
13
  return {
13
- auto: vendor === "claude",
14
- mcpOverride: vendor === "claude" && !!(session && session.queryInstance &&
14
+ auto: Array.isArray(contract.permissionModes) && contract.permissionModes.indexOf("auto") !== -1,
15
+ mcpOverride: contract.mcpPermissionOverrides === true && !!(session && session.queryInstance &&
15
16
  typeof session.queryInstance.setMcpPermissionModeOverride === "function"),
16
17
  };
17
18
  }
@@ -0,0 +1,11 @@
1
+ // Bind personal instruction reads to the existing live session/query authority.
2
+ function bind(session, sessions, options, valid, multiUser) {
3
+ var owner = session.ownerId || null;
4
+ return Object.assign({}, options, { isAvailable: function() {
5
+ if (!sessions || typeof sessions.get !== "function" || sessions.get(session.localId) !== session || !valid() || (session.ownerId || null) !== owner || session.youCurator || session.sessionVisibility === "shared" || session._mcpForeignInput) return false;
6
+ if (owner) return require("./mcp-session-access").canUsePersonalConnections(session, sessions);
7
+ return !multiUser && !session.delegated && !session._delegatedBy && !session._pairDelegation
8
+ && !(session.history || []).some(function(entry) { return entry.type === "user_message" && entry.from && entry.from !== "default"; });
9
+ } });
10
+ }
11
+ module.exports = { bind: bind };
@@ -54,7 +54,7 @@ function handleDefaultChange(ctx, ws, msg) {
54
54
  ? ctx.usersModule.getEffectivePermissions(user, ctx.osUsers) : {};
55
55
  var isOwner = !!(user && access && access.ownerId && access.ownerId === user.id);
56
56
  var isAdmin = !!(user && user.role === "admin");
57
- if (!user || !permissions.projectSettings || (!isOwner && !isAdmin)) {
57
+ if (!user || !permissions.projectSettings || !isOwner) {
58
58
  defaultChangeResult(ctx, ws, msg, { ok: false, error: "Project settings access is not permitted" });
59
59
  return true;
60
60
  }
@@ -98,7 +98,10 @@ function revokeViewers(ctx, session) {
98
98
  // Clear the server-side selection before reconnecting so no further
99
99
  // session events or input can cross the revoked access boundary.
100
100
  client._clayActiveSession = null;
101
- if (client.readyState === 1) client.close(1008, "Session access changed");
101
+ if (client.readyState === 1) {
102
+ if (ctx.sendTo) ctx.sendTo(client, { type: "access_revoked", slug: ctx.slug });
103
+ client.close(1008, "Session access changed");
104
+ }
102
105
  });
103
106
  }
104
107
  }