clay-server 5.2.0-beta.1 → 5.2.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/lib/account-auth-socket.js +1 -0
  2. package/lib/builtin-mates.js +19 -16
  3. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  4. package/lib/canonical-clay-record-authority.js +15 -0
  5. package/lib/canonical-clay-scheduling-authority.js +19 -0
  6. package/lib/claude-hook-installer.js +1 -239
  7. package/lib/claude-jsonl-watcher.js +1 -204
  8. package/lib/clay-control-presentation-binding.js +96 -0
  9. package/lib/clay-control-presentation.js +128 -0
  10. package/lib/clay-control-target-projection.js +26 -0
  11. package/lib/clay-mate-chat-receipts.js +26 -0
  12. package/lib/clay-mate-chat.js +88 -0
  13. package/lib/clay-mate-knowledge-input.js +26 -0
  14. package/lib/clay-mate-knowledge.js +95 -0
  15. package/lib/clay-mate-lifecycle.js +95 -0
  16. package/lib/clay-product-control-input.js +33 -0
  17. package/lib/clay-product-control-tools.js +51 -0
  18. package/lib/clay-product-control.js +247 -0
  19. package/lib/clay-project-lifecycle.js +154 -0
  20. package/lib/clay-project-record-input.js +44 -0
  21. package/lib/clay-project-records.js +84 -0
  22. package/lib/clay-scheduling-input.js +21 -0
  23. package/lib/clay-scheduling-receipts.js +26 -0
  24. package/lib/clay-scheduling.js +119 -0
  25. package/lib/clay-screen-controls.js +104 -0
  26. package/lib/clay-skill-install.js +1 -33
  27. package/lib/clay-workspace-controls.js +84 -0
  28. package/lib/clay-workspace-input.js +17 -0
  29. package/lib/clay-workspace-receipts.js +26 -0
  30. package/lib/cli-sessions.js +1 -300
  31. package/lib/codex-defaults.js +1 -28
  32. package/lib/context-usage.js +3 -2
  33. package/lib/contextual-screen-snapshot.js +38 -0
  34. package/lib/daemon-project-access.js +11 -0
  35. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  36. package/lib/daemon-project-lifecycle.js +262 -0
  37. package/lib/daemon-projects.js +1 -1
  38. package/lib/daemon.js +78 -276
  39. package/lib/default-ai-runtime.js +4 -8
  40. package/lib/dm-digest-cursor.js +120 -0
  41. package/lib/email-mcp-server.js +1 -1
  42. package/lib/issues-service.js +29 -15
  43. package/lib/kiro-defaults.js +1 -22
  44. package/lib/knowledge-db-import-validation.js +46 -0
  45. package/lib/knowledge-db-import.js +99 -0
  46. package/lib/knowledge-db-service.js +24 -33
  47. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  48. package/lib/knowledge-db-storage-nedb.js +66 -0
  49. package/lib/knowledge-db-storage.js +72 -0
  50. package/lib/knowledge-db-validation.js +0 -0
  51. package/lib/knowledge-document-index.js +2 -1
  52. package/lib/knowledge-file-store.js +7 -1
  53. package/lib/knowledge-product-operations.js +46 -0
  54. package/lib/mate-avatar-catalog.js +12 -0
  55. package/lib/mate-avatar-migration.js +41 -0
  56. package/lib/mate-context-service.js +138 -0
  57. package/lib/mate-context-tools.js +21 -0
  58. package/lib/mate-creation-mcp-server.js +2 -0
  59. package/lib/mate-knowledge-canonical-access.js +10 -0
  60. package/lib/mate-knowledge-mate-bound.js +53 -0
  61. package/lib/mate-knowledge-mcp-server.js +55 -8
  62. package/lib/mate-knowledge-service.js +16 -34
  63. package/lib/mate-knowledge-text-tools.js +106 -0
  64. package/lib/mate-lifecycle-service.js +94 -0
  65. package/lib/mate-message-delivery.js +43 -0
  66. package/lib/mate-ready-creation.js +9 -1
  67. package/lib/mate-schedule-input.js +29 -0
  68. package/lib/mate-schedule-lifecycle.js +151 -0
  69. package/lib/mate-scheduling.js +103 -0
  70. package/lib/mates.js +18 -6
  71. package/lib/mcp-agent-tools.js +117 -0
  72. package/lib/mcp-connection-store.js +119 -15
  73. package/lib/mcp-import-credentials.js +31 -0
  74. package/lib/mcp-local-transport.js +13 -0
  75. package/lib/mcp-oauth.js +8 -6
  76. package/lib/mcp-proxy.js +2 -32
  77. package/lib/mcp-query-bridge.js +30 -0
  78. package/lib/mcp-remote-connections.js +74 -20
  79. package/lib/mcp-source-adapters.js +1 -0
  80. package/lib/mcp-source-context.js +1 -0
  81. package/lib/mcp-source-discovery.js +1 -0
  82. package/lib/mcp-source-plugins.js +1 -0
  83. package/lib/mcp-source-restrictions.js +1 -0
  84. package/lib/mcp-tool-policy.js +9 -0
  85. package/lib/notes-checklist.js +50 -0
  86. package/lib/notes.js +49 -3
  87. package/lib/os-user-diagnostics.js +2 -4
  88. package/lib/os-users.js +24 -70
  89. package/lib/pane-pending-interactions.js +20 -0
  90. package/lib/pane-session-activation.js +114 -0
  91. package/lib/pane-session-transport.js +26 -0
  92. package/lib/project-admin-overview.js +51 -0
  93. package/lib/project-ask-user.js +8 -4
  94. package/lib/project-connection.js +14 -10
  95. package/lib/project-control-git-view.js +12 -0
  96. package/lib/project-debate.js +1 -0
  97. package/lib/project-delegated-follow-up.js +2 -1
  98. package/lib/project-directory-claim.js +65 -0
  99. package/lib/project-file-operations.js +61 -0
  100. package/lib/project-filesystem.js +15 -85
  101. package/lib/project-full-access.js +23 -2
  102. package/lib/project-http.js +7 -4
  103. package/lib/project-knowledge.js +32 -18
  104. package/lib/project-lifecycle-operations.js +98 -0
  105. package/lib/project-lifecycle-process-witness.js +32 -0
  106. package/lib/project-lifecycle-runtime.js +50 -0
  107. package/lib/project-linux-access.js +22 -0
  108. package/lib/project-logs-canonical-clay.js +27 -0
  109. package/lib/project-logs-clay-query.js +16 -0
  110. package/lib/project-logs-schema.js +4 -2
  111. package/lib/project-logs-service.js +8 -7
  112. package/lib/project-logs.js +1 -0
  113. package/lib/project-loop.js +1 -0
  114. package/lib/project-mate-chat-control.js +55 -0
  115. package/lib/project-mate-creation-proposal.js +18 -3
  116. package/lib/project-mate-interaction.js +40 -62
  117. package/lib/project-mcp.js +54 -16
  118. package/lib/project-models.js +14 -31
  119. package/lib/project-notifications.js +76 -17
  120. package/lib/project-ownership.js +77 -0
  121. package/lib/project-pair-result-delivery.js +14 -3
  122. package/lib/project-pair-usage.js +12 -13
  123. package/lib/project-pending-message-queue.js +4 -1
  124. package/lib/project-product-control.js +89 -0
  125. package/lib/project-product-session-queue.js +46 -0
  126. package/lib/project-push-access.js +28 -0
  127. package/lib/project-scheduled-message-queue.js +30 -0
  128. package/lib/project-scheduled-messages.js +67 -68
  129. package/lib/project-scheduled-task-control.js +83 -0
  130. package/lib/project-scheduled-tasks.js +13 -2
  131. package/lib/project-scheduling-access.js +10 -0
  132. package/lib/project-session-actions.js +65 -0
  133. package/lib/project-session-delete.js +8 -1
  134. package/lib/project-session-document.js +27 -7
  135. package/lib/project-session-github.js +63 -19
  136. package/lib/project-session-history-actions.js +167 -0
  137. package/lib/project-session-linear.js +14 -6
  138. package/lib/project-session-notes.js +7 -3
  139. package/lib/project-session-pair.js +1 -1
  140. package/lib/project-session-runtime-actions.js +64 -0
  141. package/lib/project-session-spawn.js +2 -3
  142. package/lib/project-session-vendor.js +55 -0
  143. package/lib/project-sessions.js +103 -272
  144. package/lib/project-shared-browser.js +78 -17
  145. package/lib/project-studio-presentation.js +58 -0
  146. package/lib/project-user-message.js +67 -1
  147. package/lib/project-vendor-login.js +6 -36
  148. package/lib/project-workspace-operations.js +126 -0
  149. package/lib/project-workspace-query.js +19 -2
  150. package/lib/project.js +178 -45
  151. package/lib/public/app.js +46 -0
  152. package/lib/public/appearance-bootstrap.js +16 -0
  153. package/lib/public/css/clay-tool-activity.css +51 -0
  154. package/lib/public/css/clay-workspace.css +29 -0
  155. package/lib/public/css/command-palette.css +12 -33
  156. package/lib/public/css/contextual-clay.css +240 -0
  157. package/lib/public/css/home-debate-planning.css +2 -0
  158. package/lib/public/css/home-mate-creation.css +5 -0
  159. package/lib/public/css/input.css +6 -0
  160. package/lib/public/css/mate-avatar-gallery.css +12 -0
  161. package/lib/public/css/mate-conversation.css +10 -5
  162. package/lib/public/css/messages.css +6 -2
  163. package/lib/public/css/overlays.css +4 -2
  164. package/lib/public/css/project-admin-overview.css +13 -0
  165. package/lib/public/css/session-folders.css +11 -0
  166. package/lib/public/css/session-github.css +46 -1
  167. package/lib/public/css/shared-browser.css +35 -1
  168. package/lib/public/css/sticky-notes.css +87 -1
  169. package/lib/public/index.html +11 -5
  170. package/lib/public/mate-avatars/B01.png +0 -0
  171. package/lib/public/mate-avatars/B02.png +0 -0
  172. package/lib/public/mate-avatars/B03.png +0 -0
  173. package/lib/public/mate-avatars/B04.png +0 -0
  174. package/lib/public/mate-avatars/B05.png +0 -0
  175. package/lib/public/mate-avatars/B06.png +0 -0
  176. package/lib/public/mate-avatars/B07.png +0 -0
  177. package/lib/public/mate-avatars/B08.png +0 -0
  178. package/lib/public/mate-avatars/B09.png +0 -0
  179. package/lib/public/mate-avatars/B10.png +0 -0
  180. package/lib/public/mate-avatars/B11.png +0 -0
  181. package/lib/public/mate-avatars/B12.png +0 -0
  182. package/lib/public/mate-avatars/B13.png +0 -0
  183. package/lib/public/mate-avatars/B14.png +0 -0
  184. package/lib/public/mate-avatars/B15.png +0 -0
  185. package/lib/public/mate-avatars/B16.png +0 -0
  186. package/lib/public/mate-avatars/B17.png +0 -0
  187. package/lib/public/mate-avatars/B18.png +0 -0
  188. package/lib/public/mate-avatars/B19.png +0 -0
  189. package/lib/public/mate-avatars/B20.png +0 -0
  190. package/lib/public/mate-avatars/B21.png +0 -0
  191. package/lib/public/mate-avatars/B22.png +0 -0
  192. package/lib/public/mate-avatars/B23.png +0 -0
  193. package/lib/public/mate-avatars/B24.png +0 -0
  194. package/lib/public/mate-avatars/B25.png +0 -0
  195. package/lib/public/mate-avatars/B26.png +0 -0
  196. package/lib/public/mate-avatars/B27.png +0 -0
  197. package/lib/public/mate-avatars/B28.png +0 -0
  198. package/lib/public/mate-avatars/B29.png +0 -0
  199. package/lib/public/mate-avatars/B30.png +0 -0
  200. package/lib/public/mate-avatars/B31.png +0 -0
  201. package/lib/public/mate-avatars/B32.png +0 -0
  202. package/lib/public/mate-avatars/B33.png +0 -0
  203. package/lib/public/mate-avatars/B34.png +0 -0
  204. package/lib/public/mate-avatars/B35.png +0 -0
  205. package/lib/public/mate-avatars/B36.png +0 -0
  206. package/lib/public/mate-avatars/B37.png +0 -0
  207. package/lib/public/mate-avatars/B38.png +0 -0
  208. package/lib/public/mate-avatars/B39.png +0 -0
  209. package/lib/public/mate-avatars/B40.png +0 -0
  210. package/lib/public/mate-avatars/B41.png +0 -0
  211. package/lib/public/mate-avatars/B42.png +0 -0
  212. package/lib/public/mate-avatars/B43.png +0 -0
  213. package/lib/public/mate-avatars/B44.png +0 -0
  214. package/lib/public/mate-avatars/B45.png +0 -0
  215. package/lib/public/mate-avatars/B46.png +0 -0
  216. package/lib/public/mate-avatars/B47.png +0 -0
  217. package/lib/public/mate-avatars/B48.png +0 -0
  218. package/lib/public/mate-avatars/C01.png +0 -0
  219. package/lib/public/mate-avatars/C02.png +0 -0
  220. package/lib/public/mate-avatars/C03.png +0 -0
  221. package/lib/public/mate-avatars/C04.png +0 -0
  222. package/lib/public/mate-avatars/C05.png +0 -0
  223. package/lib/public/mate-avatars/C06.png +0 -0
  224. package/lib/public/mate-avatars/C07.png +0 -0
  225. package/lib/public/mate-avatars/C08.png +0 -0
  226. package/lib/public/mate-avatars/C09.png +0 -0
  227. package/lib/public/mate-avatars/C10.png +0 -0
  228. package/lib/public/mate-avatars/C11.png +0 -0
  229. package/lib/public/mate-avatars/C12.png +0 -0
  230. package/lib/public/mate-avatars/C13.png +0 -0
  231. package/lib/public/mate-avatars/C14.png +0 -0
  232. package/lib/public/mate-avatars/C15.png +0 -0
  233. package/lib/public/mate-avatars/C16.png +0 -0
  234. package/lib/public/mate-avatars/C17.png +0 -0
  235. package/lib/public/mate-avatars/C18.png +0 -0
  236. package/lib/public/mate-avatars/C19.png +0 -0
  237. package/lib/public/mate-avatars/C20.png +0 -0
  238. package/lib/public/mate-avatars/C21.png +0 -0
  239. package/lib/public/mate-avatars/C22.png +0 -0
  240. package/lib/public/mate-avatars/C23.png +0 -0
  241. package/lib/public/mate-avatars/C24.png +0 -0
  242. package/lib/public/mate-avatars/C25.png +0 -0
  243. package/lib/public/mate-avatars/C26.png +0 -0
  244. package/lib/public/mate-avatars/C27.png +0 -0
  245. package/lib/public/mate-avatars/C28.png +0 -0
  246. package/lib/public/mate-avatars/C29.png +0 -0
  247. package/lib/public/mate-avatars/C30.png +0 -0
  248. package/lib/public/mate-avatars/C31.png +0 -0
  249. package/lib/public/mate-avatars/C32.png +0 -0
  250. package/lib/public/mate-avatars/C33.png +0 -0
  251. package/lib/public/mate-avatars/C34.png +0 -0
  252. package/lib/public/mate-avatars/C35.png +0 -0
  253. package/lib/public/mate-avatars/C36.png +0 -0
  254. package/lib/public/mate-avatars/C37.png +0 -0
  255. package/lib/public/mate-avatars/C38.png +0 -0
  256. package/lib/public/mate-avatars/C39.png +0 -0
  257. package/lib/public/mate-avatars/C40.png +0 -0
  258. package/lib/public/mate-avatars/C41.png +0 -0
  259. package/lib/public/mate-avatars/C42.png +0 -0
  260. package/lib/public/mate-avatars/C43.png +0 -0
  261. package/lib/public/mate-avatars/C44.png +0 -0
  262. package/lib/public/mate-avatars/C45.png +0 -0
  263. package/lib/public/mate-avatars/C46.png +0 -0
  264. package/lib/public/mate-avatars/C47.png +0 -0
  265. package/lib/public/mate-avatars/C48.png +0 -0
  266. package/lib/public/mate-avatars/catalog.json +482 -0
  267. package/lib/public/mate-avatars/lead-clay.png +0 -0
  268. package/lib/public/modules/admin-settings-projects.js +6 -2
  269. package/lib/public/modules/app-connection.js +11 -1
  270. package/lib/public/modules/app-favicon.js +18 -9
  271. package/lib/public/modules/app-header.js +7 -4
  272. package/lib/public/modules/app-loop-ui.js +2 -0
  273. package/lib/public/modules/app-message-router.js +22 -1
  274. package/lib/public/modules/app-messages.js +115 -17
  275. package/lib/public/modules/app-misc.js +3 -1
  276. package/lib/public/modules/app-notifications.js +11 -5
  277. package/lib/public/modules/app-panels.js +61 -123
  278. package/lib/public/modules/app-projects.js +13 -0
  279. package/lib/public/modules/app-rate-limit.js +7 -27
  280. package/lib/public/modules/app-rendering.js +4 -3
  281. package/lib/public/modules/avatar.js +15 -41
  282. package/lib/public/modules/chat-render-runtime.js +20 -0
  283. package/lib/public/modules/clay-browser-links.js +47 -0
  284. package/lib/public/modules/clay-control-activity.js +214 -0
  285. package/lib/public/modules/clay-control-copy.js +36 -0
  286. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  287. package/lib/public/modules/clay-control-object-targets.js +52 -0
  288. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  289. package/lib/public/modules/clay-control-targets.js +44 -0
  290. package/lib/public/modules/clay-log-links.js +23 -0
  291. package/lib/public/modules/clay-navigation-render.js +52 -0
  292. package/lib/public/modules/clay-owner-navigation.js +33 -0
  293. package/lib/public/modules/clay-session-links.js +31 -0
  294. package/lib/public/modules/clay-studio-bridge.js +20 -0
  295. package/lib/public/modules/clay-studio-document.js +67 -0
  296. package/lib/public/modules/clay-studio-render.js +146 -0
  297. package/lib/public/modules/clay-tool-activity.js +140 -0
  298. package/lib/public/modules/clay-tool-presentation.js +342 -0
  299. package/lib/public/modules/command-palette.js +162 -40
  300. package/lib/public/modules/contextual-ask-session.js +26 -0
  301. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  302. package/lib/public/modules/contextual-clay-session.js +130 -0
  303. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  304. package/lib/public/modules/contextual-clay.js +250 -0
  305. package/lib/public/modules/contextual-composer.js +91 -0
  306. package/lib/public/modules/contextual-mate-context.js +117 -0
  307. package/lib/public/modules/contextual-mate-hint.js +40 -0
  308. package/lib/public/modules/contextual-mate-identity.js +23 -0
  309. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  310. package/lib/public/modules/contextual-search.js +137 -0
  311. package/lib/public/modules/contextual-session-citations.js +58 -0
  312. package/lib/public/modules/debate.js +1 -0
  313. package/lib/public/modules/default-ai.js +11 -3
  314. package/lib/public/modules/elicitation-form.js +5 -0
  315. package/lib/public/modules/filebrowser.js +20 -1
  316. package/lib/public/modules/generation-stop.js +8 -5
  317. package/lib/public/modules/git-panel.js +3 -1
  318. package/lib/public/modules/history-replay-batch.js +13 -1
  319. package/lib/public/modules/home-debate-live.js +2 -0
  320. package/lib/public/modules/home-debate-planning.js +7 -7
  321. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  322. package/lib/public/modules/home-mate-chat.js +8 -6
  323. package/lib/public/modules/home-mate-creation.js +73 -1
  324. package/lib/public/modules/home-mate-settings.js +19 -12
  325. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  326. package/lib/public/modules/input.js +88 -10
  327. package/lib/public/modules/issues-render.js +3 -2
  328. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  329. package/lib/public/modules/markdown.js +6 -34
  330. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  331. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  332. package/lib/public/modules/mate-management.js +40 -7
  333. package/lib/public/modules/mcp-connection-view.js +31 -13
  334. package/lib/public/modules/mcp-discovery-view.js +31 -0
  335. package/lib/public/modules/mcp-ui.js +23 -4
  336. package/lib/public/modules/mention.js +3 -0
  337. package/lib/public/modules/message-delivery.js +20 -2
  338. package/lib/public/modules/model-picker.js +2 -0
  339. package/lib/public/modules/pane-activation.js +214 -0
  340. package/lib/public/modules/pane-binding.js +82 -0
  341. package/lib/public/modules/pane-bridge.js +7 -4
  342. package/lib/public/modules/pane-browser-bridge.js +22 -0
  343. package/lib/public/modules/pane-file-bridge.js +4 -0
  344. package/lib/public/modules/pane-issue-bridge.js +4 -1
  345. package/lib/public/modules/pending-message-queue.js +1 -0
  346. package/lib/public/modules/permission-control.js +5 -4
  347. package/lib/public/modules/personal-settings-dialog.js +7 -1
  348. package/lib/public/modules/product-review.js +26 -0
  349. package/lib/public/modules/profile.js +1 -238
  350. package/lib/public/modules/project-access-recovery.js +17 -0
  351. package/lib/public/modules/project-admin-overview.js +21 -0
  352. package/lib/public/modules/project-chat-identity.js +13 -4
  353. package/lib/public/modules/project-logs-render.js +3 -0
  354. package/lib/public/modules/project-mate-navigation.js +144 -22
  355. package/lib/public/modules/rewind.js +5 -0
  356. package/lib/public/modules/scheduled-tasks.js +2 -0
  357. package/lib/public/modules/scheduler.js +2 -0
  358. package/lib/public/modules/search-clay-chat.js +5 -440
  359. package/lib/public/modules/session-actions.js +5 -2
  360. package/lib/public/modules/session-context-menu.js +5 -0
  361. package/lib/public/modules/session-create-form.js +10 -10
  362. package/lib/public/modules/session-folder-layout.js +1 -1
  363. package/lib/public/modules/session-folder-view-menu.js +9 -0
  364. package/lib/public/modules/session-github.js +85 -14
  365. package/lib/public/modules/session-rich-drafts.js +21 -0
  366. package/lib/public/modules/session-switch-defer.js +67 -0
  367. package/lib/public/modules/session-work-primary.js +51 -0
  368. package/lib/public/modules/settings-defaults.js +27 -28
  369. package/lib/public/modules/shared-browser-settings.js +112 -0
  370. package/lib/public/modules/shared-browser-tabs.js +13 -3
  371. package/lib/public/modules/shared-browser.js +29 -6
  372. package/lib/public/modules/sidebar-mobile.js +4 -3
  373. package/lib/public/modules/sidebar-projects.js +1 -0
  374. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  375. package/lib/public/modules/sidebar-sessions.js +1 -0
  376. package/lib/public/modules/split-group-restore.js +68 -0
  377. package/lib/public/modules/split-pair-ui.js +1 -0
  378. package/lib/public/modules/split-pane-reconciler.js +15 -0
  379. package/lib/public/modules/split-pane-renderer.js +87 -6
  380. package/lib/public/modules/split-session-boundary.js +1 -1
  381. package/lib/public/modules/split-view.js +60 -68
  382. package/lib/public/modules/sticky-note-markdown.js +72 -6
  383. package/lib/public/modules/sticky-notes-actions.js +30 -0
  384. package/lib/public/modules/sticky-notes-browser.js +9 -2
  385. package/lib/public/modules/sticky-notes-card.js +23 -7
  386. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  387. package/lib/public/modules/sticky-notes-editor.js +108 -44
  388. package/lib/public/modules/sticky-notes-shared.js +50 -2
  389. package/lib/public/modules/sticky-notes-state.js +66 -0
  390. package/lib/public/modules/sticky-notes.js +34 -51
  391. package/lib/public/modules/stt-controller.js +4 -1
  392. package/lib/public/modules/stt-recording.js +1 -1
  393. package/lib/public/modules/stt.js +7 -2
  394. package/lib/public/modules/terminal.js +9 -0
  395. package/lib/public/modules/theme.js +8 -1
  396. package/lib/public/modules/thinking-lifecycle.js +33 -3
  397. package/lib/public/modules/thinking-view.js +23 -1
  398. package/lib/public/modules/tools.js +60 -11
  399. package/lib/public/modules/tui-grab.js +1 -2
  400. package/lib/public/modules/user-settings-appearance.js +10 -3
  401. package/lib/public/modules/user-settings-editors.js +1 -1
  402. package/lib/public/modules/user-settings-layout.js +11 -2
  403. package/lib/public/modules/user-settings-preferences.js +6 -2
  404. package/lib/public/modules/user-settings-profile.js +12 -2
  405. package/lib/public/modules/user-settings.js +3 -2
  406. package/lib/public/modules/vendor-login-browser.js +5 -3
  407. package/lib/public/modules/vendor-login.js +2 -2
  408. package/lib/public/modules/vendor-priority.js +15 -1
  409. package/lib/public/modules/wireframe-workbench.js +5 -2
  410. package/lib/public/muse-avatar.svg +4 -0
  411. package/lib/public/style.css +5 -0
  412. package/lib/public/sw.js +3 -1
  413. package/lib/safe-bash-commands.js +3 -45
  414. package/lib/scheduled-task-records.js +3 -1
  415. package/lib/scheduler.js +2 -0
  416. package/lib/sdk-bridge.js +342 -401
  417. package/lib/sdk-foreground-admission.js +16 -0
  418. package/lib/sdk-mcp-descriptors.js +2 -37
  419. package/lib/sdk-message-processor.js +52 -17
  420. package/lib/sdk-quota-snapshot.js +1 -1
  421. package/lib/sdk-response-recovery.js +1 -0
  422. package/lib/sdk-worker.js +2 -677
  423. package/lib/server-admin.js +63 -16
  424. package/lib/server-appearance-settings.js +13 -1
  425. package/lib/server-contextual-clay-settings.js +40 -0
  426. package/lib/server-contextual-mate-sessions.js +70 -0
  427. package/lib/server-dm.js +2 -1
  428. package/lib/server-global-ws.js +10 -20
  429. package/lib/server-home-chat-events.js +18 -4
  430. package/lib/server-home-chat.js +22 -20
  431. package/lib/server-home-clay-entry.js +23 -4
  432. package/lib/server-home-clay-session-links.js +29 -9
  433. package/lib/server-home-mate-creation.js +1 -0
  434. package/lib/server-home-mcp-consent.js +14 -0
  435. package/lib/server-mates.js +25 -62
  436. package/lib/server-owner-ui.js +118 -0
  437. package/lib/server-path-access.js +38 -0
  438. package/lib/server-project-removal.js +22 -0
  439. package/lib/server-settings.js +6 -1
  440. package/lib/server.js +163 -43
  441. package/lib/session-config-transition.js +45 -0
  442. package/lib/session-folders.js +7 -2
  443. package/lib/session-fork-history.js +21 -0
  444. package/lib/session-github.js +9 -2
  445. package/lib/session-hygiene.js +3 -35
  446. package/lib/session-permission-mode.js +4 -3
  447. package/lib/session-skill-scope.js +11 -0
  448. package/lib/session-visibility.js +5 -2
  449. package/lib/session-work-primary.js +50 -0
  450. package/lib/sessions.js +64 -99
  451. package/lib/shared-browser-cookie-sync.js +32 -0
  452. package/lib/shared-browser-cookies.js +79 -0
  453. package/lib/shared-browser-runtime.js +25 -9
  454. package/lib/shared-browser-storage-sync.js +43 -0
  455. package/lib/shared-browser-storage.js +101 -0
  456. package/lib/shared-browser-tools.js +2 -1
  457. package/lib/shared-browser-worker.js +46 -10
  458. package/lib/terminal-manager.js +65 -6
  459. package/lib/tool-llm.js +1 -1
  460. package/lib/tui-transcript-index.js +1 -132
  461. package/lib/users-contextual-clay-preferences.js +31 -0
  462. package/lib/users-permissions.js +2 -8
  463. package/lib/users.js +7 -0
  464. package/lib/vendor-login-browser.js +1 -11
  465. package/lib/workspace-assignment-service.js +25 -0
  466. package/lib/workspace-query-access.js +4 -1
  467. package/lib/workspace-query-mcp-server.js +1 -1
  468. package/lib/workspace-query-service.js +13 -2
  469. package/lib/ws-request.js +1 -0
  470. package/lib/ws-schema.js +18 -2
  471. package/lib/yoke/acp-agent-profiles.js +7 -5
  472. package/lib/yoke/adapters/antigravity.js +3 -14
  473. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  474. package/lib/yoke/adapters/claude.js +54 -50
  475. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  476. package/lib/yoke/adapters/codex.js +53 -111
  477. package/lib/yoke/adapters/kiro.js +3 -1
  478. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  479. package/lib/yoke/adapters/muse.js +122 -0
  480. package/lib/yoke/auth-events.js +17 -0
  481. package/lib/yoke/claude-hook-installer.js +271 -0
  482. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  483. package/lib/yoke/claude-maintenance.js +55 -0
  484. package/lib/yoke/claude-permission-patterns.js +53 -0
  485. package/lib/yoke/claude-response-recovery.js +155 -0
  486. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  487. package/lib/yoke/claude-worker-startup.js +28 -0
  488. package/lib/yoke/clay-skill-install.js +33 -0
  489. package/lib/yoke/cli-sessions.js +300 -0
  490. package/lib/yoke/codex-app-server.js +7 -12
  491. package/lib/yoke/codex-idle-recovery.js +81 -1
  492. package/lib/yoke/codex-recovery-admission.js +164 -0
  493. package/lib/yoke/configuration.js +13 -0
  494. package/lib/yoke/discovery.js +70 -0
  495. package/lib/yoke/errors.js +8 -0
  496. package/lib/yoke/host-environment.js +7 -0
  497. package/lib/yoke/index.js +9 -51
  498. package/lib/yoke/interface.js +116 -0
  499. package/lib/yoke/kiro-acp-server.js +5 -5
  500. package/lib/yoke/legacy-sessions.js +89 -0
  501. package/lib/yoke/login-protocol.js +25 -0
  502. package/lib/yoke/maintenance.js +12 -0
  503. package/lib/yoke/mcp-proxy.js +32 -0
  504. package/lib/yoke/mcp-source-adapters.js +91 -0
  505. package/lib/yoke/mcp-source-context.js +42 -0
  506. package/lib/yoke/mcp-source-discovery.js +169 -0
  507. package/lib/yoke/mcp-source-plugins.js +68 -0
  508. package/lib/yoke/mcp-source-restrictions.js +47 -0
  509. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  510. package/lib/yoke/model-preferences.js +6 -0
  511. package/lib/yoke/muse-artifacts.js +36 -0
  512. package/lib/yoke/muse-controls.js +50 -0
  513. package/lib/yoke/muse-input.js +64 -0
  514. package/lib/yoke/muse-items.js +157 -0
  515. package/lib/yoke/muse-policy.js +52 -0
  516. package/lib/yoke/muse-query.js +428 -0
  517. package/lib/yoke/muse-runtime.js +211 -0
  518. package/lib/yoke/muse-services.js +79 -0
  519. package/lib/yoke/muse-skills.js +79 -0
  520. package/lib/yoke/muse-turns.js +71 -0
  521. package/lib/yoke/options/acp.js +2 -0
  522. package/lib/yoke/options/antigravity.js +2 -0
  523. package/lib/yoke/options/claude.js +21 -0
  524. package/lib/yoke/options/codex-defaults.js +29 -0
  525. package/lib/yoke/options/codex-settings.js +21 -0
  526. package/lib/yoke/options/codex.js +6 -0
  527. package/lib/yoke/options/kiro-defaults.js +22 -0
  528. package/lib/yoke/options/kiro.js +5 -0
  529. package/lib/yoke/options/muse.js +5 -0
  530. package/lib/yoke/provider-contract.js +5 -0
  531. package/lib/yoke/providers/antigravity-executable.js +8 -0
  532. package/lib/yoke/providers/claude-executable.js +40 -0
  533. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  534. package/lib/yoke/providers/claude-process.js +97 -0
  535. package/lib/yoke/providers/claude-provision.js +75 -0
  536. package/lib/yoke/providers/codex-errors.js +8 -0
  537. package/lib/yoke/providers/muse-executable.js +17 -0
  538. package/lib/yoke/provisioning.js +6 -0
  539. package/lib/yoke/query-options.js +10 -0
  540. package/lib/yoke/response-recovery.js +41 -0
  541. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  542. package/lib/yoke/sdk-server-factory.js +7 -0
  543. package/lib/yoke/session-history.js +8 -0
  544. package/lib/yoke/session-tool-transport.js +34 -13
  545. package/lib/yoke/settings.js +23 -0
  546. package/lib/yoke/source-locations.js +4 -0
  547. package/lib/yoke/title-query.js +18 -7
  548. package/lib/yoke/tui-transcript-index.js +132 -0
  549. package/lib/yoke/usage.js +48 -0
  550. package/lib/yoke/user-input.js +13 -0
  551. package/lib/yoke/vendor-registry.js +81 -1
  552. package/package.json +10 -4
