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

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 (608) hide show
  1. package/README.md +0 -4
  2. package/lib/account-auth-socket.js +1 -0
  3. package/lib/builtin-mates.js +19 -16
  4. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  5. package/lib/canonical-clay-record-authority.js +15 -0
  6. package/lib/canonical-clay-scheduling-authority.js +19 -0
  7. package/lib/claude-hook-installer.js +1 -239
  8. package/lib/claude-jsonl-watcher.js +1 -204
  9. package/lib/clay-control-presentation-binding.js +96 -0
  10. package/lib/clay-control-presentation.js +128 -0
  11. package/lib/clay-control-target-projection.js +26 -0
  12. package/lib/clay-mate-chat-receipts.js +26 -0
  13. package/lib/clay-mate-chat.js +88 -0
  14. package/lib/clay-mate-knowledge-input.js +26 -0
  15. package/lib/clay-mate-knowledge.js +95 -0
  16. package/lib/clay-mate-lifecycle.js +95 -0
  17. package/lib/clay-product-control-input.js +33 -0
  18. package/lib/clay-product-control-tools.js +52 -0
  19. package/lib/clay-product-control.js +250 -0
  20. package/lib/clay-project-lifecycle.js +154 -0
  21. package/lib/clay-project-record-input.js +44 -0
  22. package/lib/clay-project-records.js +84 -0
  23. package/lib/clay-scheduling-input.js +21 -0
  24. package/lib/clay-scheduling-receipts.js +26 -0
  25. package/lib/clay-scheduling.js +119 -0
  26. package/lib/clay-screen-controls.js +104 -0
  27. package/lib/clay-skill-install.js +1 -33
  28. package/lib/clay-vendor-usage.js +44 -0
  29. package/lib/clay-workspace-controls.js +84 -0
  30. package/lib/clay-workspace-input.js +17 -0
  31. package/lib/clay-workspace-receipts.js +26 -0
  32. package/lib/cli-sessions.js +1 -300
  33. package/lib/codex-defaults.js +1 -28
  34. package/lib/context-usage.js +3 -2
  35. package/lib/contextual-screen-snapshot.js +38 -0
  36. package/lib/daemon-project-access.js +11 -0
  37. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  38. package/lib/daemon-project-lifecycle.js +262 -0
  39. package/lib/daemon-projects.js +1 -1
  40. package/lib/daemon.js +78 -276
  41. package/lib/default-ai-runtime.js +4 -8
  42. package/lib/dm-digest-cursor.js +120 -0
  43. package/lib/email-mcp-server.js +1 -1
  44. package/lib/github-star-count.js +147 -0
  45. package/lib/issues-service.js +29 -15
  46. package/lib/kiro-defaults.js +1 -22
  47. package/lib/knowledge-db-import-validation.js +46 -0
  48. package/lib/knowledge-db-import.js +99 -0
  49. package/lib/knowledge-db-service.js +24 -33
  50. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  51. package/lib/knowledge-db-storage-nedb.js +66 -0
  52. package/lib/knowledge-db-storage.js +72 -0
  53. package/lib/knowledge-db-validation.js +0 -0
  54. package/lib/knowledge-document-index.js +2 -1
  55. package/lib/knowledge-file-store.js +7 -1
  56. package/lib/knowledge-product-operations.js +46 -0
  57. package/lib/mate-avatar-catalog.js +12 -0
  58. package/lib/mate-avatar-migration.js +41 -0
  59. package/lib/mate-context-service.js +138 -0
  60. package/lib/mate-context-tools.js +21 -0
  61. package/lib/mate-creation-mcp-server.js +2 -0
  62. package/lib/mate-knowledge-canonical-access.js +10 -0
  63. package/lib/mate-knowledge-mate-bound.js +53 -0
  64. package/lib/mate-knowledge-mcp-server.js +55 -8
  65. package/lib/mate-knowledge-service.js +16 -34
  66. package/lib/mate-knowledge-text-tools.js +106 -0
  67. package/lib/mate-lifecycle-service.js +94 -0
  68. package/lib/mate-message-delivery.js +43 -0
  69. package/lib/mate-ready-creation.js +9 -1
  70. package/lib/mate-schedule-input.js +29 -0
  71. package/lib/mate-schedule-lifecycle.js +151 -0
  72. package/lib/mate-scheduling.js +103 -0
  73. package/lib/mates.js +18 -6
  74. package/lib/mcp-agent-tools.js +117 -0
  75. package/lib/mcp-connection-store.js +119 -15
  76. package/lib/mcp-import-credentials.js +31 -0
  77. package/lib/mcp-local-transport.js +13 -0
  78. package/lib/mcp-oauth.js +8 -6
  79. package/lib/mcp-proxy.js +2 -32
  80. package/lib/mcp-query-bridge.js +30 -0
  81. package/lib/mcp-remote-connections.js +74 -20
  82. package/lib/mcp-source-adapters.js +1 -0
  83. package/lib/mcp-source-context.js +1 -0
  84. package/lib/mcp-source-discovery.js +1 -0
  85. package/lib/mcp-source-plugins.js +1 -0
  86. package/lib/mcp-source-restrictions.js +1 -0
  87. package/lib/mcp-tool-policy.js +9 -0
  88. package/lib/notes-checklist.js +92 -0
  89. package/lib/notes.js +51 -4
  90. package/lib/os-user-diagnostics.js +2 -4
  91. package/lib/os-users.js +24 -70
  92. package/lib/pane-pending-interactions.js +20 -0
  93. package/lib/pane-session-activation.js +114 -0
  94. package/lib/pane-session-transport.js +26 -0
  95. package/lib/project-admin-overview.js +51 -0
  96. package/lib/project-ask-user.js +8 -4
  97. package/lib/project-connection.js +14 -10
  98. package/lib/project-control-git-view.js +12 -0
  99. package/lib/project-debate.js +1 -0
  100. package/lib/project-delegated-follow-up.js +2 -1
  101. package/lib/project-directory-claim.js +65 -0
  102. package/lib/project-file-operations.js +61 -0
  103. package/lib/project-filesystem.js +15 -85
  104. package/lib/project-full-access.js +23 -2
  105. package/lib/project-http.js +7 -4
  106. package/lib/project-knowledge.js +32 -18
  107. package/lib/project-lifecycle-operations.js +98 -0
  108. package/lib/project-lifecycle-process-witness.js +32 -0
  109. package/lib/project-lifecycle-runtime.js +50 -0
  110. package/lib/project-linux-access.js +22 -0
  111. package/lib/project-logs-canonical-clay.js +27 -0
  112. package/lib/project-logs-clay-query.js +16 -0
  113. package/lib/project-logs-schema.js +4 -2
  114. package/lib/project-logs-service.js +8 -7
  115. package/lib/project-logs.js +1 -0
  116. package/lib/project-loop.js +1 -0
  117. package/lib/project-mate-chat-control.js +55 -0
  118. package/lib/project-mate-creation-proposal.js +18 -3
  119. package/lib/project-mate-interaction.js +40 -62
  120. package/lib/project-mcp.js +54 -16
  121. package/lib/project-models.js +14 -31
  122. package/lib/project-notifications.js +76 -17
  123. package/lib/project-ownership.js +77 -0
  124. package/lib/project-pair-result-delivery.js +14 -3
  125. package/lib/project-pair-usage.js +12 -13
  126. package/lib/project-pending-message-queue.js +4 -1
  127. package/lib/project-product-control.js +89 -0
  128. package/lib/project-product-session-queue.js +46 -0
  129. package/lib/project-push-access.js +28 -0
  130. package/lib/project-scheduled-message-queue.js +30 -0
  131. package/lib/project-scheduled-messages.js +67 -68
  132. package/lib/project-scheduled-task-control.js +83 -0
  133. package/lib/project-scheduled-tasks.js +13 -2
  134. package/lib/project-scheduling-access.js +10 -0
  135. package/lib/project-session-actions.js +65 -0
  136. package/lib/project-session-delete.js +8 -1
  137. package/lib/project-session-document.js +27 -7
  138. package/lib/project-session-github.js +63 -19
  139. package/lib/project-session-history-actions.js +167 -0
  140. package/lib/project-session-linear.js +14 -6
  141. package/lib/project-session-notes.js +40 -11
  142. package/lib/project-session-pair.js +1 -1
  143. package/lib/project-session-runtime-actions.js +64 -0
  144. package/lib/project-session-spawn.js +2 -3
  145. package/lib/project-session-vendor.js +55 -0
  146. package/lib/project-sessions.js +160 -290
  147. package/lib/project-shared-browser.js +78 -17
  148. package/lib/project-start-protocol.js +29 -0
  149. package/lib/project-studio-presentation.js +58 -0
  150. package/lib/project-user-message.js +67 -1
  151. package/lib/project-vendor-login.js +8 -36
  152. package/lib/project-workspace-operations.js +126 -0
  153. package/lib/project-workspace-query.js +19 -2
  154. package/lib/project.js +181 -45
  155. package/lib/public/app.js +71 -17
  156. package/lib/public/appearance-bootstrap.js +16 -0
  157. package/lib/public/css/clay-tool-activity.css +51 -0
  158. package/lib/public/css/clay-workspace.css +29 -0
  159. package/lib/public/css/command-palette.css +12 -33
  160. package/lib/public/css/contextual-clay.css +240 -0
  161. package/lib/public/css/filebrowser.css +1 -1
  162. package/lib/public/css/home-debate-planning.css +2 -0
  163. package/lib/public/css/home-mate-creation.css +5 -0
  164. package/lib/public/css/input.css +6 -0
  165. package/lib/public/css/mate-avatar-gallery.css +12 -0
  166. package/lib/public/css/mate-conversation.css +10 -5
  167. package/lib/public/css/mate-loading-scene.css +21 -0
  168. package/lib/public/css/messages.css +6 -2
  169. package/lib/public/css/overlays.css +68 -258
  170. package/lib/public/css/project-admin-overview.css +13 -0
  171. package/lib/public/css/project-mate-creation.css +5 -6
  172. package/lib/public/css/project-start.css +108 -0
  173. package/lib/public/css/projects-hub.css +53 -14
  174. package/lib/public/css/session-folders.css +11 -0
  175. package/lib/public/css/session-github.css +46 -1
  176. package/lib/public/css/settings-shell.css +103 -0
  177. package/lib/public/css/shared-browser.css +35 -1
  178. package/lib/public/css/sidebar.css +7 -0
  179. package/lib/public/css/sticky-notes.css +87 -1
  180. package/lib/public/css/title-bar.css +79 -0
  181. package/lib/public/index.html +61 -68
  182. package/lib/public/mate-avatars/B01.png +0 -0
  183. package/lib/public/mate-avatars/B02.png +0 -0
  184. package/lib/public/mate-avatars/B03.png +0 -0
  185. package/lib/public/mate-avatars/B04.png +0 -0
  186. package/lib/public/mate-avatars/B05.png +0 -0
  187. package/lib/public/mate-avatars/B06.png +0 -0
  188. package/lib/public/mate-avatars/B07.png +0 -0
  189. package/lib/public/mate-avatars/B08.png +0 -0
  190. package/lib/public/mate-avatars/B09.png +0 -0
  191. package/lib/public/mate-avatars/B10.png +0 -0
  192. package/lib/public/mate-avatars/B11.png +0 -0
  193. package/lib/public/mate-avatars/B12.png +0 -0
  194. package/lib/public/mate-avatars/B13.png +0 -0
  195. package/lib/public/mate-avatars/B14.png +0 -0
  196. package/lib/public/mate-avatars/B15.png +0 -0
  197. package/lib/public/mate-avatars/B16.png +0 -0
  198. package/lib/public/mate-avatars/B17.png +0 -0
  199. package/lib/public/mate-avatars/B18.png +0 -0
  200. package/lib/public/mate-avatars/B19.png +0 -0
  201. package/lib/public/mate-avatars/B20.png +0 -0
  202. package/lib/public/mate-avatars/B21.png +0 -0
  203. package/lib/public/mate-avatars/B22.png +0 -0
  204. package/lib/public/mate-avatars/B23.png +0 -0
  205. package/lib/public/mate-avatars/B24.png +0 -0
  206. package/lib/public/mate-avatars/B25.png +0 -0
  207. package/lib/public/mate-avatars/B26.png +0 -0
  208. package/lib/public/mate-avatars/B27.png +0 -0
  209. package/lib/public/mate-avatars/B28.png +0 -0
  210. package/lib/public/mate-avatars/B29.png +0 -0
  211. package/lib/public/mate-avatars/B30.png +0 -0
  212. package/lib/public/mate-avatars/B31.png +0 -0
  213. package/lib/public/mate-avatars/B32.png +0 -0
  214. package/lib/public/mate-avatars/B33.png +0 -0
  215. package/lib/public/mate-avatars/B34.png +0 -0
  216. package/lib/public/mate-avatars/B35.png +0 -0
  217. package/lib/public/mate-avatars/B36.png +0 -0
  218. package/lib/public/mate-avatars/B37.png +0 -0
  219. package/lib/public/mate-avatars/B38.png +0 -0
  220. package/lib/public/mate-avatars/B39.png +0 -0
  221. package/lib/public/mate-avatars/B40.png +0 -0
  222. package/lib/public/mate-avatars/B41.png +0 -0
  223. package/lib/public/mate-avatars/B42.png +0 -0
  224. package/lib/public/mate-avatars/B43.png +0 -0
  225. package/lib/public/mate-avatars/B44.png +0 -0
  226. package/lib/public/mate-avatars/B45.png +0 -0
  227. package/lib/public/mate-avatars/B46.png +0 -0
  228. package/lib/public/mate-avatars/B47.png +0 -0
  229. package/lib/public/mate-avatars/B48.png +0 -0
  230. package/lib/public/mate-avatars/C01.png +0 -0
  231. package/lib/public/mate-avatars/C02.png +0 -0
  232. package/lib/public/mate-avatars/C03.png +0 -0
  233. package/lib/public/mate-avatars/C04.png +0 -0
  234. package/lib/public/mate-avatars/C05.png +0 -0
  235. package/lib/public/mate-avatars/C06.png +0 -0
  236. package/lib/public/mate-avatars/C07.png +0 -0
  237. package/lib/public/mate-avatars/C08.png +0 -0
  238. package/lib/public/mate-avatars/C09.png +0 -0
  239. package/lib/public/mate-avatars/C10.png +0 -0
  240. package/lib/public/mate-avatars/C11.png +0 -0
  241. package/lib/public/mate-avatars/C12.png +0 -0
  242. package/lib/public/mate-avatars/C13.png +0 -0
  243. package/lib/public/mate-avatars/C14.png +0 -0
  244. package/lib/public/mate-avatars/C15.png +0 -0
  245. package/lib/public/mate-avatars/C16.png +0 -0
  246. package/lib/public/mate-avatars/C17.png +0 -0
  247. package/lib/public/mate-avatars/C18.png +0 -0
  248. package/lib/public/mate-avatars/C19.png +0 -0
  249. package/lib/public/mate-avatars/C20.png +0 -0
  250. package/lib/public/mate-avatars/C21.png +0 -0
  251. package/lib/public/mate-avatars/C22.png +0 -0
  252. package/lib/public/mate-avatars/C23.png +0 -0
  253. package/lib/public/mate-avatars/C24.png +0 -0
  254. package/lib/public/mate-avatars/C25.png +0 -0
  255. package/lib/public/mate-avatars/C26.png +0 -0
  256. package/lib/public/mate-avatars/C27.png +0 -0
  257. package/lib/public/mate-avatars/C28.png +0 -0
  258. package/lib/public/mate-avatars/C29.png +0 -0
  259. package/lib/public/mate-avatars/C30.png +0 -0
  260. package/lib/public/mate-avatars/C31.png +0 -0
  261. package/lib/public/mate-avatars/C32.png +0 -0
  262. package/lib/public/mate-avatars/C33.png +0 -0
  263. package/lib/public/mate-avatars/C34.png +0 -0
  264. package/lib/public/mate-avatars/C35.png +0 -0
  265. package/lib/public/mate-avatars/C36.png +0 -0
  266. package/lib/public/mate-avatars/C37.png +0 -0
  267. package/lib/public/mate-avatars/C38.png +0 -0
  268. package/lib/public/mate-avatars/C39.png +0 -0
  269. package/lib/public/mate-avatars/C40.png +0 -0
  270. package/lib/public/mate-avatars/C41.png +0 -0
  271. package/lib/public/mate-avatars/C42.png +0 -0
  272. package/lib/public/mate-avatars/C43.png +0 -0
  273. package/lib/public/mate-avatars/C44.png +0 -0
  274. package/lib/public/mate-avatars/C45.png +0 -0
  275. package/lib/public/mate-avatars/C46.png +0 -0
  276. package/lib/public/mate-avatars/C47.png +0 -0
  277. package/lib/public/mate-avatars/C48.png +0 -0
  278. package/lib/public/mate-avatars/catalog.json +482 -0
  279. package/lib/public/mate-avatars/lead-clay.png +0 -0
  280. package/lib/public/modules/admin-settings-invitations.js +2 -2
  281. package/lib/public/modules/admin-settings-projects.js +8 -4
  282. package/lib/public/modules/admin-settings-ui.js +20 -4
  283. package/lib/public/modules/admin-settings-users.js +4 -4
  284. package/lib/public/modules/app-connection.js +11 -1
  285. package/lib/public/modules/app-favicon.js +18 -9
  286. package/lib/public/modules/app-header.js +7 -4
  287. package/lib/public/modules/app-home-hub.js +2 -1
  288. package/lib/public/modules/app-loop-ui.js +2 -0
  289. package/lib/public/modules/app-message-router.js +22 -1
  290. package/lib/public/modules/app-messages.js +125 -19
  291. package/lib/public/modules/app-misc.js +3 -1
  292. package/lib/public/modules/app-notifications.js +11 -5
  293. package/lib/public/modules/app-panels.js +61 -123
  294. package/lib/public/modules/app-projects.js +14 -407
  295. package/lib/public/modules/app-rate-limit.js +19 -28
  296. package/lib/public/modules/app-rendering.js +4 -3
  297. package/lib/public/modules/avatar.js +15 -41
  298. package/lib/public/modules/chat-render-runtime.js +20 -0
  299. package/lib/public/modules/clay-browser-links.js +47 -0
  300. package/lib/public/modules/clay-control-activity.js +214 -0
  301. package/lib/public/modules/clay-control-copy.js +36 -0
  302. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  303. package/lib/public/modules/clay-control-object-targets.js +52 -0
  304. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  305. package/lib/public/modules/clay-control-targets.js +44 -0
  306. package/lib/public/modules/clay-log-links.js +23 -0
  307. package/lib/public/modules/clay-navigation-render.js +52 -0
  308. package/lib/public/modules/clay-owner-navigation.js +33 -0
  309. package/lib/public/modules/clay-session-links.js +31 -0
  310. package/lib/public/modules/clay-studio-bridge.js +20 -0
  311. package/lib/public/modules/clay-studio-document.js +67 -0
  312. package/lib/public/modules/clay-studio-render.js +146 -0
  313. package/lib/public/modules/clay-tool-activity.js +140 -0
  314. package/lib/public/modules/clay-tool-presentation.js +343 -0
  315. package/lib/public/modules/command-palette.js +162 -40
  316. package/lib/public/modules/contextual-ask-session.js +26 -0
  317. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  318. package/lib/public/modules/contextual-clay-session.js +130 -0
  319. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  320. package/lib/public/modules/contextual-clay.js +252 -0
  321. package/lib/public/modules/contextual-composer.js +91 -0
  322. package/lib/public/modules/contextual-mate-context.js +117 -0
  323. package/lib/public/modules/contextual-mate-hint.js +40 -0
  324. package/lib/public/modules/contextual-mate-identity.js +23 -0
  325. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  326. package/lib/public/modules/contextual-search.js +137 -0
  327. package/lib/public/modules/contextual-session-citations.js +58 -0
  328. package/lib/public/modules/debate.js +1 -0
  329. package/lib/public/modules/default-ai.js +11 -3
  330. package/lib/public/modules/elicitation-form.js +5 -0
  331. package/lib/public/modules/filebrowser.js +20 -1
  332. package/lib/public/modules/generation-stop.js +8 -5
  333. package/lib/public/modules/git-panel.js +3 -1
  334. package/lib/public/modules/github-star.js +66 -0
  335. package/lib/public/modules/history-replay-batch.js +13 -1
  336. package/lib/public/modules/home-debate-live.js +2 -0
  337. package/lib/public/modules/home-debate-planning.js +7 -7
  338. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  339. package/lib/public/modules/home-mate-chat.js +8 -6
  340. package/lib/public/modules/home-mate-creation.js +73 -1
  341. package/lib/public/modules/home-mate-settings.js +19 -12
  342. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  343. package/lib/public/modules/input.js +88 -10
  344. package/lib/public/modules/issues-render.js +3 -2
  345. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  346. package/lib/public/modules/markdown.js +6 -34
  347. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  348. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  349. package/lib/public/modules/mate-loading-scene.js +17 -0
  350. package/lib/public/modules/mate-management.js +40 -7
  351. package/lib/public/modules/mcp-connection-view.js +31 -13
  352. package/lib/public/modules/mcp-discovery-view.js +31 -0
  353. package/lib/public/modules/mcp-ui.js +23 -4
  354. package/lib/public/modules/mention.js +3 -0
  355. package/lib/public/modules/message-delivery.js +20 -2
  356. package/lib/public/modules/model-picker.js +2 -0
  357. package/lib/public/modules/pane-activation.js +214 -0
  358. package/lib/public/modules/pane-binding.js +82 -0
  359. package/lib/public/modules/pane-bridge.js +7 -4
  360. package/lib/public/modules/pane-browser-bridge.js +22 -0
  361. package/lib/public/modules/pane-file-bridge.js +4 -0
  362. package/lib/public/modules/pane-issue-bridge.js +4 -1
  363. package/lib/public/modules/pending-message-queue.js +1 -0
  364. package/lib/public/modules/permission-control.js +5 -4
  365. package/lib/public/modules/personal-settings-dialog.js +7 -1
  366. package/lib/public/modules/product-review.js +26 -0
  367. package/lib/public/modules/profile.js +12 -241
  368. package/lib/public/modules/project-access-recovery.js +17 -0
  369. package/lib/public/modules/project-admin-overview.js +21 -0
  370. package/lib/public/modules/project-chat-identity.js +13 -4
  371. package/lib/public/modules/project-logs-render.js +3 -0
  372. package/lib/public/modules/project-mate-creation-workspace.js +13 -4
  373. package/lib/public/modules/project-mate-navigation.js +144 -22
  374. package/lib/public/modules/project-session-visibility-settings.js +19 -16
  375. package/lib/public/modules/project-settings.js +119 -129
  376. package/lib/public/modules/project-start-dialog.js +130 -0
  377. package/lib/public/modules/project-start-folder-state.js +78 -0
  378. package/lib/public/modules/project-start-folder-view.js +190 -0
  379. package/lib/public/modules/project-start-forms.js +66 -0
  380. package/lib/public/modules/project-start-path.js +60 -0
  381. package/lib/public/modules/project-start-state.js +54 -0
  382. package/lib/public/modules/project-start-submit.js +67 -0
  383. package/lib/public/modules/projects-hub-view.js +33 -14
  384. package/lib/public/modules/projects-hub.js +10 -6
  385. package/lib/public/modules/rewind.js +5 -0
  386. package/lib/public/modules/scheduled-tasks.js +2 -0
  387. package/lib/public/modules/scheduler.js +2 -0
  388. package/lib/public/modules/search-clay-chat.js +5 -440
  389. package/lib/public/modules/server-settings.js +36 -91
  390. package/lib/public/modules/session-actions.js +5 -2
  391. package/lib/public/modules/session-context-menu.js +5 -0
  392. package/lib/public/modules/session-create-form.js +10 -10
  393. package/lib/public/modules/session-folder-layout.js +1 -1
  394. package/lib/public/modules/session-folder-view-menu.js +9 -0
  395. package/lib/public/modules/session-github.js +85 -14
  396. package/lib/public/modules/session-rich-drafts.js +21 -0
  397. package/lib/public/modules/session-switch-defer.js +67 -0
  398. package/lib/public/modules/session-work-primary.js +51 -0
  399. package/lib/public/modules/settings-defaults.js +27 -28
  400. package/lib/public/modules/settings-project-target.js +56 -0
  401. package/lib/public/modules/settings-select.js +1 -1
  402. package/lib/public/modules/settings-shell-registry.js +88 -0
  403. package/lib/public/modules/settings-shell-view.js +104 -0
  404. package/lib/public/modules/settings-shell.js +342 -0
  405. package/lib/public/modules/shared-browser-settings.js +112 -0
  406. package/lib/public/modules/shared-browser-tabs.js +13 -3
  407. package/lib/public/modules/shared-browser.js +29 -6
  408. package/lib/public/modules/sidebar-mobile.js +12 -33
  409. package/lib/public/modules/sidebar-projects.js +3 -1
  410. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  411. package/lib/public/modules/sidebar-sessions.js +1 -0
  412. package/lib/public/modules/split-group-restore.js +68 -0
  413. package/lib/public/modules/split-pair-ui.js +1 -0
  414. package/lib/public/modules/split-pane-reconciler.js +15 -0
  415. package/lib/public/modules/split-pane-renderer.js +87 -6
  416. package/lib/public/modules/split-session-boundary.js +1 -1
  417. package/lib/public/modules/split-view.js +60 -68
  418. package/lib/public/modules/sticky-note-markdown.js +72 -6
  419. package/lib/public/modules/sticky-notes-actions.js +30 -0
  420. package/lib/public/modules/sticky-notes-browser.js +9 -2
  421. package/lib/public/modules/sticky-notes-card.js +23 -7
  422. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  423. package/lib/public/modules/sticky-notes-editor.js +108 -44
  424. package/lib/public/modules/sticky-notes-shared.js +50 -2
  425. package/lib/public/modules/sticky-notes-state.js +66 -0
  426. package/lib/public/modules/sticky-notes.js +34 -51
  427. package/lib/public/modules/stt-controller.js +4 -1
  428. package/lib/public/modules/stt-recording.js +1 -1
  429. package/lib/public/modules/stt.js +7 -2
  430. package/lib/public/modules/terminal.js +9 -0
  431. package/lib/public/modules/theme.js +18 -3
  432. package/lib/public/modules/thinking-lifecycle.js +33 -3
  433. package/lib/public/modules/thinking-view.js +23 -1
  434. package/lib/public/modules/tools.js +60 -11
  435. package/lib/public/modules/tui-grab.js +1 -2
  436. package/lib/public/modules/user-settings-appearance.js +10 -3
  437. package/lib/public/modules/user-settings-editors.js +1 -1
  438. package/lib/public/modules/user-settings-layout.js +14 -30
  439. package/lib/public/modules/user-settings-preferences.js +6 -2
  440. package/lib/public/modules/user-settings-profile.js +13 -3
  441. package/lib/public/modules/user-settings.js +18 -84
  442. package/lib/public/modules/vendor-login-browser.js +5 -3
  443. package/lib/public/modules/vendor-login.js +2 -2
  444. package/lib/public/modules/vendor-priority.js +15 -1
  445. package/lib/public/modules/vendor-usage-format.js +93 -0
  446. package/lib/public/modules/vendor-usage-list.js +45 -0
  447. package/lib/public/modules/vendor-usage-model.js +215 -0
  448. package/lib/public/modules/vendor-usage-overview.js +312 -0
  449. package/lib/public/modules/wireframe-workbench.js +5 -2
  450. package/lib/public/muse-avatar.svg +4 -0
  451. package/lib/public/style.css +14 -6
  452. package/lib/public/sw.js +3 -1
  453. package/lib/public/welcome-art/conversation-desk.png +0 -0
  454. package/lib/public/welcome-art/mate-clay.png +0 -0
  455. package/lib/public/welcome-art/project-clay.png +0 -0
  456. package/lib/safe-bash-commands.js +3 -45
  457. package/lib/scheduled-task-records.js +3 -1
  458. package/lib/scheduler.js +2 -0
  459. package/lib/sdk-bridge.js +348 -402
  460. package/lib/sdk-foreground-admission.js +16 -0
  461. package/lib/sdk-mcp-descriptors.js +2 -37
  462. package/lib/sdk-message-processor.js +61 -18
  463. package/lib/sdk-quota-snapshot.js +21 -3
  464. package/lib/sdk-response-recovery.js +1 -0
  465. package/lib/sdk-worker.js +2 -677
  466. package/lib/server-admin.js +63 -16
  467. package/lib/server-appearance-settings.js +13 -1
  468. package/lib/server-contextual-clay-settings.js +40 -0
  469. package/lib/server-contextual-mate-sessions.js +70 -0
  470. package/lib/server-dm.js +2 -1
  471. package/lib/server-github-stars.js +39 -0
  472. package/lib/server-global-ws.js +26 -32
  473. package/lib/server-home-chat-events.js +18 -4
  474. package/lib/server-home-chat.js +22 -20
  475. package/lib/server-home-clay-entry.js +23 -4
  476. package/lib/server-home-clay-session-links.js +29 -9
  477. package/lib/server-home-mate-creation.js +1 -0
  478. package/lib/server-home-mcp-consent.js +14 -0
  479. package/lib/server-mates.js +25 -62
  480. package/lib/server-owner-ui.js +118 -0
  481. package/lib/server-path-access.js +38 -0
  482. package/lib/server-project-removal.js +22 -0
  483. package/lib/server-settings.js +6 -1
  484. package/lib/server.js +167 -43
  485. package/lib/session-config-transition.js +45 -0
  486. package/lib/session-folders.js +7 -2
  487. package/lib/session-fork-history.js +21 -0
  488. package/lib/session-github.js +9 -2
  489. package/lib/session-hygiene.js +3 -35
  490. package/lib/session-notes-mcp-server.js +26 -4
  491. package/lib/session-notes-writes.js +88 -0
  492. package/lib/session-permission-mode.js +4 -3
  493. package/lib/session-skill-scope.js +11 -0
  494. package/lib/session-visibility.js +25 -10
  495. package/lib/session-work-primary.js +50 -0
  496. package/lib/sessions.js +66 -99
  497. package/lib/shared-browser-cookie-sync.js +32 -0
  498. package/lib/shared-browser-cookies.js +79 -0
  499. package/lib/shared-browser-runtime.js +25 -9
  500. package/lib/shared-browser-storage-sync.js +43 -0
  501. package/lib/shared-browser-storage.js +101 -0
  502. package/lib/shared-browser-tools.js +2 -1
  503. package/lib/shared-browser-worker.js +46 -10
  504. package/lib/terminal-manager.js +65 -6
  505. package/lib/tool-llm.js +1 -1
  506. package/lib/tui-transcript-index.js +1 -132
  507. package/lib/users-contextual-clay-preferences.js +31 -0
  508. package/lib/users-permissions.js +2 -8
  509. package/lib/users.js +7 -0
  510. package/lib/vendor-login-browser.js +1 -11
  511. package/lib/vendor-usage-acp-readers.js +97 -0
  512. package/lib/vendor-usage-capabilities.js +88 -0
  513. package/lib/vendor-usage-http-readers.js +214 -0
  514. package/lib/vendor-usage-metrics.js +47 -0
  515. package/lib/vendor-usage-native-readers.js +106 -0
  516. package/lib/vendor-usage-overview.js +406 -0
  517. package/lib/vendor-usage-service.js +281 -0
  518. package/lib/workspace-assignment-service.js +25 -0
  519. package/lib/workspace-query-access.js +4 -1
  520. package/lib/workspace-query-mcp-server.js +1 -1
  521. package/lib/workspace-query-service.js +13 -2
  522. package/lib/ws-request.js +1 -0
  523. package/lib/ws-schema.js +22 -4
  524. package/lib/yoke/acp-agent-profiles.js +7 -5
  525. package/lib/yoke/adapters/antigravity.js +3 -14
  526. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  527. package/lib/yoke/adapters/claude.js +66 -50
  528. package/lib/yoke/adapters/codex-query-contract.js +25 -0
  529. package/lib/yoke/adapters/codex.js +98 -123
  530. package/lib/yoke/adapters/kiro.js +3 -1
  531. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  532. package/lib/yoke/adapters/muse.js +122 -0
  533. package/lib/yoke/auth-events.js +17 -0
  534. package/lib/yoke/claude-hook-installer.js +272 -0
  535. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  536. package/lib/yoke/claude-maintenance.js +55 -0
  537. package/lib/yoke/claude-permission-patterns.js +53 -0
  538. package/lib/yoke/claude-response-recovery.js +155 -0
  539. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  540. package/lib/yoke/claude-worker-startup.js +28 -0
  541. package/lib/yoke/clay-skill-install.js +33 -0
  542. package/lib/yoke/cli-sessions.js +300 -0
  543. package/lib/yoke/codex-app-server.js +7 -12
  544. package/lib/yoke/codex-dynamic-tool-names.js +80 -0
  545. package/lib/yoke/codex-idle-recovery.js +81 -1
  546. package/lib/yoke/codex-model-catalog.js +37 -3
  547. package/lib/yoke/codex-recovery-admission.js +164 -0
  548. package/lib/yoke/configuration.js +13 -0
  549. package/lib/yoke/discovery.js +70 -0
  550. package/lib/yoke/errors.js +8 -0
  551. package/lib/yoke/host-environment.js +7 -0
  552. package/lib/yoke/index.js +9 -51
  553. package/lib/yoke/interface.js +116 -0
  554. package/lib/yoke/kiro-acp-server.js +5 -5
  555. package/lib/yoke/legacy-sessions.js +89 -0
  556. package/lib/yoke/login-protocol.js +25 -0
  557. package/lib/yoke/maintenance.js +12 -0
  558. package/lib/yoke/mcp-proxy.js +32 -0
  559. package/lib/yoke/mcp-source-adapters.js +91 -0
  560. package/lib/yoke/mcp-source-context.js +42 -0
  561. package/lib/yoke/mcp-source-discovery.js +169 -0
  562. package/lib/yoke/mcp-source-plugins.js +68 -0
  563. package/lib/yoke/mcp-source-restrictions.js +47 -0
  564. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  565. package/lib/yoke/model-preferences.js +6 -0
  566. package/lib/yoke/muse-artifacts.js +36 -0
  567. package/lib/yoke/muse-controls.js +50 -0
  568. package/lib/yoke/muse-input.js +64 -0
  569. package/lib/yoke/muse-items.js +157 -0
  570. package/lib/yoke/muse-policy.js +52 -0
  571. package/lib/yoke/muse-query.js +428 -0
  572. package/lib/yoke/muse-runtime.js +211 -0
  573. package/lib/yoke/muse-services.js +92 -0
  574. package/lib/yoke/muse-skills.js +79 -0
  575. package/lib/yoke/muse-turns.js +71 -0
  576. package/lib/yoke/options/acp.js +2 -0
  577. package/lib/yoke/options/antigravity.js +2 -0
  578. package/lib/yoke/options/claude.js +21 -0
  579. package/lib/yoke/options/codex-defaults.js +29 -0
  580. package/lib/yoke/options/codex-settings.js +21 -0
  581. package/lib/yoke/options/codex.js +6 -0
  582. package/lib/yoke/options/kiro-defaults.js +22 -0
  583. package/lib/yoke/options/kiro.js +5 -0
  584. package/lib/yoke/options/muse.js +5 -0
  585. package/lib/yoke/provider-contract.js +5 -0
  586. package/lib/yoke/providers/antigravity-executable.js +8 -0
  587. package/lib/yoke/providers/claude-executable.js +40 -0
  588. package/lib/yoke/providers/claude-model-descriptions.js +34 -0
  589. package/lib/yoke/providers/claude-process.js +97 -0
  590. package/lib/yoke/providers/claude-provision.js +75 -0
  591. package/lib/yoke/providers/codex-errors.js +8 -0
  592. package/lib/yoke/providers/muse-executable.js +17 -0
  593. package/lib/yoke/provisioning.js +6 -0
  594. package/lib/yoke/query-options.js +10 -0
  595. package/lib/yoke/response-recovery.js +41 -0
  596. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  597. package/lib/yoke/sdk-server-factory.js +7 -0
  598. package/lib/yoke/session-history.js +8 -0
  599. package/lib/yoke/session-tool-transport.js +34 -13
  600. package/lib/yoke/settings.js +23 -0
  601. package/lib/yoke/source-locations.js +4 -0
  602. package/lib/yoke/title-query.js +18 -7
  603. package/lib/yoke/tui-transcript-index.js +132 -0
  604. package/lib/yoke/usage.js +48 -0
  605. package/lib/yoke/user-input.js +13 -0
  606. package/lib/yoke/vendor-registry.js +87 -3
  607. package/package.json +11 -4
  608. package/lib/public/modules/server-settings-navigation.js +0 -39
