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
@@ -279,7 +279,7 @@ function flattenUpdate(update, state) {
279
279
 
280
280
  // Token usage
281
281
  if (type === "usage_update") {
282
- if (typeof update.used === "number") state.lastInputTokens = update.used;
282
+ if (typeof update.used === "number") { state.lastInputTokens = update.used; state.contextMeasurement = "observed"; }
283
283
  if (typeof update.size === "number") state.contextWindow = update.size;
284
284
  return events;
285
285
  }
@@ -294,6 +294,7 @@ function flattenUpdate(update, state) {
294
294
  if (typeof percentage !== "number") percentage = kiroMeta.usagePercentage;
295
295
  if (typeof percentage === "number" && state.contextWindow) {
296
296
  state.lastInputTokens = Math.round(state.contextWindow * percentage / 100);
297
+ state.contextMeasurement = "estimated";
297
298
  }
298
299
  }
299
300
  return events;
@@ -782,6 +783,7 @@ function createKiroQueryHandle(acp, queryOpts) {
782
783
  getContextUsage: function() {
783
784
  return Promise.resolve(state.lastInputTokens != null ? {
784
785
  input_tokens: state.lastInputTokens,
786
+ measurement: state.contextMeasurement || "observed",
785
787
  contextWindow: state.contextWindow || null,
786
788
  } : null);
787
789
  },
@@ -0,0 +1,7 @@
1
+ // Muse's sessionMcp configuration is supplied on both start and resume.
2
+ module.exports = {
3
+ toolTransport: "stdio-mcp",
4
+ catalogLifetime: "query",
5
+ permissionModes: ["auto"],
6
+ interruptionMessage: "Interrupted · What should Muse do instead?",
7
+ };
@@ -0,0 +1,122 @@
1
+ var museQuery = require("../muse-query");
2
+ var runtimeTools = require("../muse-runtime");
3
+ var findMusePath = require("../providers/muse-executable").resolve;
4
+
5
+ function createMuseAdapter(opts) {
6
+ opts = opts || {};
7
+ var adapter = {
8
+ vendor: "muse",
9
+ userInputCapability: { mode: "native", native: true },
10
+ providerContract: require("../vendor-registry").getVendorInfo("muse"),
11
+ queryContract: require("./muse-query-contract"),
12
+ cwd: opts.cwd || process.cwd(),
13
+ binaryPath: opts._binaryPath || null,
14
+ sdkPromise: null,
15
+ catalog: [],
16
+ clients: new Set(),
17
+ handles: new Set(),
18
+ shuttingDown: false,
19
+ requestTimeoutMs: opts._requestTimeoutMs || 9e4,
20
+ titleTimeoutMs: opts._titleTimeoutMs || 15e3,
21
+ shutdownTimeoutMs: opts._shutdownTimeoutMs == null ? 1e3 : opts._shutdownTimeoutMs
22
+ };
23
+ adapter.loadSdk = function() {
24
+ if (opts._sdk) return Promise.resolve(opts._sdk);
25
+ if (!adapter.sdkPromise) adapter.sdkPromise = import("@muse-code/sdk");
26
+ return adapter.sdkPromise;
27
+ };
28
+ adapter.init = async function(initOpts) {
29
+ if (opts.osUsers || opts.linuxUser || initOpts && (initOpts.linuxUser || initOpts.osUsers)) throw new Error("Muse Code does not support OS-owner isolation");
30
+ if (!adapter.binaryPath) adapter.binaryPath = findMusePath();
31
+ if (!adapter.binaryPath) throw new Error("Muse Code binary not found: muse. Install Muse Code or set MUSE_CODE_PATH.");
32
+ await adapter.loadSdk();
33
+ return {
34
+ models: [],
35
+ defaultModel: null,
36
+ skills: [],
37
+ slashCommands: [],
38
+ fastModeState: null,
39
+ capabilities: {
40
+ effort: true,
41
+ midSessionModelSwitch: true,
42
+ fork: true,
43
+ rollback: false,
44
+ sessionListing: true,
45
+ sessionRename: true,
46
+ thinking: true,
47
+ betas: false,
48
+ rewind: false,
49
+ sessionResume: true,
50
+ promptSuggestions: false,
51
+ elicitation: false,
52
+ fileCheckpointing: false,
53
+ contextCompacting: true,
54
+ queryBoundTools: {
55
+ mode: "stdio-mcp",
56
+ source: "@muse-code/sdk SessionConfig.mcpServers"
57
+ },
58
+ skillSharing: true,
59
+ toolPolicy: [ "ask", "allow-all" ]
60
+ }
61
+ };
62
+ };
63
+ adapter.supportedModels = async function() {
64
+ if (adapter.shuttingDown) throw new Error("Muse Code adapter is shutting down");
65
+ if (!adapter.binaryPath) await adapter.init();
66
+ var sdk = await adapter.loadSdk();
67
+ if (adapter.shuttingDown) throw new Error("Muse Code adapter is shutting down");
68
+ var runtime = runtimeTools.createRuntime(adapter, sdk, {
69
+ command: adapter.binaryPath,
70
+ args: [ "serve" ],
71
+ cwd: adapter.cwd,
72
+ env: Object.assign({}, process.env)
73
+ });
74
+ runtime.fail = function(error) {
75
+ runtime.close().catch(function(closeError) {
76
+ adapter.lastCloseError = closeError;
77
+ });
78
+ };
79
+ try {
80
+ var spawned = await runtime.initialize();
81
+ adapter.catalog = runtimeTools.normalizeCatalog(await runtime.waitRequest(spawned.connection.request("model/list", {})));
82
+ return adapter.catalog.slice();
83
+ } finally {
84
+ await runtime.close();
85
+ }
86
+ };
87
+ adapter.createToolServer = function() {
88
+ return null;
89
+ };
90
+ adapter.createQuery = async function(queryOpts) {
91
+ if (opts.osUsers || opts.linuxUser || queryOpts && queryOpts.linuxUser) throw new Error("Muse Code does not support OS-owner isolation");
92
+ if (!adapter.binaryPath) await adapter.init(queryOpts || {});
93
+ if (adapter.shuttingDown) throw new Error("Muse Code adapter is shutting down");
94
+ return museQuery.createMuseQueryHandle(adapter, queryOpts || {});
95
+ };
96
+ adapter.generateTitle = function(messages, titleOpts) {
97
+ return require("../title-query").generateTitle(adapter, messages, Object.assign({}, titleOpts, { timeoutMs: adapter.titleTimeoutMs }),
98
+ { skipProjectInstructions: true, skipSkills: true, adapterOptions: { MUSE: { readOnly: true, mcpServers: [] } } });
99
+ };
100
+ adapter.shutdown = async function() {
101
+ adapter.shuttingDown = true;
102
+ var results = await Promise.allSettled(Array.from(adapter.handles).map(function(handle) {
103
+ return handle.close();
104
+ }).concat(Array.from(adapter.clients).map(function(runtime) {
105
+ return runtime.close();
106
+ })));
107
+ var failed = results.find(function(result) {
108
+ return result.status === "rejected";
109
+ });
110
+ if (failed) throw failed.reason;
111
+ return true;
112
+ };
113
+ require("../muse-services").attach(adapter);
114
+ return adapter;
115
+ }
116
+
117
+ module.exports = {
118
+ createMuseAdapter: createMuseAdapter,
119
+ findMusePath: findMusePath,
120
+ isAuthError: runtimeTools.isAuthError,
121
+ chooseApprovalDecision: require("../muse-policy").chooseApprovalDecision
122
+ };
@@ -0,0 +1,17 @@
1
+ function loginPrompt(event, preview, provider) {
2
+ if (event.cost && event.cost !== 0 || String(preview || '').length >= 100) return false;
3
+ var text = String(preview || '').trim();
4
+ if (/not logged in/i.test(text) && /\/login/i.test(text)) return true;
5
+ var policy = require('./provider-contract').resolve(provider);
6
+ return typeof policy.authenticationReply === 'function' && policy.authenticationReply(text);
7
+ }
8
+ function authenticationReply(text) { return /^Failed to authenticate: OAuth session expired and could not be refreshed\.?$/i.test(text); }
9
+ function isAuthenticationError(detail) {
10
+ var text = String(detail || '').toLowerCase();
11
+ return /not logged in|unauthenticated|authentication|sign in|log in|please login/.test(text);
12
+ }
13
+ function normalize(event, preview, provider) {
14
+ if (!event || event.yokeType !== "result") return event;
15
+ return Object.assign({}, event, { authenticationRequired: event.authenticationRequired === true || loginPrompt(event, preview, provider) });
16
+ }
17
+ module.exports = { normalize: normalize, loginPrompt: loginPrompt, authenticationReply: authenticationReply, isAuthenticationError: isAuthenticationError };
@@ -0,0 +1,272 @@
1
+ // claude-hook-installer.js
2
+ //
3
+ // Registers Clay's notification webhook in `~/.claude/settings.json` so the
4
+ // `claude` CLI fires a request to the Clay daemon whenever it surfaces a
5
+ // Notification (permission requests, idle prompts, etc.). This is what makes
6
+ // TUI sessions feel like first-class Clay sessions: the user gets the same
7
+ // toasts and push notifications they would in GUI mode.
8
+ //
9
+ // Design notes:
10
+ // - Settings merge is idempotent: existing hooks are preserved, ours are
11
+ // identified by a marker substring so re-runs don't duplicate them.
12
+ // - The hook command uses curl with --max-time / --connect-timeout so that
13
+ // a downed daemon can't stall claude's UI for more than ~1s.
14
+ // - Multi-user mode: caller passes one home directory per OS user; we
15
+ // write each user's own settings.json so per-user filtering works.
16
+
17
+ var fs = require("fs");
18
+ var path = require("path");
19
+ var { buildClayBashAllowPatterns, isClayManagedBashPattern } = require("../safe-bash-commands");
20
+
21
+ // Substring that uniquely identifies a Clay-installed hook entry so we can
22
+ // safely remove/replace it without touching user-authored hooks.
23
+ var CLAY_HOOK_MARKER = "clay:tui-notify";
24
+
25
+ // Allow-patterns Clay manages in ~/.claude/settings.json `permissions.allow`.
26
+ // The Bash(...) patterns are GENERATED from safe-bash-commands.js so this
27
+ // list and sdk-bridge.js `checkToolWhitelist` can never drift - there is one
28
+ // source of truth for which bash commands Clay auto-approves.
29
+ //
30
+ // Pattern syntax note: claude 2.x uses the space-wildcard form `Bash(cmd *)`
31
+ // for prefix matching. The older colon form `Bash(cmd:*)` is flagged as
32
+ // legacy in the CLI and no longer reliably matches argument-bearing commands
33
+ // (the TUI kept prompting for read-only invocations like `ls -la`). The
34
+ // generator emits the modern form plus a bare `Bash(cmd)` for zero-arg use.
35
+ //
36
+ // User-authored entries are preserved -- on re-install we only strip patterns
37
+ // that are Clay-managed (current generated list or the legacy colon shape).
38
+ var CLAY_MANAGED_ALLOW = [
39
+ // Read-only built-in tools (no side effects).
40
+ "Read", "Glob", "Grep", "WebFetch", "WebSearch",
41
+
42
+ // Clay's own MCP servers. Strictly read/safe by design.
43
+ "mcp__clay-browser__browser_watch_tab",
44
+ "mcp__clay-browser__browser_unwatch_tab",
45
+ "mcp__clay-debate__propose_debate",
46
+ "mcp__clay-mate-creation__propose_mate",
47
+ "mcp__clay-history__*",
48
+ "mcp__clay-workspace__read_current_context",
49
+ "mcp__clay-workspace__read_selected_context",
50
+ "mcp__clay-workspace__open_context_conversation",
51
+ "mcp__clay-workspace__read_context_navigation_receipt",
52
+ "mcp__clay-workspace__read_owner_screen",
53
+ "mcp__clay-workspace__inspect_owner_screen_change",
54
+ "mcp__clay-workspace__control_owner_screen",
55
+ "mcp__clay-workspace__inspect_project_control",
56
+ "mcp__clay-workspace__control_project_lifecycle",
57
+ "mcp__clay-workspace__discover_product_controls",
58
+ "mcp__clay-workspace__list_owned_mates",
59
+ "mcp__clay-workspace__begin_schedule_control_interview",
60
+ "mcp__clay-workspace__read_schedule_controls",
61
+ "mcp__clay-workspace__inspect_schedule_change",
62
+ "mcp__clay-workspace__control_schedules",
63
+ "mcp__clay-workspace__read_mate_chat_control",
64
+ "mcp__clay-workspace__inspect_mate_chat_change",
65
+ "mcp__clay-workspace__control_mate_chat",
66
+ "mcp__clay-workspace__read_project_workspace",
67
+ "mcp__clay-workspace__read_workspace_receipt",
68
+ "mcp__clay-workspace__inspect_workspace_change",
69
+ "mcp__clay-workspace__control_project_workspace",
70
+ "mcp__clay-workspace__read_vendor_usage",
71
+ "mcp__clay-workspace__read_project_records",
72
+ "mcp__clay-workspace__inspect_project_record_change",
73
+ "mcp__clay-workspace__control_project_records",
74
+ "mcp__clay-workspace__read_mate_knowledge_control",
75
+ "mcp__clay-workspace__inspect_mate_knowledge_change",
76
+ "mcp__clay-workspace__control_mate_knowledge",
77
+ "mcp__clay-workspace__inspect_mate_control",
78
+ "mcp__clay-workspace__control_mate_lifecycle",
79
+ "mcp__clay-workspace__inspect_session_control",
80
+ "mcp__clay-workspace__control_project_session",
81
+ "mcp__clay-workspace__list_projects",
82
+ "mcp__clay-workspace__list_project_sessions",
83
+ "mcp__clay-workspace__search_project_history",
84
+ "mcp__clay-workspace__read_project_session",
85
+ "mcp__clay-workspace__search_workspace_history",
86
+ "mcp__clay-workspace__list_workspace_activity",
87
+ "mcp__clay-workspace__propose_project_assignment",
88
+ "mcp__clay-workspace__propose_project_follow_up",
89
+ "mcp__clay-workspace__get_assignment_status",
90
+ "mcp__clay-tools__clay_tool_list",
91
+ "mcp__clay-tools__clay_tool_snapshot",
92
+ "mcp__clay-tools__clay_tool_act",
93
+ "mcp__clay-tools__clay_tool_set",
94
+ "mcp__clay-tools__clay_tool_source",
95
+ // Email: read-side only. Send / reply / mark_read still prompt.
96
+ "mcp__clay-email__clay_read_email",
97
+ "mcp__clay-email__clay_read_email_body",
98
+ "mcp__clay-email__clay_search_email",
99
+ "mcp__clay-email__clay_list_labels",
100
+ ].concat(buildClayBashAllowPatterns());
101
+
102
+ function buildHookCommand(notifyUrl) {
103
+ // Read stdin once (the JSON Claude Code pipes in), then post it. --max-time
104
+ // and --connect-timeout cap total hook latency around ~1s even if the
105
+ // daemon is down. --insecure (-k) is needed because Clay's optional TLS
106
+ // mode uses a locally generated CA that curl won't trust by default;
107
+ // safe to skip verification since we're going to 127.0.0.1. Output is
108
+ // silenced so it doesn't leak into the TUI. The marker comment keeps the
109
+ // entry recognizable when we re-merge.
110
+ var insecure = notifyUrl.indexOf("https://") === 0 ? " --insecure" : "";
111
+ return "curl --silent --show-error --max-time 1 --connect-timeout 1" + insecure +
112
+ " -X POST -H 'Content-Type: application/json' --data-binary @- " +
113
+ JSON.stringify(notifyUrl) + " > /dev/null 2>&1 # " + CLAY_HOOK_MARKER;
114
+ }
115
+
116
+ function readSettings(settingsPath) {
117
+ try {
118
+ var raw = fs.readFileSync(settingsPath, "utf8");
119
+ return JSON.parse(raw);
120
+ } catch (e) {
121
+ return {};
122
+ }
123
+ }
124
+
125
+ function writeSettings(settingsPath, data) {
126
+ var dir = path.dirname(settingsPath);
127
+ try { fs.mkdirSync(dir, { recursive: true }); } catch (e) {}
128
+ fs.writeFileSync(settingsPath, JSON.stringify(data, null, 2) + "\n");
129
+ }
130
+
131
+ // Merge our Notification hook into the user's settings.json without
132
+ // clobbering anything else. Returns true if the file changed.
133
+ function mergeHook(settingsPath, command) {
134
+ var data = readSettings(settingsPath);
135
+ if (!data.hooks || typeof data.hooks !== "object") data.hooks = {};
136
+ if (!Array.isArray(data.hooks.Notification)) data.hooks.Notification = [];
137
+
138
+ // Strip any prior Clay entries before inserting the fresh one so port /
139
+ // URL changes propagate cleanly.
140
+ var before = JSON.stringify(data.hooks.Notification);
141
+ var cleaned = [];
142
+ for (var i = 0; i < data.hooks.Notification.length; i++) {
143
+ var group = data.hooks.Notification[i];
144
+ if (!group || !Array.isArray(group.hooks)) { cleaned.push(group); continue; }
145
+ var filtered = group.hooks.filter(function (h) {
146
+ return !(h && typeof h.command === "string" && h.command.indexOf(CLAY_HOOK_MARKER) !== -1);
147
+ });
148
+ if (filtered.length > 0) cleaned.push({ matcher: group.matcher || "", hooks: filtered });
149
+ else if (group.matcher) cleaned.push(group);
150
+ }
151
+ data.hooks.Notification = cleaned;
152
+
153
+ data.hooks.Notification.push({
154
+ matcher: "",
155
+ hooks: [{ type: "command", command: command }],
156
+ });
157
+
158
+ var after = JSON.stringify(data.hooks.Notification);
159
+ if (before === after) return false;
160
+ writeSettings(settingsPath, data);
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Install (or refresh) the Notification hook in one or more user home dirs.
166
+ *
167
+ * opts:
168
+ * notifyUrl -- full URL Clay listens on, e.g. "http://127.0.0.1:2633/api/tui-notify".
169
+ * homeDirs -- array of absolute paths to user home directories. Each one
170
+ * gets its own settings.json updated. Defaults to [os.homedir()].
171
+ *
172
+ * Returns { installed: [paths], errors: [{path, error}] } so the caller can log.
173
+ */
174
+ function installNotificationHook(opts) {
175
+ opts = opts || {};
176
+ var os = require("os");
177
+ var homes = opts.homeDirs && opts.homeDirs.length ? opts.homeDirs : [os.homedir()];
178
+ var notifyUrl = opts.notifyUrl;
179
+ if (!notifyUrl) throw new Error("installNotificationHook: notifyUrl is required");
180
+
181
+ var command = buildHookCommand(notifyUrl);
182
+ var installed = [];
183
+ var errors = [];
184
+ for (var i = 0; i < homes.length; i++) {
185
+ var home = homes[i];
186
+ if (!home) continue;
187
+ var settingsPath = path.join(home, ".claude", "settings.json");
188
+ try {
189
+ var changed = mergeHook(settingsPath, command);
190
+ if (changed) installed.push(settingsPath);
191
+ } catch (e) {
192
+ errors.push({ path: settingsPath, error: e && e.message ? e.message : String(e) });
193
+ }
194
+ }
195
+ return { installed: installed, errors: errors };
196
+ }
197
+
198
+ // Old colon-prefix Bash patterns Clay wrote before claude 2.x: Bash(ls:*),
199
+ // Bash(git status:*), etc. Stripped on upgrade so they don't linger next to
200
+ // the modern space-wildcard form. Modern Clay patterns never contain ":)" so
201
+ // this only catches the deprecated shape; it can't tell a user-authored colon
202
+ // pattern apart, but claude is phasing the colon form out anyway.
203
+ function isLegacyClayPattern(p) {
204
+ if (typeof p !== "string") return false;
205
+ if (p.indexOf("Bash(") === 0 && p.indexOf(":*)") !== -1) return true;
206
+ return false;
207
+ }
208
+
209
+ // Merge Clay's managed allow-list into permissions.allow without disturbing
210
+ // the user's own entries. "Ours" = exact membership in CLAY_MANAGED_ALLOW
211
+ // (the non-Bash built-in / MCP entries) OR isClayManagedBashPattern (any
212
+ // shape of a bash command we own, so stale variants from older versions get
213
+ // swept) OR the legacy colon shape. Everything else is preserved, then the
214
+ // fresh list is appended. Because the Bash patterns are generated from
215
+ // safe-bash-commands.js, a re-install always writes the current set and can
216
+ // never leave a stale Clay block behind.
217
+ function mergeAllowList(settingsPath, patterns) {
218
+ var data = readSettings(settingsPath);
219
+ if (!data.permissions || typeof data.permissions !== "object") data.permissions = {};
220
+ var allow = Array.isArray(data.permissions.allow) ? data.permissions.allow : [];
221
+
222
+ var managedSet = {};
223
+ for (var i = 0; i < CLAY_MANAGED_ALLOW.length; i++) managedSet[CLAY_MANAGED_ALLOW[i]] = true;
224
+
225
+ var preserved = allow.filter(function (p) {
226
+ if (managedSet[p]) return false;
227
+ if (isClayManagedBashPattern(p)) return false;
228
+ if (isLegacyClayPattern(p)) return false;
229
+ return true;
230
+ });
231
+ var next = preserved.concat(patterns);
232
+
233
+ var before = JSON.stringify(allow);
234
+ var after = JSON.stringify(next);
235
+ if (before === after) return false;
236
+
237
+ data.permissions.allow = next;
238
+ writeSettings(settingsPath, data);
239
+ return true;
240
+ }
241
+
242
+ /**
243
+ * Install (or refresh) Clay's auto-approve patterns into permissions.allow
244
+ * for one or more user home dirs. Mirrors installNotificationHook's API.
245
+ */
246
+ function installAllowList(opts) {
247
+ opts = opts || {};
248
+ var os = require("os");
249
+ var homes = opts.homeDirs && opts.homeDirs.length ? opts.homeDirs : [os.homedir()];
250
+ var patterns = (opts.patterns && opts.patterns.length) ? opts.patterns : CLAY_MANAGED_ALLOW;
251
+ var installed = [];
252
+ var errors = [];
253
+ for (var i = 0; i < homes.length; i++) {
254
+ var home = homes[i];
255
+ if (!home) continue;
256
+ var settingsPath = path.join(home, ".claude", "settings.json");
257
+ try {
258
+ var changed = mergeAllowList(settingsPath, patterns);
259
+ if (changed) installed.push(settingsPath);
260
+ } catch (e) {
261
+ errors.push({ path: settingsPath, error: e && e.message ? e.message : String(e) });
262
+ }
263
+ }
264
+ return { installed: installed, errors: errors };
265
+ }
266
+
267
+ module.exports = {
268
+ installNotificationHook: installNotificationHook,
269
+ installAllowList: installAllowList,
270
+ CLAY_HOOK_MARKER: CLAY_HOOK_MARKER,
271
+ CLAY_MANAGED_ALLOW: CLAY_MANAGED_ALLOW,
272
+ };
@@ -0,0 +1,204 @@
1
+ // claude-jsonl-watcher.js
2
+ //
3
+ // Tails the per-session jsonl that Claude Code writes to
4
+ // ~/.claude/projects/<encoded-cwd>/<cliSessionId>.jsonl, parsing new lines
5
+ // for title events:
6
+ //
7
+ // {"type":"ai-title","aiTitle":"..."} - auto-generated after the
8
+ // first exchange
9
+ // {"type":"custom-title","customTitle":"..."} - explicit /title or
10
+ // similar override
11
+ //
12
+ // Used by Clay TUI sessions to mirror claude's session naming into the
13
+ // sidebar so they don't sit as "New Session" forever.
14
+ //
15
+ // Public API:
16
+ // start(jsonlPath, onTitle) -> stop()
17
+ // onTitle(title, source) where source is "ai-title" or "custom-title".
18
+ // stop() detaches the watcher and clears any timer.
19
+
20
+ var fs = require("fs");
21
+ var path = require("path");
22
+
23
+ function pickLatestTitle(lines, current) {
24
+ // Walk lines in order; the final ai-title and custom-title win. Custom
25
+ // beats ai because users explicitly chose it.
26
+ var ai = current.aiTitle || null;
27
+ var custom = current.customTitle || null;
28
+ for (var i = 0; i < lines.length; i++) {
29
+ var raw = lines[i].trim();
30
+ if (!raw || raw[0] !== "{") continue;
31
+ var obj = null;
32
+ try { obj = JSON.parse(raw); } catch (e) { continue; }
33
+ if (!obj || !obj.type) continue;
34
+ if (obj.type === "ai-title" && typeof obj.aiTitle === "string") {
35
+ ai = obj.aiTitle;
36
+ } else if (obj.type === "custom-title" && typeof obj.customTitle === "string") {
37
+ custom = obj.customTitle;
38
+ }
39
+ }
40
+ current.aiTitle = ai;
41
+ current.customTitle = custom;
42
+ return custom || ai;
43
+ }
44
+
45
+ // Pull the latest visible "text" block from any new assistant entries.
46
+ // Thinking and tool_use blocks are skipped - they're internals, not the
47
+ // response surface. Returns the most recent text seen, or null.
48
+ function extractLatestAssistantText(lines, seenUuids) {
49
+ var latest = null;
50
+ for (var i = 0; i < lines.length; i++) {
51
+ var raw = lines[i].trim();
52
+ if (!raw || raw[0] !== "{") continue;
53
+ var obj = null;
54
+ try { obj = JSON.parse(raw); } catch (e) { continue; }
55
+ if (!obj || obj.type !== "assistant" || !obj.message) continue;
56
+ if (obj.uuid && seenUuids[obj.uuid]) continue;
57
+ if (obj.uuid) seenUuids[obj.uuid] = true;
58
+ var blocks = obj.message.content || [];
59
+ if (!Array.isArray(blocks)) continue;
60
+ for (var j = 0; j < blocks.length; j++) {
61
+ var b = blocks[j];
62
+ if (b && b.type === "text" && typeof b.text === "string" && b.text.trim()) {
63
+ latest = b.text;
64
+ }
65
+ }
66
+ }
67
+ return latest;
68
+ }
69
+
70
+ /**
71
+ * Watch a Claude Code session jsonl for title and response updates.
72
+ *
73
+ * start(jsonlPath, { onTitle, onResponse }) -> stop()
74
+ *
75
+ * onTitle(text, source) fires on ai-title / custom-title updates.
76
+ * onResponse(text) fires on new assistant text blocks (debounced so
77
+ * a multi-block turn coalesces to one callback,
78
+ * using only the *final* visible text). Pre-existing
79
+ * entries from before start() are ignored - the
80
+ * initial scan seeds the "seen" set so we don't
81
+ * spam notifications when the watcher boots up.
82
+ */
83
+ function start(jsonlPath, opts) {
84
+ if (!jsonlPath) return function () {};
85
+ var onTitle = (opts && typeof opts.onTitle === "function") ? opts.onTitle : null;
86
+ var onResponse = (opts && typeof opts.onResponse === "function") ? opts.onResponse : null;
87
+ if (!onTitle && !onResponse) return function () {};
88
+
89
+ var pos = 0;
90
+ var leftover = "";
91
+ var current = { aiTitle: null, customTitle: null };
92
+ var lastTitleEmitted = null;
93
+ var seenAssistantUuids = {};
94
+ var didInitialScan = false;
95
+ var responseDebounceTimer = null;
96
+ var pendingResponseText = null;
97
+ var lastResponseEmitted = null;
98
+ var watcher = null;
99
+ var pollTimer = null;
100
+ var stopped = false;
101
+
102
+ var RESPONSE_DEBOUNCE_MS = 1500;
103
+ function maybeFireResponse() {
104
+ if (responseDebounceTimer) clearTimeout(responseDebounceTimer);
105
+ responseDebounceTimer = setTimeout(function () {
106
+ responseDebounceTimer = null;
107
+ if (!pendingResponseText) return;
108
+ if (pendingResponseText === lastResponseEmitted) return;
109
+ var t = pendingResponseText;
110
+ pendingResponseText = null;
111
+ lastResponseEmitted = t;
112
+ try { if (onResponse) onResponse(t); } catch (e) {}
113
+ }, RESPONSE_DEBOUNCE_MS);
114
+ }
115
+
116
+ function readNew() {
117
+ if (stopped) return;
118
+ try {
119
+ var stat = fs.statSync(jsonlPath);
120
+ if (stat.size <= pos) return;
121
+ var fd = fs.openSync(jsonlPath, "r");
122
+ var len = stat.size - pos;
123
+ var buf = Buffer.alloc(len);
124
+ fs.readSync(fd, buf, 0, len, pos);
125
+ fs.closeSync(fd);
126
+ pos = stat.size;
127
+ var chunk = leftover + buf.toString("utf8");
128
+ var parts = chunk.split("\n");
129
+ // Last fragment may be a partial line; hold it for next read.
130
+ leftover = parts.pop();
131
+
132
+ // Title side: fire whenever we see a new value.
133
+ if (onTitle) {
134
+ var resolved = pickLatestTitle(parts, current);
135
+ if (resolved && resolved !== lastTitleEmitted) {
136
+ lastTitleEmitted = resolved;
137
+ try { onTitle(resolved, current.customTitle === resolved ? "custom-title" : "ai-title"); } catch (e) {}
138
+ }
139
+ }
140
+
141
+ // Response side: collect new assistant text blocks. Initial scan
142
+ // seeds the "seen" set silently so old history doesn't fire.
143
+ var latest = extractLatestAssistantText(parts, seenAssistantUuids);
144
+ if (onResponse && didInitialScan && latest) {
145
+ pendingResponseText = latest;
146
+ maybeFireResponse();
147
+ }
148
+ } catch (e) {
149
+ // File may not exist yet; readNew is called again on the next event.
150
+ }
151
+ }
152
+
153
+ function arm() {
154
+ if (stopped) return;
155
+ if (watcher) return;
156
+ try {
157
+ watcher = fs.watch(jsonlPath, { persistent: false }, function () {
158
+ readNew();
159
+ });
160
+ watcher.on("error", function () {
161
+ try { watcher.close(); } catch (e) {}
162
+ watcher = null;
163
+ // Fall back to polling; some filesystems (network mounts) don't
164
+ // deliver fs.watch events reliably.
165
+ });
166
+ } catch (e) {
167
+ // Path doesn't exist yet; rely on the poll loop to retry once it appears.
168
+ }
169
+ }
170
+
171
+ // Initial pass to capture anything already written before we attached.
172
+ // didInitialScan stays false during this pass so onResponse doesn't fire
173
+ // for old history; subsequent reads (live updates) will emit.
174
+ readNew();
175
+ didInitialScan = true;
176
+ arm();
177
+
178
+ // Poll every 2s as a safety net for fs.watch misses and for the
179
+ // "file doesn't exist yet" boot case.
180
+ pollTimer = setInterval(function () {
181
+ if (!watcher) arm();
182
+ readNew();
183
+ }, 2000);
184
+
185
+ return function stop() {
186
+ stopped = true;
187
+ if (pollTimer) { clearInterval(pollTimer); pollTimer = null; }
188
+ if (responseDebounceTimer) { clearTimeout(responseDebounceTimer); responseDebounceTimer = null; }
189
+ if (watcher) { try { watcher.close(); } catch (e) {} watcher = null; }
190
+ };
191
+ }
192
+
193
+ // Resolve the jsonl path for a (cwd, cliSessionId) without depending on
194
+ // utils.js so this module stays self-contained.
195
+ function jsonlPathFor(home, cwd, cliSessionId) {
196
+ if (!home || !cwd || !cliSessionId) return null;
197
+ var encoded = cwd.replace(/[^a-zA-Z0-9]/g, "-");
198
+ return path.join(home, ".claude", "projects", encoded, cliSessionId + ".jsonl");
199
+ }
200
+
201
+ module.exports = {
202
+ start: start,
203
+ jsonlPathFor: jsonlPathFor,
204
+ };