@@ -0,0 +1,262 @@
1
+ // Shared ordinary-project mutations. Persistence precedes runtime publication.
2
+ var fs = require('fs');
3
+ var path = require('path');
4
+ var cp = require('child_process');
5
+ var access = require('./daemon-project-access');
6
+ var ownership = require('./project-ownership');
7
+ var configModule = require('./config');
8
+ function attachProjectLifecycle(ctx) {
9
+ var pending = new Map();
10
+ var operations = require('./project-lifecycle-operations').attachLifecycleOperations({ config: config, find: find, snapshot: snapshot, save: save, record: record,
11
+ storageDir: configModule.CONFIG_DIR, directory: identity, relay: relay, publish: publish, publishRuntime: publishRuntime });
12
+ function config() { return ctx.getConfig(); }
13
+ function relay() { return ctx.getRelay(); }
14
+ function find(slug) { return (config().projects || []).find(function (p) { return p.slug === slug; }); }
15
+ function ordinary(project) {
16
+ if (!project || ownership.isPersonal(project) || access.parentSlugFor(project.slug)) throw new Error('Choose a registered ordinary parent project. Clay, Mates and worktrees are excluded.');
17
+ if (project.lifecycleState) throw new Error('Project removal is still pending; inspect its receipt before another action.');
18
+ return project;
19
+ }
20
+ function save(next) { ctx.saveConfig(next); ctx.setConfig(next); }
21
+ function publish() {
22
+ try { configModule.syncClayrc(config().projects); } catch (error) {}
23
+ relay().broadcastAll({ type: 'projects_updated', projects: relay().getProjects(), projectCount: config().projects.length });
24
+ }
25
+ function identity(candidate) {
26
+ var canonical = fs.realpathSync(candidate), stat = fs.statSync(canonical);
27
+ if (!stat.isDirectory()) throw new Error('Choose an existing directory.');
28
+ return { path: canonical, dev: stat.dev, ino: stat.ino, uid: stat.uid };
29
+ }
30
+ function existing(candidate, user) {
31
+ var target = identity(candidate), found = (config().projects || []).find(function (project) { return require('./project-directory-claim').canonical(project.path) === target.path; });
32
+ if (!found) return null;
33
+ var users = require('./users');
34
+ if (users.isMultiUser() ? !user || !users.canAccessProject(user.id, access.getProjectAccess(config(), found.slug, config().osUsers)) : !!found.ownerId && found.ownerId !== (user && user.id || null)) throw new Error('Directory access is not permitted.');
35
+ ordinary(found);
36
+ return found;
37
+ }
38
+ function registration(candidate, user) {
39
+ var target = identity(candidate);
40
+ var dataRoot = require('./project-directory-claim').canonical(configModule.CONFIG_DIR);
41
+ var relative = path.relative(dataRoot, target.path), inverse = path.relative(target.path, dataRoot);
42
+ if (relative !== '..' && relative.indexOf('..' + path.sep) !== 0 && !path.isAbsolute(relative) || inverse !== '..' && inverse.indexOf('..' + path.sep) !== 0 && !path.isAbsolute(inverse)) throw new Error('Clay private storage cannot be registered as an ordinary project.');
43
+ (config().projects || []).forEach(function (p) {
44
+ var root = identity(p.path).path;
45
+ function inside(a, b) { var rel = path.relative(a, b); return rel !== '..' && rel.indexOf('..' + path.sep) !== 0 && !path.isAbsolute(rel); }
46
+ if (inside(target.path, root) || inside(root, target.path) && p.ownerId !== (user && user.id)) throw new Error('Directory intersects a registered project.');
47
+ });
48
+ return target;
49
+ }
50
+ function assertSupported(action) {
51
+ if (config().osUsers && ['visibility', 'allowed_users', 'owner'].indexOf(action) >= 0) throw new Error('OS filesystem sharing and ownership changes are unavailable through canonical Clay; the OS sharing/ownership transaction has no completion acknowledgement.');
52
+ }
53
+ function creationPlan(name) {
54
+ var current = config(), base = current.osUsers ? '/var/clay/projects' : current.projectsDir || path.join(configModule.REAL_HOME, 'clay-projects');
55
+ var canonical = require('./project-directory-claim').canonical;
56
+ var slug = configModule.generateSlug(path.join(base, name), current.projects.map(function (p) { return p.slug; }));
57
+ return { base: base, path: path.join(canonical(base), slug), slug: slug };
58
+ }
59
+ function creationRevision(anchor) {
60
+ var plan = creationPlan('inspection');
61
+ var canonical = require('./project-directory-claim').canonical;
62
+ if (!anchor) {
63
+ anchor = plan.base;
64
+ while (!fs.existsSync(anchor)) { var parent = path.dirname(anchor); if (parent === anchor) break; anchor = parent; }
65
+ }
66
+ return JSON.stringify({ base: plan.base, canonicalBase: canonical(plan.base), anchor: anchor, directory: identity(anchor), osUsers: config().osUsers, projects: config().projects });
67
+ }
68
+ function inspect(slug) {
69
+ var project = ordinary(find(slug));
70
+ return { project: JSON.parse(JSON.stringify(project)), directory: identity(project.path) };
71
+ }
72
+ function stamp(slug) { return JSON.stringify(inspect(slug)); }
73
+ function receipt(key, fingerprint, userId) {
74
+ var item = key && (config().projectControlReceipts || {})[key];
75
+ if (!item) return null;
76
+ if (item.fingerprint !== fingerprint || item.ownerId !== (userId || null)) throw new Error('requestId already names another exact project action.');
77
+ var live = item.slug && find(item.slug);
78
+ if (!live && item.result.filesDeleted !== false && item.result.outcome !== 'removal_reserved_runtime_pending') throw new Error('The receipt target registration was deleted. No action was repeated.');
79
+ if (live && (live.projectKnowledgeId !== item.projectKnowledgeId || live.ownerId !== item.ownerId && !(item.action === 'owner' && item.result.status === 'completed'))) throw new Error('The receipt target was replaced or transferred.');
80
+ return item.result;
81
+ }
82
+ function record(next, correlation, result, project, action) {
83
+ if (!correlation) return;
84
+ var receipts = Object.assign({}, next.projectControlReceipts || {});
85
+ if (!receipts[correlation.key] && Object.keys(receipts).length >= 5000) throw new Error('Project control receipt capacity reached.');
86
+ receipts[correlation.key] = { action: action || correlation.action, sourceKey: correlation.sourceKey || null, fingerprint: correlation.fingerprint, ownerId: correlation.ownerId || null, slug: project && project.slug, projectKnowledgeId: project && project.projectKnowledgeId, result: result };
87
+ next.projectControlReceipts = receipts;
88
+ }
89
+ function runtime(slug) { var found; relay().forEachProject(function (project, candidate) { if (candidate === slug) found = project; }); return found; }
90
+ function publishRuntime(project, action) {
91
+ if (config().osUsers && (action === 'register' || action === 'create')) require('./project-linux-access').verify(project.path, ctx.findUser(project.ownerId), ctx.resolveIdentity);
92
+ var current = runtime(project.slug), status = current && current.getStatus();
93
+ if (status && (status.path !== project.path || status.projectKnowledgeId !== project.projectKnowledgeId)) throw new Error('A replacement runtime occupies the saved registration.');
94
+ if (!current && relay().addProject(project.path, project.slug, project.title || null, project.icon || null, project.ownerId || null, null, { projectKnowledgeId: project.projectKnowledgeId }) === false) throw new Error('Saved project runtime publication was not acknowledged.');
95
+ relay().setProjectTitle(project.slug, project.title || null);
96
+ relay().forEachProject(function (target, slug) {
97
+ if (slug === project.slug || access.parentSlugFor(slug) === project.slug) {
98
+ target.setProjectOwner(project.ownerId || null);
99
+ if ((action === 'environment' || action === 'recovered') && target.refreshEnvironmentRuntime) target.refreshEnvironmentRuntime();
100
+ }
101
+ });
102
+ if (action === 'owner' || action === 'visibility' || action === 'allowed_users' || action === 'recovered') relay().refreshProjectAccess();
103
+ if ((action === 'create' || action === 'register') && ctx.registerWorktrees) ctx.registerWorktrees(project, project.ownerId && ctx.findUser(project.ownerId));
104
+ }
105
+ function publication(next, project, action, result, correlation) {
106
+ var op = operations.begin(next, project, action, result, correlation);
107
+ save(next);
108
+ try {
109
+ publishRuntime(project, action);
110
+ if (correlation && correlation.authorize) correlation.authorize();
111
+ operations.exact(op);
112
+ var completed = snapshot(); operations.complete(completed, op, project); save(completed);
113
+ try { publish(); } catch (error) { result.notificationPending = true; }
114
+ return Object.assign({}, result, { operationId: op.id });
115
+ } catch (error) { error.lifecycleResult = Object.assign({}, error.lifecycleResult || {}, operations.partial(op, error.message)); throw error; }
116
+ }
117
+ function receiptPreview(fingerprint, sourceKey, ownerId) {
118
+ return Object.values(config().projectControlReceipts || {}).find(function (item) {
119
+ return item.action === 'owner' && item.result.status === 'completed' && item.fingerprint === fingerprint && item.sourceKey === sourceKey && item.ownerId === ownerId;
120
+ });
121
+ }
122
+ function snapshot() { var lastConfig = config(); return Object.assign({}, lastConfig, JSON.parse(JSON.stringify(lastConfig))); }
123
+ function creatingAccount(user, existingOnly) {
124
+ var users = require('./users');
125
+ if (!users.isMultiUser()) return null;
126
+ var live = user && ctx.findUser(user.id);
127
+ if (!live || !existingOnly && !users.getEffectivePermissions(live, config().osUsers).createProject) throw new Error('Live project creation permission is required.');
128
+ return live;
129
+ }
130
+ function create(name, user, correlation, validate) {
131
+ user = creatingAccount(user);
132
+ if (!/^[a-zA-Z0-9_-]{1,100}$/.test(name) || (/^mate-/i.test(name) || name.indexOf('--') >= 0)) throw new Error('Invalid ordinary project name.');
133
+ if (validate) validate();
134
+ var current = config(), base = current.osUsers ? '/var/clay/projects' : current.projectsDir || path.join(configModule.REAL_HOME, 'clay-projects');
135
+ var creatingIdentity = JSON.stringify([user && user.id, user && user.linuxUser]);
136
+ var osIdentity = null;
137
+ if (current.osUsers) {
138
+ if (!user || !user.linuxUser) throw new Error('A provisioned Linux account is required.');
139
+ osIdentity = ctx.resolveIdentity(user.linuxUser);
140
+ if (!Number.isInteger(osIdentity.uid) || !Number.isInteger(osIdentity.gid)) throw new Error('Linux identity unavailable.');
141
+ }
142
+ var slug = configModule.generateSlug(path.join(base, name), current.projects.map(function (p) { return p.slug; }));
143
+ var claim = require('./project-directory-claim').claim({ baseDir: base, slug: slug, projects: current.projects, userId: user && user.id });
144
+ var persisted = false;
145
+ try {
146
+ claim.assertOwned();
147
+ var options = { cwd: claim.path, stdio: 'pipe' };
148
+ if (osIdentity) {
149
+ fs.chownSync(claim.path, osIdentity.uid, osIdentity.gid);
150
+ options = Object.assign({}, options, { uid: osIdentity.uid, gid: osIdentity.gid, env: { HOME: osIdentity.home, USER: user.linuxUser, PATH: '/usr/local/bin:/usr/bin:/bin' } });
151
+ var wrapped = require('./os-users').wrapSpawnAsUser('git', ['init'], options);
152
+ cp.execFileSync(wrapped.command, wrapped.args, wrapped.options);
153
+ } else cp.execFileSync('git', ['init'], options);
154
+ claim.assertOwned();
155
+ user = creatingAccount(user);
156
+ if (JSON.stringify([user && user.id, user && user.linuxUser]) !== creatingIdentity) throw new Error('Creating OS account identity changed.');
157
+ if (osIdentity && JSON.stringify(ctx.resolveIdentity(user.linuxUser)) !== JSON.stringify(osIdentity)) throw new Error('Resolved OS identity changed during creation.');
158
+ if (osIdentity) { fs.chmodSync(claim.path, 0o700); require('./project-linux-access').verify(claim.path, user, ctx.resolveIdentity); }
159
+ if (validate) validate();
160
+ var next = snapshot(), project = { slug: slug, path: claim.path, ownerId: user && user.id || null, visibility: 'private', addedAt: Date.now(), projectKnowledgeId: require('./project-log-context').createProjectKnowledgeId() };
161
+ next.projects.push(project);
162
+ var result = { ok: true, slug: slug, status: 'completed' };
163
+ return publication(next, project, 'create', result, correlation);
164
+ } catch (error) {
165
+ persisted = !!(error.lifecycleResult && error.lifecycleResult.persisted);
166
+ if (!persisted) { try { if (!claim.cleanup()) error.message += '; claimed directory was replaced; cleanup skipped'; } catch (cleanupError) { error.message += '; directory cleanup failed: ' + cleanupError.message; } }
167
+ else error.message += '; registration persisted; inspect operationId and explicitly reconcile rather than creating again';
168
+ throw error;
169
+ }
170
+ }
171
+ function register(candidate, user, correlation, validate) {
172
+ user = creatingAccount(user, true);
173
+ if (validate) validate();
174
+ var registered = existing(candidate, user);
175
+ if (registered) {
176
+ if (config().osUsers) require('./project-linux-access').verify(registered.path, user, ctx.resolveIdentity);
177
+ if (!runtime(registered.slug)) {
178
+ var pendingOperation = Object.values(config().projectLifecycleOperations || {}).reverse().find(function (item) { return item.slug === registered.slug && item.phase === 'pending'; });
179
+ if (pendingOperation) return operations.partial(pendingOperation);
180
+ throw new Error('The registration exists but its runtime is unavailable.');
181
+ }
182
+ return { ok: true, status: 'completed', slug: registered.slug, existing: true };
183
+ }
184
+ user = creatingAccount(user);
185
+ var target = registration(candidate, user), next = snapshot();
186
+ if (config().osUsers) require('./project-linux-access').verify(candidate, user, ctx.resolveIdentity);
187
+ var slug = configModule.generateSlug(target.path, next.projects.map(function (p) { return p.slug; }));
188
+ if (/^mate-/.test(slug) || access.parentSlugFor(slug)) throw new Error('Reserved private project identity.');
189
+ var removed = (next.removedProjects || []).find(function (p) { return p.path === target.path && (p.userId || null) === (user && user.id || null); });
190
+ var project = { slug: slug, path: target.path, ownerId: user && user.id || null, visibility: 'private', addedAt: Date.now(), projectKnowledgeId: removed && removed.projectKnowledgeId || require('./project-log-context').createProjectKnowledgeId() };
191
+ next.projects.push(project); next.removedProjects = (next.removedProjects || []).filter(function (p) { return p.path !== target.path; });
192
+ if (validate) validate();
193
+ var result = { ok: true, status: 'completed', slug: slug };
194
+ return publication(next, project, 'register', result, correlation);
195
+ }
196
+ function update(slug, action, value, correlation, validate) {
197
+ if (validate) validate();
198
+ ordinary(find(slug));
199
+ var next = snapshot(), project = next.projects.find(function (p) { return p.slug === slug; });
200
+ if (action === 'rename') {
201
+ if (value !== null && (typeof value !== 'string' || value.length > 100 || /[\u0000-\u001f\u007f]/.test(value))) throw new Error('Invalid project title.');
202
+ project.title = value;
203
+ } else if (action === 'environment') {
204
+ if (typeof value !== 'string' || value.length > 100000 || /\u0000/.test(value)) throw new Error('Invalid project environment.');
205
+ var envError = require('./runtime-env').validateEnvString(value);
206
+ if (envError) throw new Error(envError);
207
+ project.envrc = value;
208
+ } else if (action === 'visibility') {
209
+ if (next.osUsers) throw new Error('OS filesystem sharing changes are unavailable through this service.');
210
+ if (value !== 'public' && value !== 'private') throw new Error('Invalid visibility.'); project.visibility = value;
211
+ } else if (action === 'allowed_users') {
212
+ if (next.osUsers) throw new Error('OS filesystem sharing changes are unavailable through this service.');
213
+ if (!Array.isArray(value) || value.length > 100 || value.some(function (id, i) { return !ctx.findUser(id) || value.indexOf(id) !== i; })) throw new Error('Choose existing unique accounts.');
214
+ project.allowedUsers = value;
215
+ } else if (action === 'owner') {
216
+ if (next.osUsers) throw new Error('OS ownership transfers are unavailable through this service.');
217
+ if (typeof value !== 'string' || !ctx.findUser(value)) throw new Error('Choose an existing owner account.');
218
+ project.ownerId = value;
219
+ } else if (action === 'session_visibility') {
220
+ var changed = access.setSessionVisibilityDefault(next, slug, value); if (!changed.ok) throw new Error(changed.error);
221
+ } else throw new Error('Unsupported project mutation.');
222
+ var result = { ok: true, status: 'completed', slug: slug };
223
+ if (action === 'environment') result.runtimeRefreshed = true;
224
+ if (action === 'environment') result.timing = 'Applies to newly created coding-agent processes. Active processes keep their current environment.';
225
+ return publication(next, project, action, result, correlation);
226
+ }
227
+ async function remove(slug, userId, correlation, validate) {
228
+ if (validate) validate();
229
+ var project = ordinary(find(slug)), next = snapshot();
230
+ var savedProject = next.projects.find(function (item) { return item.slug === slug; });
231
+ var result = { ok: true, status: 'completed', slug: slug, filesDeleted: false, semantics: 'Removed the Clay registration and stopped project runtimes. Project files and stored history remain on disk.' };
232
+ var targets = relay().getProjectLifecycleTargets(slug);
233
+ var op = operations.begin(next, savedProject, 'remove', result, correlation, targets); save(next);
234
+ return operations.reconcile(slug, op.id, { userId: userId || null }, correlation && correlation.authorize || function () {}, null);
235
+ }
236
+ function execute(args, user, correlation, validate) {
237
+ var old = correlation && receipt(correlation.key, correlation.fingerprint, correlation.ownerId);
238
+ if (old) return pending.get(correlation.key) || old;
239
+ if (args.action === 'reconcile' || args.action === 'recover_registration') return operations.reconcile(args.projectSlug, args.value, { userId: user && user.id || null }, correlation.authorize, validate, args.action === 'recover_registration');
240
+ if (args.action === 'create') return create(args.name, user, correlation, validate);
241
+ if (args.action === 'register') return register(args.path, user, correlation, validate);
242
+ if (args.action !== 'remove') return update(args.projectSlug, args.action, args.value, correlation, validate);
243
+ var promise = remove(args.projectSlug, user && user.id, correlation, validate).catch(function (error) {
244
+ var current = find(args.projectSlug);
245
+ if (current && current.lifecycleState === 'removing' && !error.lifecycleResult) error.lifecycleResult = { outcome: 'removal_reserved_runtime_pending', persisted: true, retrySafe: false, slug: args.projectSlug, operationId: current.lifecycleOperationId, recoveryAction: 'reconcile' };
246
+ throw error;
247
+ });
248
+ if (correlation) { pending.set(correlation.key, promise); promise.finally(function () { pending.delete(correlation.key); }).catch(function () {}); }
249
+ return promise;
250
+ }
251
+ function resumeRecovered(slug, userId) {
252
+ var project = ordinary(find(slug));
253
+ var pendingOperation = access.pendingLifecycleOperation(config(), project);
254
+ if (pendingOperation) throw new Error('Review and reconcile pending project operation ' + pendingOperation.id + ' before resuming execution.');
255
+ if (!project.lifecycleExecutionPaused) return true;
256
+ if (project.ownerId !== userId || !ctx.findUser(userId)) throw new Error('Only the current owner can explicitly resume recovered project execution.');
257
+ var next = snapshot(); delete next.projects.find(function (item) { return item.slug === slug; }).lifecycleExecutionPaused; save(next); return true;
258
+ }
259
+ function canRestore(project) { return !project.lifecycleState; }
260
+ return { resumeRecovered: resumeRecovered, inspectRecovery: operations.inspect, receiptPreview: receiptPreview, canRestore: canRestore, assertSupported: assertSupported, creationPlan: creationPlan, creationRevision: creationRevision, inspect: inspect, stamp: stamp, registration: registration, receipt: receipt, execute: execute, create: create, register: register, update: update, remove: remove };
261
+ }
262
+ module.exports = { attachProjectLifecycle: attachProjectLifecycle };
@@ -146,7 +146,7 @@ function cleanupWorktreesForParent(relay, parentSlug) {
146
146
  function getFilteredRemovedProjects(config, userId) {
147
147
  if (!config.removedProjects || config.removedProjects.length === 0) return [];
148
148
  return config.removedProjects.filter(function (rp) {
149
- if (userId && rp.userId && rp.userId !== userId) return false;
149
+ if (userId && rp.userId !== userId) return false;
150
150
  if (!userId && rp.userId) return false;
151
151
  return fs.existsSync(rp.path);
152
152
  });