package/lib/server.js CHANGED
@@ -10,7 +10,7 @@ var dm = require("./dm");
10
10
  var mates = require("./mates");
11
11
  var serverAuth = require("./server-auth");
12
12
  var serverSkills = require("./server-skills");
13
- var claudeHookInstaller = require("./claude-hook-installer");
13
+ var claudeHookInstaller = require("./yoke/claude-hook-installer");
14
14
  var serverDm = require("./server-dm");
15
15
  var serverMates = require("./server-mates");
16
16
  var serverHomeChat = require("./server-home-chat");
@@ -219,6 +219,14 @@ function createServer(opts) {
219
219
  var isRequestAuthed = auth.isRequestAuthed;
220
220
  var parseCookies = auth.parseCookies;
221
221
 
222
+ var projectAdminOverview = require("./project-admin-overview");
223
+
224
+ function administrativeMetadata(userId, slug) {
225
+ var user = userId && users.findUserById(userId);
226
+ var context = projects.get(slug);
227
+ return projectAdminOverview.metadataFor(user, context && context.getStatus(), onGetProjectAccess && onGetProjectAccess(slug), users);
228
+ }
229
+
222
230
  function canUserAccessSlug(userId, slug) {
223
231
  if (!userId || !slug) return false;
224
232
  var project = projects && projects.get(slug);
@@ -237,6 +245,13 @@ function createServer(opts) {
237
245
  return users.canAccessProject(userId, access) === true;
238
246
  }
239
247
 
248
+ var projects = new Map(); // slug → projectContext
249
+ var lifecycleRuntime = require("./project-lifecycle-runtime").attachLifecycleRuntime({ projects: projects });
250
+ var canUsePath = require("./server-path-access").attachPathAccess({
251
+ users: users, projects: projects, canAccess: canUserAccessSlug, osUsers: osUsers,
252
+ resolveIdentity: require("./os-users").resolveOsUserInfo,
253
+ });
254
+
240
255
  var realVersion = require("../package.json").version;
241
256
  var currentVersion = debug ? "0.0.9" : realVersion;
242
257
 
@@ -341,8 +356,13 @@ function createServer(opts) {
341
356
  var caContent = caPath ? (function () { try { return fs.readFileSync(caPath); } catch (e) { return null; } })() : null;
342
357
 
343
358
  // --- Project registry ---
344
- var projects = new Map(); // slug → projectContext
345
359
  var assignmentService = attachWorkspaceAssignmentService({
360
+ getPresentation: function (principal) {
361
+ var project = projects.get(principal.sourceProjectSlug), manager = project && project.getSessionManager(), status = project && project.getStatus();
362
+ var session = manager && manager.sessions.get(principal.sourceSessionId);
363
+ var bound = clayProductControl && session && clayProductControl.bind({ projectSlug: principal.sourceProjectSlug, projectOwnerId: status.projectOwnerId, isMate: status.isMate, mateId: status.mateId, session: session });
364
+ return bound && bound._presentation;
365
+ },
346
366
  storageDir: path.join(CONFIG_DIR, "workspace-assignments"),
347
367
  getProjects: function () { return projects; },
348
368
  isMultiUser: function () { return users.isMultiUser(); },
@@ -363,6 +383,36 @@ function createServer(opts) {
363
383
  },
364
384
  assignmentService: assignmentService,
365
385
  });
386
+ var ownerUiService = require('./server-owner-ui').attachOwnerUi({
387
+ isMultiUser: users.isMultiUser, findUser: users.findUserById,
388
+ forEachClient: function (visit) {
389
+ if (globalWs) globalWs.forEachClient(function (ws) { visit(ws, null); });
390
+ projects.forEach(function (project, slug) { project.forEachClient(function (ws) { visit(ws, slug); }); });
391
+ }
392
+ });
393
+ var mateContextService = require('./mate-context-service').attachMateContextService({
394
+ getOwnerUi: function () { return ownerUiService; }, workspace: workspaceQueryService,
395
+ getProjects: function () { return projects; }, isMultiUser: users.isMultiUser,
396
+ findUser: users.findUserById, onGetProjectAccess: onGetProjectAccess,
397
+ canAccessProject: users.canAccessProject,
398
+ resolveMate: function (owner, id) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? owner : null), id); }
399
+ });
400
+ var clayProductControl = require("./clay-product-control").attachClayProductControl({
401
+ getOwnerUi: function () { return ownerUiService; },
402
+ getNotifications: function () { return _globalNotifications; },
403
+ getRecordServices: function () { return { issues: issuesService, logs: projectLogsService }; },
404
+ projectLifecycle: opts.projectLifecycle || null,
405
+ getMateLifecycle: function () { return mateHandler && mateHandler.lifecycle; },
406
+ getMateDir: function (ownerId, mateId) { return mates.getMateDir(mates.buildMateCtx(users.isMultiUser() ? ownerId : null), mateId); },
407
+ lifecyclePermissions: function (user) { return users.getEffectivePermissions(user, osUsers); },
408
+ canUsePath: canUsePath,
409
+ getProjects: function () { return projects; },
410
+ isMultiUser: function () { return users.isMultiUser(); },
411
+ onGetProjectAccess: onGetProjectAccess,
412
+ canAccessProject: function (userId, access) { return users.canAccessProject(userId, access) === true; },
413
+ findUser: function (userId) { return users.findUserById(userId); },
414
+ resolveMate: function (userId, mateId) { return mates.getMate(mates.buildMateCtx(users.isMultiUser() ? userId : null), mateId); },
415
+ });
366
416
  // Project access is resolved from the authoritative project record, not from
