clay-server 5.1.1-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 (588) hide show
  1. package/lib/account-auth-policy.js +21 -0
  2. package/lib/account-auth-socket.js +30 -0
  3. package/lib/account-auth-throttle.js +44 -0
  4. package/lib/account-auth-transport.js +48 -0
  5. package/lib/account-login-page.js +28 -0
  6. package/lib/account-passkey-challenges.js +31 -0
  7. package/lib/account-passkey-page.js +89 -0
  8. package/lib/account-passkey-policy.js +39 -0
  9. package/lib/account-password-page.js +69 -0
  10. package/lib/account-passwords.js +36 -0
  11. package/lib/account-remembered.js +77 -0
  12. package/lib/account-session-page.js +51 -0
  13. package/lib/account-session-store.js +82 -0
  14. package/lib/builtin-mates.js +19 -16
  15. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  16. package/lib/canonical-clay-record-authority.js +15 -0
  17. package/lib/canonical-clay-scheduling-authority.js +19 -0
  18. package/lib/claude-hook-installer.js +1 -239
  19. package/lib/claude-jsonl-watcher.js +1 -204
  20. package/lib/clay-control-presentation-binding.js +96 -0
  21. package/lib/clay-control-presentation.js +128 -0
  22. package/lib/clay-control-target-projection.js +26 -0
  23. package/lib/clay-mate-chat-receipts.js +26 -0
  24. package/lib/clay-mate-chat.js +88 -0
  25. package/lib/clay-mate-knowledge-input.js +26 -0
  26. package/lib/clay-mate-knowledge.js +95 -0
  27. package/lib/clay-mate-lifecycle.js +95 -0
  28. package/lib/clay-product-control-input.js +33 -0
  29. package/lib/clay-product-control-tools.js +51 -0
  30. package/lib/clay-product-control.js +247 -0
  31. package/lib/clay-project-lifecycle.js +154 -0
  32. package/lib/clay-project-record-input.js +44 -0
  33. package/lib/clay-project-records.js +84 -0
  34. package/lib/clay-scheduling-input.js +21 -0
  35. package/lib/clay-scheduling-receipts.js +26 -0
  36. package/lib/clay-scheduling.js +119 -0
  37. package/lib/clay-screen-controls.js +104 -0
  38. package/lib/clay-skill-install.js +1 -33
  39. package/lib/clay-workspace-controls.js +84 -0
  40. package/lib/clay-workspace-input.js +17 -0
  41. package/lib/clay-workspace-receipts.js +26 -0
  42. package/lib/cli-sessions.js +1 -300
  43. package/lib/codex-defaults.js +1 -28
  44. package/lib/context-usage.js +3 -2
  45. package/lib/contextual-screen-snapshot.js +38 -0
  46. package/lib/daemon-project-access.js +11 -0
  47. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  48. package/lib/daemon-project-lifecycle.js +262 -0
  49. package/lib/daemon-projects.js +1 -1
  50. package/lib/daemon.js +80 -276
  51. package/lib/default-ai-runtime.js +4 -8
  52. package/lib/dm-digest-cursor.js +120 -0
  53. package/lib/email-mcp-server.js +1 -1
  54. package/lib/issues-service.js +29 -15
  55. package/lib/kiro-defaults.js +1 -22
  56. package/lib/knowledge-db-import-validation.js +46 -0
  57. package/lib/knowledge-db-import.js +99 -0
  58. package/lib/knowledge-db-service.js +24 -33
  59. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  60. package/lib/knowledge-db-storage-nedb.js +66 -0
  61. package/lib/knowledge-db-storage.js +72 -0
  62. package/lib/knowledge-db-validation.js +0 -0
  63. package/lib/knowledge-document-index.js +2 -1
  64. package/lib/knowledge-file-store.js +7 -1
  65. package/lib/knowledge-product-operations.js +46 -0
  66. package/lib/mate-avatar-catalog.js +12 -0
  67. package/lib/mate-avatar-migration.js +41 -0
  68. package/lib/mate-context-service.js +138 -0
  69. package/lib/mate-context-tools.js +21 -0
  70. package/lib/mate-creation-mcp-server.js +2 -0
  71. package/lib/mate-knowledge-canonical-access.js +10 -0
  72. package/lib/mate-knowledge-mate-bound.js +53 -0
  73. package/lib/mate-knowledge-mcp-server.js +55 -8
  74. package/lib/mate-knowledge-service.js +16 -34
  75. package/lib/mate-knowledge-text-tools.js +106 -0
  76. package/lib/mate-lifecycle-service.js +94 -0
  77. package/lib/mate-message-delivery.js +43 -0
  78. package/lib/mate-ready-creation.js +9 -1
  79. package/lib/mate-schedule-input.js +29 -0
  80. package/lib/mate-schedule-lifecycle.js +151 -0
  81. package/lib/mate-scheduling.js +103 -0
  82. package/lib/mates.js +18 -6
  83. package/lib/mcp-agent-tools.js +117 -0
  84. package/lib/mcp-connection-store.js +119 -15
  85. package/lib/mcp-import-credentials.js +31 -0
  86. package/lib/mcp-local-transport.js +13 -0
  87. package/lib/mcp-oauth.js +8 -6
  88. package/lib/mcp-proxy.js +2 -32
  89. package/lib/mcp-query-bridge.js +30 -0
  90. package/lib/mcp-remote-connections.js +74 -20
  91. package/lib/mcp-source-adapters.js +1 -0
  92. package/lib/mcp-source-context.js +1 -0
  93. package/lib/mcp-source-discovery.js +1 -0
  94. package/lib/mcp-source-plugins.js +1 -0
  95. package/lib/mcp-source-restrictions.js +1 -0
  96. package/lib/mcp-tool-policy.js +9 -0
  97. package/lib/migrate-single-user.js +3 -23
  98. package/lib/notes-checklist.js +50 -0
  99. package/lib/notes.js +49 -3
  100. package/lib/os-user-diagnostics.js +2 -4
  101. package/lib/os-users.js +24 -70
  102. package/lib/pane-pending-interactions.js +20 -0
  103. package/lib/pane-session-activation.js +114 -0
  104. package/lib/pane-session-transport.js +26 -0
  105. package/lib/project-admin-overview.js +51 -0
  106. package/lib/project-ask-user.js +8 -4
  107. package/lib/project-connection.js +14 -10
  108. package/lib/project-control-git-view.js +12 -0
  109. package/lib/project-debate.js +1 -0
  110. package/lib/project-delegated-follow-up.js +2 -1
  111. package/lib/project-directory-claim.js +65 -0
  112. package/lib/project-file-operations.js +61 -0
  113. package/lib/project-filesystem.js +15 -85
  114. package/lib/project-full-access.js +23 -2
  115. package/lib/project-http.js +7 -4
  116. package/lib/project-knowledge.js +32 -18
  117. package/lib/project-lifecycle-operations.js +98 -0
  118. package/lib/project-lifecycle-process-witness.js +32 -0
  119. package/lib/project-lifecycle-runtime.js +50 -0
  120. package/lib/project-linux-access.js +22 -0
  121. package/lib/project-logs-canonical-clay.js +27 -0
  122. package/lib/project-logs-clay-query.js +16 -0
  123. package/lib/project-logs-schema.js +4 -2
  124. package/lib/project-logs-service.js +8 -7
  125. package/lib/project-logs.js +1 -0
  126. package/lib/project-loop.js +1 -0
  127. package/lib/project-mate-chat-control.js +55 -0
  128. package/lib/project-mate-creation-proposal.js +18 -3
  129. package/lib/project-mate-interaction.js +40 -62
  130. package/lib/project-mcp.js +54 -16
  131. package/lib/project-models.js +14 -31
  132. package/lib/project-notifications.js +76 -17
  133. package/lib/project-ownership.js +77 -0
  134. package/lib/project-pair-result-delivery.js +14 -3
  135. package/lib/project-pair-usage.js +12 -13
  136. package/lib/project-pending-message-queue.js +4 -1
  137. package/lib/project-product-control.js +89 -0
  138. package/lib/project-product-session-queue.js +46 -0
  139. package/lib/project-push-access.js +28 -0
  140. package/lib/project-scheduled-message-queue.js +30 -0
  141. package/lib/project-scheduled-messages.js +67 -68
  142. package/lib/project-scheduled-task-control.js +83 -0
  143. package/lib/project-scheduled-tasks.js +13 -2
  144. package/lib/project-scheduling-access.js +10 -0
  145. package/lib/project-server-settings.js +1 -0
  146. package/lib/project-session-actions.js +65 -0
  147. package/lib/project-session-delete.js +8 -1
  148. package/lib/project-session-document.js +27 -7
  149. package/lib/project-session-github.js +63 -19
  150. package/lib/project-session-history-actions.js +167 -0
  151. package/lib/project-session-linear.js +14 -6
  152. package/lib/project-session-notes.js +7 -3
  153. package/lib/project-session-pair.js +1 -1
  154. package/lib/project-session-runtime-actions.js +64 -0
  155. package/lib/project-session-spawn.js +2 -3
  156. package/lib/project-session-vendor.js +55 -0
  157. package/lib/project-sessions.js +103 -272
  158. package/lib/project-shared-browser.js +78 -17
  159. package/lib/project-studio-presentation.js +58 -0
  160. package/lib/project-user-knowledge.js +2 -1
  161. package/lib/project-user-message.js +67 -1
  162. package/lib/project-vendor-login.js +6 -36
  163. package/lib/project-workspace-operations.js +126 -0
  164. package/lib/project-workspace-query.js +19 -2
  165. package/lib/project.js +178 -45
  166. package/lib/public/app.js +46 -0
  167. package/lib/public/appearance-bootstrap.js +16 -0
  168. package/lib/public/auth/account-login.css +98 -0
  169. package/lib/public/auth/account-login.js +104 -0
  170. package/lib/public/css/clay-tool-activity.css +51 -0
  171. package/lib/public/css/clay-workspace.css +29 -0
  172. package/lib/public/css/command-palette.css +12 -33
  173. package/lib/public/css/contextual-clay.css +240 -0
  174. package/lib/public/css/home-debate-planning.css +2 -0
  175. package/lib/public/css/home-mate-creation.css +5 -0
  176. package/lib/public/css/input.css +6 -0
  177. package/lib/public/css/mate-avatar-gallery.css +12 -0
  178. package/lib/public/css/mate-conversation.css +10 -5
  179. package/lib/public/css/messages.css +6 -2
  180. package/lib/public/css/overlays.css +4 -2
  181. package/lib/public/css/project-admin-overview.css +13 -0
  182. package/lib/public/css/session-folders.css +11 -0
  183. package/lib/public/css/session-github.css +46 -1
  184. package/lib/public/css/shared-browser.css +35 -1
  185. package/lib/public/css/sticky-notes.css +87 -1
  186. package/lib/public/css/user-settings-sessions.css +42 -0
  187. package/lib/public/index.html +28 -10
  188. package/lib/public/mate-avatars/B01.png +0 -0
  189. package/lib/public/mate-avatars/B02.png +0 -0
  190. package/lib/public/mate-avatars/B03.png +0 -0
  191. package/lib/public/mate-avatars/B04.png +0 -0
  192. package/lib/public/mate-avatars/B05.png +0 -0
  193. package/lib/public/mate-avatars/B06.png +0 -0
  194. package/lib/public/mate-avatars/B07.png +0 -0
  195. package/lib/public/mate-avatars/B08.png +0 -0
  196. package/lib/public/mate-avatars/B09.png +0 -0
  197. package/lib/public/mate-avatars/B10.png +0 -0
  198. package/lib/public/mate-avatars/B11.png +0 -0
  199. package/lib/public/mate-avatars/B12.png +0 -0
  200. package/lib/public/mate-avatars/B13.png +0 -0
  201. package/lib/public/mate-avatars/B14.png +0 -0
  202. package/lib/public/mate-avatars/B15.png +0 -0
  203. package/lib/public/mate-avatars/B16.png +0 -0
  204. package/lib/public/mate-avatars/B17.png +0 -0
  205. package/lib/public/mate-avatars/B18.png +0 -0
  206. package/lib/public/mate-avatars/B19.png +0 -0
  207. package/lib/public/mate-avatars/B20.png +0 -0
  208. package/lib/public/mate-avatars/B21.png +0 -0
  209. package/lib/public/mate-avatars/B22.png +0 -0
  210. package/lib/public/mate-avatars/B23.png +0 -0
  211. package/lib/public/mate-avatars/B24.png +0 -0
  212. package/lib/public/mate-avatars/B25.png +0 -0
  213. package/lib/public/mate-avatars/B26.png +0 -0
  214. package/lib/public/mate-avatars/B27.png +0 -0
  215. package/lib/public/mate-avatars/B28.png +0 -0
  216. package/lib/public/mate-avatars/B29.png +0 -0
  217. package/lib/public/mate-avatars/B30.png +0 -0
  218. package/lib/public/mate-avatars/B31.png +0 -0
  219. package/lib/public/mate-avatars/B32.png +0 -0
  220. package/lib/public/mate-avatars/B33.png +0 -0
  221. package/lib/public/mate-avatars/B34.png +0 -0
  222. package/lib/public/mate-avatars/B35.png +0 -0
  223. package/lib/public/mate-avatars/B36.png +0 -0
  224. package/lib/public/mate-avatars/B37.png +0 -0
  225. package/lib/public/mate-avatars/B38.png +0 -0
  226. package/lib/public/mate-avatars/B39.png +0 -0
  227. package/lib/public/mate-avatars/B40.png +0 -0
  228. package/lib/public/mate-avatars/B41.png +0 -0
  229. package/lib/public/mate-avatars/B42.png +0 -0
  230. package/lib/public/mate-avatars/B43.png +0 -0
  231. package/lib/public/mate-avatars/B44.png +0 -0
  232. package/lib/public/mate-avatars/B45.png +0 -0
  233. package/lib/public/mate-avatars/B46.png +0 -0
  234. package/lib/public/mate-avatars/B47.png +0 -0
  235. package/lib/public/mate-avatars/B48.png +0 -0
  236. package/lib/public/mate-avatars/C01.png +0 -0
  237. package/lib/public/mate-avatars/C02.png +0 -0
  238. package/lib/public/mate-avatars/C03.png +0 -0
  239. package/lib/public/mate-avatars/C04.png +0 -0
  240. package/lib/public/mate-avatars/C05.png +0 -0
  241. package/lib/public/mate-avatars/C06.png +0 -0
  242. package/lib/public/mate-avatars/C07.png +0 -0
  243. package/lib/public/mate-avatars/C08.png +0 -0
  244. package/lib/public/mate-avatars/C09.png +0 -0
  245. package/lib/public/mate-avatars/C10.png +0 -0
  246. package/lib/public/mate-avatars/C11.png +0 -0
  247. package/lib/public/mate-avatars/C12.png +0 -0
  248. package/lib/public/mate-avatars/C13.png +0 -0
  249. package/lib/public/mate-avatars/C14.png +0 -0
  250. package/lib/public/mate-avatars/C15.png +0 -0
  251. package/lib/public/mate-avatars/C16.png +0 -0
  252. package/lib/public/mate-avatars/C17.png +0 -0
  253. package/lib/public/mate-avatars/C18.png +0 -0
  254. package/lib/public/mate-avatars/C19.png +0 -0
  255. package/lib/public/mate-avatars/C20.png +0 -0
  256. package/lib/public/mate-avatars/C21.png +0 -0
  257. package/lib/public/mate-avatars/C22.png +0 -0
  258. package/lib/public/mate-avatars/C23.png +0 -0
  259. package/lib/public/mate-avatars/C24.png +0 -0
  260. package/lib/public/mate-avatars/C25.png +0 -0
  261. package/lib/public/mate-avatars/C26.png +0 -0
  262. package/lib/public/mate-avatars/C27.png +0 -0
  263. package/lib/public/mate-avatars/C28.png +0 -0
  264. package/lib/public/mate-avatars/C29.png +0 -0
  265. package/lib/public/mate-avatars/C30.png +0 -0
  266. package/lib/public/mate-avatars/C31.png +0 -0
  267. package/lib/public/mate-avatars/C32.png +0 -0
  268. package/lib/public/mate-avatars/C33.png +0 -0
  269. package/lib/public/mate-avatars/C34.png +0 -0
  270. package/lib/public/mate-avatars/C35.png +0 -0
  271. package/lib/public/mate-avatars/C36.png +0 -0
  272. package/lib/public/mate-avatars/C37.png +0 -0
  273. package/lib/public/mate-avatars/C38.png +0 -0
  274. package/lib/public/mate-avatars/C39.png +0 -0
  275. package/lib/public/mate-avatars/C40.png +0 -0
  276. package/lib/public/mate-avatars/C41.png +0 -0
  277. package/lib/public/mate-avatars/C42.png +0 -0
  278. package/lib/public/mate-avatars/C43.png +0 -0
  279. package/lib/public/mate-avatars/C44.png +0 -0
  280. package/lib/public/mate-avatars/C45.png +0 -0
  281. package/lib/public/mate-avatars/C46.png +0 -0
  282. package/lib/public/mate-avatars/C47.png +0 -0
  283. package/lib/public/mate-avatars/C48.png +0 -0
  284. package/lib/public/mate-avatars/catalog.json +482 -0
  285. package/lib/public/mate-avatars/lead-clay.png +0 -0
  286. package/lib/public/modules/account-auth-settings.js +71 -0
  287. package/lib/public/modules/account-transport-settings.js +51 -0
  288. package/lib/public/modules/admin-settings-projects.js +6 -2
  289. package/lib/public/modules/app-connection.js +11 -1
  290. package/lib/public/modules/app-favicon.js +18 -9
  291. package/lib/public/modules/app-header.js +7 -4
  292. package/lib/public/modules/app-loop-ui.js +2 -0
  293. package/lib/public/modules/app-message-router.js +22 -1
  294. package/lib/public/modules/app-messages.js +119 -17
  295. package/lib/public/modules/app-misc.js +3 -1
  296. package/lib/public/modules/app-notifications.js +11 -5
  297. package/lib/public/modules/app-panels.js +61 -123
  298. package/lib/public/modules/app-projects.js +13 -0
  299. package/lib/public/modules/app-rate-limit.js +7 -27
  300. package/lib/public/modules/app-rendering.js +4 -3
  301. package/lib/public/modules/avatar.js +15 -41
  302. package/lib/public/modules/chat-render-runtime.js +20 -0
  303. package/lib/public/modules/clay-browser-links.js +47 -0
  304. package/lib/public/modules/clay-control-activity.js +214 -0
  305. package/lib/public/modules/clay-control-copy.js +36 -0
  306. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  307. package/lib/public/modules/clay-control-object-targets.js +52 -0
  308. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  309. package/lib/public/modules/clay-control-targets.js +44 -0
  310. package/lib/public/modules/clay-log-links.js +23 -0
  311. package/lib/public/modules/clay-navigation-render.js +52 -0
  312. package/lib/public/modules/clay-owner-navigation.js +33 -0
  313. package/lib/public/modules/clay-session-links.js +31 -0
  314. package/lib/public/modules/clay-studio-bridge.js +20 -0
  315. package/lib/public/modules/clay-studio-document.js +67 -0
  316. package/lib/public/modules/clay-studio-render.js +146 -0
  317. package/lib/public/modules/clay-tool-activity.js +140 -0
  318. package/lib/public/modules/clay-tool-presentation.js +342 -0
  319. package/lib/public/modules/command-palette.js +162 -40
  320. package/lib/public/modules/contextual-ask-session.js +26 -0
  321. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  322. package/lib/public/modules/contextual-clay-session.js +130 -0
  323. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  324. package/lib/public/modules/contextual-clay.js +250 -0
  325. package/lib/public/modules/contextual-composer.js +91 -0
  326. package/lib/public/modules/contextual-mate-context.js +117 -0
  327. package/lib/public/modules/contextual-mate-hint.js +40 -0
  328. package/lib/public/modules/contextual-mate-identity.js +23 -0
  329. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  330. package/lib/public/modules/contextual-search.js +137 -0
  331. package/lib/public/modules/contextual-session-citations.js +58 -0
  332. package/lib/public/modules/debate.js +1 -0
  333. package/lib/public/modules/default-ai.js +11 -3
  334. package/lib/public/modules/elicitation-form.js +5 -0
  335. package/lib/public/modules/filebrowser.js +20 -1
  336. package/lib/public/modules/generation-stop.js +8 -5
  337. package/lib/public/modules/git-panel.js +3 -1
  338. package/lib/public/modules/history-replay-batch.js +13 -1
  339. package/lib/public/modules/home-debate-live.js +2 -0
  340. package/lib/public/modules/home-debate-planning.js +7 -7
  341. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  342. package/lib/public/modules/home-mate-chat.js +8 -6
  343. package/lib/public/modules/home-mate-creation.js +73 -1
  344. package/lib/public/modules/home-mate-settings.js +19 -12
  345. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  346. package/lib/public/modules/input.js +88 -10
  347. package/lib/public/modules/issues-render.js +3 -2
  348. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  349. package/lib/public/modules/markdown.js +6 -34
  350. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  351. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  352. package/lib/public/modules/mate-management.js +40 -7
  353. package/lib/public/modules/mcp-connection-view.js +31 -13
  354. package/lib/public/modules/mcp-discovery-view.js +31 -0
  355. package/lib/public/modules/mcp-ui.js +23 -4
  356. package/lib/public/modules/mention.js +3 -0
  357. package/lib/public/modules/message-delivery.js +20 -2
  358. package/lib/public/modules/model-picker.js +2 -0
  359. package/lib/public/modules/pane-activation.js +214 -0
  360. package/lib/public/modules/pane-binding.js +82 -0
  361. package/lib/public/modules/pane-bridge.js +7 -4
  362. package/lib/public/modules/pane-browser-bridge.js +22 -0
  363. package/lib/public/modules/pane-file-bridge.js +4 -0
  364. package/lib/public/modules/pane-issue-bridge.js +4 -1
  365. package/lib/public/modules/passkey-browser.js +69 -0
  366. package/lib/public/modules/passkey-server-settings.js +57 -0
  367. package/lib/public/modules/pending-message-queue.js +1 -0
  368. package/lib/public/modules/permission-control.js +5 -4
  369. package/lib/public/modules/personal-settings-dialog.js +7 -1
  370. package/lib/public/modules/product-review.js +26 -0
  371. package/lib/public/modules/profile.js +1 -238
  372. package/lib/public/modules/project-access-recovery.js +17 -0
  373. package/lib/public/modules/project-admin-overview.js +21 -0
  374. package/lib/public/modules/project-chat-identity.js +13 -4
  375. package/lib/public/modules/project-logs-render.js +6 -2
  376. package/lib/public/modules/project-mate-navigation.js +144 -22
  377. package/lib/public/modules/rewind.js +5 -0
  378. package/lib/public/modules/scheduled-tasks.js +2 -0
  379. package/lib/public/modules/scheduler.js +2 -0
  380. package/lib/public/modules/search-clay-chat.js +5 -440
  381. package/lib/public/modules/server-settings-controls.js +10 -0
  382. package/lib/public/modules/server-settings.js +7 -2
  383. package/lib/public/modules/session-actions.js +5 -2
  384. package/lib/public/modules/session-context-menu.js +5 -0
  385. package/lib/public/modules/session-create-form.js +10 -10
  386. package/lib/public/modules/session-folder-layout.js +1 -1
  387. package/lib/public/modules/session-folder-view-menu.js +9 -0
  388. package/lib/public/modules/session-github.js +85 -14
  389. package/lib/public/modules/session-rich-drafts.js +21 -0
  390. package/lib/public/modules/session-switch-defer.js +67 -0
  391. package/lib/public/modules/session-work-primary.js +51 -0
  392. package/lib/public/modules/settings-defaults.js +27 -28
  393. package/lib/public/modules/shared-browser-settings.js +112 -0
  394. package/lib/public/modules/shared-browser-tabs.js +13 -3
  395. package/lib/public/modules/shared-browser.js +29 -6
  396. package/lib/public/modules/sidebar-mobile.js +4 -3
  397. package/lib/public/modules/sidebar-projects.js +1 -0
  398. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  399. package/lib/public/modules/sidebar-sessions.js +1 -0
  400. package/lib/public/modules/split-group-restore.js +68 -0
  401. package/lib/public/modules/split-pair-ui.js +1 -0
  402. package/lib/public/modules/split-pane-reconciler.js +15 -0
  403. package/lib/public/modules/split-pane-renderer.js +87 -6
  404. package/lib/public/modules/split-session-boundary.js +1 -1
  405. package/lib/public/modules/split-view.js +60 -68
  406. package/lib/public/modules/sticky-note-markdown.js +72 -6
  407. package/lib/public/modules/sticky-notes-actions.js +30 -0
  408. package/lib/public/modules/sticky-notes-browser.js +9 -2
  409. package/lib/public/modules/sticky-notes-card.js +23 -7
  410. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  411. package/lib/public/modules/sticky-notes-editor.js +108 -44
  412. package/lib/public/modules/sticky-notes-shared.js +50 -2
  413. package/lib/public/modules/sticky-notes-state.js +66 -0
  414. package/lib/public/modules/sticky-notes.js +34 -51
  415. package/lib/public/modules/stt-controller.js +4 -1
  416. package/lib/public/modules/stt-recording.js +1 -1
  417. package/lib/public/modules/stt.js +7 -2
  418. package/lib/public/modules/terminal.js +9 -0
  419. package/lib/public/modules/theme.js +8 -1
  420. package/lib/public/modules/thinking-lifecycle.js +33 -3
  421. package/lib/public/modules/thinking-view.js +23 -1
  422. package/lib/public/modules/tools.js +60 -11
  423. package/lib/public/modules/tui-grab.js +1 -2
  424. package/lib/public/modules/user-settings-account.js +14 -1
  425. package/lib/public/modules/user-settings-appearance.js +10 -3
  426. package/lib/public/modules/user-settings-editors.js +1 -1
  427. package/lib/public/modules/user-settings-layout.js +11 -2
  428. package/lib/public/modules/user-settings-preferences.js +6 -2
  429. package/lib/public/modules/user-settings-profile.js +12 -2
  430. package/lib/public/modules/user-settings-sessions.js +120 -0
  431. package/lib/public/modules/user-settings.js +6 -2
  432. package/lib/public/modules/vendor-login-browser.js +5 -3
  433. package/lib/public/modules/vendor-login.js +2 -2
  434. package/lib/public/modules/vendor-priority.js +15 -1
  435. package/lib/public/modules/wireframe-workbench.js +5 -2
  436. package/lib/public/modules/you-activity.js +3 -1
  437. package/lib/public/modules/you.js +91 -6
  438. package/lib/public/muse-avatar.svg +4 -0
  439. package/lib/public/style.css +6 -0
  440. package/lib/public/sw.js +3 -1
  441. package/lib/safe-bash-commands.js +3 -45
  442. package/lib/scheduled-task-records.js +3 -1
  443. package/lib/scheduler.js +2 -0
  444. package/lib/sdk-bridge.js +342 -401
  445. package/lib/sdk-foreground-admission.js +16 -0
  446. package/lib/sdk-mcp-descriptors.js +2 -37
  447. package/lib/sdk-message-processor.js +52 -17
  448. package/lib/sdk-quota-snapshot.js +1 -1
  449. package/lib/sdk-response-recovery.js +1 -0
  450. package/lib/sdk-worker.js +2 -677
  451. package/lib/server-account-passkeys.js +186 -0
  452. package/lib/server-account-passwords.js +127 -0
  453. package/lib/server-account-security.js +53 -0
  454. package/lib/server-admin.js +63 -16
  455. package/lib/server-appearance-settings.js +13 -1
  456. package/lib/server-auth.js +107 -79
  457. package/lib/server-contextual-clay-settings.js +40 -0
  458. package/lib/server-contextual-mate-sessions.js +70 -0
  459. package/lib/server-dm.js +2 -1
  460. package/lib/server-global-ws.js +10 -20
  461. package/lib/server-home-chat-events.js +18 -4
  462. package/lib/server-home-chat.js +22 -20
  463. package/lib/server-home-clay-entry.js +23 -4
  464. package/lib/server-home-clay-session-links.js +29 -9
  465. package/lib/server-home-mate-creation.js +1 -0
  466. package/lib/server-home-mcp-consent.js +14 -0
  467. package/lib/server-mates.js +25 -62
  468. package/lib/server-owner-ui.js +118 -0
  469. package/lib/server-path-access.js +38 -0
  470. package/lib/server-project-removal.js +22 -0
  471. package/lib/server-settings.js +8 -2
  472. package/lib/server.js +165 -43
  473. package/lib/session-config-transition.js +45 -0
  474. package/lib/session-folders.js +7 -2
  475. package/lib/session-fork-history.js +21 -0
  476. package/lib/session-github.js +9 -2
  477. package/lib/session-hygiene.js +3 -35
  478. package/lib/session-permission-mode.js +4 -3
  479. package/lib/session-skill-scope.js +11 -0
  480. package/lib/session-visibility.js +5 -2
  481. package/lib/session-work-primary.js +50 -0
  482. package/lib/sessions.js +64 -99
  483. package/lib/shared-browser-cookie-sync.js +32 -0
  484. package/lib/shared-browser-cookies.js +79 -0
  485. package/lib/shared-browser-runtime.js +25 -9
  486. package/lib/shared-browser-storage-sync.js +43 -0
  487. package/lib/shared-browser-storage.js +101 -0
  488. package/lib/shared-browser-tools.js +2 -1
  489. package/lib/shared-browser-worker.js +46 -10
  490. package/lib/terminal-manager.js +65 -6
  491. package/lib/tool-llm.js +1 -1
  492. package/lib/tui-transcript-index.js +1 -132
  493. package/lib/user-knowledge-service.js +23 -1
  494. package/lib/users-auth.js +38 -3
  495. package/lib/users-contextual-clay-preferences.js +31 -0
  496. package/lib/users-create.js +97 -0
  497. package/lib/users-permissions.js +2 -8
  498. package/lib/users-server-pin.js +37 -0
  499. package/lib/users.js +18 -84
  500. package/lib/vendor-login-browser.js +1 -11
  501. package/lib/workspace-assignment-service.js +25 -0
  502. package/lib/workspace-query-access.js +4 -1
  503. package/lib/workspace-query-mcp-server.js +1 -1
  504. package/lib/workspace-query-service.js +13 -2
  505. package/lib/ws-request.js +1 -0
  506. package/lib/ws-schema.js +18 -2
  507. package/lib/yoke/acp-agent-profiles.js +7 -5
  508. package/lib/yoke/adapters/antigravity.js +3 -14
  509. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  510. package/lib/yoke/adapters/claude.js +54 -50
  511. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  512. package/lib/yoke/adapters/codex.js +53 -111
  513. package/lib/yoke/adapters/kiro.js +3 -1
  514. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  515. package/lib/yoke/adapters/muse.js +122 -0
  516. package/lib/yoke/auth-events.js +17 -0
  517. package/lib/yoke/claude-hook-installer.js +271 -0
  518. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  519. package/lib/yoke/claude-maintenance.js +55 -0
  520. package/lib/yoke/claude-permission-patterns.js +53 -0
  521. package/lib/yoke/claude-response-recovery.js +155 -0
  522. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  523. package/lib/yoke/claude-worker-startup.js +28 -0
  524. package/lib/yoke/clay-skill-install.js +33 -0
  525. package/lib/yoke/cli-sessions.js +300 -0
  526. package/lib/yoke/codex-app-server.js +7 -12
  527. package/lib/yoke/codex-idle-recovery.js +81 -1
  528. package/lib/yoke/codex-recovery-admission.js +164 -0
  529. package/lib/yoke/configuration.js +13 -0
  530. package/lib/yoke/discovery.js +70 -0
  531. package/lib/yoke/errors.js +8 -0
  532. package/lib/yoke/host-environment.js +7 -0
  533. package/lib/yoke/index.js +9 -51
  534. package/lib/yoke/interface.js +116 -0
  535. package/lib/yoke/kiro-acp-server.js +5 -5
  536. package/lib/yoke/legacy-sessions.js +89 -0
  537. package/lib/yoke/login-protocol.js +25 -0
  538. package/lib/yoke/maintenance.js +12 -0
  539. package/lib/yoke/mcp-proxy.js +32 -0
  540. package/lib/yoke/mcp-source-adapters.js +91 -0
  541. package/lib/yoke/mcp-source-context.js +42 -0
  542. package/lib/yoke/mcp-source-discovery.js +169 -0
  543. package/lib/yoke/mcp-source-plugins.js +68 -0
  544. package/lib/yoke/mcp-source-restrictions.js +47 -0
  545. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  546. package/lib/yoke/model-preferences.js +6 -0
  547. package/lib/yoke/muse-artifacts.js +36 -0
  548. package/lib/yoke/muse-controls.js +50 -0
  549. package/lib/yoke/muse-input.js +64 -0
  550. package/lib/yoke/muse-items.js +157 -0
  551. package/lib/yoke/muse-policy.js +52 -0
  552. package/lib/yoke/muse-query.js +428 -0
  553. package/lib/yoke/muse-runtime.js +211 -0
  554. package/lib/yoke/muse-services.js +79 -0
  555. package/lib/yoke/muse-skills.js +79 -0
  556. package/lib/yoke/muse-turns.js +71 -0
  557. package/lib/yoke/options/acp.js +2 -0
  558. package/lib/yoke/options/antigravity.js +2 -0
  559. package/lib/yoke/options/claude.js +21 -0
  560. package/lib/yoke/options/codex-defaults.js +29 -0
  561. package/lib/yoke/options/codex-settings.js +21 -0
  562. package/lib/yoke/options/codex.js +6 -0
  563. package/lib/yoke/options/kiro-defaults.js +22 -0
  564. package/lib/yoke/options/kiro.js +5 -0
  565. package/lib/yoke/options/muse.js +5 -0
  566. package/lib/yoke/provider-contract.js +5 -0
  567. package/lib/yoke/providers/antigravity-executable.js +8 -0
  568. package/lib/yoke/providers/claude-executable.js +40 -0
  569. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  570. package/lib/yoke/providers/claude-process.js +97 -0
  571. package/lib/yoke/providers/claude-provision.js +75 -0
  572. package/lib/yoke/providers/codex-errors.js +8 -0
  573. package/lib/yoke/providers/muse-executable.js +17 -0
  574. package/lib/yoke/provisioning.js +6 -0
  575. package/lib/yoke/query-options.js +10 -0
  576. package/lib/yoke/response-recovery.js +41 -0
  577. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  578. package/lib/yoke/sdk-server-factory.js +7 -0
  579. package/lib/yoke/session-history.js +8 -0
  580. package/lib/yoke/session-tool-transport.js +34 -13
  581. package/lib/yoke/settings.js +23 -0
  582. package/lib/yoke/source-locations.js +4 -0
  583. package/lib/yoke/title-query.js +18 -7
  584. package/lib/yoke/tui-transcript-index.js +132 -0
  585. package/lib/yoke/usage.js +48 -0
  586. package/lib/yoke/user-input.js +13 -0
  587. package/lib/yoke/vendor-registry.js +81 -1
  588. package/package.json +11 -4
