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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/lib/account-auth-socket.js +1 -0
  2. package/lib/builtin-mates.js +19 -16
  3. package/lib/bundled-skills/clay-agent-browser/SKILL.md +6 -2
  4. package/lib/canonical-clay-record-authority.js +15 -0
  5. package/lib/canonical-clay-scheduling-authority.js +19 -0
  6. package/lib/claude-hook-installer.js +1 -239
  7. package/lib/claude-jsonl-watcher.js +1 -204
  8. package/lib/clay-control-presentation-binding.js +96 -0
  9. package/lib/clay-control-presentation.js +128 -0
  10. package/lib/clay-control-target-projection.js +26 -0
  11. package/lib/clay-mate-chat-receipts.js +26 -0
  12. package/lib/clay-mate-chat.js +88 -0
  13. package/lib/clay-mate-knowledge-input.js +26 -0
  14. package/lib/clay-mate-knowledge.js +95 -0
  15. package/lib/clay-mate-lifecycle.js +95 -0
  16. package/lib/clay-product-control-input.js +33 -0
  17. package/lib/clay-product-control-tools.js +51 -0
  18. package/lib/clay-product-control.js +247 -0
  19. package/lib/clay-project-lifecycle.js +154 -0
  20. package/lib/clay-project-record-input.js +44 -0
  21. package/lib/clay-project-records.js +84 -0
  22. package/lib/clay-scheduling-input.js +21 -0
  23. package/lib/clay-scheduling-receipts.js +26 -0
  24. package/lib/clay-scheduling.js +119 -0
  25. package/lib/clay-screen-controls.js +104 -0
  26. package/lib/clay-skill-install.js +1 -33
  27. package/lib/clay-workspace-controls.js +84 -0
  28. package/lib/clay-workspace-input.js +17 -0
  29. package/lib/clay-workspace-receipts.js +26 -0
  30. package/lib/cli-sessions.js +1 -300
  31. package/lib/codex-defaults.js +1 -28
  32. package/lib/context-usage.js +3 -2
  33. package/lib/contextual-screen-snapshot.js +38 -0
  34. package/lib/daemon-project-access.js +11 -0
  35. package/lib/daemon-project-lifecycle-callbacks.js +15 -0
  36. package/lib/daemon-project-lifecycle.js +262 -0
  37. package/lib/daemon-projects.js +1 -1
  38. package/lib/daemon.js +78 -276
  39. package/lib/default-ai-runtime.js +4 -8
  40. package/lib/dm-digest-cursor.js +120 -0
  41. package/lib/email-mcp-server.js +1 -1
  42. package/lib/issues-service.js +29 -15
  43. package/lib/kiro-defaults.js +1 -22
  44. package/lib/knowledge-db-import-validation.js +46 -0
  45. package/lib/knowledge-db-import.js +99 -0
  46. package/lib/knowledge-db-service.js +24 -33
  47. package/lib/knowledge-db-storage-nedb-maintenance.js +99 -0
  48. package/lib/knowledge-db-storage-nedb.js +66 -0
  49. package/lib/knowledge-db-storage.js +72 -0
  50. package/lib/knowledge-db-validation.js +0 -0
  51. package/lib/knowledge-document-index.js +2 -1
  52. package/lib/knowledge-file-store.js +7 -1
  53. package/lib/knowledge-product-operations.js +46 -0
  54. package/lib/mate-avatar-catalog.js +12 -0
  55. package/lib/mate-avatar-migration.js +41 -0
  56. package/lib/mate-context-service.js +138 -0
  57. package/lib/mate-context-tools.js +21 -0
  58. package/lib/mate-creation-mcp-server.js +2 -0
  59. package/lib/mate-knowledge-canonical-access.js +10 -0
  60. package/lib/mate-knowledge-mate-bound.js +53 -0
  61. package/lib/mate-knowledge-mcp-server.js +55 -8
  62. package/lib/mate-knowledge-service.js +16 -34
  63. package/lib/mate-knowledge-text-tools.js +106 -0
  64. package/lib/mate-lifecycle-service.js +94 -0
  65. package/lib/mate-message-delivery.js +43 -0
  66. package/lib/mate-ready-creation.js +9 -1
  67. package/lib/mate-schedule-input.js +29 -0
  68. package/lib/mate-schedule-lifecycle.js +151 -0
  69. package/lib/mate-scheduling.js +103 -0
  70. package/lib/mates.js +18 -6
  71. package/lib/mcp-agent-tools.js +117 -0
  72. package/lib/mcp-connection-store.js +119 -15
  73. package/lib/mcp-import-credentials.js +31 -0
  74. package/lib/mcp-local-transport.js +13 -0
  75. package/lib/mcp-oauth.js +8 -6
  76. package/lib/mcp-proxy.js +2 -32
  77. package/lib/mcp-query-bridge.js +30 -0
  78. package/lib/mcp-remote-connections.js +74 -20
  79. package/lib/mcp-source-adapters.js +1 -0
  80. package/lib/mcp-source-context.js +1 -0
  81. package/lib/mcp-source-discovery.js +1 -0
  82. package/lib/mcp-source-plugins.js +1 -0
  83. package/lib/mcp-source-restrictions.js +1 -0
  84. package/lib/mcp-tool-policy.js +9 -0
  85. package/lib/notes-checklist.js +50 -0
  86. package/lib/notes.js +49 -3
  87. package/lib/os-user-diagnostics.js +2 -4
  88. package/lib/os-users.js +24 -70
  89. package/lib/pane-pending-interactions.js +20 -0
  90. package/lib/pane-session-activation.js +114 -0
  91. package/lib/pane-session-transport.js +26 -0
  92. package/lib/project-admin-overview.js +51 -0
  93. package/lib/project-ask-user.js +8 -4
  94. package/lib/project-connection.js +14 -10
  95. package/lib/project-control-git-view.js +12 -0
  96. package/lib/project-debate.js +1 -0
  97. package/lib/project-delegated-follow-up.js +2 -1
  98. package/lib/project-directory-claim.js +65 -0
  99. package/lib/project-file-operations.js +61 -0
  100. package/lib/project-filesystem.js +15 -85
  101. package/lib/project-full-access.js +23 -2
  102. package/lib/project-http.js +7 -4
  103. package/lib/project-knowledge.js +32 -18
  104. package/lib/project-lifecycle-operations.js +98 -0
  105. package/lib/project-lifecycle-process-witness.js +32 -0
  106. package/lib/project-lifecycle-runtime.js +50 -0
  107. package/lib/project-linux-access.js +22 -0
  108. package/lib/project-logs-canonical-clay.js +27 -0
  109. package/lib/project-logs-clay-query.js +16 -0
  110. package/lib/project-logs-schema.js +4 -2
  111. package/lib/project-logs-service.js +8 -7
  112. package/lib/project-logs.js +1 -0
  113. package/lib/project-loop.js +1 -0
  114. package/lib/project-mate-chat-control.js +55 -0
  115. package/lib/project-mate-creation-proposal.js +18 -3
  116. package/lib/project-mate-interaction.js +40 -62
  117. package/lib/project-mcp.js +54 -16
  118. package/lib/project-models.js +14 -31
  119. package/lib/project-notifications.js +76 -17
  120. package/lib/project-ownership.js +77 -0
  121. package/lib/project-pair-result-delivery.js +14 -3
  122. package/lib/project-pair-usage.js +12 -13
  123. package/lib/project-pending-message-queue.js +4 -1
  124. package/lib/project-product-control.js +89 -0
  125. package/lib/project-product-session-queue.js +46 -0
  126. package/lib/project-push-access.js +28 -0
  127. package/lib/project-scheduled-message-queue.js +30 -0
  128. package/lib/project-scheduled-messages.js +67 -68
  129. package/lib/project-scheduled-task-control.js +83 -0
  130. package/lib/project-scheduled-tasks.js +13 -2
  131. package/lib/project-scheduling-access.js +10 -0
  132. package/lib/project-session-actions.js +65 -0
  133. package/lib/project-session-delete.js +8 -1
  134. package/lib/project-session-document.js +27 -7
  135. package/lib/project-session-github.js +63 -19
  136. package/lib/project-session-history-actions.js +167 -0
  137. package/lib/project-session-linear.js +14 -6
  138. package/lib/project-session-notes.js +7 -3
  139. package/lib/project-session-pair.js +1 -1
  140. package/lib/project-session-runtime-actions.js +64 -0
  141. package/lib/project-session-spawn.js +2 -3
  142. package/lib/project-session-vendor.js +55 -0
  143. package/lib/project-sessions.js +103 -272
  144. package/lib/project-shared-browser.js +78 -17
  145. package/lib/project-studio-presentation.js +58 -0
  146. package/lib/project-user-message.js +67 -1
  147. package/lib/project-vendor-login.js +6 -36
  148. package/lib/project-workspace-operations.js +126 -0
  149. package/lib/project-workspace-query.js +19 -2
  150. package/lib/project.js +178 -45
  151. package/lib/public/app.js +46 -0
  152. package/lib/public/appearance-bootstrap.js +16 -0
  153. package/lib/public/css/clay-tool-activity.css +51 -0
  154. package/lib/public/css/clay-workspace.css +29 -0
  155. package/lib/public/css/command-palette.css +12 -33
  156. package/lib/public/css/contextual-clay.css +240 -0
  157. package/lib/public/css/home-debate-planning.css +2 -0
  158. package/lib/public/css/home-mate-creation.css +5 -0
  159. package/lib/public/css/input.css +6 -0
  160. package/lib/public/css/mate-avatar-gallery.css +12 -0
  161. package/lib/public/css/mate-conversation.css +10 -5
  162. package/lib/public/css/messages.css +6 -2
  163. package/lib/public/css/overlays.css +4 -2
  164. package/lib/public/css/project-admin-overview.css +13 -0
  165. package/lib/public/css/session-folders.css +11 -0
  166. package/lib/public/css/session-github.css +46 -1
  167. package/lib/public/css/shared-browser.css +35 -1
  168. package/lib/public/css/sticky-notes.css +87 -1
  169. package/lib/public/index.html +11 -5
  170. package/lib/public/mate-avatars/B01.png +0 -0
  171. package/lib/public/mate-avatars/B02.png +0 -0
  172. package/lib/public/mate-avatars/B03.png +0 -0
  173. package/lib/public/mate-avatars/B04.png +0 -0
  174. package/lib/public/mate-avatars/B05.png +0 -0
  175. package/lib/public/mate-avatars/B06.png +0 -0
  176. package/lib/public/mate-avatars/B07.png +0 -0
  177. package/lib/public/mate-avatars/B08.png +0 -0
  178. package/lib/public/mate-avatars/B09.png +0 -0
  179. package/lib/public/mate-avatars/B10.png +0 -0
  180. package/lib/public/mate-avatars/B11.png +0 -0
  181. package/lib/public/mate-avatars/B12.png +0 -0
  182. package/lib/public/mate-avatars/B13.png +0 -0
  183. package/lib/public/mate-avatars/B14.png +0 -0
  184. package/lib/public/mate-avatars/B15.png +0 -0
  185. package/lib/public/mate-avatars/B16.png +0 -0
  186. package/lib/public/mate-avatars/B17.png +0 -0
  187. package/lib/public/mate-avatars/B18.png +0 -0
  188. package/lib/public/mate-avatars/B19.png +0 -0
  189. package/lib/public/mate-avatars/B20.png +0 -0
  190. package/lib/public/mate-avatars/B21.png +0 -0
  191. package/lib/public/mate-avatars/B22.png +0 -0
  192. package/lib/public/mate-avatars/B23.png +0 -0
  193. package/lib/public/mate-avatars/B24.png +0 -0
  194. package/lib/public/mate-avatars/B25.png +0 -0
  195. package/lib/public/mate-avatars/B26.png +0 -0
  196. package/lib/public/mate-avatars/B27.png +0 -0
  197. package/lib/public/mate-avatars/B28.png +0 -0
  198. package/lib/public/mate-avatars/B29.png +0 -0
  199. package/lib/public/mate-avatars/B30.png +0 -0
  200. package/lib/public/mate-avatars/B31.png +0 -0
  201. package/lib/public/mate-avatars/B32.png +0 -0
  202. package/lib/public/mate-avatars/B33.png +0 -0
  203. package/lib/public/mate-avatars/B34.png +0 -0
  204. package/lib/public/mate-avatars/B35.png +0 -0
  205. package/lib/public/mate-avatars/B36.png +0 -0
  206. package/lib/public/mate-avatars/B37.png +0 -0
  207. package/lib/public/mate-avatars/B38.png +0 -0
  208. package/lib/public/mate-avatars/B39.png +0 -0
  209. package/lib/public/mate-avatars/B40.png +0 -0
  210. package/lib/public/mate-avatars/B41.png +0 -0
  211. package/lib/public/mate-avatars/B42.png +0 -0
  212. package/lib/public/mate-avatars/B43.png +0 -0
  213. package/lib/public/mate-avatars/B44.png +0 -0
  214. package/lib/public/mate-avatars/B45.png +0 -0
  215. package/lib/public/mate-avatars/B46.png +0 -0
  216. package/lib/public/mate-avatars/B47.png +0 -0
  217. package/lib/public/mate-avatars/B48.png +0 -0
  218. package/lib/public/mate-avatars/C01.png +0 -0
  219. package/lib/public/mate-avatars/C02.png +0 -0
  220. package/lib/public/mate-avatars/C03.png +0 -0
  221. package/lib/public/mate-avatars/C04.png +0 -0
  222. package/lib/public/mate-avatars/C05.png +0 -0
  223. package/lib/public/mate-avatars/C06.png +0 -0
  224. package/lib/public/mate-avatars/C07.png +0 -0
  225. package/lib/public/mate-avatars/C08.png +0 -0
  226. package/lib/public/mate-avatars/C09.png +0 -0
  227. package/lib/public/mate-avatars/C10.png +0 -0
  228. package/lib/public/mate-avatars/C11.png +0 -0
  229. package/lib/public/mate-avatars/C12.png +0 -0
  230. package/lib/public/mate-avatars/C13.png +0 -0
  231. package/lib/public/mate-avatars/C14.png +0 -0
  232. package/lib/public/mate-avatars/C15.png +0 -0
  233. package/lib/public/mate-avatars/C16.png +0 -0
  234. package/lib/public/mate-avatars/C17.png +0 -0
  235. package/lib/public/mate-avatars/C18.png +0 -0
  236. package/lib/public/mate-avatars/C19.png +0 -0
  237. package/lib/public/mate-avatars/C20.png +0 -0
  238. package/lib/public/mate-avatars/C21.png +0 -0
  239. package/lib/public/mate-avatars/C22.png +0 -0
  240. package/lib/public/mate-avatars/C23.png +0 -0
  241. package/lib/public/mate-avatars/C24.png +0 -0
  242. package/lib/public/mate-avatars/C25.png +0 -0
  243. package/lib/public/mate-avatars/C26.png +0 -0
  244. package/lib/public/mate-avatars/C27.png +0 -0
  245. package/lib/public/mate-avatars/C28.png +0 -0
  246. package/lib/public/mate-avatars/C29.png +0 -0
  247. package/lib/public/mate-avatars/C30.png +0 -0
  248. package/lib/public/mate-avatars/C31.png +0 -0
  249. package/lib/public/mate-avatars/C32.png +0 -0
  250. package/lib/public/mate-avatars/C33.png +0 -0
  251. package/lib/public/mate-avatars/C34.png +0 -0
  252. package/lib/public/mate-avatars/C35.png +0 -0
  253. package/lib/public/mate-avatars/C36.png +0 -0
  254. package/lib/public/mate-avatars/C37.png +0 -0
  255. package/lib/public/mate-avatars/C38.png +0 -0
  256. package/lib/public/mate-avatars/C39.png +0 -0
  257. package/lib/public/mate-avatars/C40.png +0 -0
  258. package/lib/public/mate-avatars/C41.png +0 -0
  259. package/lib/public/mate-avatars/C42.png +0 -0
  260. package/lib/public/mate-avatars/C43.png +0 -0
  261. package/lib/public/mate-avatars/C44.png +0 -0
  262. package/lib/public/mate-avatars/C45.png +0 -0
  263. package/lib/public/mate-avatars/C46.png +0 -0
  264. package/lib/public/mate-avatars/C47.png +0 -0
  265. package/lib/public/mate-avatars/C48.png +0 -0
  266. package/lib/public/mate-avatars/catalog.json +482 -0
  267. package/lib/public/mate-avatars/lead-clay.png +0 -0
  268. package/lib/public/modules/admin-settings-projects.js +6 -2
  269. package/lib/public/modules/app-connection.js +11 -1
  270. package/lib/public/modules/app-favicon.js +18 -9
  271. package/lib/public/modules/app-header.js +7 -4
  272. package/lib/public/modules/app-loop-ui.js +2 -0
  273. package/lib/public/modules/app-message-router.js +22 -1
  274. package/lib/public/modules/app-messages.js +115 -17
  275. package/lib/public/modules/app-misc.js +3 -1
  276. package/lib/public/modules/app-notifications.js +11 -5
  277. package/lib/public/modules/app-panels.js +61 -123
  278. package/lib/public/modules/app-projects.js +13 -0
  279. package/lib/public/modules/app-rate-limit.js +7 -27
  280. package/lib/public/modules/app-rendering.js +4 -3
  281. package/lib/public/modules/avatar.js +15 -41
  282. package/lib/public/modules/chat-render-runtime.js +20 -0
  283. package/lib/public/modules/clay-browser-links.js +47 -0
  284. package/lib/public/modules/clay-control-activity.js +214 -0
  285. package/lib/public/modules/clay-control-copy.js +36 -0
  286. package/lib/public/modules/clay-control-detail-targets.js +44 -0
  287. package/lib/public/modules/clay-control-object-targets.js +52 -0
  288. package/lib/public/modules/clay-control-target-visibility.js +12 -0
  289. package/lib/public/modules/clay-control-targets.js +44 -0
  290. package/lib/public/modules/clay-log-links.js +23 -0
  291. package/lib/public/modules/clay-navigation-render.js +52 -0
  292. package/lib/public/modules/clay-owner-navigation.js +33 -0
  293. package/lib/public/modules/clay-session-links.js +31 -0
  294. package/lib/public/modules/clay-studio-bridge.js +20 -0
  295. package/lib/public/modules/clay-studio-document.js +67 -0
  296. package/lib/public/modules/clay-studio-render.js +146 -0
  297. package/lib/public/modules/clay-tool-activity.js +140 -0
  298. package/lib/public/modules/clay-tool-presentation.js +342 -0
  299. package/lib/public/modules/command-palette.js +162 -40
  300. package/lib/public/modules/contextual-ask-session.js +26 -0
  301. package/lib/public/modules/contextual-clay-geometry.js +155 -0
  302. package/lib/public/modules/contextual-clay-session.js +130 -0
  303. package/lib/public/modules/contextual-clay-workspace.js +169 -0
  304. package/lib/public/modules/contextual-clay.js +250 -0
  305. package/lib/public/modules/contextual-composer.js +91 -0
  306. package/lib/public/modules/contextual-mate-context.js +117 -0
  307. package/lib/public/modules/contextual-mate-hint.js +40 -0
  308. package/lib/public/modules/contextual-mate-identity.js +23 -0
  309. package/lib/public/modules/contextual-mate-sessions.js +134 -0
  310. package/lib/public/modules/contextual-search.js +137 -0
  311. package/lib/public/modules/contextual-session-citations.js +58 -0
  312. package/lib/public/modules/debate.js +1 -0
  313. package/lib/public/modules/default-ai.js +11 -3
  314. package/lib/public/modules/elicitation-form.js +5 -0
  315. package/lib/public/modules/filebrowser.js +20 -1
  316. package/lib/public/modules/generation-stop.js +8 -5
  317. package/lib/public/modules/git-panel.js +3 -1
  318. package/lib/public/modules/history-replay-batch.js +13 -1
  319. package/lib/public/modules/home-debate-live.js +2 -0
  320. package/lib/public/modules/home-debate-planning.js +7 -7
  321. package/lib/public/modules/home-mate-avatar-editor.js +127 -208
  322. package/lib/public/modules/home-mate-chat.js +8 -6
  323. package/lib/public/modules/home-mate-creation.js +73 -1
  324. package/lib/public/modules/home-mate-settings.js +19 -12
  325. package/lib/public/modules/icon-strip-tooltip.js +2 -1
  326. package/lib/public/modules/input.js +88 -10
  327. package/lib/public/modules/issues-render.js +3 -2
  328. package/lib/public/modules/knowledge-db-workbench.js +4 -4
  329. package/lib/public/modules/markdown.js +6 -34
  330. package/lib/public/modules/mate-avatar-catalog.js +97 -0
  331. package/lib/public/modules/mate-knowledge-workbench.js +1 -1
  332. package/lib/public/modules/mate-management.js +40 -7
  333. package/lib/public/modules/mcp-connection-view.js +31 -13
  334. package/lib/public/modules/mcp-discovery-view.js +31 -0
  335. package/lib/public/modules/mcp-ui.js +23 -4
  336. package/lib/public/modules/mention.js +3 -0
  337. package/lib/public/modules/message-delivery.js +20 -2
  338. package/lib/public/modules/model-picker.js +2 -0
  339. package/lib/public/modules/pane-activation.js +214 -0
  340. package/lib/public/modules/pane-binding.js +82 -0
  341. package/lib/public/modules/pane-bridge.js +7 -4
  342. package/lib/public/modules/pane-browser-bridge.js +22 -0
  343. package/lib/public/modules/pane-file-bridge.js +4 -0
  344. package/lib/public/modules/pane-issue-bridge.js +4 -1
  345. package/lib/public/modules/pending-message-queue.js +1 -0
  346. package/lib/public/modules/permission-control.js +5 -4
  347. package/lib/public/modules/personal-settings-dialog.js +7 -1
  348. package/lib/public/modules/product-review.js +26 -0
  349. package/lib/public/modules/profile.js +1 -238
  350. package/lib/public/modules/project-access-recovery.js +17 -0
  351. package/lib/public/modules/project-admin-overview.js +21 -0
  352. package/lib/public/modules/project-chat-identity.js +13 -4
  353. package/lib/public/modules/project-logs-render.js +3 -0
  354. package/lib/public/modules/project-mate-navigation.js +144 -22
  355. package/lib/public/modules/rewind.js +5 -0
  356. package/lib/public/modules/scheduled-tasks.js +2 -0
  357. package/lib/public/modules/scheduler.js +2 -0
  358. package/lib/public/modules/search-clay-chat.js +5 -440
  359. package/lib/public/modules/session-actions.js +5 -2
  360. package/lib/public/modules/session-context-menu.js +5 -0
  361. package/lib/public/modules/session-create-form.js +10 -10
  362. package/lib/public/modules/session-folder-layout.js +1 -1
  363. package/lib/public/modules/session-folder-view-menu.js +9 -0
  364. package/lib/public/modules/session-github.js +85 -14
  365. package/lib/public/modules/session-rich-drafts.js +21 -0
  366. package/lib/public/modules/session-switch-defer.js +67 -0
  367. package/lib/public/modules/session-work-primary.js +51 -0
  368. package/lib/public/modules/settings-defaults.js +27 -28
  369. package/lib/public/modules/shared-browser-settings.js +112 -0
  370. package/lib/public/modules/shared-browser-tabs.js +13 -3
  371. package/lib/public/modules/shared-browser.js +29 -6
  372. package/lib/public/modules/sidebar-mobile.js +4 -3
  373. package/lib/public/modules/sidebar-projects.js +1 -0
  374. package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
  375. package/lib/public/modules/sidebar-sessions.js +1 -0
  376. package/lib/public/modules/split-group-restore.js +68 -0
  377. package/lib/public/modules/split-pair-ui.js +1 -0
  378. package/lib/public/modules/split-pane-reconciler.js +15 -0
  379. package/lib/public/modules/split-pane-renderer.js +87 -6
  380. package/lib/public/modules/split-session-boundary.js +1 -1
  381. package/lib/public/modules/split-view.js +60 -68
  382. package/lib/public/modules/sticky-note-markdown.js +72 -6
  383. package/lib/public/modules/sticky-notes-actions.js +30 -0
  384. package/lib/public/modules/sticky-notes-browser.js +9 -2
  385. package/lib/public/modules/sticky-notes-card.js +23 -7
  386. package/lib/public/modules/sticky-notes-checklist.js +116 -0
  387. package/lib/public/modules/sticky-notes-editor.js +108 -44
  388. package/lib/public/modules/sticky-notes-shared.js +50 -2
  389. package/lib/public/modules/sticky-notes-state.js +66 -0
  390. package/lib/public/modules/sticky-notes.js +34 -51
  391. package/lib/public/modules/stt-controller.js +4 -1
  392. package/lib/public/modules/stt-recording.js +1 -1
  393. package/lib/public/modules/stt.js +7 -2
  394. package/lib/public/modules/terminal.js +9 -0
  395. package/lib/public/modules/theme.js +8 -1
  396. package/lib/public/modules/thinking-lifecycle.js +33 -3
  397. package/lib/public/modules/thinking-view.js +23 -1
  398. package/lib/public/modules/tools.js +60 -11
  399. package/lib/public/modules/tui-grab.js +1 -2
  400. package/lib/public/modules/user-settings-appearance.js +10 -3
  401. package/lib/public/modules/user-settings-editors.js +1 -1
  402. package/lib/public/modules/user-settings-layout.js +11 -2
  403. package/lib/public/modules/user-settings-preferences.js +6 -2
  404. package/lib/public/modules/user-settings-profile.js +12 -2
  405. package/lib/public/modules/user-settings.js +3 -2
  406. package/lib/public/modules/vendor-login-browser.js +5 -3
  407. package/lib/public/modules/vendor-login.js +2 -2
  408. package/lib/public/modules/vendor-priority.js +15 -1
  409. package/lib/public/modules/wireframe-workbench.js +5 -2
  410. package/lib/public/muse-avatar.svg +4 -0
  411. package/lib/public/style.css +5 -0
  412. package/lib/public/sw.js +3 -1
  413. package/lib/safe-bash-commands.js +3 -45
  414. package/lib/scheduled-task-records.js +3 -1
  415. package/lib/scheduler.js +2 -0
  416. package/lib/sdk-bridge.js +342 -401
  417. package/lib/sdk-foreground-admission.js +16 -0
  418. package/lib/sdk-mcp-descriptors.js +2 -37
  419. package/lib/sdk-message-processor.js +52 -17
  420. package/lib/sdk-quota-snapshot.js +1 -1
  421. package/lib/sdk-response-recovery.js +1 -0
  422. package/lib/sdk-worker.js +2 -677
  423. package/lib/server-admin.js +63 -16
  424. package/lib/server-appearance-settings.js +13 -1
  425. package/lib/server-contextual-clay-settings.js +40 -0
  426. package/lib/server-contextual-mate-sessions.js +70 -0
  427. package/lib/server-dm.js +2 -1
  428. package/lib/server-global-ws.js +10 -20
  429. package/lib/server-home-chat-events.js +18 -4
  430. package/lib/server-home-chat.js +22 -20
  431. package/lib/server-home-clay-entry.js +23 -4
  432. package/lib/server-home-clay-session-links.js +29 -9
  433. package/lib/server-home-mate-creation.js +1 -0
  434. package/lib/server-home-mcp-consent.js +14 -0
  435. package/lib/server-mates.js +25 -62
  436. package/lib/server-owner-ui.js +118 -0
  437. package/lib/server-path-access.js +38 -0
  438. package/lib/server-project-removal.js +22 -0
  439. package/lib/server-settings.js +6 -1
  440. package/lib/server.js +163 -43
  441. package/lib/session-config-transition.js +45 -0
  442. package/lib/session-folders.js +7 -2
  443. package/lib/session-fork-history.js +21 -0
  444. package/lib/session-github.js +9 -2
  445. package/lib/session-hygiene.js +3 -35
  446. package/lib/session-permission-mode.js +4 -3
  447. package/lib/session-skill-scope.js +11 -0
  448. package/lib/session-visibility.js +5 -2
  449. package/lib/session-work-primary.js +50 -0
  450. package/lib/sessions.js +64 -99
  451. package/lib/shared-browser-cookie-sync.js +32 -0
  452. package/lib/shared-browser-cookies.js +79 -0
  453. package/lib/shared-browser-runtime.js +25 -9
  454. package/lib/shared-browser-storage-sync.js +43 -0
  455. package/lib/shared-browser-storage.js +101 -0
  456. package/lib/shared-browser-tools.js +2 -1
  457. package/lib/shared-browser-worker.js +46 -10
  458. package/lib/terminal-manager.js +65 -6
  459. package/lib/tool-llm.js +1 -1
  460. package/lib/tui-transcript-index.js +1 -132
  461. package/lib/users-contextual-clay-preferences.js +31 -0
  462. package/lib/users-permissions.js +2 -8
  463. package/lib/users.js +7 -0
  464. package/lib/vendor-login-browser.js +1 -11
  465. package/lib/workspace-assignment-service.js +25 -0
  466. package/lib/workspace-query-access.js +4 -1
  467. package/lib/workspace-query-mcp-server.js +1 -1
  468. package/lib/workspace-query-service.js +13 -2
  469. package/lib/ws-request.js +1 -0
  470. package/lib/ws-schema.js +18 -2
  471. package/lib/yoke/acp-agent-profiles.js +7 -5
  472. package/lib/yoke/adapters/antigravity.js +3 -14
  473. package/lib/yoke/adapters/claude-query-contract.js +9 -0
  474. package/lib/yoke/adapters/claude.js +54 -50
  475. package/lib/yoke/adapters/codex-query-contract.js +24 -0
  476. package/lib/yoke/adapters/codex.js +53 -111
  477. package/lib/yoke/adapters/kiro.js +3 -1
  478. package/lib/yoke/adapters/muse-query-contract.js +7 -0
  479. package/lib/yoke/adapters/muse.js +122 -0
  480. package/lib/yoke/auth-events.js +17 -0
  481. package/lib/yoke/claude-hook-installer.js +271 -0
  482. package/lib/yoke/claude-jsonl-watcher.js +204 -0
  483. package/lib/yoke/claude-maintenance.js +55 -0
  484. package/lib/yoke/claude-permission-patterns.js +53 -0
  485. package/lib/yoke/claude-response-recovery.js +155 -0
  486. package/lib/yoke/claude-transcript-hygiene.js +34 -0
  487. package/lib/yoke/claude-worker-startup.js +28 -0
  488. package/lib/yoke/clay-skill-install.js +33 -0
  489. package/lib/yoke/cli-sessions.js +300 -0
  490. package/lib/yoke/codex-app-server.js +7 -12
  491. package/lib/yoke/codex-idle-recovery.js +81 -1
  492. package/lib/yoke/codex-recovery-admission.js +164 -0
  493. package/lib/yoke/configuration.js +13 -0
  494. package/lib/yoke/discovery.js +70 -0
  495. package/lib/yoke/errors.js +8 -0
  496. package/lib/yoke/host-environment.js +7 -0
  497. package/lib/yoke/index.js +9 -51
  498. package/lib/yoke/interface.js +116 -0
  499. package/lib/yoke/kiro-acp-server.js +5 -5
  500. package/lib/yoke/legacy-sessions.js +89 -0
  501. package/lib/yoke/login-protocol.js +25 -0
  502. package/lib/yoke/maintenance.js +12 -0
  503. package/lib/yoke/mcp-proxy.js +32 -0
  504. package/lib/yoke/mcp-source-adapters.js +91 -0
  505. package/lib/yoke/mcp-source-context.js +42 -0
  506. package/lib/yoke/mcp-source-discovery.js +169 -0
  507. package/lib/yoke/mcp-source-plugins.js +68 -0
  508. package/lib/yoke/mcp-source-restrictions.js +47 -0
  509. package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
  510. package/lib/yoke/model-preferences.js +6 -0
  511. package/lib/yoke/muse-artifacts.js +36 -0
  512. package/lib/yoke/muse-controls.js +50 -0
  513. package/lib/yoke/muse-input.js +64 -0
  514. package/lib/yoke/muse-items.js +157 -0
  515. package/lib/yoke/muse-policy.js +52 -0
  516. package/lib/yoke/muse-query.js +428 -0
  517. package/lib/yoke/muse-runtime.js +211 -0
  518. package/lib/yoke/muse-services.js +79 -0
  519. package/lib/yoke/muse-skills.js +79 -0
  520. package/lib/yoke/muse-turns.js +71 -0
  521. package/lib/yoke/options/acp.js +2 -0
  522. package/lib/yoke/options/antigravity.js +2 -0
  523. package/lib/yoke/options/claude.js +21 -0
  524. package/lib/yoke/options/codex-defaults.js +29 -0
  525. package/lib/yoke/options/codex-settings.js +21 -0
  526. package/lib/yoke/options/codex.js +6 -0
  527. package/lib/yoke/options/kiro-defaults.js +22 -0
  528. package/lib/yoke/options/kiro.js +5 -0
  529. package/lib/yoke/options/muse.js +5 -0
  530. package/lib/yoke/provider-contract.js +5 -0
  531. package/lib/yoke/providers/antigravity-executable.js +8 -0
  532. package/lib/yoke/providers/claude-executable.js +40 -0
  533. package/lib/yoke/providers/claude-model-descriptions.js +14 -0
  534. package/lib/yoke/providers/claude-process.js +97 -0
  535. package/lib/yoke/providers/claude-provision.js +75 -0
  536. package/lib/yoke/providers/codex-errors.js +8 -0
  537. package/lib/yoke/providers/muse-executable.js +17 -0
  538. package/lib/yoke/provisioning.js +6 -0
  539. package/lib/yoke/query-options.js +10 -0
  540. package/lib/yoke/response-recovery.js +41 -0
  541. package/lib/yoke/sdk-mcp-descriptors.js +37 -0
  542. package/lib/yoke/sdk-server-factory.js +7 -0
  543. package/lib/yoke/session-history.js +8 -0
  544. package/lib/yoke/session-tool-transport.js +34 -13
  545. package/lib/yoke/settings.js +23 -0
  546. package/lib/yoke/source-locations.js +4 -0
  547. package/lib/yoke/title-query.js +18 -7
  548. package/lib/yoke/tui-transcript-index.js +132 -0
  549. package/lib/yoke/usage.js +48 -0
  550. package/lib/yoke/user-input.js +13 -0
  551. package/lib/yoke/vendor-registry.js +81 -1
  552. package/package.json +10 -4