367
417
  // getStatus(), which carries no visibility or allowedUsers fields.
368
418
  var projectLogsService = attachProjectLogsService({
@@ -409,6 +459,7 @@ function createServer(opts) {
409
459
  // Mate Knowledge reads the synchronized Knowledge records. The Mate list is
410
460
  // derived from the owning user alone, so a binding can never span users.
411
461
  var mateKnowledgeService = attachMateKnowledgeService({
462
+ findUser: function (userId) { return users.findUserById(userId); },
412
463
  getProjects: function () { return projects; },
413
464
  isMultiUser: function () { return users.isMultiUser(); },
414
465
  resolveMate: function (userId, mateId) {
@@ -456,6 +507,8 @@ function createServer(opts) {
456
507
  var linear = require('./server-linear').attachLinear({ users: users, getMultiUserFromReq: getMultiUserFromReq,
457
508
  isRequestAuthed: isRequestAuthed, CONFIG_DIR: CONFIG_DIR });
458
509
 
510
+ var githubStars = require('./server-github-stars').attachGithubStars({ isRequestAuthed: isRequestAuthed });
511
+
459
512
  var speech = serverSpeech.attachSpeech({ users: users, getMultiUserFromReq: getMultiUserFromReq,
460
513
  isRequestAuthed: isRequestAuthed, CONFIG_DIR: CONFIG_DIR, getAllowedOrigins: getAllowedOrigins });
461
514
 
@@ -491,6 +544,41 @@ function createServer(opts) {
491
544
  },
492
545
  });
493
546
 
547
+ function injectAppearanceSeed(html, appearance) {
548
+ var validId = function (value) {
549
+ return typeof value === "string" && /^[a-zA-Z0-9_-]{1,120}$/.test(value) ? value : null;
550
+ };
551
+ var mode = appearance && ["light", "dark"].indexOf(appearance.mode) >= 0 ? appearance.mode : null;
552
+ var seed = appearance && appearance.configured === true ? {
553
+ configured: true,
554
+ theme: validId(appearance.theme),
555
+ mode: mode,
556
+ lightTheme: validId(appearance.lightTheme),
557
+ darkTheme: validId(appearance.darkTheme),
558
+ } : null;
559
+ var payload = JSON.stringify(seed).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
560
+ var script = '<script>window.__clayAppearanceSeed=' + payload + ';</script>';
561
+ return html.replace('<script src="appearance-bootstrap.js"></script>', script + '<script src="appearance-bootstrap.js"></script>');
562
+ }
563
+
564
+ function sendAppShell(req, res, slug) {
565
+ try {
566
+ var shell = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
567
+ if (slug) shell = injectRootProjectSlug(shell, slug);
568
+ var appearance = null;
569
+ try { appearance = settings.getInitialAppearance(req); } catch (e) {}
570
+ shell = injectAppearanceSeed(shell, appearance);
571
+ res.writeHead(200, {
572
+ "Content-Type": "text/html; charset=utf-8",
573
+ "Cache-Control": "private, no-store",
574
+ });
575
+ res.end(shell);
576
+ } catch (e) {
577
+ res.writeHead(500, { "Content-Type": "text/plain" });
578
+ res.end("App shell missing.");
579
+ }
580
+ }
581
+
494
582
  var palette = serverPalette.attachPalette({
495
583
  users: users,
496
584
  projects: projects,
@@ -512,7 +600,28 @@ function createServer(opts) {
512
600
  broadcastAll: function (msg) { broadcastAll(msg); },
513
601
  sendToUser: function (userId, msg) { sendToUser(userId, msg); },
514
602
  pushModule: pushModule,
603
+ forEachClient: forEachAppClient,
604
+ getUsers: function () { return users.getAllUsers(); },
605
+ canView: function (ws, notification) { return canViewNotification(ws && ws._clayUser && ws._clayUser.id, notification); },
606
+ canViewPrincipal: function (principal, notification) { return canViewNotification(principal.userId, notification); },
515
607
  });
608
+ function canViewNotification(userId, notification) {
609
+ if (!users.isMultiUser()) return true;
610
+ if (!userId || !users.findUserById(userId)) return false;
611
+ if (notification.targetUserId && notification.targetUserId !== userId) return false;
612
+ if (notification.slug) {
613
+ if (!canUserAccessSlug(userId, notification.slug)) return false;
614
+ if (notification.sessionId) {
615
+ var project = projects.get(notification.slug);
616
+ var session = project && project.getSessionManager().sessions.get(notification.sessionId);
617
+ var status = project && project.getStatus();
618
+ var access = status && status.isMate ? { isMate: true, visibility: "private", ownerId: status.projectOwnerId } : onGetProjectAccess(notification.slug);
619
+ if (!session || !users.canAccessSession(userId, session, access)) return false;
620
+ }
621
+ return !notification.ownerId || notification.ownerId === userId || !!notification.sessionId;
622
+ }
623
+ return notification.targetUserId === userId || notification.ownerId === userId;
624
+ }
516
625
 
517
626
  // --- Security headers ---
518
627
  var securityHeaders = {
@@ -818,6 +927,7 @@ function createServer(opts) {
818
927
 
819
928
  if (linear.handleRequest(req, res, fullUrl)) return;
820
929
  if (speech.handleRequest(req, res, fullUrl)) return;
930
+ if (githubStars.handleRequest(req, res, fullUrl)) return;
821
931
  if (networkSettings.handleRequest(req, res, fullUrl)) return;
822
932
  if (storageSettings.handleRequest(req, res, fullUrl)) return;
823
933
  if (settings.handleRequest(req, res, fullUrl)) return;
@@ -910,15 +1020,7 @@ function createServer(opts) {
910
1020
  });
911
1021
  }
912
1022
  if (targetSlug) {
913
- try {
914
- var homeHtml = fs.readFileSync(path.join(publicDir, "index.html"), "utf8");
915
- homeHtml = injectRootProjectSlug(homeHtml, targetSlug);
916
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-cache" });
917
- res.end(homeHtml);
918
- } catch (e) {
919
- res.writeHead(500, { "Content-Type": "text/plain" });
920
- res.end("App shell missing.");
921
- }
1023
+ sendAppShell(req, res, targetSlug);
922
1024
  return;
923
1025
  }
924
1026
  }
@@ -936,9 +1038,7 @@ function createServer(opts) {
936
1038
  return;
937
1039
  }
938
1040
  }
939
- if (serveStatic("/index.html", res)) return;
940
- res.writeHead(500, { "Content-Type": "text/plain" });
941
- res.end("App shell missing.");
1041
+ sendAppShell(req, res, null);
942
1042
  return;
943
1043
  }
944
1044
 
@@ -955,8 +1055,8 @@ function createServer(opts) {
955
1055
  var projectList = [];
956
1056
  var infoUser = users.isMultiUser() ? getMultiUserFromReq(req) : null;
957
1057
  projects.forEach(function (ctx, slug) {
958
- if (users.isMultiUser() && (!infoUser || !canUserAccessSlug(infoUser.id, slug))) return;
959
- projectList.push({ slug: slug, project: ctx.project });
1058
+ if (users.isMultiUser() && (!infoUser || (!canUserAccessSlug(infoUser.id, slug) && !administrativeMetadata(infoUser.id, slug)))) return;
1059
+ projectList.push({ slug: slug, project: ctx.project, contentAccess: !users.isMultiUser() || canUserAccessSlug(infoUser.id, slug) });
960
1060
  });
961
1061
  res.writeHead(200, { "Content-Type": "application/json" });
962
1062
  res.end(JSON.stringify({ projects: projectList, version: currentVersion, authenticated: true }));
@@ -965,6 +1065,10 @@ function createServer(opts) {
965
1065
 
966
1066
  // Static files (favicon, manifest, icons, sw.js, mate avatars, etc.)
967
1067
  if (!fullUrl.includes("..") && !fullUrl.startsWith("/p/") && !fullUrl.startsWith("/api/")) {
1068
+ if (fullUrl === "/index.html") {
1069
+ sendAppShell(req, res, null);
1070
+ return;
1071
+ }
968
1072
  if (serveStatic(fullUrl, res)) return;
969
1073
  }
970
1074
 
@@ -1028,8 +1132,14 @@ function createServer(opts) {
1028
1132
  if (users.isMultiUser() && !isMcpBridgeAuthenticated) {
1029
1133
  var httpUser = getMultiUserFromReq(req);
1030
1134
  if (!httpUser || !canUserAccessSlug(httpUser.id, slug)) {
1031
- res.writeHead(302, { "Location": "/" });
1032
- res.end();
1135
+ var overview = httpUser && administrativeMetadata(httpUser.id, slug);
1136
+ if (overview && req.method === "GET" && (projectUrlForAuth === "/" || projectUrlForAuth === "/index.html")) {
1137
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
1138
+ res.end(projectAdminOverview.page(overview, getVisibleProjects(httpUser.id)));
1139
+ return;
1140
+ }
1141
+ res.writeHead(403, { "Content-Type": "application/json", "Cache-Control": "no-store" });
1142
+ res.end(JSON.stringify({ error: "Project content access is not permitted" }));
1033
1143
  return;
1034
1144
  }
1035
1145
  }
@@ -1054,6 +1164,10 @@ function createServer(opts) {
1054
1164
 
1055
1165
  // Static files (same assets for all projects)
1056
1166
  if (req.method === "GET") {
1167
+ if (projectUrl === "/" || projectUrl === "/index.html") {
1168
+ sendAppShell(req, res, slug);
1169
+ return;
1170
+ }
1057
1171
  if (serveStatic(projectUrl, res)) return;
1058
1172
  }
1059
1173
 
@@ -1134,6 +1248,7 @@ function createServer(opts) {
1134
1248
  var globalWs = serverGlobalWs.attachGlobalWs({
1135
1249
  osUsers: osUsers,
1136
1250
  usersModule: users,
1251
+ canUsePath: canUsePath,
1137
1252
  onAddProject: onAddProject,
1138
1253
  onCreateProject: onCreateProject,
1139
1254
  onCloneProject: onCloneProject,
@@ -1185,6 +1300,7 @@ function createServer(opts) {
1185
1300
  if (!require('./account-auth-socket').guardSocket(ws, req, isRequestAuthed, auth.touchSession)) return;
1186
1301
  ws._clayPane = wsRequest.pane;
1187
1302
  ws._clayPaneSession = wsRequest.paneSession;
1303
+ ws._clayContextual = wsRequest.contextual;
1188
1304
  globalWs.handleConnection(ws, globalUser);
1189
1305
  });
1190
1306
  return;
@@ -1230,6 +1346,7 @@ function createServer(opts) {
1230
1346
  ws._clayUser = wsUser; // attach user context
1231
1347
  ws._clayPane = wsRequest.pane;
1232
1348
  ws._clayPaneSession = wsRequest.paneSession;
1349
+ ws._clayContextual = wsRequest.contextual;
1233
1350
  var remoteAddr = req.socket.remoteAddress || "";
1234
1351
  ws._clayLocal = (remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1");
1235
1352
  // Clear cross-project unread for this project when client connects
@@ -1274,17 +1391,10 @@ function createServer(opts) {
1274
1391
  if (processingUpdateTimer) clearTimeout(processingUpdateTimer);
1275
1392
  processingUpdateTimer = setTimeout(function () {
1276
1393
  processingUpdateTimer = null;
1277
- var allProjectsList = getProjects();
1278
1394
  // Always send per-client to include cross-project unread counts
1279
1395
  projects.forEach(function (ctx, projSlug) {
1280
1396
  ctx.forEachClient(function (ws) {
1281
- var filtered = allProjectsList;
1282
- if (users.isMultiUser() && onGetProjectAccess) {
1283
- var wsUser = ws._clayUser;
1284
- filtered = wsUser ? allProjectsList.filter(function (p) {
1285
- return canUserAccessSlug(wsUser.id, p.slug);
1286
- }) : [];
1287
- }
1397
+ var filtered = getVisibleProjects(ws._clayUser ? ws._clayUser.id : null);
1288
1398
  // Attach per-project unread counts for this client
1289
1399
  var unreadMap = getCrossProjectUnread(ws);
1290
1400
  var projectsWithUnread = filtered.map(function (p) {
@@ -1334,6 +1444,10 @@ function createServer(opts) {
1334
1444
  function addProject(cwd, slug, title, icon, projectOwnerId, worktreeMeta, extraOpts) {
1335
1445
  if (projects.has(slug)) return false;
1336
1446
  var extra = extraOpts || {};
1447
+ if (extra.isMate) {
1448
+ var registeredMate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
1449
+ if (registeredMate && registeredMate.lifecycleDeletion) return false;
1450
+ }
1337
1451
  var ctx = createProjectContext({
1338
1452
  cwd: cwd,
1339
1453
  slug: slug,
@@ -1353,6 +1467,9 @@ function createServer(opts) {
1353
1467
  return mateHandler.createReadyMateFromInterview(ws, userId, definition);
1354
1468
  },
1355
1469
  workspaceQueryService: workspaceQueryService,
1470
+ clayProductControl: clayProductControl,
1471
+ mateContextService: mateContextService,
1472
+ resumeLifecycleProject: function (userId) { return opts.projectLifecycle ? opts.projectLifecycle.resumeRecovered(slug, userId) : true; },
1356
1473
  projectLogsService: projectLogsService,
1357
1474
  issuesService: issuesService,
1358
1475
  linearStorage: linear.storage,
@@ -1374,13 +1491,19 @@ function createServer(opts) {
1374
1491
  return !!(access && !access.error && users.canAccessProject(userId, access));
1375
1492
  },
1376
1493
  getProjectAccess: function () {
1377
- if (extra.isMate) return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [] };
1494
+ if (extra.isMate) {
1495
+ var mate = mates.getMate(mates.buildMateCtx(users.isMultiUser() ? projectOwnerId : null), extra.mateId || path.basename(cwd));
1496
+ return { isMate: true, visibility: "private", ownerId: projectOwnerId || null, allowedUsers: [], lifecycleExecutionPaused: !mate || !!mate.lifecycleDeletion };
1497
+ }
1378
1498
  return onGetProjectAccess ? onGetProjectAccess(slug) : { visibility: "public", ownerId: projectOwnerId || null };
1379
1499
  },
1380
1500
  shouldSuppressResponseNotification: function (session) {
1381
1501
  return shouldSuppressHomeResponse(projects, slug, session);
1382
1502
  },
1383
- pushModule: pushModule,
1503
+ pushModule: require("./project-push-access").scopedPush(pushModule, {
1504
+ slug: slug, users: users, getProject: function (target) { return projects.get(target); },
1505
+ canAccessProject: canUserAccessSlug, getAccess: onGetProjectAccess,
1506
+ }),
1384
1507
  debug: debug,
1385
1508
  dangerouslySkipPermissions: dangerouslySkipPermissions,
1386
1509
  osUsers: osUsers,
@@ -1412,6 +1535,7 @@ function createServer(opts) {
1412
1535
  var status = ctx.getStatus();
1413
1536
  var recs = ctx.getSchedules();
1414
1537
  for (var i = 0; i < recs.length; i++) {
1538
+ if (users.isMultiUser() && recs[i].ownerId !== userId) continue;
1415
1539
  // Shallow-copy full record and augment with project metadata
1416
1540
  var copy = {};
1417
1541
  var keys = Object.keys(recs[i]);
@@ -1469,6 +1593,8 @@ function createServer(opts) {
1469
1593
  return ctx.getSchedules().length;
1470
1594
  },
1471
1595
  canAccessProjectSlug: canUserAccessSlug,
1596
+ onGetProjectAccess: onGetProjectAccess,
1597
+ canUsePath: canUsePath,
1472
1598
  onPresenceChange: broadcastPresenceChange,
1473
1599
  onProcessingChanged: broadcastProcessingChange,
1474
1600
  onSessionDone: function () { onSessionDone(slug); },
@@ -1622,6 +1748,8 @@ function createServer(opts) {
1622
1748
  }
1623
1749
 
1624
1750
  function handleDmMessage(ws, msg, routedProjectSlug) {
1751
+ if (ownerUiService.handleMessage(ws, msg)) return true;
1752
+ if (mateContextService.handleMessage(ws, msg)) return true;
1625
1753
  if (cursorSharingService && cursorSharingService.handleMessage(ws, msg)) return true;
1626
1754
  if (defaultVendorService && defaultVendorService.handleMessage(ws, msg, routedProjectSlug)) return true;
1627
1755
  if (contextViewService && contextViewService.handleMessage(ws, msg)) return true;
@@ -1630,25 +1758,14 @@ function createServer(opts) {
1630
1758
  if (dmHandler.handleMessage(ws, msg)) return true;
1631
1759
  if (mateHandler && mateHandler.handleMessage(ws, msg)) return true;
1632
1760
  if (emailHandler.handleMessage(ws, msg)) return true;
1633
- if (homeChatHandler.handleMessage(ws, msg)) return true;
1761
+ if (homeChatHandler.handleMessage(ws, msg, routedProjectSlug)) return true;
1634
1762
  if (homePreferencesHandler.handleMessage(ws, msg)) return true;
1635
1763
  if (toolsHandler.handleMessage(ws, msg)) return true;
1636
1764
  return false;
1637
1765
  }
1638
1766
 
1639
- function removeProject(slug) {
1640
- var ctx = projects.get(slug);
1641
- if (!ctx) return false;
1642
- var wasMate = ctx.getStatus().isMate;
1643
- var shutdownResult = ctx.destroy();
1644
- projects.delete(slug);
1645
- if (shutdownResult && typeof shutdownResult.catch === "function") {
1646
- shutdownResult.catch(function(err) {
1647
- console.error("[server] Project destroy failed for " + slug + ":", err && err.message ? err.message : err);
1648
- });
1649
- }
1650
- if (!wasMate) scheduleRegistryRefresh();
1651
- return true;
1767
+ function removeProject(slug, awaitCompletion) {
1768
+ return require('./server-project-removal').removeProjectRuntime(projects, slug, awaitCompletion, scheduleRegistryRefresh);
1652
1769
  }
1653
1770
 
1654
1771
  // Now that addProject and removeProject are defined, initialize mateHandler
@@ -1734,7 +1851,11 @@ function createServer(opts) {
1734
1851
  function getVisibleProjects(userId) {
1735
1852
  var visible = [];
1736
1853
  projects.forEach(function (ctx, slug) {
1737
- if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) return;
1854
+ if (users.isMultiUser() && (!userId || !canUserAccessSlug(userId, slug))) {
1855
+ var metadata = administrativeMetadata(userId, slug);
1856
+ if (metadata) visible.push(metadata);
1857
+ return;
1858
+ }
1738
1859
  var status = ctx.getStatus();
1739
1860
  if (!status.isMate && onGetProjectAccess) {
1740
1861
  var access = onGetProjectAccess(slug);
@@ -1933,6 +2054,7 @@ function createServer(opts) {
1933
2054
  speech.destroy();
1934
2055
  var shutdowns = [];
1935
2056
  shutdowns.push(durableSchedulerLifecycle.shutdown());
2057
+ shutdowns.push(lifecycleRuntime.shutdown());
1936
2058
  projects.forEach(function (ctx, slug) {
1937
2059
  console.log("[server] Destroying project:", slug);
1938
2060
  var result = ctx.destroy();
@@ -2000,6 +2122,8 @@ function createServer(opts) {
2000
2122
  isTLS: !!tlsOptions,
2001
2123
  addProject: addProject,
2002
2124
  removeProject: removeProject,
2125
+ getProjectLifecycleTargets: lifecycleRuntime.targets,
2126
+ closeProjectLifecycle: lifecycleRuntime.close,
2003
2127
  getProjects: getProjects,
2004
2128
  reorderProjects: reorderProjects,
2005
2129
  setProjectTitle: setProjectTitle,
@@ -0,0 +1,45 @@
1
+ // Guarded configuration commit shared by SDK setters and permission transitions.
2
+ // Provider acknowledgement is distinct from local persistence. Once a request
3
+ // has crossed that boundary, failures never imply the provider was rolled back.
4
+ async function applySessionConfig(ctx) {
5
+ var session = ctx.session, sm = ctx.sm, handle = session.queryInstance;
6
+ var generation = Number(session._sdkQueryGeneration || 0), owner = session.ownerId;
7
+ var paused = !!session._pendingMessageDrainPaused, signal = session.abortController && session.abortController.signal;
8
+ var attempted = false, acknowledged = false, persisted = false, previous = {};
9
+ function current() {
10
+ ctx.revalidate();
11
+ if (sm.sessions.get(session.localId) !== session || session.ownerId !== owner || session.queryInstance !== handle ||
12
+ Number(session._sdkQueryGeneration || 0) !== generation || session.taskStopRequested ||
13
+ !!session._pendingMessageDrainPaused !== paused || signal && signal.aborted) throw new Error("Target ownership, runtime, or Stop state changed during the configuration request.");
14
+ }
15
+ try {
16
+ current();
17
+ if (handle) {
18
+ if (typeof handle[ctx.method] !== "function") throw new Error("This provider cannot apply this configuration to the active runtime.");
19
+ attempted = true;
20
+ var reply = await handle[ctx.method](ctx.nativeValue);
21
+ if (reply === false || reply && reply.ok === false) throw new Error(reply && reply.error || "The provider refused the configuration change.");
22
+ acknowledged = true;
23
+ current();
24
+ }
25
+ var changes = typeof ctx.changes === "function" ? ctx.changes() : ctx.changes;
26
+ Object.keys(changes).forEach(function (key) { previous[key] = { present: Object.prototype.hasOwnProperty.call(session, key), value: session[key] }; });
27
+ Object.assign(session, changes);
28
+ try {
29
+ if (sm.saveSessionFile(session) !== true) throw new Error("Could not persist the configuration change.");
30
+ persisted = true;
31
+ } catch (error) {
32
+ Object.keys(previous).forEach(function (key) { if (previous[key].present) session[key] = previous[key].value; else delete session[key]; });
33
+ throw error;
34
+ }
35
+ // There is no await between the last authorization check, disk commit and
36
+ // publication. Never broadcast a desired value before its save succeeds.
37
+ ctx.publish();
38
+ return Object.assign({ ok: true, status: "completed", persisted: true, runtimeEffect: acknowledged ? "applied" : "none" }, changes);
39
+ } catch (error) {
40
+ return { ok: false, status: "failed", outcome: persisted ? "partial" : attempted ? "uncertain" : "failed", persisted: persisted,
41
+ runtimeEffect: acknowledged ? "applied" : attempted ? "unknown" : "none", retrySafe: !attempted && !persisted,
42
+ error: (persisted ? "The configuration was saved, but publication did not complete. " : "") + (attempted ? "The provider may retain the requested change; no external rollback was attempted. " : "") + (error.message || String(error)) };
43
+ }
44
+ }
45
+ module.exports = { applySessionConfig: applySessionConfig };
@@ -9,7 +9,7 @@
9
9
  // also keeps its folder (or Unfiled) assignment
10
10
  // orders: { containerKey: [keys] } manual order per container ("unfiled", custom id, "all")
11
11
  // collapsed: { containerKey: true }
12
- // view: { group, sort, direction }
12
+ // view: { group, sort, direction, showDateHeadings }
13
13
  // sessionKey is the session's opaque, durable sessionOriginId.
14
14
 
15
15
  var crypto = require("crypto");
@@ -35,7 +35,7 @@ function defaultState() {
35
35
  favorites: [],
36
36
  orders: {},
37
37
  collapsed: {},
38
- view: { group: "folders", sort: "activity", direction: "desc" },
38
+ view: { group: "folders", sort: "activity", direction: "desc", showDateHeadings: true },
39
39
  legacyFavoritesMigrated: false,
40
40
  };
41
41
  }
@@ -147,6 +147,7 @@ function normalizeState(raw) {
147
147
  var view = isPlainObject(source.view) ? source.view : {};
148
148
  if (SORTS.indexOf(view.sort) !== -1) state.view.sort = view.sort;
149
149
  if (DIRECTIONS.indexOf(view.direction) !== -1) state.view.direction = view.direction;
150
+ if (typeof view.showDateHeadings === "boolean") state.view.showDateHeadings = view.showDateHeadings;
150
151
  state.legacyFavoritesMigrated = source.legacyFavoritesMigrated === true;
151
152
  return state;
152
153
  }
@@ -334,6 +335,10 @@ function applyRaw(input, op, env) {
334
335
  if (DIRECTIONS.indexOf(op.direction) === -1) return { error: "Invalid direction" };
335
336
  state.view.direction = op.direction;
336
337
  }
338
+ if (op.showDateHeadings !== undefined) {
339
+ if (typeof op.showDateHeadings !== "boolean") return { error: "Invalid date heading setting" };
340
+ state.view.showDateHeadings = op.showDateHeadings;
341
+ }
337
342
  return { state: state };
338
343
  }
339
344
 
@@ -0,0 +1,21 @@
1
+ // Product transcript slicing for providers that include a completed turn.
2
+ function endIndex(session, uuid, boundary) {
3
+ if (boundary === undefined) return undefined;
4
+ if (boundary !== "completed-turn-inclusive") throw new Error("Unsupported local fork history boundary");
5
+ var history = session.history || [];
6
+ var markers = (session.messageUUIDs || []).filter(function(marker) { return marker.uuid === uuid && marker.type === "user"; });
7
+ var marker = markers.length === 1 && markers[0];
8
+ var index = marker && marker.historyIndex;
9
+ var entry = Number.isInteger(index) && history[index];
10
+ if (!entry || entry.type !== "message_uuid" || entry.uuid !== uuid) throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
11
+ for (var i = index + 1; i < history.length; i++) {
12
+ entry = history[i];
13
+ if (entry.type === "user_message" || entry.type === "message_uuid" && entry.messageType === "user") break;
14
+ if (entry.type === "done") {
15
+ if (entry.code === 0) return i + 1;
16
+ break;
17
+ }
18
+ }
19
+ throw new Error("Cannot safely represent this completed-turn fork boundary in local history");
20
+ }
21
+ module.exports = { endIndex: endIndex };
@@ -33,22 +33,29 @@ function runGh(cwd, args, identity, input) {
33
33
  }
34
34
  async function readReference(cwd, url, identity, run, statusOnly) {
35
35
  var ref = parseReference(url);
36
- var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
36
+ var fields = "title,state,url" + (ref.kind === "pr" ? (statusOnly ? ",isDraft,reviewDecision,reviewRequests" : ",isDraft,headRefName,reviewDecision,statusCheckRollup") : "");
37
37
  var data = await (run || runGh)(cwd, [ref.kind === "pr" ? "pr" : "issue", "view", String(ref.number), "--repo", ref.repository, "--json", fields], identity);
38
38
  var verified = parseReference(data.url);
39
39
  if (verified.url.toLowerCase() !== ref.url.toLowerCase()) throw new Error("GitHub returned a different reference.");
40
40
  ref.title = String(data.title || "").slice(0, 200);
41
41
  ref.state = data.state === "MERGED" ? "merged" : data.state === "CLOSED" ? "closed" : data.state === "OPEN" ? (data.isDraft ? "draft" : "open") : "unknown";
42
42
  ref.checkedAt = Date.now();
43
+ if (ref.kind === "pr") {
44
+ ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
45
+ }
43
46
  if (ref.kind === "pr" && !statusOnly) {
44
47
  ref.branch = String(data.headRefName || "").slice(0, 200);
45
- ref.review = ["APPROVED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"].indexOf(data.reviewDecision) >= 0 ? data.reviewDecision : "";
46
48
  ref.checks = (data.statusCheckRollup || []).slice(0, 30).map(function (check) {
47
49
  var target = check.detailsUrl || check.targetUrl || "";
48
50
  if (!/^https:\/\//i.test(target)) target = "";
49
51
  return { name: String(check.name || check.context || "Check").slice(0, 100), state: String(check.conclusion || check.state || check.status || "PENDING").slice(0, 40), url: target };
50
52
  });
51
53
  }
54
+ if (ref.kind === "pr" && statusOnly) {
55
+ ref.reviewRequests = Array.isArray(data.reviewRequests) ? data.reviewRequests.slice(0, 30).map(function (request) {
56
+ return String(request.login || "").trim().toLowerCase().slice(0, 100);
57
+ }).filter(Boolean) : [];
58
+ }
52
59
  return ref;
53
60
  }
54
61
  module.exports = { parseReference: parseReference, readReference: readReference, runGh: runGh };
@@ -5,7 +5,7 @@
5
5
  var sessionProvenance = require("./session-provenance");
6
6
 
7
7
  var BLANK_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
8
- var CLAUDE_INTERRUPTED_TEXT = "[Request interrupted by user]";
8
+ var transcriptHygiene = require("./yoke/claude-transcript-hygiene");
9
9
 
10
10
  // A session is "blank" when nothing has ever happened in it and nothing is
11
11
  // attached to it. Adopted external sessions are never blank (their transcript
@@ -61,43 +61,11 @@ function collectStaleBlankSessions(sessions, activeSessionId, now) {
61
61
  return stale;
62
62
  }
63
63
 
64
- function extractClaudeUserText(event) {
65
- var content = event && event.message && event.message.content;
66
- if (typeof content === "string") return content;
67
- if (!Array.isArray(content)) return "";
68
- var parts = [];
69
- for (var i = 0; i < content.length; i++) {
70
- if (content[i] && content[i].type === "text" && typeof content[i].text === "string") {
71
- parts.push(content[i].text);
72
- }
73
- }
74
- return parts.join("");
75
- }
76
-
77
- // SDK capability probes create a real Claude transcript with a single "hi"
78
- // prompt. Newer Claude Code versions append an interruption record when Clay
79
- // aborts the probe, so that bookkeeping record must not make the transcript
80
- // look like a real two-turn conversation.
81
- function isClaudeWarmupTranscript(events) {
82
- var promptCount = 0;
83
- for (var i = 0; i < events.length; i++) {
84
- var event = events[i];
85
- if (!event || typeof event !== "object") continue;
86
- if (event.type === "assistant") return false;
87
- if (event.type !== "user" || !event.message || event.message.role !== "user") continue;
88
- var text = extractClaudeUserText(event);
89
- if (text === CLAUDE_INTERRUPTED_TEXT) continue;
90
- if (text !== "hi") return false;
91
- promptCount++;
92
- }
93
- return promptCount === 1;
94
- }
95
-
96
64
  module.exports = {
97
65
  isBlankSession: isBlankSession,
98
66
  findReusableBlankSession: findReusableBlankSession,
99
67
  collectStaleBlankSessions: collectStaleBlankSessions,
100
- extractClaudeUserText: extractClaudeUserText,
101
- isClaudeWarmupTranscript: isClaudeWarmupTranscript,
68
+ extractClaudeUserText: transcriptHygiene.extractClaudeUserText,
69
+ isClaudeWarmupTranscript: transcriptHygiene.isClaudeWarmupTranscript,
102
70
  BLANK_SESSION_MAX_AGE_MS: BLANK_SESSION_MAX_AGE_MS,
103
71
  };