@@ -2,7 +2,7 @@ var serverSettingsMessages = require("./project-server-settings");
2
2
  var fs = require("fs");
3
3
  var path = require("path");
4
4
  var { execFileSync } = require("child_process");
5
- var { CODEX_DEFAULTS, getCodexConfig } = require("./codex-defaults");
5
+ var providerSettings = require("./yoke/settings");
6
6
  var updateSnooze = require("./update-snooze");
7
7
  var yoke = require("./yoke");
8
8
  var sessionVisibility = require("./session-visibility");
@@ -118,14 +118,20 @@ function attachSessions(ctx) {
118
118
  var ensureProjectAccessForSession = ctx.ensureProjectAccessForSession;
119
119
  var getOsUserInfoForWs = ctx.getOsUserInfoForWs;
120
120
  var hydrateSkillCatalog = ctx.hydrateSkillCatalog || function () { return []; };
121
+ var sessionActions = require("./project-session-actions").attachSessionActions(ctx);
122
+ var sessionVendor = require("./project-session-vendor").attachSessionVendor(ctx);
123
+ var sessionRuntime = require("./project-session-runtime-actions").attachSessionRuntimeActions({ sm: sm, tm: tm, prepareGui: prepareTuiSessionForGuiView, isPendingQueuePaused: ctx.isPendingQueuePaused,
124
+ publishGui: function (session) {
125
+ clients.forEach(function (ws) {
126
+ if (ws.readyState !== 1 || ws._clayActiveSession !== session.localId) return;
127
+ if (usersModule.isMultiUser() && (!ws._clayUser || !usersModule.findUserById(ws._clayUser.id) || !usersModule.canAccessProject(ws._clayUser.id, getProjectAccess()) || !usersModule.canAccessSession(ws._clayUser.id, session, getProjectAccess()))) return;
128
+ sm.switchSession(session.localId, ws, ctx.hydrateImageRefs);
129
+ });
130
+ },
131
+ });
121
132
  function stopSession(session, actor) {
122
133
  if (!session) return false;
123
- session._pendingMessageDrainPaused = true;
124
- if (typeof ctx.onPendingQueuePause === "function") ctx.onPendingQueuePause(session, actor || null);
125
- if (!session.isProcessing && !session._queryStarting) return true;
126
- if (typeof ctx.onHumanPairStop === "function") ctx.onHumanPairStop(session);
127
- session.taskStopRequested = true;
128
- if (session.abortController) session.abortController.abort();
134
+ sessionActions.stop(session, actor);
129
135
  return true;
130
136
  }
131
137
  var hydrateImageRefs = ctx.hydrateImageRefs;
@@ -143,12 +149,16 @@ function attachSessions(ctx) {
143
149
  return !session.ownerId;
144
150
  }
145
151
 
146
- function respondToAskUser(session, msg) {
152
+ function respondToAskUser(session, msg, ws) {
147
153
  if (!session || !msg || !msg.toolId) return false;
148
154
  var toolId = msg.toolId;
149
155
  var answers = msg.answers || {};
150
156
  var pending = session.pendingAskUser && session.pendingAskUser[toolId];
151
157
  if (!pending) return false;
158
+ if (pending.request && ["mcp-import", "product-control"].indexOf(pending.request.source) >= 0 &&
159
+ (typeof pending.request.authorizeResponse !== "function" || !pending.request.authorizeResponse(ws))) return false;
160
+ if (pending.request && ["work-primary", "mate-schedule"].indexOf(pending.request.source) >= 0 && usersModule.isMultiUser() &&
161
+ (!ws || !ws._clayUser || ws._clayUser.id !== session.ownerId)) return false;
152
162
  if (pending.mode === "yoke") {
153
163
  try { yoke.userInput.normalizeAnswers(pending.request.questions, answers); }
154
164
  catch (e) { return false; }
@@ -209,6 +219,10 @@ function attachSessions(ctx) {
209
219
  var setLatestVersion = ctx.setLatestVersion;
210
220
  var loadContextSources = ctx.loadContextSources;
211
221
 
222
+ var sessionHistory = require("./project-session-history-actions").attachSessionHistoryActions(Object.assign({}, ctx, {
223
+ resolveSessionHome: resolveSessionHome, cancelPendingAskUser: cancelPendingAskUser,
224
+ }));
225
+
212
226
  function canAccessProjectSlug(ws, targetSlug) {
213
227
  if (!targetSlug) return false;
214
228
  if (!usersModule || typeof usersModule.isMultiUser !== "function" || !usersModule.isMultiUser()) return true;
@@ -244,7 +258,7 @@ function attachSessions(ctx) {
244
258
  if (!session || !session.cliSessionId) return;
245
259
  if (session._titleWatcherStop) return; // already watching
246
260
  var watcher;
247
- try { watcher = require("./claude-jsonl-watcher"); } catch (e) { return; }
261
+ try { watcher = require("./yoke/claude-jsonl-watcher"); } catch (e) { return; }
248
262
  var home = resolveSessionHome(session);
249
263
  var jsonlPath = watcher.jsonlPathFor(home, cwd, session.cliSessionId);
250
264
  if (!jsonlPath) return;
@@ -312,7 +326,7 @@ function attachSessions(ctx) {
312
326
  // message right away. The transcript is small enough that a full
313
327
  // re-send beats maintaining a delta protocol.
314
328
  try {
315
- var newIndex = require("./tui-transcript-index").readAssistantIndex(resolveSessionHome(s), cwd, s.cliSessionId);
329
+ var newIndex = require("./yoke/tui-transcript-index").readAssistantIndex(resolveSessionHome(s), cwd, s.cliSessionId);
316
330
  send({
317
331
  type: "tui_transcript_state",
318
332
  id: s.localId,
@@ -436,10 +450,10 @@ function attachSessions(ctx) {
436
450
  // Idempotent: if the PTY is already gone and history is populated, this
437
451
  // is a no-op (avoids re-reading jsonl and re-writing the session file on
438
452
  // every click while the user is reading the session in GUI mode).
439
- function prepareTuiSessionForGuiView(session) {
453
+ function prepareTuiSessionForGuiView(session, options) {
440
454
  if (!session || session.cliSessionId == null) return;
441
455
  var cliSess;
442
- try { cliSess = require("./cli-sessions"); } catch (e) { return; }
456
+ try { cliSess = require("./yoke/cli-sessions"); } catch (e) { return; }
443
457
  // Re-read whenever the jsonl has changed since the last hydrate (a TUI
444
458
  // turn appended messages), not just when history is empty. The earlier
445
459
  // "already hydrated" short-circuit kept stale history after a
@@ -463,7 +477,7 @@ function attachSessions(ctx) {
463
477
  try { tm.close(session.terminalId); } catch (e) {}
464
478
  }
465
479
  session.terminalId = null;
466
- try { sm.saveSessionFile(session); } catch (e) {}
480
+ if (!options || !options.deferSave) { try { sm.saveSessionFile(session); } catch (e) {} }
467
481
  }
468
482
 
469
483
  // Resolve how a session should be presented to a viewer WITHOUT spawning a
@@ -588,7 +602,9 @@ function attachSessions(ctx) {
588
602
  var targetFrom = typeof msg.target === "number" ? msg.target : before - sm.HISTORY_PAGE_SIZE;
589
603
  var from = sm.findTurnBoundary(session.history, Math.max(0, targetFrom));
590
604
  var to = before;
591
- var items = session.history.slice(from, to).map(hydrateImageRefs);
605
+ var items = session.history.slice(from, to).map(function (item, index) {
606
+ return Object.assign({}, hydrateImageRefs(require("./yoke/usage").clientEvent(item, session.vendor || "claude")), { _historyIndex: from + index });
607
+ });
592
608
  sendTo(ws, {
593
609
  type: "history_prepend",
594
610
  items: items,
@@ -762,11 +778,10 @@ function attachSessions(ctx) {
762
778
  sendTo(ws, { type: "error", text: "Cannot transfer ownership of home directory projects." });
763
779
  return true;
764
780
  }
765
- var projectOwnerId = getProjectOwnerId();
766
- var isAdmin = ws._clayUser && ws._clayUser.role === "admin";
781
+ var projectOwnerId = getProjectAccess().ownerId;
767
782
  var isProjectOwner = ws._clayUser && projectOwnerId && ws._clayUser.id === projectOwnerId;
768
- if (!ws._clayUser || (!isAdmin && !isProjectOwner)) {
769
- sendTo(ws, { type: "error", text: "Only project owners or admins can transfer ownership." });
783
+ if (!ws._clayUser || !isProjectOwner) {
784
+ sendTo(ws, { type: "error", text: "Only project owners can transfer ownership." });
770
785
  return true;
771
786
  }
772
787
  var targetUser = msg.userId ? usersModule.findUserById(msg.userId) : null;
@@ -774,11 +789,11 @@ function attachSessions(ctx) {
774
789
  sendTo(ws, { type: "error", text: "User not found." });
775
790
  return true;
776
791
  }
792
+ // Persist before publishing runtime ownership.
793
+ if (!opts.onProjectOwnerChanged) return true;
794
+ var savedOwner = opts.onProjectOwnerChanged(slug, targetUser.id);
795
+ if (savedOwner && savedOwner.error) { sendTo(ws, { type: "error", text: savedOwner.error }); return true; }
777
796
  setProjectOwnerId(targetUser.id);
778
- // Persist via daemon callback
779
- if (opts.onProjectOwnerChanged) {
780
- opts.onProjectOwnerChanged(slug, targetUser.id);
781
- }
782
797
  send({ type: "project_owner_changed", ownerId: targetUser.id, ownerName: targetUser.displayName || targetUser.username });
783
798
  return true;
784
799
  }
@@ -789,18 +804,22 @@ function attachSessions(ctx) {
789
804
  // adoptOrphanedCliSessions). Click a session in the sidebar instead.
790
805
 
791
806
  if (msg.type === "switch_session") {
807
+ var paneActivation = require('./pane-session-activation').begin(ctx, ws, msg);
808
+ if (paneActivation === false) return true;
792
809
  if (msg.id && sm.sessions.has(msg.id)) {
793
810
  // resolveSessionForView sets runtimeMode / runtimeTerminalId /
794
811
  // tuiSuspended (and hydrates the transcript) before sm.switchSession
795
812
  // broadcasts session_switched. A live runtime keeps its actual mode
796
813
  // for every viewer; idle sessions open in chat. Nothing is spawned here.
797
814
  var xmTarget = sm.sessions.get(msg.id);
815
+ if (usersModule.isMultiUser() && (!ws._clayUser || !usersModule.canAccessSession(ws._clayUser.id, xmTarget, getProjectAccess()))) return true;
798
816
  if (xmTarget && (!xmTarget.vendor || vendorSupportsTui(xmTarget.vendor))) {
799
817
  // Single source of truth: live runtime wins (tui stays tui, gui stays
800
818
  // gui); idle legacy sessions hydrate their transcript into chat.
801
819
  resolveSessionForView(xmTarget, ws);
802
820
  }
803
821
  var switchTargetSess = sm.sessions.get(msg.id);
822
+ if (paneActivation && !paneActivation.validate()) return true;
804
823
  var switchTargetVendor = switchTargetSess && (switchTargetSess.vendor || sm.defaultVendor || "claude");
805
824
  if (switchTargetSess && !switchTargetSess.effort) {
806
825
  switchTargetSess.effort = yoke.clampEffort(
@@ -813,20 +832,20 @@ function attachSessions(ctx) {
813
832
  if (usersModule.isMultiUser() && ws._clayUser) {
814
833
  var switchTarget = sm.sessions.get(msg.id);
815
834
  if (!usersModule.canAccessSession(ws._clayUser.id, switchTarget, { visibility: "public" })) return true;
816
- ws._clayActiveSession = msg.id;
817
- sm.switchSession(msg.id, ws, hydrateImageRefs);
835
+ sm.switchSession(msg.id, ws, hydrateImageRefs, paneActivation && paneActivation.send, paneActivation && paneActivation.validate);
818
836
  if (!ws._clayPane) broadcastPresence();
819
837
  } else {
820
- ws._clayActiveSession = msg.id;
821
- sm.switchSession(msg.id, ws, hydrateImageRefs);
838
+ sm.switchSession(msg.id, ws, hydrateImageRefs, paneActivation && paneActivation.send, paneActivation && paneActivation.validate);
822
839
  }
823
840
  // Send per-session context sources
824
841
  if (typeof loadContextSources === "function") {
825
842
  var switchedSources = loadContextSources(slug, msg.id);
826
- sendTo(ws, { type: "context_sources_state", active: switchedSources });
843
+ if (paneActivation) paneActivation.send({ type: "context_sources_state", active: switchedSources });
844
+ else sendTo(ws, { type: "context_sources_state", active: switchedSources });
827
845
  }
828
846
  var swPresKey = ws._clayUser ? ws._clayUser.id : "_default";
829
847
  if (!ws._clayPane) userPresence.setPresence(slug, swPresKey, userPresence.sessionIdForPersistence(switchTargetSess), null);
848
+ if (paneActivation) paneActivation.finish();
830
849
  }
831
850
  return true;
832
851
  }
@@ -902,7 +921,7 @@ function attachSessions(ctx) {
902
921
  return true;
903
922
  }
904
923
  try {
905
- var tprIndex = require("./tui-transcript-index").readAssistantIndex(resolveSessionHome(tprSess), cwd, tprSess.cliSessionId);
924
+ var tprIndex = require("./yoke/tui-transcript-index").readAssistantIndex(resolveSessionHome(tprSess), cwd, tprSess.cliSessionId);
906
925
  sendTo(ws, {
907
926
  type: "tui_transcript_state",
908
927
  id: tprId,
@@ -933,19 +952,7 @@ function attachSessions(ctx) {
933
952
  var s = sm.sessions.get(msg.id);
934
953
  if (usersModule.isMultiUser() && (!ws._clayUser ||
935
954
  !usersModule.canAccessSession(ws._clayUser.id, s, getProjectAccess()))) return true;
936
- s.title = String(msg.title).substring(0, 100);
937
- s.titleProvisional = false;
938
- s.titleAutoGenerated = false;
939
- s.titleManuallySet = true;
940
- sm.saveSessionFile(s);
941
- sm.notifySessionRenamed(s.localId);
942
- sm.broadcastSessionList();
943
- // Sync title to SDK session
944
- if (s.cliSessionId) {
945
- adapter.renameSession(s.cliSessionId, s.title, { dir: cwd }).catch(function(e) {
946
- console.error("[project] SDK renameSession failed:", e.message);
947
- });
948
- }
955
+ sessionActions.rename(s, String(msg.title).substring(0, 100));
949
956
  }
950
957
  return true;
951
958
  }
@@ -1080,7 +1087,12 @@ function attachSessions(ctx) {
1080
1087
 
1081
1088
  if (msg.type === "stop") {
1082
1089
  var session = getSessionForWs(ws);
1083
- if (autonomousRun && session && session.autonomousRun) autonomousRun.finish(session, "stopped", "Stopped by the user.");
1090
+ if (msg.sessionId != null || msg.sessionOriginId != null) {
1091
+ session = sm.sessions.get(msg.sessionId);
1092
+ if (!session || session.sessionOriginId !== msg.sessionOriginId ||
1093
+ !usersModule.isMultiUser() && session.ownerId ||
1094
+ usersModule.isMultiUser() && (!ws._clayUser || !usersModule.canAccessSession(ws._clayUser.id, session, getProjectAccess()))) return true;
1095
+ }
1084
1096
  stopSession(session, ws && ws._clayUser);
1085
1097
  return true;
1086
1098
  }
@@ -1096,14 +1108,14 @@ function attachSessions(ctx) {
1096
1108
  var pid = msg.pid;
1097
1109
  if (!pid || typeof pid !== "number") return true;
1098
1110
  // Verify target is actually a claude process before killing
1099
- if (!sdk.isClaudeProcess(pid)) {
1100
- console.error("[project] Refused to kill PID " + pid + ": not a claude process");
1101
- sendTo(ws, { type: "error", text: "Process " + pid + " is not a Claude process." });
1111
+ if (!sdk.isProviderProcess(pid, getSessionForWs(ws))) {
1112
+ console.error("[project] Refused to kill PID " + pid + ": not a verified provider process");
1113
+ sendTo(ws, { type: "error", text: "Process " + pid + " is not a verified provider process." });
1102
1114
  return true;
1103
1115
  }
1104
1116
  try {
1105
1117
  process.kill(pid, "SIGTERM");
1106
- console.log("[project] Sent SIGTERM to conflicting Claude process PID " + pid);
1118
+ console.log("[project] Sent SIGTERM to conflicting provider process PID " + pid);
1107
1119
  sendTo(ws, { type: "process_killed", pid: pid });
1108
1120
  } catch (e) {
1109
1121
  console.error("[project] Failed to kill PID " + pid + ":", e.message);
@@ -1181,38 +1193,14 @@ function attachSessions(ctx) {
1181
1193
 
1182
1194
  if (msg.type === "set_vendor" && msg.vendor) {
1183
1195
  var vendorSession = getSessionForWs(ws);
1184
- if (vendorSession) {
1185
- // Refuse to rebind vendor on a session that is already bound to a
1186
- // different CLI (cliSessionId is vendor-specific). This prevents a
1187
- // stale client-side vendor state from clobbering the persisted vendor
1188
- // on page reload / server restart.
1189
- var alreadyBound = vendorSession.cliSessionId && vendorSession.vendor && vendorSession.vendor !== msg.vendor;
1190
- if (alreadyBound) {
1191
- console.warn("[project] set_vendor ignored: session " + vendorSession.localId +
1192
- " is bound to '" + vendorSession.vendor + "', refused rebind to '" + msg.vendor + "'");
1193
- } else {
1194
- vendorSession.vendor = msg.vendor;
1195
- if (vendorSession.permissionMode === "auto" && msg.vendor !== "claude") {
1196
- vendorSession.permissionMode = "default";
1197
- vendorSession.effectivePermissionMode = null;
1198
- }
1199
- if (vendorSession.vendor !== msg.vendor) vendorSession.model = "";
1200
- sm.saveSessionFile(vendorSession);
1201
- sm.broadcastSessionList();
1202
- }
1203
- }
1204
- if (msg.vendor) {
1205
- var vendorModels = (sm.modelsByVendor && sm.modelsByVendor[msg.vendor]) || [];
1206
- sendTo(ws, {
1207
- type: "model_info",
1208
- model: "",
1209
- models: vendorModels,
1210
- vendor: msg.vendor, sessionId: vendorSession ? vendorSession.localId : null,
1211
- availableVendors: sm.availableVendors || [],
1212
- installedVendors: sm.installedVendors || [],
1213
- });
1214
- send({ type: "config_state", vendor: null, sessionId: null, mode: sm.currentPermissionMode || "default", effort: sm.currentEffort || "medium", betas: sm.currentBetas || [], thinking: sm.currentThinking || "adaptive", thinkingBudget: sm.currentThinkingBudget || 10000 });
1196
+ if (!vendorSession) return true;
1197
+ // Re-selecting the provider of an established thread does not rebind it.
1198
+ if (vendorSession.cliSessionId && vendorSession.vendor === msg.vendor) return true;
1199
+ try {
1200
+ var vendorResult = sessionVendor.setVendor(vendorSession, msg.vendor);
1201
+ if (vendorResult.status === "failed") sendTo(ws, { type: "error", text: vendorResult.error });
1215
1202
  }
1203
+ catch (error) { sendTo(ws, { type: "error", text: error.message }); }
1216
1204
  return true;
1217
1205
  }
1218
1206
 
@@ -1280,15 +1268,7 @@ function attachSessions(ctx) {
1280
1268
  if (!valid.ok) { permissionResult(false, valid.error, true); return true; }
1281
1269
  (async function() {
1282
1270
  try {
1283
- if (session.permissionMode === "bypassPermissions" && valid.mode !== "bypassPermissions" && autonomousRun) {
1284
- await autonomousRun.stopForPermissionChange(session);
1285
- }
1286
- await fullAccessService.setMode(session, valid.mode);
1287
- var state = permissionModes.clientState(session, sm.currentPermissionMode, sm.defaultVendor);
1288
- sm.sendToSession(session, { type: "config_state", sessionId: session.localId, vendor: session.vendor || sm.defaultVendor || "claude", mode: state.requestedPermissionMode,
1289
- effectivePermissionMode: state.effectivePermissionMode, permissionRequestId: requestId,
1290
- permissionCapabilities: state.permissionCapabilities, mcpPermissionModeOverrides: state.mcpPermissionModeOverrides,
1291
- effort: session.effort || sm.currentEffort || "medium", betas: sm.currentBetas || [] });
1271
+ await sessionActions.permission(session, valid.mode, requestId);
1292
1272
  permissionResult(true, null, true);
1293
1273
  } catch (error) {
1294
1274
  permissionResult(false, "Failed to change permission mode: " + (error.message || error), true);
@@ -1358,10 +1338,9 @@ function attachSessions(ctx) {
1358
1338
  sendTo(ws, { type: "error", text: "This effort level is not supported by the selected vendor." });
1359
1339
  return true;
1360
1340
  }
1361
- sdk.setEffort(session, sessionEffort).catch(function (e) {
1341
+ sessionActions.effort(session, sessionEffort).catch(function (e) {
1362
1342
  sendTo(ws, { type: "error", text: "Failed to change reasoning effort: " + (e.message || e) });
1363
1343
  });
1364
- sm.sendToSession(session, { type: "config_state", model: session.model || ((sm.defaultModelByVendor || {})[effortVendor]) || "", vendor: effortVendor, sessionId: session.localId, mode: session.permissionMode || sm.currentPermissionMode || "default", effort: sessionEffort, betas: sm.currentBetas || [], thinking: sm.currentThinking || "adaptive", thinkingBudget: sm.currentThinkingBudget || 10000 });
1365
1344
  }
1366
1345
  return true;
1367
1346
  }
@@ -1397,20 +1376,12 @@ function attachSessions(ctx) {
1397
1376
  return true;
1398
1377
  }
1399
1378
 
1400
- // Codex-specific settings (stored on sessionManager, passed to adapter via adapterOptions)
1401
- if (msg.type === "set_codex_approval") {
1402
- sm.codexApproval = getCodexConfig({ codexApproval: msg.approval }).approval;
1403
- send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
1404
- return true;
1405
- }
1406
- if (msg.type === "set_codex_sandbox") {
1407
- sm.codexSandbox = msg.sandbox || CODEX_DEFAULTS.sandbox;
1408
- send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
1409
- return true;
1410
- }
1411
- if (msg.type === "set_codex_websearch") {
1412
- sm.codexWebSearch = msg.webSearch || CODEX_DEFAULTS.webSearch;
1413
- send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
1379
+ var providerChange;
1380
+ try { providerChange = providerSettings.change(msg, sm); }
1381
+ catch (error) { sendTo(ws, { type: "error", text: error.message }); return true; }
1382
+ if (providerChange) {
1383
+ Object.keys(providerChange.patch).forEach(function(key) { sm[key] = providerChange.patch[key]; });
1384
+ providerChange.messages.forEach(function(message) { send(message); });
1414
1385
  return true;
1415
1386
  }
1416
1387
 
@@ -1438,92 +1409,9 @@ function attachSessions(ctx) {
1438
1409
  sendTo(ws, { type: "rewind_error", text: "Rewind already in progress." });
1439
1410
  return true;
1440
1411
  }
1441
- session._rewindInProgress = true;
1442
- var mode = msg.mode || "both";
1443
-
1444
- (async function () {
1445
- try {
1446
- // File restoration (delegated to adapter via sdk-bridge)
1447
- if (mode !== "chat") {
1448
- await sdk.rewindExecuteFiles(session, msg.uuid);
1449
- }
1450
-
1451
- // Conversation rollback (skip for files-only mode)
1452
- if (mode !== "files") {
1453
- var targetIdx = -1;
1454
- for (var i = 0; i < session.messageUUIDs.length; i++) {
1455
- if (session.messageUUIDs[i].uuid === msg.uuid) {
1456
- targetIdx = i;
1457
- break;
1458
- }
1459
- }
1460
-
1461
- // Codex's thread/revert cuts at a turn id, not a count. Read the
1462
- // target entry's turnId BEFORE trimming local history below.
1463
- var hasTurnsToRollBack = false;
1464
- var targetTurnId = null;
1465
- if (targetIdx >= 0) {
1466
- targetTurnId = session.messageUUIDs[targetIdx].turnId || null;
1467
- for (var ri = targetIdx; ri < session.messageUUIDs.length; ri++) {
1468
- if (session.messageUUIDs[ri].type === "user") { hasTurnsToRollBack = true; break; }
1469
- }
1470
- }
1471
-
1472
- // Notify adapter of conversation rollback (e.g. Codex thread/revert)
1473
- // BEFORE trimming local history below. Deliberately not caught
1474
- // here: a failed or impossible (missing turnId) provider-side
1475
- // rollback must abort the whole rewind via the outer catch, never
1476
- // leave local history trimmed ahead of the real provider thread.
1477
- if (hasTurnsToRollBack) {
1478
- await sdk.rollbackConversation(session, targetTurnId);
1479
- }
1480
-
1481
- if (targetIdx >= 0) {
1482
- var trimTo = session.messageUUIDs[targetIdx].historyIndex;
1483
- for (var k = trimTo - 1; k >= 0; k--) {
1484
- if (session.history[k].type === "user_message") {
1485
- trimTo = k;
1486
- break;
1487
- }
1488
- }
1489
- session.history = session.history.slice(0, trimTo);
1490
- session.messageUUIDs = session.messageUUIDs.slice(0, targetIdx);
1491
- // Reset digest checkpoint if it points past the trimmed history
1492
- if (typeof session._dmLastDigestedIndex === "number" && session._dmLastDigestedIndex > trimTo) {
1493
- session._dmLastDigestedIndex = trimTo;
1494
- }
1495
- }
1496
-
1497
- var kept = session.messageUUIDs;
1498
- session.lastRewindUuid = kept.length > 0 ? kept[kept.length - 1].uuid : null;
1499
- }
1500
-
1501
- if (session.abortController) {
1502
- try { session.abortController.abort(); } catch (e) {}
1503
- }
1504
- if (session.messageQueue) {
1505
- try { session.messageQueue.end(); } catch (e) {}
1506
- }
1507
- session.queryInstance = null;
1508
- session.messageQueue = null;
1509
- session.abortController = null;
1510
- session.blocks = {};
1511
- session.sentToolResults = {};
1512
- session.pendingPermissions = {};
1513
- cancelPendingAskUser(session, "Conversation rewound");
1514
- session.isProcessing = false;
1515
- onProcessingChanged();
1516
-
1517
- sm.saveSessionFile(session);
1518
- sm.switchSession(session.localId, ws, hydrateImageRefs);
1519
- sm.sendAndRecord(session, { type: "rewind_complete", mode: mode });
1520
- sm.broadcastSessionList();
1521
- } catch (err) {
1522
- sendTo(ws, { type: "rewind_error", text: "Rewind failed: " + err.message });
1523
- } finally {
1524
- session._rewindInProgress = false;
1525
- }
1526
- })();
1412
+ sessionHistory.rewind(session, msg.uuid, msg.mode || "both", ws, function () {}).catch(function (error) {
1413
+ sendTo(ws, { type: "rewind_error", text: "Rewind failed: " + error.message });
1414
+ });
1527
1415
  return true;
1528
1416
  }
1529
1417
 
@@ -1533,69 +1421,17 @@ function attachSessions(ctx) {
1533
1421
  sendTo(ws, { type: "error", text: "Cannot fork: no CLI session" });
1534
1422
  return true;
1535
1423
  }
1536
- var forkTitle = (session.title || "New Session") + " (fork)";
1537
-
1538
- sdk.forkSession(session, msg.uuid).then(function(result) {
1539
- if (result.useLocalHistory) {
1540
- // Copy local history up to the target UUID
1541
- var targetIdx = -1;
1542
- for (var fi = 0; fi < session.messageUUIDs.length; fi++) {
1543
- if (session.messageUUIDs[fi].uuid === msg.uuid) { targetIdx = fi; break; }
1544
- }
1545
- var forkHistory = [];
1546
- if (targetIdx >= 0) {
1547
- var trimTo = session.messageUUIDs[targetIdx].historyIndex;
1548
- forkHistory = session.history.slice(0, trimTo);
1549
- } else {
1550
- forkHistory = session.history.slice();
1551
- }
1552
- var forked = sm.createSession({
1553
- vendor: session.vendor,
1554
- ownerId: session.ownerId || null,
1555
- userKnowledgeOwnerId: session.userKnowledgeOwnerId || null,
1556
- sessionVisibility: sessionVisibility.normalize(session.sessionVisibility),
1557
- }, ws);
1558
- forked.cliSessionId = result.sessionId;
1559
- forked.title = forkTitle;
1560
- forked.history = forkHistory;
1561
- forked.messageUUIDs = [];
1562
- for (var hi = 0; hi < forkHistory.length; hi++) {
1563
- if (forkHistory[hi].type === "message_uuid") {
1564
- forked.messageUUIDs.push({ uuid: forkHistory[hi].uuid, type: forkHistory[hi].messageType, historyIndex: hi, turnId: forkHistory[hi].turnId || null });
1565
- }
1566
- }
1567
- sm.saveSessionFile(forked);
1568
- sm.switchSession(forked.localId, ws, hydrateImageRefs);
1569
- sendTo(ws, { type: "fork_complete", sessionId: forked.localId });
1570
- sm.broadcastSessionList();
1571
- } else {
1572
- // Read history from CLI session files
1573
- var cliSess = require("./cli-sessions");
1574
- return cliSess.readCliSessionHistory(resolveSessionHome(session), cwd, result.sessionId).then(function(history) {
1575
- var forked = sm.resumeSession(result.sessionId, {
1576
- history: history,
1577
- title: forkTitle,
1578
- vendor: session.vendor,
1579
- ownerId: session.ownerId || null,
1580
- userKnowledgeOwnerId: session.userKnowledgeOwnerId || null,
1581
- sessionVisibility: sessionVisibility.normalize(session.sessionVisibility),
1582
- sessionVisibilityExplicit: session.sessionVisibilityExplicit === true,
1583
- }, ws);
1584
- if (forked) {
1585
- ws._clayActiveSession = forked.localId;
1586
- sendTo(ws, { type: "fork_complete", sessionId: forked.localId });
1587
- }
1588
- });
1589
- }
1590
- }).catch(function(e) {
1591
- sendTo(ws, { type: "error", text: "Fork failed: " + (e.message || e) });
1424
+ sessionHistory.fork(session, msg.uuid, ws, function () {}).then(function (forked) {
1425
+ if (forked) sendTo(ws, { type: "fork_complete", sessionId: forked.localId });
1426
+ }).catch(function (error) {
1427
+ sendTo(ws, { type: "error", text: "Fork failed: " + error.message });
1592
1428
  });
1593
1429
  return true;
1594
1430
  }
1595
1431
 
1596
1432
  if (msg.type === "ask_user_response") {
1597
1433
  var session = getSessionForWs(ws);
1598
- if (session) respondToAskUser(session, msg);
1434
+ if (session) respondToAskUser(session, msg, ws);
1599
1435
  return true;
1600
1436
  }
1601
1437
 
@@ -1638,6 +1474,7 @@ function attachSessions(ctx) {
1638
1474
  var sessionId = sm.permissionRequestIndex[requestId];
1639
1475
  var session = sessionId ? sm.sessions.get(sessionId) : getSessionForWs(ws);
1640
1476
  if (!session) return true;
1477
+ if (ws._clayPaneActivation && session.localId !== ws._clayPaneActivation.sessionId) return true;
1641
1478
  var pending = session.pendingPermissions[requestId];
1642
1479
  if (!pending) return true;
1643
1480
  delete sm.permissionRequestIndex[requestId];
@@ -1803,14 +1640,6 @@ function attachSessions(ctx) {
1803
1640
  if (msg.type === "browse_dir") {
1804
1641
  var rawPath = (msg.path || "").replace(/^~/, require("./config").REAL_HOME);
1805
1642
  var absTarget = path.resolve(rawPath);
1806
- // Multi-user mode: non-admins can only browse their home directory
1807
- if (osUsers && osUsers.length > 0 && ws._clayUser && ws._clayUser.role !== "admin") {
1808
- var browseHome = ws._clayUser.linuxUser ? "/home/" + ws._clayUser.linuxUser : null;
1809
- if (!browseHome || (absTarget !== browseHome && (absTarget + "/").indexOf(browseHome + "/") !== 0)) {
1810
- sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: [], error: "Access restricted to your home directory" });
1811
- return true;
1812
- }
1813
- }
1814
1643
  var parentDir, prefix;
1815
1644
  try {
1816
1645
  var stat = fs.statSync(absTarget);
@@ -1827,12 +1656,17 @@ function attachSessions(ctx) {
1827
1656
  parentDir = path.dirname(absTarget);
1828
1657
  prefix = path.basename(absTarget).toLowerCase();
1829
1658
  }
1659
+ if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, parentDir)) {
1660
+ sendTo(ws, { type: "browse_dir_result", entries: [], error: "Directory access is not permitted" });
1661
+ return true;
1662
+ }
1830
1663
  try {
1831
1664
  var dirItems = fs.readdirSync(parentDir, { withFileTypes: true });
1832
1665
  var dirEntries = [];
1833
1666
  for (var di = 0; di < dirItems.length; di++) {
1834
1667
  var d = dirItems[di];
1835
1668
  if (!d.isDirectory()) continue;
1669
+ if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, path.join(parentDir, d.name))) continue;
1836
1670
  if (d.name.charAt(0) === ".") continue;
1837
1671
  if (IGNORED_DIRS.has(d.name)) continue;
1838
1672
  if (prefix && !d.name.toLowerCase().startsWith(prefix)) continue;
@@ -1850,17 +1684,9 @@ function attachSessions(ctx) {
1850
1684
  if (msg.type === "add_project") {
1851
1685
  var addPath = (msg.path || "").replace(/^~/, require("./config").REAL_HOME);
1852
1686
  var addAbs = path.resolve(addPath);
1853
- // Multi-user mode: normal users restricted to their home directory
1854
- if (osUsers && osUsers.length > 0 && ws._clayUser && ws._clayUser.role !== "admin") {
1855
- if (!ws._clayUser.linuxUser) {
1856
- sendTo(ws, { type: "add_project_result", ok: false, error: "No Linux user assigned" });
1857
- return true;
1858
- }
1859
- var userHome = "/home/" + ws._clayUser.linuxUser;
1860
- if (addAbs !== userHome && (addAbs + "/").indexOf(userHome + "/") !== 0) {
1861
- sendTo(ws, { type: "add_project_result", ok: false, error: "Path not allowed. You can only add directories under " + userHome });
1862
- return true;
1863
- }
1687
+ if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, addAbs)) {
1688
+ sendTo(ws, { type: "add_project_result", ok: false, error: "Directory access is not permitted" });
1689
+ return true;
1864
1690
  }
1865
1691
  try {
1866
1692
  var addStat = fs.statSync(addAbs);
@@ -1874,7 +1700,7 @@ function attachSessions(ctx) {
1874
1700
  }
1875
1701
  if (typeof opts.onAddProject === "function") {
1876
1702
  var result = opts.onAddProject(addAbs, ws._clayUser);
1877
- sendTo(ws, { type: "add_project_result", ok: result.ok, slug: result.slug, error: result.error, existing: result.existing });
1703
+ sendTo(ws, Object.assign({}, result, { type: "add_project_result" }));
1878
1704
  } else {
1879
1705
  sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
1880
1706
  }
@@ -1899,7 +1725,7 @@ function attachSessions(ctx) {
1899
1725
  }
1900
1726
  if (typeof opts.onCreateProject === "function") {
1901
1727
  var createResult = opts.onCreateProject(createName, ws._clayUser);
1902
- sendTo(ws, { type: "add_project_result", ok: createResult.ok, slug: createResult.slug, error: createResult.error });
1728
+ sendTo(ws, Object.assign({}, createResult, { type: "add_project_result" }));
1903
1729
  } else {
1904
1730
  sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
1905
1731
  }
@@ -1989,10 +1815,10 @@ function attachSessions(ctx) {
1989
1815
  moveAllSchedulesToProject(removeSlug, msg.moveTasksTo);
1990
1816
  }
1991
1817
  if (typeof opts.onRemoveProject === "function") {
1992
- // Send result before removing so the WS is still open
1993
- sendTo(ws, { type: "remove_project_result", ok: true, slug: removeSlug });
1994
1818
  var removeUserId = ws._clayUser ? ws._clayUser.id : null;
1995
- opts.onRemoveProject(removeSlug, removeUserId);
1819
+ Promise.resolve().then(function () { return opts.onRemoveProject(removeSlug, removeUserId); }).then(function (result) {
1820
+ sendTo(ws, { type: "remove_project_result", ok: !!result && result.ok === true, slug: removeSlug, error: result && result.error });
1821
+ }, function (error) { sendTo(ws, { type: "remove_project_result", ok: false, slug: removeSlug, error: error.message }); });
1996
1822
  } else {
1997
1823
  sendTo(ws, { type: "remove_project_result", ok: false, error: "Not supported" });
1998
1824
  }
@@ -2038,7 +1864,7 @@ function attachSessions(ctx) {
2038
1864
  }
2039
1865
  if (typeof opts.onSetProjectTitle === "function") {
2040
1866
  var titleResult = opts.onSetProjectTitle(msg.slug, msg.title || null);
2041
- sendTo(ws, { type: "set_project_title_result", ok: titleResult.ok, slug: msg.slug, error: titleResult.error });
1867
+ sendTo(ws, Object.assign({}, titleResult, { type: "set_project_title_result", slug: msg.slug }));
2042
1868
  } else {
2043
1869
  sendTo(ws, { type: "set_project_title_result", ok: false, error: "Not supported" });
2044
1870
  }
@@ -2100,7 +1926,7 @@ function attachSessions(ctx) {
2100
1926
  var galManaged = [];
2101
1927
  var galUser = [];
2102
1928
  try {
2103
- var galInstaller = require("./claude-hook-installer");
1929
+ var galInstaller = require("./yoke/claude-hook-installer");
2104
1930
  galManaged = galInstaller.CLAY_MANAGED_ALLOW || [];
2105
1931
  } catch (e) {}
2106
1932
  if (galUid) {
@@ -2126,7 +1952,7 @@ function attachSessions(ctx) {
2126
1952
  // home (OS-mode: getent passwd; single-user: os.homedir()).
2127
1953
  var salEffective = false;
2128
1954
  try {
2129
- var salInstaller = require("./claude-hook-installer");
1955
+ var salInstaller = require("./yoke/claude-hook-installer");
2130
1956
  var salHome = null;
2131
1957
  if (osUsers && ws._clayUser && ws._clayUser.linuxUser) {
2132
1958
  try {
@@ -2192,6 +2018,11 @@ function attachSessions(ctx) {
2192
2018
  return handleSessionsMessage(ws, { type: "permission_response", requestId: msg.requestId, decision: msg.decision });
2193
2019
  },
2194
2020
  stopHomeSession: stopSession,
2021
+ sessionActions: sessionActions,
2022
+ sessionHistoryActions: sessionHistory,
2023
+ sessionVendorActions: sessionVendor,
2024
+ sessionRuntimeActions: sessionRuntime,
2025
+ deleteProductControlPlan: function (plan) { sessionDelete.executeOwnedDeletion(plan); },
2195
2026
  };
2196
2027
  }
2197
2028