@@ -93,42 +93,6 @@ var MODE_OPTIONS = [
93
93
  var MODE_FULL_AUTO = { value: "auto", label: "Auto" };
94
94
  var MODE_SKIP = { value: "bypassPermissions", label: "Skip permissions" };
95
95
  var EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
96
- var EFFORT_LEVELS_BY_VENDOR = {
97
- claude: ["low", "medium", "high", "xhigh", "max"],
98
- codex: ["low", "medium", "high", "xhigh", "max"],
99
- antigravity: [],
100
- opencode: [],
101
- kiro: ["low", "medium", "high", "xhigh", "max"],
102
- };
103
- var THINKING_OPTIONS = ["disabled", "adaptive", "budget"];
104
- var CODEX_APPROVAL_OPTIONS = [
105
- { value: "never", label: "Auto" },
106
- { value: "untrusted", label: "Untrusted" },
107
- { value: "on-request", label: "Ask" },
108
- ];
109
- var CODEX_SANDBOX_OPTIONS = [
110
- { value: "read-only", label: "Read Only" },
111
- { value: "workspace-write", label: "Workspace" },
112
- { value: "danger-full-access", label: "Full Access" },
113
- ];
114
- var CODEX_WEBSEARCH_OPTIONS = [
115
- { value: "disabled", label: "Off" },
116
- { value: "cached", label: "Cached" },
117
- { value: "live", label: "Live" },
118
- ];
119
- var KNOWN_CONTEXT_WINDOWS = {
120
- "opus-4-6": 1000000,
121
- "claude-sonnet-4": 1000000,
122
- "gpt-6-astra": 1050000,
123
- "gpt-5.6": 1050000,
124
- "gpt-5.5": 1048576,
125
- "gpt-5.4": 1048576,
126
- "gpt-5.3": 1048576,
127
- "gpt-5.2": 1048576,
128
- "gpt-4.1": 1047576,
129
- "o3": 200000,
130
- "o4-mini": 200000,
131
- };
132
96
  // Categories to hide from the legend (noise, not actionable)
133
97
  var CTX_HIDDEN_CATS = { "Free space": 1, "Autocompact buffer": 1 };
134
98
 
@@ -160,12 +124,12 @@ export function effortDisplayName(value) {
160
124
  // uses this for sessions other than the active one). Falls back from the
161
125
  // model's own supportedEffortLevels to the vendor table.
162
126
  export function effortLevelsFor(vendor, models, modelValue) {
163
- var defaults = EFFORT_LEVELS_BY_VENDOR[vendor] || EFFORT_LEVELS;
127
+ var defaults = ((store.get("vendorInfo") || {})[vendor] || {}).effortLevels || [];
164
128
  var list = models || [];
165
129
  for (var i = 0; i < list.length; i++) {
166
130
  var value = typeof list[i] === "string" ? list[i] : (list[i] && (list[i].value || list[i].id)) || "";
167
131
  if (value === modelValue) {
168
- if (list[i].supportedEffortLevels && list[i].supportedEffortLevels.length > 0) {
132
+ if (Array.isArray(list[i].supportedEffortLevels)) {
169
133
  return list[i].supportedEffortLevels;
170
134
  }
171
135
  return defaults;
@@ -182,9 +146,8 @@ function thinkingDisplayName(value) {
182
146
  }
183
147
 
184
148
  function isSonnetModel(model) {
185
- if (!model) return false;
186
- var lower = model.toLowerCase();
187
- return lower.indexOf("sonnet") !== -1;
149
+ var models = store.get("currentModels") || [];
150
+ return models.some(function(entry) { return entry && entry.value === model && entry.supportsBetaContext === true; });
188
151
  }
189
152
 
190
153
  function hasBeta(name) {
@@ -198,7 +161,7 @@ function hasBeta(name) {
198
161
  function rebuildModeList() {
199
162
  if (!configModeList) return;
200
163
  configModeList.innerHTML = "";
201
- var options = MODE_OPTIONS.slice();
164
+ var options = (providerConfiguration().permissionModes || []).slice();
202
165
  options.push(MODE_FULL_AUTO);
203
166
  options.push(MODE_SKIP);
204
167
  var autoSupported = store.get('permissionCapabilities').auto === true;
@@ -212,8 +175,8 @@ function rebuildModeList() {
212
175
  btn.textContent = opt.label;
213
176
  if (opt.value === "auto" && !autoSupported) {
214
177
  btn.disabled = true;
215
- btn.title = "Auto permissions require a Claude session.";
216
- btn.setAttribute("aria-description", "Unavailable because this is not a Claude session.");
178
+ btn.title = "Auto permissions are unavailable for this session.";
179
+ btn.setAttribute("aria-description", "The current runtime does not support Auto permissions.");
217
180
  }
218
181
  if (globallyForced) {
219
182
  btn.disabled = true;
@@ -232,13 +195,13 @@ function rebuildModeList() {
232
195
  function rebuildEffortBar() {
233
196
  if (!configEffortBar || !configEffortSection) return;
234
197
  var supportsEffort = getModelSupportsEffort();
235
- if (!supportsEffort) {
198
+ var levels = getModelEffortLevels();
199
+ if (!supportsEffort || !levels.length) {
236
200
  configEffortSection.style.display = "none";
237
201
  return;
238
202
  }
239
203
  configEffortSection.style.display = "";
240
204
  configEffortBar.innerHTML = "";
241
- var levels = getModelEffortLevels();
242
205
  for (var i = 0; i < levels.length; i++) {
243
206
  var level = levels[i];
244
207
  var btn = document.createElement("button");
@@ -277,8 +240,9 @@ function rebuildThinkingSection() {
277
240
  configThinkingSection.style.display = "";
278
241
  configThinkingBar.innerHTML = "";
279
242
  var s = store.snap();
280
- for (var i = 0; i < THINKING_OPTIONS.length; i++) {
281
- var opt = THINKING_OPTIONS[i];
243
+ var thinkingOptions = (providerConfiguration().thinking || {}).options || [];
244
+ for (var i = 0; i < thinkingOptions.length; i++) {
245
+ var opt = thinkingOptions[i];
282
246
  var btn = document.createElement("button");
283
247
  btn.className = "config-segment-btn";
284
248
  if (opt === s.currentThinking) btn.classList.add("active");
@@ -329,22 +293,21 @@ function buildSegmentedBar(barEl, options, currentValue, msgType, msgKey) {
329
293
  }
330
294
  }
331
295
 
332
- function rebuildCodexSections() {
333
- var s = store.snap();
334
- var isCodex = (s.currentVendor || "claude") === "codex";
296
+ function providerConfiguration() {
297
+ var state = store.snap();
298
+ return ((state.vendorInfo || {})[state.currentVendor] || {}).configuration || {};
299
+ }
335
300
 
336
- if (configApprovalSection) {
337
- configApprovalSection.style.display = isCodex ? "" : "none";
338
- if (isCodex) buildSegmentedBar(configApprovalBar, CODEX_APPROVAL_OPTIONS, s.codexApproval, "set_codex_approval", "approval");
339
- }
340
- if (configSandboxSection) {
341
- configSandboxSection.style.display = isCodex ? "" : "none";
342
- if (isCodex) buildSegmentedBar(configSandboxBar, CODEX_SANDBOX_OPTIONS, s.codexSandbox, "set_codex_sandbox", "sandbox");
343
- }
344
- if (configWebsearchSection) {
345
- configWebsearchSection.style.display = isCodex ? "" : "none";
346
- if (isCodex) buildSegmentedBar(configWebsearchBar, CODEX_WEBSEARCH_OPTIONS, s.codexWebSearch, "set_codex_websearch", "webSearch");
301
+ function rebuildProviderSections() {
302
+ var state = store.snap(), config = providerConfiguration();
303
+ function section(element, bar, description) {
304
+ if (!element) return;
305
+ element.style.display = description ? "" : "none";
306
+ if (description) buildSegmentedBar(bar, description.options || [], state[description.state], description.message, description.key);
347
307
  }
308
+ section(configApprovalSection, configApprovalBar, config.approval);
309
+ section(configSandboxSection, configSandboxBar, config.sandbox);
310
+ section(configWebsearchSection, configWebsearchBar, config.webSearch);
348
311
  }
349
312
 
350
313
  function escHtml(s) {
@@ -584,25 +547,17 @@ export function updateConfigChip() {
584
547
  if (!configChipWrap || !configChip) return;
585
548
  configChipWrap.classList.remove("hidden");
586
549
  var s = store.snap();
587
- var vendor = s.currentVendor || "claude";
588
550
  configChipLabel.textContent = modelDisplayName(s.currentModel, s.currentModels);
589
551
  renderModelPicker();
590
552
  rebuildModeList();
591
553
  rebuildEffortBar();
592
554
 
593
- // MODE remains Claude-specific until adapter modes become capabilities.
594
- var isClaude = vendor === "claude";
595
- if (configModeList && configModeList.parentElement) configModeList.parentElement.style.display = isClaude ? "" : "none";
555
+ var configuration = providerConfiguration();
556
+ if (configModeList && configModeList.parentElement) configModeList.parentElement.style.display = configuration.permissionModes ? "" : "none";
596
557
  rebuildThinkingSection();
597
- // capabilities.thinking means "emits a thinking stream" (true for every
598
- // vendor), NOT "accepts thinking config". The adaptive/extended toggle and
599
- // budget only feed Claude queries (sm.currentThinking), so the section
600
- // stays Claude-only until a dedicated thinkingConfig capability exists.
601
- if (configThinkingSection) configThinkingSection.style.display = isClaude ? "" : "none";
602
- // BETA section deprecated (1M context is now standard)
558
+ if (configThinkingSection) configThinkingSection.style.display = configuration.thinking ? "" : "none";
603
559
  if (configBetaSection) configBetaSection.style.display = "none";
604
- // APPROVAL, SANDBOX, WEB SEARCH are Codex-only
605
- rebuildCodexSections();
560
+ rebuildProviderSections();
606
561
  }
607
562
 
608
563
  export function getModelSupportsEffort() {
@@ -645,10 +600,10 @@ export function accumulateUsage(cost, usage) {
645
600
  // Assign directly instead of summing to avoid overcounting.
646
601
  if (cost != null) sessionUsage.cost = cost;
647
602
  if (usage) {
648
- sessionUsage.input += usage.input_tokens || usage.inputTokens || 0;
649
- sessionUsage.output += usage.output_tokens || usage.outputTokens || 0;
650
- sessionUsage.cacheRead += usage.cache_read_input_tokens || usage.cacheReadInputTokens || 0;
651
- sessionUsage.cacheWrite += usage.cache_creation_input_tokens || usage.cacheCreationInputTokens || 0;
603
+ sessionUsage.input += usage.inputTokens || 0;
604
+ sessionUsage.output += usage.outputTokens || 0;
605
+ sessionUsage.cacheRead += usage.cacheReadInputTokens || 0;
606
+ sessionUsage.cacheWrite += usage.cacheCreationInputTokens || 0;
652
607
  }
653
608
  sessionUsage.turns++;
654
609
  if (!store.get('replayingHistory')) updateUsagePanel();
@@ -724,14 +679,8 @@ export function toggleStatusPanel() {
724
679
 
725
680
  // --- Context panel ---
726
681
 
727
- export function resolveContextWindow(model, sdkValue) {
728
- var lc = (model || "").toLowerCase();
729
- if (lc.includes("[1m]")) return 1000000;
730
- if (sdkValue) return sdkValue;
731
- for (var key in KNOWN_CONTEXT_WINDOWS) {
732
- if (lc.includes(key)) return KNOWN_CONTEXT_WINDOWS[key];
733
- }
734
- return 200000;
682
+ export function resolveContextWindow(model, reported) {
683
+ return typeof reported === "number" && reported > 0 ? reported : 0;
735
684
  }
736
685
 
737
686
  export function contextPctClass(pct) {
@@ -744,21 +693,21 @@ export function updateContextPanel() {
744
693
  // only supplies currentInput from a verified last-turn snapshot; rich
745
694
  // context usage is more authoritative when available.
746
695
  var rich = store.get('richContextUsage');
747
- var hasRich = rich && (
748
- (typeof rich.totalTokens === "number" && typeof rich.maxTokens === "number" && rich.maxTokens > 0) ||
749
- (typeof rich.input_tokens === "number" && typeof rich.contextWindow === "number" && rich.contextWindow > 0)
750
- );
696
+ var richContext = rich && rich.context;
697
+ var hasRich = richContext && typeof richContext.usedTokens === "number" && typeof richContext.windowTokens === "number" && richContext.windowTokens > 0;
751
698
  var hasCurrent = typeof contextData.currentInput === "number";
752
699
  var hasContext = !!(hasRich || hasCurrent);
753
- var used = hasRich ? (typeof rich.totalTokens === "number" ? rich.totalTokens : rich.input_tokens) : (hasCurrent ? contextData.currentInput : 0);
754
- var win = hasRich ? (typeof rich.maxTokens === "number" ? rich.maxTokens : rich.contextWindow) : (hasCurrent ? contextData.contextWindow : 0);
700
+ var used = hasRich ? richContext.usedTokens : (hasCurrent ? contextData.currentInput : 0);
701
+ var win = hasRich ? richContext.windowTokens : (hasCurrent ? contextData.contextWindow : 0);
702
+ hasContext = hasContext && win > 0;
703
+ var measurement = hasRich ? richContext.measurement : store.get("contextMeasurement");
755
704
  var pct = win > 0 ? Math.min(100, (used / win) * 100) : 0;
756
705
  var cls = contextPctClass(pct);
757
706
  reportPaneContext({ pct: pct, used: used, win: win, cls: cls, model: contextData.model, cost: contextData.cost });
758
707
  // Panel bar
759
708
  contextBarFill.style.width = pct.toFixed(1) + "%";
760
709
  contextBarFill.className = "context-bar-fill" + cls;
761
- contextBarPct.textContent = pct.toFixed(0) + "%";
710
+ contextBarPct.textContent = hasContext ? pct.toFixed(0) + "%" : "-";
762
711
  // Mini bar
763
712
  if (contextMiniFill) {
764
713
  contextMiniFill.style.width = pct.toFixed(1) + "%";
@@ -807,7 +756,8 @@ export function updateContextPanel() {
807
756
  }
808
757
  }
809
758
  }
810
- contextUsedEl.textContent = formatTokens(used);
759
+ contextUsedEl.textContent = hasRich || hasCurrent ? (measurement === "estimated" ? "~" : "") + formatTokens(used) : "-";
760
+ contextUsedEl.title = hasRich || hasCurrent ? (measurement === "estimated" ? "Estimated current context" : "Observed current context") : "Current context unavailable";
811
761
  contextWindowEl.textContent = win > 0 ? formatTokens(win) : "-";
812
762
  contextMaxOutputEl.textContent = contextData.maxOutputTokens > 0 ? formatTokens(contextData.maxOutputTokens) : "-";
813
763
  contextInputEl.textContent = formatTokens(contextData.input);
@@ -829,7 +779,13 @@ export function updateContextPanel() {
829
779
  contextTurnsEl.textContent = String(contextData.turns);
830
780
  }
831
781
 
832
- export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens) {
782
+ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens, context) {
783
+ if (context) {
784
+ if (context.source === "last_turn") store.set({ richContextUsage: null });
785
+ store.set({ contextMeasurement: context.measurement || "unavailable" });
786
+ contextData.currentInput = typeof context.usedTokens === "number" ? context.usedTokens : null;
787
+ if (typeof context.windowTokens === "number") contextData.contextWindow = context.windowTokens;
788
+ }
833
789
  // cost is the SDK's total_cost_usd -- a cumulative running total, not a delta.
834
790
  if (cost != null) contextData.cost = cost;
835
791
  // Use latest turn values (not cumulative) since each turn's input_tokens
@@ -842,17 +798,14 @@ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens
842
798
  if (typeof lastStreamInputTokens === "number") {
843
799
  contextData.input = lastStreamInputTokens;
844
800
  } else {
845
- contextData.input = (usage.input_tokens || usage.inputTokens || 0)
846
- + (usage.cache_read_input_tokens || usage.cacheReadInputTokens || 0);
847
- }
848
- contextData.output = usage.output_tokens || usage.outputTokens || 0;
849
- contextData.cacheRead = usage.cache_read_input_tokens || usage.cacheReadInputTokens || 0;
850
- contextData.cacheWrite = usage.cache_creation_input_tokens || usage.cacheCreationInputTokens || 0;
851
- if (store.get('currentVendor') === "codex") {
852
- contextData.currentInput = typeof lastStreamInputTokens === "number" ? lastStreamInputTokens : null;
853
- } else {
854
- contextData.currentInput = typeof lastStreamInputTokens === "number" ? lastStreamInputTokens : contextData.input;
801
+ contextData.input = (usage.inputTokens || 0)
802
+ + (usage.cacheReadInputTokens || 0);
855
803
  }
804
+ contextData.output = usage.outputTokens || 0;
805
+ contextData.cacheRead = usage.cacheReadInputTokens || 0;
806
+ contextData.cacheWrite = usage.cacheCreationInputTokens || 0;
807
+ contextData.currentInput = context && typeof context.usedTokens === "number" ? context.usedTokens : null;
808
+ if (context && typeof context.windowTokens === "number") contextData.contextWindow = context.windowTokens;
856
809
  }
857
810
  contextData.turns++;
858
811
  if (modelUsage) {
@@ -864,23 +817,8 @@ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens
864
817
  // (e.g. CLI reports "claude-sonnet-4-6" even when running as opus[1m])
865
818
  var displayModel = store.get('currentModel') || m;
866
819
  contextData.model = displayModel;
867
- contextData.contextWindow = resolveContextWindow(displayModel, mu.contextWindow);
820
+ contextData.contextWindow = context && typeof context.windowTokens === "number" ? context.windowTokens : resolveContextWindow(displayModel, mu.contextWindow);
868
821
  if (mu.maxOutputTokens) contextData.maxOutputTokens = mu.maxOutputTokens;
869
- if (store.get('currentVendor') === "codex") {
870
- var snapshot = mu.contextSnapshot;
871
- if (snapshot) store.set({ richContextUsage: null });
872
- if (snapshot && snapshot.valid === true
873
- && typeof snapshot.inputTokens === "number"
874
- && typeof snapshot.contextWindow === "number"
875
- && snapshot.contextWindow > 0) {
876
- contextData.currentInput = snapshot.inputTokens;
877
- contextData.contextWindow = snapshot.contextWindow;
878
- } else {
879
- // An explicit invalid marker is authoritative: do not retain an
880
- // occupancy value from the previous live turn or history replay.
881
- contextData.currentInput = null;
882
- }
883
- }
884
822
 
885
823
  // thinkingTokens and costBasis are per-model and optional: absent on
886
824
  // older CLI builds and, for a resumed session, on the turns that ran
@@ -1009,8 +947,8 @@ export function renderCtxPopover() {
1009
947
  if (!ctxPopoverEl || !richContextUsage) return;
1010
948
  var d = richContextUsage;
1011
949
  var cats = d.categories || [];
1012
- var total = d.totalTokens != null ? d.totalTokens : (d.input_tokens || 0);
1013
- var max = d.maxTokens != null ? d.maxTokens : (d.contextWindow || 0);
950
+ var total = d.context && d.context.usedTokens || 0;
951
+ var max = d.context && d.context.windowTokens || 0;
1014
952
  var pct = d.percentage != null ? d.percentage : (max > 0 ? (total / max) * 100 : 0);
1015
953
 
1016
954
  var html = "";
@@ -1,3 +1,5 @@
1
+ import { prepareContextualWorkspaceDeparture } from './contextual-clay-workspace.js';
2
+ import { checkComposerDeparture, saveSessionRichDraft } from './session-rich-drafts.js';
1
3
  // app-projects.js - Project list, switching, add/remove project modals
2
4
  // Extracted from app.js (PR-29)
3
5
 
@@ -311,6 +313,7 @@ export function renderProjectList() {
311
313
  }).map(function (p) {
312
314
  return {
313
315
  slug: p.slug,
316
+ controlRuntimeId: p.controlRuntimeId || null,
314
317
  name: p.title || p.project,
315
318
  icon: p.icon || null,
316
319
  isProcessing: p.isProcessing,
@@ -389,6 +392,16 @@ export function resetClientState() {
389
392
 
390
393
  export function switchProject(slug) {
391
394
  if (!slug) return;
395
+ if (slug !== store.get('currentSlug')) {
396
+ try { checkComposerDeparture(); saveSessionRichDraft(); }
397
+ catch (error) { showToast(error.message, 'warn'); return; }
398
+ }
399
+ if (prepareContextualWorkspaceDeparture(slug) === false) return;
400
+ var target = cachedProjects.find(function (project) { return project.slug === slug; });
401
+ if (target && target.contentAccess === false && target.administrativeAccess === true) {
402
+ window.location.assign("/p/" + encodeURIComponent(slug) + "/");
403
+ return;
404
+ }
392
405
  document.cookie = "clay_last_project=" + encodeURIComponent(slug) + "; Path=/; SameSite=Strict; Max-Age=31536000";
393
406
  var st = store.snap();
394
407
  var ws = getWs();
@@ -22,34 +22,15 @@ function getVendorUsageMeta(vendor) {
22
22
  var vendors = store.get('vendorInfo') || {};
23
23
  var info = vendors[vendor];
24
24
  if (info && info.usageDashboard) return info.usageDashboard;
25
- var fallbacks = {
26
- codex: {
27
- icon: "/codex-avatar.png",
28
- alt: "Codex",
29
- href: "https://chatgpt.com/codex/settings/usage",
30
- title: "Check usage on ChatGPT",
31
- },
32
- claude: {
33
- icon: "/claude-code-avatar.png",
34
- alt: "Claude Code",
35
- href: "https://claude.ai/settings/usage",
36
- title: "Check usage on claude.ai",
37
- },
38
- };
39
- return fallbacks[vendor] || null;
25
+ return null;
40
26
  }
41
27
 
42
28
  function vendorTracksRateLimits(vendor) {
43
- var vendors = store.get('vendorInfo') || {};
44
- var info = vendors[vendor];
45
- if (info) return info.rateLimitTracking !== false;
46
- var legacyTrackedVendors = ["claude", "codex"];
47
- return legacyTrackedVendors.indexOf(vendor) !== -1;
29
+ return ((store.get('vendorInfo') || {})[vendor] || {}).rateLimitTracking === true;
48
30
  }
49
31
 
50
32
  function vendorSupportsScheduledMessages(vendor) {
51
- var scheduledMessageVendors = ["claude"];
52
- return scheduledMessageVendors.indexOf(vendor) !== -1;
33
+ return ((store.get('vendorInfo') || {})[vendor] || {}).rateLimitScheduling === true;
53
34
  }
54
35
 
55
36
  function rateLimitEventAppliesToPane(msg, state) {
@@ -60,7 +41,7 @@ function rateLimitEventAppliesToPane(msg, state) {
60
41
  if (msg.vendor) return msg.vendor === activeVendor;
61
42
  // Legacy Claude records predate vendor/session stamps. Never project them
62
43
  // into a non-Claude pane, where they would look like Claude usage.
63
- return activeVendor === "claude";
44
+ return ((state.vendorInfo || {})[activeVendor] || {}).acceptsUnstampedQuota === true;
64
45
  }
65
46
 
66
47
  function rateLimitStateKey(sessionId, vendor) {
@@ -84,7 +65,6 @@ function setActiveRateLimitState(next) {
84
65
  }
85
66
 
86
67
  function extraUsageDescription(msg) {
87
- if (msg.vendor && msg.vendor !== "claude") return "";
88
68
  var reason = msg.overageDisabledReason;
89
69
  if (reason === "out_of_credits") return "Extra usage has no credits remaining";
90
70
  if (reason === "fetch_error") return "Extra usage availability could not be checked";
@@ -350,7 +330,7 @@ export function initRateLimit() {
350
330
  export function handleRateLimitEvent(msg) {
351
331
  if (!rateLimitEventAppliesToPane(msg, store.snap())) return;
352
332
  // Old Codex history contains quota snapshots misrecorded as rejections.
353
- if (msg.vendor === "codex" && !msg.source) return;
333
+ if (msg.ignored === true) return;
354
334
  if (msg.resetsAt && msg.resetsAt <= Date.now()) {
355
335
  var expiredState = Object.assign({}, getActiveRateLimitState());
356
336
  if (msg.rateLimitType) delete expiredState[msg.rateLimitType];
@@ -408,12 +388,12 @@ export function handleRateLimitEvent(msg) {
408
388
 
409
389
  export function updateRateLimitUsage(msg) {
410
390
  if (!rateLimitEventAppliesToPane(msg, store.snap())) return;
411
- if (msg.vendor === "codex" && msg.source === "account_snapshot" && Array.isArray(msg.quotaWindows)) {
391
+ if (msg.source === "account_snapshot" && Array.isArray(msg.quotaWindows)) {
412
392
  applyQuotaSnapshot(msg);
413
393
  renderRateLimitUsage();
414
394
  return;
415
395
  }
416
- if (msg.vendor === "codex" && !msg.source) return;
396
+ if (msg.ignored === true) return;
417
397
  var activeVendor = store.get('currentVendor') || "claude";
418
398
  if (!vendorTracksRateLimits(activeVendor)) {
419
399
  renderRateLimitUsage();
@@ -8,10 +8,10 @@ import { refreshIcons } from './icons.js';
8
8
  import { closeToolGroup } from './tools.js';
9
9
  import { sendMessage, hasSendableContent } from './input.js';
10
10
  import { getChatLayout } from './theme.js';
11
- import { addToMessages, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, getActivityEl } from './chat-render-runtime.js';
11
+ import { addToMessages, addHistoryIndex, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, getActivityEl } from './chat-render-runtime.js';
12
12
  import { resolveProjectAssistantIdentity, applyProjectAssistantIdentity } from './project-chat-identity.js';
13
13
  export { VENDOR_ORDER, EXPERIMENTAL_VENDORS, isExperimentalVendor } from './vendor-priority.js';
14
- export { initRendering, addToMessages, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, getActivityEl, setActivityEl, getIsUserScrolledUp, setIsUserScrolledUp, getStickyBottom, armStickyBottom, disarmStickyBottom, VENDOR_AVATARS, VENDOR_NAMES, VENDOR_HOMEPAGES } from './chat-render-runtime.js';
14
+ export { initRendering, addToMessages, addHistoryIndex, scrollToBottom, forceScrollToBottom, getMsgTime, shouldGroupMessage, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, getActivityEl, setActivityEl, getIsUserScrolledUp, setIsUserScrolledUp, getStickyBottom, armStickyBottom, disarmStickyBottom, VENDOR_AVATARS, VENDOR_NAMES, VENDOR_HOMEPAGES } from './chat-render-runtime.js';
15
15
  export { addUserMessage, addSystemMessage, addConflictMessage, addContextOverflowMessage } from './app-message-cards.js';
16
16
 
17
17
  // --- Module-owned state (not in store) ---
@@ -44,7 +44,8 @@ export function addCopyHandler(msgEl, rawText) {
44
44
  }
45
45
 
46
46
  export function appendDelta(text) {
47
- ensureAssistantBlock();
47
+ var assistantEl = ensureAssistantBlock();
48
+ if (store.get('replayingHistory')) addHistoryIndex(assistantEl, store.get('currentHistoryIndexes') || store.get('currentHistoryIndex'));
48
49
  streamBuffer += text;
49
50
  if (store.get('replayingHistory')) {
50
51
  store.set({ currentFullText: store.get('currentFullText') + streamBuffer });
@@ -1,37 +1,11 @@
1
1
  // Centralized local avatar URL builder for people and Mates.
2
- import { imprintDataUrl, mateMarkDataUrl } from './avatar-imprint.js';
3
-
4
- var mateMarkCache = new Map();
5
-
6
- // Historical DiceBear 9.x choices, now generated by Clay's local server.
7
- export var MATE_AVATAR_STYLES = [
8
- { id: 'thumbs', name: 'Thumbs' },
9
- { id: 'bottts', name: 'Bots' },
10
- { id: 'pixel-art', name: 'Pixel' },
11
- { id: 'adventurer', name: 'Adventurer' },
12
- { id: 'micah', name: 'Micah' },
13
- { id: 'fun-emoji', name: 'Emoji' },
14
- { id: 'icons', name: 'Icons' },
15
- ];
2
+ import { imprintDataUrl } from './avatar-imprint.js';
16
3
 
17
4
  export function avatarUrl(style, seed, size) {
18
5
  // Legacy user styles remain part of the seed identity, never the artwork.
19
6
  return imprintDataUrl({ style: style || 'imprint', seed: seed || 'anonymous', size: size || 64 });
20
7
  }
21
8
 
22
- export function mateStyleAvatarUrl(style, seed, size) {
23
- var normalizedStyle = style || 'imprint';
24
- var normalizedSeed = seed || 'anonymous';
25
- var normalizedSize = size || 64;
26
- var isHistorical = MATE_AVATAR_STYLES.some(function (entry) { return entry.id === normalizedStyle; });
27
- if (isHistorical) {
28
- return '/api/generated-avatar?style=' + encodeURIComponent(normalizedStyle)
29
- + '&seed=' + encodeURIComponent(normalizedSeed)
30
- + '&size=' + encodeURIComponent(normalizedSize);
31
- }
32
- return imprintDataUrl({ style: normalizedStyle, seed: normalizedSeed, size: normalizedSize });
33
- }
34
-
35
9
  // Use the same bounded account identity for fresh fallbacks across every surface.
36
10
  export function userAvatarSeed(user) {
37
11
  var profile = user && user.profile ? user.profile : user;
@@ -48,24 +22,24 @@ export function userAvatarUrl(user, size) {
48
22
  return avatarUrl(style, userAvatarSeed(user), size);
49
23
  }
50
24
 
51
- export function mateMarkUrl(seed, size) {
52
- var cacheKey = [seed || 'mate', size || 64].join('|');
53
- if (mateMarkCache.has(cacheKey)) return mateMarkCache.get(cacheKey);
54
- var url = mateMarkDataUrl({ seed: seed || 'mate', size: size || 64 });
55
- if (mateMarkCache.size >= 256) mateMarkCache.delete(mateMarkCache.keys().next().value);
56
- mateMarkCache.set(cacheKey, url);
57
- return url;
25
+ function mappedMateAvatarId(mate) {
26
+ var p = mate.profile || mate;
27
+ var key = JSON.stringify([mate.id || '', p.avatarStyle || 'imprint', p.avatarSeed || mate.id || p.displayName || mate.name || 'Mate']);
28
+ var hash = 2166136261;
29
+ for (var i = 0; i < key.length; i++) hash = Math.imul(hash ^ key.charCodeAt(i), 16777619) >>> 0;
30
+ var index = hash % 96;
31
+ return (index < 48 ? 'B' : 'C') + String(index % 48 + 1).padStart(2, '0');
32
+ }
33
+
34
+ export function mateCatalogAvatarUrl(id) {
35
+ if (id === 'lead-clay') return '/mate-avatars/lead-clay.png?v=4';
36
+ return typeof id === 'string' && /^[BC](0[1-9]|[1-3][0-9]|4[0-8])$/.test(id) ? '/mate-avatars/' + id + '.png?v=4' : '';
58
37
  }
59
38
 
60
39
  // Build avatar URL for a mate object, preferring custom avatar if set.
61
40
  export function mateAvatarUrl(mate, size) {
62
- if (!mate) return mateMarkUrl('mate', size);
41
+ if (!mate) return mateCatalogAvatarUrl('B01');
63
42
  var p = mate.profile || mate;
64
43
  if (p.avatarCustom || mate.avatarCustom) return p.avatarCustom || mate.avatarCustom;
65
- var identity = p.displayName || mate.name || mate.displayName || 'Mate';
66
- var style = p.avatarStyle || mate.avatarStyle || 'imprint';
67
- if (style !== 'imprint' && style !== 'initial') {
68
- return mateStyleAvatarUrl(style, p.avatarSeed || mate.avatarSeed || mate.id || identity, size);
69
- }
70
- return mateMarkUrl(identity, size);
44
+ return mateCatalogAvatarUrl(p.avatarCatalogId) || mateCatalogAvatarUrl(mate.builtinKey === 'clay' ? 'lead-clay' : mappedMateAvatarId(mate));
71
45
  }
@@ -7,6 +7,7 @@ import { getProjectAssistantPlaceholder } from './project-chat-identity.js';
7
7
  export var VENDOR_AVATARS = {
8
8
  claude: "/claude-code-avatar.png",
9
9
  codex: "/codex-avatar.png",
10
+ muse: "/muse-avatar.svg",
10
11
  antigravity: "/antigravity-avatar.png",
11
12
  opencode: "/opencode-avatar.svg",
12
13
  kimi: "/kimi-avatar.svg",
@@ -20,6 +21,7 @@ export var VENDOR_AVATARS = {
20
21
  export var VENDOR_NAMES = {
21
22
  claude: "Claude Code",
22
23
  codex: "Codex",
24
+ muse: "Muse Code",
23
25
  antigravity: "Antigravity CLI",
24
26
  opencode: "OpenCode",
25
27
  kimi: "Kimi Code",
@@ -33,6 +35,7 @@ export var VENDOR_NAMES = {
33
35
  export var VENDOR_HOMEPAGES = {
34
36
  claude: "https://claude.com/product/claude-code",
35
37
  codex: "https://openai.com/codex/",
38
+ muse: "https://dev.meta.ai/docs/muse-code",
36
39
  antigravity: "https://antigravity.google/product/antigravity-cli",
37
40
  opencode: "https://opencode.ai/",
38
41
  kimi: "https://www.kimi.com/code/",
@@ -155,11 +158,28 @@ export function setIsUserScrolledUp(value) { isUserScrolledUp = value; }
155
158
 
156
159
  export function addToMessages(element) {
157
160
  var messagesEl = getMessagesEl();
161
+ addHistoryIndex(element, store.get('currentHistoryIndexes') || store.get('currentHistoryIndex'));
158
162
  if (prependAnchor) messagesEl.insertBefore(element, prependAnchor);
159
163
  else messagesEl.appendChild(element);
160
164
  keepActiveThinkingAtTail();
161
165
  }
162
166
 
167
+ export function addHistoryIndex(element, historyIndex) {
168
+ if (Array.isArray(historyIndex)) {
169
+ if (!element) return;
170
+ var indexes = new Set((element.dataset.historyIndexes || "").split(",").filter(Boolean));
171
+ for (var i = 0; i < historyIndex.length; i++) {
172
+ if (Number.isSafeInteger(historyIndex[i]) && historyIndex[i] >= 0) indexes.add(String(historyIndex[i]));
173
+ }
174
+ element.dataset.historyIndexes = Array.from(indexes).join(",");
175
+ return;
176
+ }
177
+ if (!element || !Number.isSafeInteger(historyIndex) || historyIndex < 0) return;
178
+ var existing = element.dataset.historyIndexes || "";
179
+ if (existing.split(",").indexOf(String(historyIndex)) !== -1) return;
180
+ element.dataset.historyIndexes = existing ? existing + "," + historyIndex : String(historyIndex);
181
+ }
182
+
163
183
  // Thinking is a single accumulating record for the active turn. Other live
164
184
  // transcript entries may arrive between reasoning segments, so keep only the
165
185
  // currently active record after the tail activity indicator.
@@ -0,0 +1,47 @@
1
+ import { store } from './store.js';
2
+ import { iconHtml, refreshIcons } from './icons.js';
3
+ import { showToast } from './utils.js';
4
+ import { forwardPaneBrowserLink } from './pane-browser-bridge.js';
5
+
6
+ function escape(value) { return String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;'); }
7
+ export function browserLinkTarget(href) {
8
+ if (typeof href !== 'string' || !href.startsWith('browser:') || href.length > 8200) return null;
9
+ var raw = href.slice(8);
10
+ if (!/^https?:\/\//i.test(raw) || /[\u0000-\u0020]/.test(raw)) return null;
11
+ try {
12
+ var url = new URL(raw);
13
+ if (url.username || url.password || !['http:', 'https:'].includes(url.protocol)) return null;
14
+ return url.href;
15
+ } catch (error) { return null; }
16
+ }
17
+ export function renderBrowserLink(href, title, text) {
18
+ var url = browserLinkTarget(href);
19
+ if (!url) return null;
20
+ var label = String(text || '').replace(/<[^>]*>/g, '').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#39;/g, "'").trim();
21
+ if (!label || label === href || label === url) label = new URL(url).host;
22
+ return '<button type="button" class="clay-browser-link clayos-record-link" data-browser-url="' + escape(url) + '" data-browser-project="' + escape(store.get('currentSlug') || '') + '" title="' + escape('Open in Clay Browser · ' + url) + '" aria-label="' + escape('Open in Clay Browser: ' + label) + '">' + iconHtml('globe') + '<span>Browser</span><small>' + escape(label) + '</small></button>';
23
+ }
24
+ export function enhanceBrowserLinks(root) {
25
+ if (!root || typeof document === 'undefined') return;
26
+ root.querySelectorAll('a[href]').forEach(function (anchor) {
27
+ if (anchor.closest('pre, code, button')) return;
28
+ var html = renderBrowserLink(anchor.getAttribute('href'), '', anchor.textContent);
29
+ if (html) { var template = document.createElement('template'); template.innerHTML = html; anchor.replaceWith(template.content); }
30
+ });
31
+ initBrowserLinks();
32
+ refreshIcons();
33
+ }
34
+ export function initBrowserLinks() {
35
+ if (store.get('browserLinksBound')) return;
36
+ store.set({ browserLinksBound: true });
37
+ document.addEventListener('click', function (event) {
38
+ var button = event.target.closest && event.target.closest('.clay-browser-link');
39
+ if (!button) return;
40
+ event.preventDefault(); event.stopPropagation();
41
+ var url = browserLinkTarget('browser:' + button.dataset.browserUrl);
42
+ if (!url) { showToast('This browser link is invalid.', 'warn'); return; }
43
+ if (button.dataset.browserProject && button.dataset.browserProject !== store.get('currentSlug')) { showToast('Open this link from its original project.', 'warn'); return; }
44
+ if (forwardPaneBrowserLink(url)) return;
45
+ import('./shared-browser.js').then(function (module) { module.openSharedBrowserAt(url); }).catch(function (error) { showToast(error.message || 'Could not open the browser.', 'warn'); });
46
+ });
47
+ }