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
package/lib/daemon.js CHANGED
@@ -20,7 +20,7 @@ process.setMaxListeners(50);
20
20
 
21
21
  // Remove CLAUDECODE env var so the SDK can spawn Claude Code child processes
22
22
  // (prevents "cannot be launched inside another Claude Code session" error)
23
- delete process.env.CLAUDECODE;
23
+ require("./yoke/host-environment").prepare(process.env);
24
24
 
25
25
  var fs = require("fs");
26
26
  var path = require("path");
@@ -67,6 +67,8 @@ try {
67
67
  console.error("[daemon] ensureMultiUser threw (continuing):", e && e.message);
68
68
  }
69
69
 
70
+ config = require("./project-ownership").repair(config, usersModule.getAllUsers(), saveConfig, osUsersMod.resolveOsUserInfo);
71
+
70
72
  if (projectLogContext.initializeProjectKnowledge(config)) {
71
73
  saveConfig(config);
72
74
  console.log("[daemon] Assigned stable knowledge identities to existing projects");
@@ -187,7 +189,14 @@ function registerProjectWorktrees(project, requestUser) {
187
189
  }
188
190
  }
189
191
 
192
+ var projectLifecycle = require("./daemon-project-lifecycle").attachProjectLifecycle({
193
+ getConfig: function () { return config; }, setConfig: function (next) { config = next; }, saveConfig: saveConfig,
194
+ getRelay: function () { return relay; }, resolveIdentity: osUsersMod.resolveOsUserInfo,
195
+ findUser: usersModule.findUserById, registerWorktrees: registerProjectWorktrees,
196
+ });
197
+ var lifecycleCallbacks = require("./daemon-project-lifecycle-callbacks").attachLifecycleCallbacks({ service: projectLifecycle });
190
198
  var relay = createServer({
199
+ projectLifecycle: projectLifecycle,
191
200
  tlsOptions: tlsOptions,
192
201
  caPath: caRoot,
193
202
  builtinCert: config.builtinCert || false,
@@ -198,122 +207,11 @@ var relay = createServer({
198
207
  osUsers: config.osUsers || false,
199
208
  lanHost: lanIp ? lanIp + ":" + config.port : null,
200
209
  getRemovedProjects: function (userId) { return getFilteredRemovedProjects(config, userId); },
201
- onAddProject: function (absPath, wsUser) {
202
- // Check if already registered
203
- for (var j = 0; j < config.projects.length; j++) {
204
- if (config.projects[j].path === absPath) {
205
- return { ok: true, slug: config.projects[j].slug, existing: true };
206
- }
207
- }
208
- var slugs = config.projects.map(function (p) { return p.slug; });
209
- var slug = generateSlug(absPath, slugs);
210
- var projectEntry = { path: absPath, slug: slug, addedAt: Date.now(), visibility: "private" };
211
- projectEntry.projectKnowledgeId = rememberedProjectKnowledgeId(absPath);
212
- // The user who adds a project always becomes the owner
213
- if (wsUser && wsUser.id) {
214
- projectEntry.ownerId = wsUser.id;
215
- }
216
- config.projects.push(projectEntry);
217
- relay.addProject(absPath, slug, null, null, wsUser ? wsUser.id : null, null, projectRuntimeOptions(projectEntry));
218
- // Remove from removedProjects if present
219
- if (config.removedProjects) {
220
- config.removedProjects = config.removedProjects.filter(function (rp) { return rp.path !== absPath; });
221
- }
222
- saveConfig(config);
223
- try { syncClayrc(config.projects); } catch (e) {}
224
- console.log("[daemon] Added project (web):", slug, "→", absPath);
225
- // OS users mode: grant ACL to project owner
226
- if (config.osUsers) {
227
- var newProj = config.projects[config.projects.length - 1];
228
- if (newProj.ownerId) {
229
- var ownerUser = usersModule.findUserById(newProj.ownerId);
230
- if (ownerUser && ownerUser.linuxUser) {
231
- grantProjectAccess(absPath, ownerUser.linuxUser);
232
- }
233
- }
234
- }
235
- // Discover and register worktrees for the new project
236
- registerProjectWorktrees(projectEntry, wsUser);
237
- // Broadcast updated project list to all clients
238
- relay.broadcastAll({
239
- type: "projects_updated",
240
- projects: relay.getProjects(),
241
- projectCount: config.projects.length,
242
- });
243
- return { ok: true, slug: slug };
244
- },
245
- onCreateProject: function (projectName, wsUser) {
246
- console.log("[daemon] onCreateProject wsUser:", JSON.stringify(wsUser ? { id: wsUser.id, role: wsUser.role, username: wsUser.username, linuxUser: wsUser.linuxUser } : null));
247
- var os = require("os");
248
- var execFileSync = require("child_process").execFileSync;
249
- var baseDir;
250
- if (config.osUsers) {
251
- baseDir = "/var/clay/projects";
252
- } else {
253
- baseDir = config.projectsDir || path.join(REAL_HOME, "clay-projects");
254
- }
255
- try { fs.mkdirSync(baseDir, { recursive: true }); } catch (e) {}
256
- // Generate slug and deduplicate
257
- var slugs = config.projects.map(function (p) { return p.slug; });
258
- var slug = generateSlug(path.join(baseDir, projectName), slugs);
259
- var targetDir = path.join(baseDir, slug);
260
- try {
261
- fs.mkdirSync(targetDir, { recursive: true });
262
- // Run git init
263
- if (config.osUsers && wsUser) {
264
- var linuxUser = wsUser.linuxUser;
265
- if (linuxUser) {
266
- var uidGid = null;
267
- try {
268
- uidGid = {
269
- uid: parseInt(execFileSync("id", ["-u", linuxUser], { encoding: "utf8", stdio: "pipe" }).trim(), 10),
270
- gid: parseInt(execFileSync("id", ["-g", linuxUser], { encoding: "utf8", stdio: "pipe" }).trim(), 10),
271
- };
272
- } catch (e) {}
273
- if (uidGid) {
274
- fs.chmodSync(targetDir, 0o700);
275
- execFileSync("chown", ["-R", linuxUser + ":" + linuxUser, targetDir]);
276
- var gitInit = osUsersMod.wrapSpawnAsUser("git", ["init"], { cwd: targetDir, uid: uidGid.uid, gid: uidGid.gid, env: { PATH: "/usr/local/bin:/usr/bin:/bin" } });
277
- execFileSync(gitInit.command, gitInit.args, gitInit.options);
278
- } else {
279
- execFileSync("git", ["init"], { cwd: targetDir });
280
- }
281
- } else {
282
- execFileSync("git", ["init"], { cwd: targetDir });
283
- }
284
- } else {
285
- execFileSync("git", ["init"], { cwd: targetDir });
286
- }
287
- } catch (e) {
288
- try { fs.rmSync(targetDir, { recursive: true, force: true }); } catch (ce) {}
289
- return { ok: false, error: "Failed to create project: " + e.message };
290
- }
291
- // Register project - creator always becomes owner, default private
292
- var projectEntry = { path: targetDir, slug: slug, addedAt: Date.now(), visibility: "private" };
293
- projectEntry.projectKnowledgeId = projectLogContext.createProjectKnowledgeId();
294
- if (wsUser && wsUser.id) {
295
- projectEntry.ownerId = wsUser.id;
296
- }
297
- relay.addProject(targetDir, slug, null, null, wsUser ? wsUser.id : null, null, projectRuntimeOptions(projectEntry));
298
- config.projects.push(projectEntry);
299
- saveConfig(config);
300
- try { syncClayrc(config.projects); } catch (e) {}
301
- console.log("[daemon] Created project:", slug, "→", targetDir, "entry:", JSON.stringify({ ownerId: projectEntry.ownerId, visibility: projectEntry.visibility }));
302
- // OS users mode: grant ACL
303
- if (config.osUsers && wsUser && wsUser.linuxUser) {
304
- console.log("[daemon] Granting ACL:", targetDir, "→", wsUser.linuxUser);
305
- grantProjectAccess(targetDir, wsUser.linuxUser);
306
- } else if (config.osUsers) {
307
- console.log("[daemon] Skipping ACL grant: osUsers=true but linuxUser=", wsUser && wsUser.linuxUser);
308
- }
309
- relay.broadcastAll({
310
- type: "projects_updated",
311
- projects: relay.getProjects(),
312
- projectCount: config.projects.length,
313
- });
314
- return { ok: true, slug: slug };
315
- },
210
+ onAddProject: lifecycleCallbacks.onAddProject,
211
+ onCreateProject: lifecycleCallbacks.onCreateProject,
316
212
  onCloneProject: function (cloneUrl, wsUser, callback) {
213
+ wsUser = wsUser && usersModule.findUserById(wsUser.id);
214
+ if (usersModule.isMultiUser() && !wsUser) { callback({ ok: false, error: "A valid account is required." }); return; }
317
215
  var os = require("os");
318
216
  var spawn = require("child_process").spawn;
319
217
  var execFileSync = require("child_process").execFileSync;
@@ -323,12 +221,15 @@ var relay = createServer({
323
221
  } else {
324
222
  baseDir = config.projectsDir || path.join(REAL_HOME, "clay-projects");
325
223
  }
326
- try { fs.mkdirSync(baseDir, { recursive: true }); } catch (e) {}
327
224
  // Derive slug from repo URL
328
225
  var repoName = cloneUrl.replace(/\.git$/, "").split("/").pop() || "project";
329
226
  var slugs = config.projects.map(function (p) { return p.slug; });
330
227
  var slug = generateSlug(path.join(baseDir, repoName), slugs);
331
- var targetDir = path.join(baseDir, slug);
228
+ var targetDir;
229
+ var directoryClaim;
230
+ var settled = false;
231
+ function finish(result) { if (settled) return; settled = true; callback(result); }
232
+ function cleanup() { if (directoryClaim) { try { directoryClaim.cleanup(); } catch (error) {} } }
332
233
  // Clone as user to use their git credentials
333
234
  var spawnOpts = { cwd: baseDir };
334
235
  if (config.osUsers && wsUser && wsUser.linuxUser) {
@@ -341,22 +242,23 @@ var relay = createServer({
341
242
  });
342
243
  } catch (e) {}
343
244
  }
344
- // Pre-create target directory as root and chown to user
345
- if (fs.existsSync(targetDir)) {
346
- callback({ ok: false, error: "Target directory already exists: " + targetDir });
245
+ try {
246
+ directoryClaim = require("./project-directory-claim").claim({ baseDir: baseDir, slug: slug, projects: config.projects, userId: wsUser && wsUser.id });
247
+ targetDir = directoryClaim.path;
248
+ directoryClaim.assertOwned();
249
+ if (config.osUsers && wsUser && wsUser.linuxUser && spawnOpts.uid != null) fs.chownSync(targetDir, spawnOpts.uid, spawnOpts.gid);
250
+ directoryClaim.assertOwned();
251
+ } catch (error) {
252
+ cleanup();
253
+ finish({ ok: false, error: "Failed to prepare project directory: " + error.message });
347
254
  return;
348
255
  }
349
- if (config.osUsers && wsUser && wsUser.linuxUser && spawnOpts.uid != null) {
350
- try {
351
- fs.mkdirSync(targetDir, { mode: 0o700 });
352
- fs.chownSync(targetDir, spawnOpts.uid, spawnOpts.gid);
353
- } catch (e) {
354
- callback({ ok: false, error: "Failed to prepare project directory: " + e.message });
355
- return;
356
- }
357
- }
358
- var cloneSpawn = osUsersMod.wrapSpawnAsUser("git", ["clone", cloneUrl, targetDir], spawnOpts);
359
- var proc = spawn(cloneSpawn.command, cloneSpawn.args, cloneSpawn.options);
256
+ var proc;
257
+ try {
258
+ directoryClaim.assertOwned();
259
+ var cloneSpawn = osUsersMod.wrapSpawnAsUser("git", ["clone", cloneUrl, targetDir], spawnOpts);
260
+ proc = spawn(cloneSpawn.command, cloneSpawn.args, cloneSpawn.options);
261
+ } catch (error) { cleanup(); finish({ ok: false, error: "Failed to start git clone: " + error.message }); return; }
360
262
  var stderrBuf = "";
361
263
  proc.stderr.on("data", function (chunk) { stderrBuf += chunk.toString(); });
362
264
  // 5 minute timeout
@@ -365,19 +267,23 @@ var relay = createServer({
365
267
  }, 5 * 60 * 1000);
366
268
  proc.on("close", function (code) {
367
269
  clearTimeout(cloneTimeout);
270
+ if (settled) return;
271
+ try { directoryClaim.assertOwned(); } catch (error) { finish({ ok: false, error: error.message }); return; }
368
272
  if (code !== 0) {
369
- try { fs.rmSync(targetDir, { recursive: true, force: true }); } catch (ce) {}
273
+ cleanup();
370
274
  var errMsg = stderrBuf.trim().split("\n").pop() || "Clone failed (exit code " + code + ")";
371
- callback({ ok: false, error: errMsg });
275
+ finish({ ok: false, error: errMsg });
372
276
  return;
373
277
  }
374
278
  // chown and restrict permissions if osUsers
375
279
  if (config.osUsers && wsUser && wsUser.linuxUser) {
376
280
  try {
281
+ directoryClaim.assertOwned();
377
282
  fs.chmodSync(targetDir, 0o700);
378
283
  execFileSync("chown", ["-R", wsUser.linuxUser + ":" + wsUser.linuxUser, targetDir]);
379
284
  } catch (e) {}
380
285
  }
286
+ if (usersModule.isMultiUser() && (!wsUser || !usersModule.findUserById(wsUser.id))) { finish({ ok: false, error: "The creating account is no longer available." }); return; }
381
287
  // Register project - creator always becomes owner
382
288
  // Creator always becomes owner, default private
383
289
  var projectEntry = { path: targetDir, slug: slug, addedAt: Date.now(), visibility: "private" };
@@ -385,9 +291,11 @@ var relay = createServer({
385
291
  if (wsUser && wsUser.id) {
386
292
  projectEntry.ownerId = wsUser.id;
387
293
  }
388
- relay.addProject(targetDir, slug, null, null, wsUser ? wsUser.id : null, null, projectRuntimeOptions(projectEntry));
389
- config.projects.push(projectEntry);
390
- saveConfig(config);
294
+ try {
295
+ directoryClaim.assertOwned();
296
+ config = require("./project-ownership").register(config, projectEntry, usersModule.getAllUsers(), saveConfig, osUsersMod.resolveOsUserInfo);
297
+ } catch (error) { finish({ ok: false, error: "Failed to register project: " + error.message }); return; }
298
+ relay.addProject(targetDir, slug, null, null, projectEntry.ownerId || null, null, projectRuntimeOptions(projectEntry));
391
299
  try { syncClayrc(config.projects); } catch (e) {}
392
300
  console.log("[daemon] Cloned project:", slug, "→", targetDir);
393
301
  if (config.osUsers && wsUser && wsUser.linuxUser) {
@@ -398,12 +306,13 @@ var relay = createServer({
398
306
  projects: relay.getProjects(),
399
307
  projectCount: config.projects.length,
400
308
  });
401
- callback({ ok: true, slug: slug });
309
+ finish({ ok: true, slug: slug });
402
310
  });
403
311
  proc.on("error", function (err) {
404
312
  clearTimeout(cloneTimeout);
405
- try { fs.rmSync(targetDir, { recursive: true, force: true }); } catch (ce) {}
406
- callback({ ok: false, error: "Failed to start git clone: " + err.message });
313
+ if (settled) return;
314
+ cleanup();
315
+ finish({ ok: false, error: "Failed to start git clone: " + err.message });
407
316
  });
408
317
  },
409
318
  onRemoveProject: function (slug, userId) {
@@ -444,40 +353,7 @@ var relay = createServer({
444
353
  });
445
354
  return { ok: true };
446
355
  }
447
- var found = null;
448
- for (var j = 0; j < config.projects.length; j++) {
449
- if (config.projects[j].slug === slug) { found = config.projects[j]; break; }
450
- }
451
- if (!found) return { ok: false, error: "Project not found" };
452
- // Cascade remove worktrees belonging to this parent
453
- cleanupWorktreesForParent(relay, slug);
454
- // Save to removedProjects for re-add functionality
455
- if (!config.removedProjects) config.removedProjects = [];
456
- config.removedProjects.push({
457
- path: found.path,
458
- title: found.title || null,
459
- icon: found.icon || null,
460
- userId: userId || null,
461
- projectKnowledgeId: found.projectKnowledgeId || null,
462
- removedAt: Date.now(),
463
- });
464
- // Cap at 20 entries (oldest first)
465
- if (config.removedProjects.length > 20) {
466
- config.removedProjects = config.removedProjects.slice(config.removedProjects.length - 20);
467
- }
468
- relay.removeProject(slug);
469
- config.projects = config.projects.filter(function (p) { return p.slug !== slug; });
470
- saveConfig(config);
471
- // Remove from .clayrc so it doesn't appear in restore prompt
472
- if (found.path) { try { removeFromClayrc(found.path); } catch (e) {} }
473
- try { syncClayrc(config.projects); } catch (e) {}
474
- console.log("[daemon] Removed project (web):", slug);
475
- relay.broadcastAll({
476
- type: "projects_updated",
477
- projects: relay.getProjects(),
478
- projectCount: config.projects.length,
479
- });
480
- return { ok: true };
356
+ return lifecycleCallbacks.onRemoveProject(slug, userId);
481
357
  },
482
358
  onReorderProjects: function (slugs) {
483
359
  // Build a slug->project map from current projects
@@ -511,25 +387,8 @@ var relay = createServer({
511
387
  return { ok: true };
512
388
  },
513
389
  onSetProjectTitle: function (slug, newTitle) {
514
- relay.setProjectTitle(slug, newTitle);
515
- for (var ti = 0; ti < config.projects.length; ti++) {
516
- if (config.projects[ti].slug === slug) {
517
- if (newTitle) {
518
- config.projects[ti].title = newTitle;
519
- } else {
520
- delete config.projects[ti].title;
521
- }
522
- break;
523
- }
524
- }
525
- saveConfig(config);
526
- try { syncClayrc(config.projects); } catch (e) {}
527
- relay.broadcastAll({
528
- type: "projects_updated",
529
- projects: relay.getProjects(),
530
- projectCount: config.projects.length,
531
- });
532
- return { ok: true };
390
+ if (isWorktreeSlug(slug)) { relay.setProjectTitle(slug, newTitle); return { ok: true }; }
391
+ return lifecycleCallbacks.onSetProjectTitle(slug, newTitle);
533
392
  },
534
393
  onSetProjectIcon: function (slug, newIcon) {
535
394
  relay.setProjectIcon(slug, newIcon);
@@ -553,30 +412,28 @@ var relay = createServer({
553
412
  return { ok: true };
554
413
  },
555
414
  onSetProjectSessionVisibilityDefault: function (slug, visibility) {
556
- var result = daemonProjectAccess.setSessionVisibilityDefault(config, slug, visibility);
557
- if (result.error) return { ok: false, error: result.error };
558
- saveConfig(config);
559
- relay.broadcastAll({ type: "projects_updated", projects: relay.getProjects(), projectCount: config.projects.length });
560
- return result;
415
+ return projectLifecycle.update(slug, "session_visibility", visibility);
561
416
  },
562
417
  onProjectOwnerChanged: function (slug, ownerId) {
418
+ if (!config.osUsers) return projectLifecycle.update(slug, "owner", ownerId);
563
419
  if (slug.indexOf("mate-") === 0) return {error:"Mate ownership cannot be transferred."};
420
+ if (!ownerId || !usersModule.findUserById(ownerId)) return { error: "A valid owner is required." };
564
421
  console.log("[daemon] onProjectOwnerChanged:", slug, "→", ownerId);
422
+ var previousConfig = JSON.parse(JSON.stringify(config));
565
423
  var oldOwnerId = null;
566
424
  var projectIdx = -1;
567
425
  for (var oi = 0; oi < config.projects.length; oi++) {
568
426
  if (config.projects[oi].slug === slug) {
569
427
  oldOwnerId = config.projects[oi].ownerId || null;
570
428
  projectIdx = oi;
571
- if (ownerId) {
572
- config.projects[oi].ownerId = ownerId;
573
- } else {
574
- delete config.projects[oi].ownerId;
575
- }
429
+ config.projects[oi].ownerId = ownerId;
576
430
  break;
577
431
  }
578
432
  }
579
- saveConfig(config);
433
+ try { saveConfig(config); } catch (error) { config = previousConfig; throw error; }
434
+ relay.forEachProject(function (project, projectSlug) {
435
+ if (projectSlug === slug || daemonProjectAccess.parentSlugFor(projectSlug) === slug) project.setProjectOwner(ownerId);
436
+ });
580
437
  // OS users mode: revoke old owner ACL, grant new owner ACL
581
438
  if (config.osUsers && projectIdx >= 0) {
582
439
  var projectPath = config.projects[projectIdx].path;
@@ -615,18 +472,7 @@ var relay = createServer({
615
472
  return { envrc: "" };
616
473
  },
617
474
  onSetProjectEnv: function (slug, envrc) {
618
- for (var ei = 0; ei < config.projects.length; ei++) {
619
- if (config.projects[ei].slug === slug) {
620
- if (envrc) {
621
- config.projects[ei].envrc = envrc;
622
- } else {
623
- delete config.projects[ei].envrc;
624
- }
625
- saveConfig(config);
626
- return { ok: true };
627
- }
628
- }
629
- return { ok: false, error: "Project not found" };
475
+ return lifecycleCallbacks.onSetProjectEnv(slug, envrc);
630
476
  },
631
477
  onGetSharedEnv: function () {
632
478
  return { envrc: config.sharedEnv || "" };
@@ -826,6 +672,7 @@ var relay = createServer({
826
672
  return { ok: true, updateChannel: config.updateChannel };
827
673
  },
828
674
  onSetPin: function (pin) {
675
+ if (usersModule.isMultiUser()) return { ok: false, error: 'Server PIN is unavailable while account authentication is enabled.' };
829
676
  saveDaemonSetting(config, "pinHash", pin ? generateAuthToken(pin) : null, saveConfig);
830
677
  relay.setAuthToken(config.pinHash);
831
678
  console.log("[daemon] PIN", pin ? "set" : "removed", "(web)");
@@ -926,6 +773,7 @@ var relay = createServer({
926
773
  spawnAndRestart();
927
774
  },
928
775
  onSetProjectVisibility: function (slug, visibility) {
776
+ if (!config.osUsers) return projectLifecycle.update(slug, "visibility", visibility);
929
777
  if (slug.indexOf("mate-") === 0) return {error:"Mates cannot be shared."};
930
778
  for (var i = 0; i < config.projects.length; i++) {
931
779
  if (config.projects[i].slug === slug) {
@@ -961,6 +809,7 @@ var relay = createServer({
961
809
  return { error: "Project not found" };
962
810
  },
963
811
  onSetProjectAllowedUsers: function (slug, allowedUsers) {
812
+ if (!config.osUsers && !daemonProjectAccess.parentSlugFor(slug)) return projectLifecycle.update(slug, "allowed_users", allowedUsers);
964
813
  var accessBefore = daemonProjectAccess.getProjectAccess(config, slug, config.osUsers);
965
814
  var result = daemonProjectAccess.setAllowedUsers(config, slug, allowedUsers);
966
815
  if (result.error) return result;
@@ -1061,8 +910,9 @@ var relay = createServer({
1061
910
  // process may implement the optional shutdownIfIdle(ms); adapters without one
1062
911
  // (Claude, which runs in-process or under sdk-worker) are simply skipped.
1063
912
  // The CLAY_CODEX_* names are kept as aliases for backwards compatibility.
1064
- var IDLE_MS = Number(process.env.CLAY_ADAPTER_IDLE_MS) || Number(process.env.CLAY_CODEX_IDLE_MS) || 5 * 60 * 1000;
1065
- var REAP_MS = Number(process.env.CLAY_ADAPTER_REAPER_MS) || Number(process.env.CLAY_CODEX_REAPER_MS) || 60 * 1000;
913
+ var adapterReaperConfig = require("./yoke/host-environment").reaper(process.env);
914
+ var IDLE_MS = adapterReaperConfig.idleMs;
915
+ var REAP_MS = adapterReaperConfig.reapMs;
1066
916
  var reaperHandle = setInterval(function () {
1067
917
  if (!relay || typeof relay.forEachProject !== "function") return;
1068
918
  relay.forEachProject(function (ctx) {
@@ -1130,11 +980,11 @@ var ipc = createIPCServer(socketPath(), function (msg) {
1130
980
  }
1131
981
  var slugs = config.projects.map(function (p) { return p.slug; });
1132
982
  var slug = generateSlug(absPath, slugs);
1133
- var projectEntry = { path: absPath, slug: slug, addedAt: Date.now(), visibility: "private" };
983
+ var projectEntry = { path: absPath, slug: slug, addedAt: Date.now(), visibility: "private", ownershipRecovery: "required" };
1134
984
  projectEntry.projectKnowledgeId = rememberedProjectKnowledgeId(absPath);
1135
- relay.addProject(absPath, slug, null, null, null, null, projectRuntimeOptions(projectEntry));
1136
- config.projects.push(projectEntry);
1137
- saveConfig(config);
985
+ config = require("./project-ownership").register(config, projectEntry, usersModule.getAllUsers(), saveConfig, osUsersMod.resolveOsUserInfo);
986
+ var registeredProject = config.projects[config.projects.length - 1];
987
+ relay.addProject(absPath, slug, null, null, registeredProject.ownerId || null, null, projectRuntimeOptions(registeredProject));
1138
988
  try { syncClayrc(config.projects); } catch (e) {}
1139
989
  console.log("[daemon] Added project:", slug, "→", absPath);
1140
990
  // Discover and register worktrees for the new project
@@ -1203,6 +1053,7 @@ var ipc = createIPCServer(socketPath(), function (msg) {
1203
1053
  };
1204
1054
 
1205
1055
  case "set_pin": {
1056
+ if (usersModule.isMultiUser()) return { ok: false, error: 'Server PIN is unavailable while account authentication is enabled.' };
1206
1057
  config.pinHash = msg.pinHash || null;
1207
1058
  relay.setAuthToken(config.pinHash);
1208
1059
  saveConfig(config);
@@ -1365,6 +1216,10 @@ var ipc = createIPCServer(socketPath(), function (msg) {
1365
1216
  var projects = config.projects || [];
1366
1217
  for (var i = 0; i < projects.length; i++) {
1367
1218
  var p = projects[i];
1219
+ if (!projectLifecycle.canRestore(p)) {
1220
+ console.log("[daemon] Project removal needs recovery; runtime remains stopped:", p.slug);
1221
+ continue;
1222
+ }
1368
1223
  if (fs.existsSync(p.path)) {
1369
1224
  console.log("[daemon] Adding project:", p.slug, "→", p.path);
1370
1225
  relay.addProject(p.path, p.slug, p.title, p.icon, p.ownerId, null, projectRuntimeOptions(p));
@@ -1411,7 +1266,7 @@ if (usersModule.isMultiUser()) {
1411
1266
  var mateDir = mates.getMateDir(mateCtx, m.id);
1412
1267
  var mateSlug = "mate-" + m.id;
1413
1268
  var mateName = (m.profile && m.profile.displayName) || m.name || "New Mate";
1414
- if (fs.existsSync(mateDir)) {
1269
+ if (!m.lifecycleDeletion && fs.existsSync(mateDir)) {
1415
1270
  var mateDef = m.builtinKey ? require("./builtin-mates").getBuiltinByKey(m.builtinKey) : null;
1416
1271
  var isHost = !!(mateDef && mateDef.hostAgent);
1417
1272
  console.log("[daemon] Adding mate project:", mateSlug + (isHost ? " (host agent)" : ""));
@@ -1428,7 +1283,7 @@ if (usersModule.isMultiUser()) {
1428
1283
  var mateDir = mates.getMateDir(mateCtx, m.id);
1429
1284
  var mateSlug = "mate-" + m.id;
1430
1285
  var mateName = (m.profile && m.profile.displayName) || m.name || "New Mate";
1431
- if (fs.existsSync(mateDir)) {
1286
+ if (!m.lifecycleDeletion && fs.existsSync(mateDir)) {
1432
1287
  var mateDef2 = m.builtinKey ? require("./builtin-mates").getBuiltinByKey(m.builtinKey) : null;
1433
1288
  var isHost2 = !!(mateDef2 && mateDef2.hostAgent);
1434
1289
  console.log("[daemon] Adding mate project:", mateSlug + (isHost2 ? " (host agent)" : ""));
@@ -1465,58 +1320,7 @@ try { syncClayrc(config.projects); } catch (e) {}
1465
1320
  // Multi-user OS-isolated installs have per-user ~/.claude trees that the
1466
1321
  // daemon process can't traverse; the inline cleanup in claude-worker.js
1467
1322
  // covers those.
1468
- function cleanupSdkWarmupSessions() {
1469
- var sessionHygiene = require("./session-hygiene");
1470
- var projectsRoot = path.join(REAL_HOME, ".claude", "projects");
1471
- var projectDirs;
1472
- try { projectDirs = fs.readdirSync(projectsRoot, { withFileTypes: true }); }
1473
- catch (e) { return; }
1474
-
1475
- var deleted = 0;
1476
- var nowMs = Date.now();
1477
- var MAX_BYTES = 64 * 1024;
1478
- var MIN_AGE_MS = 60 * 1000;
1479
-
1480
- for (var di = 0; di < projectDirs.length; di++) {
1481
- if (!projectDirs[di].isDirectory()) continue;
1482
- var projDir = path.join(projectsRoot, projectDirs[di].name);
1483
- var files;
1484
- try { files = fs.readdirSync(projDir); } catch (e) { continue; }
1485
-
1486
- for (var fi = 0; fi < files.length; fi++) {
1487
- var f = files[fi];
1488
- if (!f.endsWith(".jsonl")) continue;
1489
- var fp = path.join(projDir, f);
1490
-
1491
- var st;
1492
- try { st = fs.statSync(fp); } catch (e) { continue; }
1493
- if (st.size >= MAX_BYTES) continue;
1494
- if (nowMs - st.mtimeMs < MIN_AGE_MS) continue;
1495
-
1496
- var raw;
1497
- try { raw = fs.readFileSync(fp, "utf8"); } catch (e) { continue; }
1498
- var lines = raw.split("\n");
1499
- var events = [];
1500
- var parseOk = true;
1501
- for (var li = 0; li < lines.length; li++) {
1502
- var line = lines[li];
1503
- if (!line) continue;
1504
- var ev;
1505
- try { ev = JSON.parse(line); } catch (e) { parseOk = false; break; }
1506
- if (!ev || typeof ev !== "object") continue;
1507
- events.push(ev);
1508
- }
1509
- if (!parseOk) continue;
1510
- if (!sessionHygiene.isClaudeWarmupTranscript(events)) continue;
1511
-
1512
- try { fs.unlinkSync(fp); deleted++; } catch (e) {}
1513
- }
1514
- }
1515
-
1516
- if (deleted > 0) {
1517
- console.log("[daemon] Removed " + deleted + " stale SDK warmup session file(s)");
1518
- }
1519
- }
1323
+ function cleanupSdkWarmupSessions() { return require("./yoke/maintenance").cleanup(REAL_HOME); }
1520
1324
 
1521
1325
  // --- Start listening (with retry for port-in-use during update handoff) ---
1522
1326
  var listenRetries = 0;
@@ -3,11 +3,7 @@
3
3
  var modelEntryMatches = require("./model-entry").modelEntryMatches;
4
4
  var modelEntryValue = require("./model-entry").modelEntryValue;
5
5
 
6
- var KNOWN_VENDORS = ["claude", "codex", "grok", "kimi", "copilot", "qwen", "junie", "antigravity", "opencode", "kiro"];
7
- var VENDOR_FAMILY_ORDER = {
8
- claude: ["opus", "sonnet", "haiku"],
9
- codex: ["astra", "sol", "gpt", "o"],
10
- };
6
+ var providerInfo = require("./yoke/vendor-registry").getVendorInfo;
11
7
 
12
8
  function text(entry) {
13
9
  if (typeof entry === "string") return entry;
@@ -18,10 +14,10 @@ function selectTopModel(vendor, catalog) {
18
14
  var models = catalog && Array.isArray(catalog.models) ? catalog.models : [];
19
15
  if (!models.length) return "";
20
16
  var defaultModel = catalog.defaultModel;
21
- if (KNOWN_VENDORS.indexOf(vendor) === -1 && defaultModel) {
17
+ if (!providerInfo(vendor) && defaultModel) {
22
18
  for (var di = 0; di < models.length; di++) if (modelEntryMatches(models[di], defaultModel)) return modelEntryValue(models[di]);
23
19
  }
24
- var familyOrder = VENDOR_FAMILY_ORDER[vendor] || [];
20
+ var familyOrder = (providerInfo(vendor) || {}).preferredModelFamilies || [];
25
21
  if (familyOrder.length) {
26
22
  for (var fi = 0; fi < familyOrder.length; fi++) {
27
23
  for (var mi = 0; mi < models.length; mi++) if (new RegExp("(^|[^a-z])" + familyOrder[fi] + "([^a-z]|$)", "i").test(text(models[mi]))) return modelEntryValue(models[mi]);
@@ -114,4 +110,4 @@ function createDefaultAiRuntimeResolver(deps) {
114
110
  };
115
111
  }
116
112
 
117
- module.exports = { resolveDefaultAiRuntime: resolveDefaultAiRuntime, createDefaultAiRuntimeResolver: createDefaultAiRuntimeResolver, selectTopModel: selectTopModel, exactModel: exactModel, resolveEffort: resolveEffort, KNOWN_VENDORS: KNOWN_VENDORS, VENDOR_FAMILY_ORDER: VENDOR_FAMILY_ORDER };
113
+ module.exports = { resolveDefaultAiRuntime: resolveDefaultAiRuntime, createDefaultAiRuntimeResolver: createDefaultAiRuntimeResolver, selectTopModel: selectTopModel, exactModel: exactModel, resolveEffort: resolveEffort, KNOWN_VENDORS: Object.keys(require("./yoke/vendor-registry").VENDOR_REGISTRY), VENDOR_FAMILY_ORDER: require("./yoke/model-preferences").families() };