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
@@ -0,0 +1,281 @@
1
+ // Shared acquisition service for vendor account usage.
2
+ //
3
+ // One place decides whether a direct read is allowed, runs it with a bounded
4
+ // timeout (cancelling the underlying work), shares an in-flight read between
5
+ // callers, caches results and backs off after failures. Provider-specific
6
+ // parsing lives in the reader modules; the capability table says which vendors
7
+ // have a reader at all.
8
+ //
9
+ // Identity: a direct read is allowed only when the credential provably belongs
10
+ // to the requester. In account mode, vendors that run as the server's own user
11
+ // (Muse, Kimi, Grok, Kiro) and Codex without a mapped OS user are refused with a
12
+ // clear status instead of showing the server user's account to every owner.
13
+ // Cache entries are keyed by owner + OS user + vendor. Where a cheap credential
14
+ // fingerprint exists (Kimi, Grok) it is re-read before cached figures are
15
+ // returned (including while a read is in flight) and again when a read
16
+ // completes; rotation or deletion discards the figures. Figures from a source
17
+ // whose account cannot be verified (Muse, Kiro, Claude, Codex) are shown for at
18
+ // most one TTL (60 s) from the reading: after that, in peek and read alike,
19
+ // they are replaced by an explicit "expired" state with no numbers, and a failed
20
+ // refresh never extends them. Verified-identity figures may be kept, marked
21
+ // stale, across a transient failure for at most `staleMaxMs`. A Claude reading
22
+ // is bound to the exact live session and query that produced it and is dropped
23
+ // when that source is replaced. Sign-in failures and account changes always drop
24
+ // figures. A result is used only if the caller is still current when the work
25
+ // starts, while it waits, and when it settles.
26
+
27
+ var capabilities = require("./vendor-usage-capabilities");
28
+ var metrics = require("./vendor-usage-metrics");
29
+ var nativeReaders = require("./vendor-usage-native-readers");
30
+ var httpReaders = require("./vendor-usage-http-readers");
31
+ var acpReaders = require("./vendor-usage-acp-readers");
32
+
33
+ var DEFAULTS = { ttlMs: 60 * 1000, minForceMs: 10 * 1000, timeoutMs: 15 * 1000, backoffBaseMs: 30 * 1000, backoffMaxMs: 10 * 60 * 1000, noAuthRetryMs: 5 * 60 * 1000, staleMaxMs: 10 * 60 * 1000 };
34
+
35
+ // Failures that mean the credential or account is not (or no longer) the one
36
+ // the cached figures described, so those figures must not be shown again.
37
+ var DROPS_FIGURES = ["no_auth", "expired_auth", "unauthorized", "untrusted_origin", "account_changed", "source_changed"];
38
+
39
+ var MESSAGES = {
40
+ identity_unprovable: "Clay cannot prove which account this vendor uses for you, so it will not read one.",
41
+ account_changed: "The saved sign-in changed while usage was being read; figures from the previous account were discarded.",
42
+ source_changed: "The session that reported this usage was replaced; its figures were discarded.",
43
+ expired: "The last reading is too old and its account cannot be verified, so it is not shown. Read again.",
44
+ };
45
+
46
+ function defaultFetchJson(timeoutMs) {
47
+ return async function (url, headers) {
48
+ var response = await fetch(url, { headers: headers, signal: AbortSignal.timeout(timeoutMs), redirect: "error" });
49
+ var body = null;
50
+ try { body = await response.json(); } catch (e) { body = null; }
51
+ return { status: response.status, body: body };
52
+ };
53
+ }
54
+
55
+ function createUsageService(options) {
56
+ options = options || {};
57
+ var now = typeof options.now === "function" ? options.now : Date.now;
58
+ var timing = Object.assign({}, DEFAULTS, options.timing || {});
59
+ var fs = require("fs");
60
+ var os = require("os");
61
+ var httpDeps = Object.assign({
62
+ readText: function (file) { return fs.promises.readFile(file, "utf8"); },
63
+ readTextSync: function (file) { return fs.readFileSync(file, "utf8"); },
64
+ fetchJson: defaultFetchJson(timing.timeoutMs),
65
+ env: process.env, homedir: os.homedir,
66
+ }, options.http || {});
67
+ httpDeps.now = now;
68
+ var acpDeps = Object.assign({
69
+ binary: function () { try { return require("./yoke/kiro-acp-server").findKiroPath(); } catch (e) { return null; } },
70
+ spawn: function (command, args, spawnOptions) { return require("child_process").spawn(command, args, spawnOptions); },
71
+ tmpdir: os.tmpdir, env: process.env,
72
+ }, options.acp || {});
73
+ var readers = Object.assign({
74
+ claude: nativeReaders.claude,
75
+ codex: nativeReaders.codex,
76
+ muse: nativeReaders.muse,
77
+ kimi: function () { return httpReaders.kimi(httpDeps); },
78
+ grok: function () { return httpReaders.grok(httpDeps); },
79
+ kiro: function (context) { return acpReaders.kiro(context, acpDeps); },
80
+ }, options.readers || {});
81
+ var identities = Object.assign({
82
+ kimi: function () { return httpReaders.identities.kimi(httpDeps); },
83
+ grok: function () { return httpReaders.identities.grok(httpDeps); },
84
+ }, options.identities || {});
85
+ var multiUser = typeof options.multiUser === "function" ? options.multiUser : function () { return false; };
86
+ var osUsersEnabled = typeof options.osUsersEnabled === "function" ? options.osUsersEnabled : function () { return false; };
87
+ var sourceLive = typeof options.sourceLive === "function" ? options.sourceLive : function () { return true; };
88
+ var getAdapter = typeof options.getAdapter === "function" ? options.getAdapter : function () { return null; };
89
+ var entries = Object.create(null);
90
+ var generations = Object.create(null);
91
+
92
+ function keyOf(owner, linuxUser, vendor) { return owner + "\u0000" + (linuxUser || "") + "\u0000" + vendor; }
93
+
94
+ function identityOf(vendor) {
95
+ try { return identities[vendor] ? identities[vendor]() : null; } catch (e) { return null; }
96
+ }
97
+
98
+ function refusal(vendor, linuxUser, hasSession) {
99
+ var cap = capabilities.capabilityFor(vendor);
100
+ if (cap.mode !== "query") return { status: "unintegrated", failureKind: "unintegrated", message: cap.reason || "No usage source is integrated." };
101
+ if (cap.identity === "owner-session") return hasSession === false ? { status: "idle", failureKind: null, message: null } : null;
102
+ if (!multiUser()) return null;
103
+ if (cap.identity === "owner-os-user" && osUsersEnabled() && linuxUser) return null;
104
+ return { status: "refused", failureKind: "identity_unprovable", message: MESSAGES.identity_unprovable };
105
+ }
106
+
107
+ function blank(status, failureKind, message) {
108
+ return { status: status, metrics: [], fetchedAtMs: null, stale: false, failureKind: failureKind || null, message: message || null, retryAtMs: null, planType: null, accountId: null, fetching: false };
109
+ }
110
+
111
+ function bindingOf(session) {
112
+ return session ? { session: session, query: session.queryInstance } : null;
113
+ }
114
+
115
+ function bindingLive(binding) {
116
+ return !binding || (binding.session.queryInstance === binding.query && sourceLive(binding.session) !== false);
117
+ }
118
+
119
+ function sameBinding(a, b) {
120
+ return (!a && !b) || (!!a && !!b && a.session === b.session && a.query === b.query);
121
+ }
122
+
123
+ // Figures whose account cannot be verified live only for one TTL; verified
124
+ // ones may stay (stale) a bounded while. Past that the numbers are removed.
125
+ function expire(entry) {
126
+ var a = entry.account;
127
+ if (!a.metrics.length) return;
128
+ var age = a.fetchedAtMs === null ? Infinity : now() - a.fetchedAtMs;
129
+ var limit = entry.identity ? timing.staleMaxMs : timing.ttlMs;
130
+ if (age < limit) return;
131
+ entry.account = { status: "idle", metrics: [], fetchedAtMs: null, stale: false, failureKind: "expired", message: MESSAGES.expired, planType: null, accountId: null };
132
+ entry.identity = null;
133
+ }
134
+
135
+ function snapshotOf(entry) {
136
+ expire(entry);
137
+ var a = entry.account;
138
+ return {
139
+ status: a.status, metrics: a.metrics.slice(), fetchedAtMs: a.fetchedAtMs, stale: a.stale === true,
140
+ failureKind: a.failureKind || null, message: a.message || null, retryAtMs: entry.retryAtMs || null,
141
+ planType: a.planType || null, accountId: a.accountId || null, sourceSessionId: a.sourceSessionId === undefined ? null : a.sourceSessionId,
142
+ fetching: !!entry.inflight,
143
+ };
144
+ }
145
+
146
+ function emptyEntry() {
147
+ return { account: { status: "idle", metrics: [], fetchedAtMs: null }, identity: null, binding: null, failures: 0, retryAtMs: 0, inflight: null, token: 0 };
148
+ }
149
+
150
+ function drop(key) {
151
+ var entry = entries[key];
152
+ if (!entry) return;
153
+ entry.token++;
154
+ delete entries[key];
155
+ }
156
+
157
+ // True when the cached projection no longer describes the live source: the
158
+ // credential fingerprint differs (rotation or deletion, even mid-read) or the
159
+ // session/query that produced it was replaced.
160
+ function sourceChanged(entry, vendor) {
161
+ if (entry.identity && identityOf(vendor) !== entry.identity) return true;
162
+ return !bindingLive(entry.binding);
163
+ }
164
+
165
+ // The current known state, without starting a read.
166
+ function peek(owner, linuxUser, vendor) {
167
+ var refused = refusal(vendor, linuxUser, null);
168
+ if (refused && refused.status !== "idle") return blank(refused.status, refused.failureKind, refused.message);
169
+ var key = keyOf(owner, linuxUser, vendor);
170
+ var entry = entries[key];
171
+ if (!entry) return blank("idle");
172
+ if (sourceChanged(entry, vendor)) { drop(key); return blank("idle"); }
173
+ return snapshotOf(entry);
174
+ }
175
+
176
+ function failureDelay(entry, kind) {
177
+ if (kind === "no_auth") return timing.noAuthRetryMs;
178
+ return Math.min(timing.backoffMaxMs, timing.backoffBaseMs * Math.pow(2, Math.max(0, entry.failures - 1)));
179
+ }
180
+
181
+ function settleFailure(entry, error) {
182
+ var kind = error && error.failureKind ? error.failureKind : "error";
183
+ entry.failures += 1;
184
+ entry.retryAtMs = now() + failureDelay(entry, kind);
185
+ var prior = entry.account;
186
+ // Only a transient failure keeps the last good figures (marked stale);
187
+ // a sign-in problem or account change must not leave a former account's numbers.
188
+ // Figures survive only when their account is verifiable (a fingerprint) and
189
+ // they are still inside the bounded stale window.
190
+ var keep = DROPS_FIGURES.indexOf(kind) === -1 && !!entry.identity && prior.metrics.length > 0 && (prior.status === "ok" || prior.stale === true) && prior.fetchedAtMs !== null && now() - prior.fetchedAtMs < timing.staleMaxMs;
191
+ entry.account = {
192
+ status: kind === "no_auth" ? "no_auth" : kind === "expired_auth" ? "expired_auth" : "error",
193
+ metrics: keep ? prior.metrics : [], fetchedAtMs: keep ? prior.fetchedAtMs : null, stale: keep,
194
+ failureKind: kind, message: error && error.failureKind ? error.message : "Usage could not be read.",
195
+ planType: keep ? prior.planType || null : null, accountId: keep ? prior.accountId || null : null,
196
+ sourceSessionId: keep ? prior.sourceSessionId : null,
197
+ };
198
+ if (!keep) { entry.identity = null; entry.binding = null; }
199
+ }
200
+
201
+ function withTimeout(promise, controller) {
202
+ var timer;
203
+ var limit = new Promise(function (resolve, reject) {
204
+ timer = setTimeout(function () {
205
+ controller.abort();
206
+ reject(nativeReaders.failure("timeout", "The usage read timed out."));
207
+ }, timing.timeoutMs);
208
+ });
209
+ return Promise.race([promise, limit]).then(function (v) { clearTimeout(timer); return v; }, function (e) { clearTimeout(timer); throw e; });
210
+ }
211
+
212
+ // Resolves to a snapshot, or null when the result must not be used because
213
+ // the caller or the account changed. Nothing is started for a caller that is
214
+ // already stale.
215
+ async function read(request) {
216
+ var owner = request.owner, linuxUser = request.linuxUser || null, vendor = request.vendor;
217
+ var isCurrent = typeof request.isCurrent === "function" ? request.isCurrent : function () { return true; };
218
+ if (!isCurrent()) return null;
219
+ var refused = refusal(vendor, linuxUser, !!request.session);
220
+ if (refused) return refused.status === "idle" ? peek(owner, linuxUser, vendor) : blank(refused.status, refused.failureKind, refused.message);
221
+ var key = keyOf(owner, linuxUser, vendor);
222
+ var entry = entries[key] || (entries[key] = emptyEntry());
223
+ var startedGeneration = generations[owner] || 0;
224
+ var before = identityOf(vendor);
225
+ var binding = bindingOf(request.session);
226
+ if ((entry.identity && before !== entry.identity) || !bindingLive(entry.binding) || (entry.binding && !sameBinding(entry.binding, binding))) {
227
+ drop(key);
228
+ entry = entries[key] = emptyEntry();
229
+ }
230
+ expire(entry);
231
+ var current = now();
232
+ var age = entry.account.fetchedAtMs === null ? Infinity : current - entry.account.fetchedAtMs;
233
+ var coolingDown = entry.retryAtMs > current;
234
+ var fresh = entry.account.status === "ok" && age < (request.force ? timing.minForceMs : timing.ttlMs);
235
+ if (!entry.inflight && (fresh || coolingDown)) return isCurrent() ? snapshotOf(entry) : null;
236
+ if (!entry.inflight) {
237
+ var token = ++entry.token;
238
+ var controller = new AbortController();
239
+ var context = { adapter: getAdapter(vendor), linuxUser: linuxUser, session: request.session || null, signal: controller.signal };
240
+ entry.binding = binding;
241
+ var run = Promise.resolve().then(function () { return withTimeout(readers[vendor](context), controller); });
242
+ entry.inflight = run.then(function (result) {
243
+ if (entry.token !== token || (generations[owner] || 0) !== startedGeneration) return;
244
+ var list = (result && Array.isArray(result.metrics) ? result.metrics : []).filter(metrics.valid);
245
+ if (list.length === 0) throw nativeReaders.failure("unavailable", "The vendor reported no usage figures for this account.");
246
+ if (!bindingLive(binding)) throw nativeReaders.failure("source_changed", MESSAGES.source_changed);
247
+ // The credential is re-read AFTER the response. For a fingerprinted
248
+ // source it must equal the one the reader used (or, failing that, the
249
+ // one seen before the call); rotation, deletion or first appearance
250
+ // mid-read means neither account's figures can be attributed.
251
+ var expected = result.identity || before;
252
+ if (identities[vendor]) {
253
+ var fresh = identityOf(vendor);
254
+ if (fresh !== expected) throw nativeReaders.failure("account_changed", MESSAGES.account_changed);
255
+ }
256
+ entry.failures = 0; entry.retryAtMs = 0;
257
+ entry.identity = identities[vendor] ? expected || null : null;
258
+ entry.account = { status: "ok", metrics: list, fetchedAtMs: Number.isFinite(result.observedAtMs) ? result.observedAtMs : now(), stale: false, planType: result.planType || null, accountId: result.accountId || null, sourceSessionId: result.sourceSessionId === undefined ? null : result.sourceSessionId };
259
+ }).catch(function (error) {
260
+ if (entry.token !== token || (generations[owner] || 0) !== startedGeneration) return;
261
+ settleFailure(entry, error);
262
+ }).then(function () { if (entry.token === token) entry.inflight = null; });
263
+ }
264
+ await entry.inflight;
265
+ if (!isCurrent() || (generations[owner] || 0) !== startedGeneration || entries[key] !== entry) return null;
266
+ return snapshotOf(entry);
267
+ }
268
+
269
+ // Forget everything for an owner (account switch, logout, access change);
270
+ // reads still in flight can no longer store or return a result.
271
+ function invalidate(owner) {
272
+ generations[owner] = (generations[owner] || 0) + 1;
273
+ Object.keys(entries).forEach(function (key) {
274
+ if (key.indexOf(owner + "\u0000") === 0) drop(key);
275
+ });
276
+ }
277
+
278
+ return { read: read, peek: peek, invalidate: invalidate, refusal: refusal };
279
+ }
280
+
281
+ module.exports = { createUsageService: createUsageService, DEFAULTS: DEFAULTS };
@@ -19,6 +19,8 @@ function attachWorkspaceAssignmentService(ctx) {
19
19
  var records = [];
20
20
  var unsubscribers = {};
21
21
  var pendingRestartReplay = {};
22
+ var presentations = new WeakMap();
23
+ var presentationTargets = new WeakMap();
22
24
 
23
25
  function recordFile(userId) {
24
26
  return storageDir ? path.join(storageDir, userStorageKey(userId)) : null;
@@ -130,7 +132,27 @@ function attachWorkspaceAssignmentService(ctx) {
130
132
  return { project: project, manager: manager, session: session };
131
133
  }
132
134
 
135
+ function present(record, principal) {
136
+ try {
137
+ var display = ctx.getPresentation && ctx.getPresentation(principal), project = exactTarget(record);
138
+ if (!display || !project) return;
139
+ var view = { project: project, session: null, origin: null }; presentationTargets.set(record, view);
140
+ if (record.delivery === 'follow_up') project.getSessionManager().sessions.forEach(function (session) { if (ctx.sessionRef(record.targetProjectSlug, session) === record.targetSessionRef) { view.session = session; view.origin = session.sessionOriginId; } });
141
+ var projection = require('./clay-control-target-projection');
142
+ var target = view.session ? { kind: 'session', projectSlug: record.targetProjectSlug, sessionId: view.session.localId, sessionOriginId: view.origin } : { kind: 'project', projectSlug: record.targetProjectSlug, runtimeId: projection.runtime(project.getSessionManager()) };
143
+ var observer = display.track('assignment', record.delivery === 'follow_up' ? 'follow_up' : 'assign', target, function () {
144
+ if (exactTarget(record) !== project || view.session && (project.getSessionManager().sessions.get(view.session.localId) !== view.session || view.session.sessionOriginId !== view.origin || (view.session.ownerId || null) !== (record.userId || null))) throw new Error('Assignment target changed.');
145
+ }, 'review');
146
+ if (observer) { presentations.set(record, observer); var expiry = setTimeout(function () { presentations.delete(record); }, 300000); expiry.unref(); }
147
+ } catch (error) { /* Presentation never changes the assignment decision. */ }
148
+ }
133
149
  function emit(record, eventType) {
150
+ var observer = presentations.get(record);
151
+ if (observer) {
152
+ if (record.status === 'starting') observer.phase('queued');
153
+ else if (record.status === 'running') observer.phase('running');
154
+ else if (record.status !== 'proposed') { observer.finish({ status: record.status === 'interrupted' ? 'failed' : record.status, outcome: record.status === 'interrupted' ? 'uncertain' : undefined }); presentations.delete(record); }
155
+ }
134
156
  var source = exactSource(record);
135
157
  if (!source) return;
136
158
  source.manager.sendAndRecord(source.session, {
@@ -193,6 +215,7 @@ function attachWorkspaceAssignmentService(ctx) {
193
215
  if (!exactSource(record)) throw new Error("Source conversation is no longer available.");
194
216
  records.push(record);
195
217
  saveUser(record.userId);
218
+ present(record, principal);
196
219
  emit(record, "project_assignment_proposal");
197
220
  return publicRecord(record);
198
221
  }
@@ -229,6 +252,7 @@ function attachWorkspaceAssignmentService(ctx) {
229
252
  if (!exactSource(record)) throw new Error("Source conversation is no longer available.");
230
253
  records.push(record);
231
254
  saveUser(record.userId);
255
+ present(record, principal);
232
256
  emit(record, "project_assignment_proposal");
233
257
  return publicRecord(record);
234
258
  }
@@ -267,6 +291,7 @@ function attachWorkspaceAssignmentService(ctx) {
267
291
  }
268
292
 
269
293
  function watch(record, manager, session) {
294
+ var view = presentationTargets.get(record); if (view) { view.session = session; view.origin = session.sessionOriginId; var observer = presentations.get(record); if (observer && observer.target) observer.target({ kind: 'session', projectSlug: record.targetProjectSlug, sessionId: session.localId, sessionOriginId: session.sessionOriginId }); }
270
295
  var unsubscribe = manager.subscribeSession(session.localId, function (event) {
271
296
  if (event.type === "session_id") {
272
297
  record.targetSessionRef = ctx.sessionRef(record.targetProjectSlug, session);
@@ -96,7 +96,10 @@ function attachWorkspaceQueryAccess(deps) {
96
96
  // as ownership would let a stale status skip the authoritative record.
97
97
  var access = record(status);
98
98
  if (!access) return denied;
99
- if (access.ownerId && access.ownerId === principal.userId) return { owned: true, accessible: true };
99
+ if (access.ownerId && access.ownerId === principal.userId) {
100
+ var ownerPermitted = permitted(principal.userId, access);
101
+ return { owned: ownerPermitted, accessible: ownerPermitted };
102
+ }
100
103
  return { owned: false, accessible: permitted(principal.userId, access) };
101
104
  }
102
105
 
@@ -32,7 +32,7 @@ function handler(bound, method) {
32
32
  };
33
33
  }
34
34
 
35
- var SESSION_CITATION = " When citing a returned session in user-visible text, write [clayos/<sessionRef> — short label] so Clay Studio renders an owner-validated session control.";
35
+ var SESSION_CITATION = " Cite returned sessions as Markdown links: [short human label](session:OPAQUE_REFERENCE), replacing the entire target with the exact returned sessionRef. Do not prepend a project name, change the opaque reference, or wrap citations in backticks/code. For a specific returned entry, append #entry-<entryIndex> using its exact returned entry index. Legacy [clayos/<sessionRef> — short label] remains supported. Labels are presentation only; Clay Studio resolves the exact reference with the authenticated owner's permissions.";
36
36
 
37
37
  function commonTools(bound) {
38
38
  return [
@@ -168,6 +168,13 @@ function attachWorkspaceQueryService(ctx) {
168
168
  } else if (source.session.ownerId) {
169
169
  return null;
170
170
  }
171
+ if (source.viewerId !== undefined) {
172
+ var viewerPrincipal = {
173
+ userId: isMultiUser() ? source.viewerId : null,
174
+ singleUserOwnerId: isMultiUser() ? null : source.viewerId,
175
+ };
176
+ if (!ownsSession(viewerPrincipal, source.session)) return null;
177
+ }
171
178
  return createBound({
172
179
  userId: isMultiUser() ? source.session.ownerId : null,
173
180
  sourceProjectSlug: source.projectSlug,
@@ -366,11 +373,13 @@ function attachWorkspaceQueryService(ctx) {
366
373
 
367
374
  function resolveSessionNavigation(principal, ref) {
368
375
  if (typeof ref !== "string" || !/^session:[A-Za-z0-9_-]{24}$/.test(ref)) throw new Error("Invalid session reference.");
376
+ var entryIndex = arguments.length > 2 ? arguments[2] : null;
377
+ if (entryIndex !== null && entryIndex !== undefined && (!Number.isSafeInteger(entryIndex) || entryIndex < 0)) throw new Error("Invalid session entry reference.");
369
378
  var projects = collect(principal);
370
379
  for (var p = 0; p < projects.length; p++) {
371
380
  var session = findSession(projects[p], ref);
372
381
  if (!session) continue;
373
- return {
382
+ var target = {
374
383
  projectSlug: projects[p].projectSlug,
375
384
  projectTitle: projects[p].projectTitle,
376
385
  isMate: projects[p].isMate,
@@ -379,6 +388,8 @@ function attachWorkspaceQueryService(ctx) {
379
388
  homeSessionId: session.cliSessionId || "local:" + session.localId,
380
389
  title: cleanMetadata(session.title || "New Session", 160),
381
390
  };
391
+ if (entryIndex !== null && entryIndex !== undefined) target.entryIndex = entryIndex;
392
+ return target;
382
393
  }
383
394
  throw new Error("Session not found in the owned workspace.");
384
395
  }
@@ -450,7 +461,7 @@ function attachWorkspaceQueryService(ctx) {
450
461
  if (!principal.isClay) throw new Error("Workspace-wide activity is available only to builtin Clay.");
451
462
  return workspaceActivity(principal, args || {});
452
463
  },
453
- resolveSessionNavigation: function (args) { return resolveSessionNavigation(principal, args && args.sessionRef); },
464
+ resolveSessionNavigation: function (args) { return resolveSessionNavigation(principal, args && args.sessionRef, args && args.entryIndex); },
454
465
  listRecentDecisions: function (args) {
455
466
  if (!principal.isClay) throw new Error("Workspace decisions are available only to builtin Clay.");
456
467
  return recentDecisions(principal, args || {});
package/lib/ws-request.js CHANGED
@@ -8,6 +8,7 @@ function parseWsRequestUrl(requestUrl) {
8
8
  path: parsed.pathname || "/",
9
9
  pane: parsed.query.pane === "1",
10
10
  paneSession: paneSession,
11
+ contextual: parsed.query.pane === "1" && parsed.query.contextual === "1",
11
12
  };
12
13
  }
13
14
 
package/lib/ws-schema.js CHANGED
@@ -11,6 +11,11 @@
11
11
  * Use it as a reference when adding new message types.
12
12
  */
13
13
 
14
+ // message.contextualSnapshot: version=1, viewId, nullable projectTitle,
15
+ // conversationTitle/projectSlug (160 characters), nullable positive sessionId,
16
+ // screen=Home|Project|Direct message. Private canonical owner delivery only.
17
+ // Persisted user_message metadata is echoed in message_ack only after recording;
18
+ // queued admission ACK has no snapshot. Never part of user text/pastes or authority.
14
19
  var schema = {
15
20
 
16
21
  // -----------------------------------------------------------------------
@@ -32,6 +37,8 @@ var schema = {
32
37
  "session_folders_state": { direction: "s2c", handler: "lib/public/modules/session-folders.js", description: "Authoritative per-user, per-project session folder state; sent on connect and after every change to all of that user's sockets" },
33
38
  "new_session_options_get": { direction: "c2s", handler: "lib/project-session-creation.js", description: "Ask for the installed providers, the project's default provider and whether the caller may set it" },
34
39
  "new_session_default_set": { direction: "c2s", handler: "lib/project-session-creation.js", description: "Save the project-scoped default provider the inline New session row preselects" },
40
+ "vendor_usage_get": { direction: "c2s", handler: "lib/vendor-usage-overview.js", description: "Ask for the caller's observed per-vendor usage overview for this project" },
41
+ "vendor_usage_overview": { direction: "s2c", handler: "lib/public/modules/vendor-usage-overview.js", description: "Owner-scoped observed vendor usage windows, reset times and observation times; unknown vendors carry no windows" },
35
42
  "new_session_options": { direction: "s2c", handler: "lib/public/modules/session-create.js", description: "Installed providers, project default provider and default-setting permission for the inline New session row" },
36
43
  "new_session_default_result": { direction: "s2c", handler: "lib/public/modules/session-create.js", description: "Outcome of saving the project New session default" },
37
44
  "new_session_project_default": { direction: "s2c", handler: "lib/public/modules/session-create.js", description: "The project New session default changed" },
@@ -62,6 +69,7 @@ var schema = {
62
69
  "project_assignment_response": { direction: "c2s", handler: "lib/workspace-assignment-service.js", description: "Approve or cancel an exact-session cross-project assignment proposal" },
63
70
  "home_clay_session_resolve": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Resolve an opaque Mate session reference through the exact bound source session" },
64
71
  "home_clay_session_target": { direction: "s2c", handler: "lib/public/modules/command-palette.js", description: "Return an owner-validated navigation target for a rendered Mate session reference" },
72
+ "home_clay_contextual_session": { direction: "s2c", handler: "lib/public/modules/contextual-search.js", description: "Return the exact fresh canonical session for an idempotent contextual Ask request; does not submit or execute a message" },
65
73
  "issues_list": { direction: "c2s", handler: "lib/project-issues.js", description: "Project Issues issues list" },
66
74
  "issue_read": { direction: "c2s", handler: "lib/project-issues.js", description: "Project Issues issue read" },
67
75
  "issue_create": { direction: "c2s", handler: "lib/project-issues.js", description: "Project Issues issue create" },
@@ -398,9 +406,9 @@ var schema = {
398
406
  // -----------------------------------------------------------------------
399
407
  // Projects
400
408
  // -----------------------------------------------------------------------
401
- "browse_dir": { direction: "c2s", handler: "lib/project-sessions.js", description: "Browse directory entries for project creation" },
409
+ "browse_dir": { direction: "c2s", handler: "lib/project-sessions.js", description: "Browse directory entries for project creation (requestId echoed; reply adds canonical dir, prefix, permitted parent)" },
402
410
  "browse_dir_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Directory listing result" },
403
- "add_project": { direction: "c2s", handler: "lib/project-sessions.js", description: "Add an existing directory as a project" },
411
+ "add_project": { direction: "c2s", handler: "lib/project-sessions.js", description: "Add an existing directory as a project (optional requestId echoed on add_project_result, also for create/clone)" },
404
412
  "add_project_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Add project result" },
405
413
  "create_project": { direction: "c2s", handler: "lib/project-sessions.js", description: "Create a new empty project directory" },
406
414
  "clone_project": { direction: "c2s", handler: "lib/project-sessions.js", description: "Clone a git repository as a new project" },
@@ -482,6 +490,7 @@ var schema = {
482
490
  "term_resized": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Terminal was resized" },
483
491
  "term_exited": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Terminal process exited" },
484
492
  "term_closed": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Terminal session was closed" },
493
+ "term_control_projection": { direction: "s2c", handler: "lib/public/modules/terminal.js", description: "Authoritative terminal identity/revision after owner resize without echoing resize input" },
485
494
  "term_list": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full list of open terminals" },
486
495
  "term_error": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Terminal error (e.g. access denied)" },
487
496
  "shell_command": { direction: "c2s", handler: "lib/project-shell-command.js", description: "Run a one-shot shell command for agent context" },
@@ -495,10 +504,11 @@ var schema = {
495
504
  "note_written": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Agent created or updated a sticky note" },
496
505
  "note_update": { direction: "c2s", handler: "lib/project-user-message.js", description: "Update a sticky note" },
497
506
  "note_updated": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Sticky note was updated" },
498
- "note_close": { direction: "c2s", handler: "lib/project-user-message.js", description: "Close a sticky note (reversible; never deletes)" },
507
+ "note_update_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Correlated sticky note update result" },
508
+ "note_close": { direction: "c2s", handler: "lib/project-user-message.js", description: "Close a sticky note; human draft-aware requests remove empty notes, tool and legacy closes stay reversible" },
499
509
  "note_reopen": { direction: "c2s", handler: "lib/project-user-message.js", description: "Reopen a closed sticky note" },
500
510
  "note_delete": { direction: "c2s", handler: "lib/project-user-message.js", description: "Retired: older clients still send this; handled as a non-destructive close" },
501
- "note_deleted": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Retired: never sent. Closing broadcasts note_updated instead" },
511
+ "note_deleted": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "A sticky note was permanently removed after a human-authorized storage transaction" },
502
512
  "note_list_request": { direction: "c2s", handler: "lib/project-user-message.js", description: "Request the full notes list" },
503
513
  "note_bring_front": { direction: "c2s", handler: "lib/project-user-message.js", description: "Bring a note to front (update z-order)" },
504
514
  "notes_list": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full list of sticky notes" },
@@ -784,6 +794,7 @@ var schema = {
784
794
  // -----------------------------------------------------------------------
785
795
  "home_mate_open": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Open or restore the selected mate's embedded chat session" },
786
796
  "home_clay_ask": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Start a fresh builtin Clay conversation from the global search drawer" },
797
+ "contextual_mate_sessions_result": { direction: "s2c", handler: "lib/public/modules/contextual-mate-sessions.js", description: "Exact owner-private saved Mate conversation list or selection receipt; no transcript tap or underlying navigation" },
787
798
  "home_mate_sessions_list": { direction: "c2s", handler: "lib/server-home-chat.js", description: "List the current user's conversations with the selected mate" },
788
799
  "home_mate_session_open": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Open one explicit conversation with the selected mate" },
789
800
  "home_mate_send": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Send a message to the selected mate from the home hub" },
@@ -809,6 +820,13 @@ var schema = {
809
820
  "default_vendor_get": { direction: "c2s", handler: "lib/server-default-vendor.js", description: "Read the authenticated user's New session vendor preference" },
810
821
  "default_vendor_set": { direction: "c2s", handler: "lib/server-default-vendor.js", description: "Validate and persist the authenticated user's New session vendor preference" },
811
822
  "default_vendor_state": { direction: "s2c", handler: "lib/public/modules/default-vendor.js", description: "Correlated or same-user-broadcast New session vendor preference" },
823
+ "clay_ui_ready": { direction: "c2s", handler: "lib/server-owner-ui.js", description: "Advertise exact owner UI navigation support on this socket" },
824
+ "clay_navigation_offer": { direction: "s2c", handler: "lib/public/modules/clay-owner-navigation.js", description: "Offer one exact reviewed navigation to a selected owner connection" },
825
+ "clay_navigation_claim": { direction: "c2s", handler: "lib/server-owner-ui.js", description: "Claim an offered navigation with live source/target revalidation" },
826
+ "clay_navigation_apply": { direction: "s2c", handler: "lib/public/modules/clay-owner-navigation.js", description: "Invoke the shared conversation navigator after live claim" },
827
+ "clay_studio_rendered": { direction: "c2s", handler: "lib/project-studio-presentation.js", description: "Exact source-viewer workbench render receipt; no product effects" },
828
+ "clay_navigation_rendered": { direction: "c2s", handler: "lib/server-owner-ui.js", description: "Bounded exact-viewer rendered conversation evidence; acceptance alone remains separate" },
829
+ "clay_navigation_ack": { direction: "c2s", handler: "lib/server-owner-ui.js", description: "Client invocation acknowledgement; never proof of visible rendering" },
812
830
  "context_view_get": { direction: "c2s", handler: "lib/server-context-view.js", description: "Read the authenticated user's context display preference" },
813
831
  "context_view_set": { direction: "c2s", handler: "lib/server-context-view.js", description: "Persist the authenticated user's context display preference" },
814
832
  "context_view_state": { direction: "s2c", handler: "lib/public/modules/context-view-preference.js", description: "Correlated or same-user-broadcast context display preference" },
@@ -9,8 +9,9 @@ var execFile = require("child_process").execFile;
9
9
  var execFileSync = require("child_process").execFileSync;
10
10
 
11
11
  function findOnPath(binaryName, overrideName) {
12
- var overridePath = overrideName && process.env[overrideName];
13
- if (overridePath && fs.existsSync(overridePath)) return overridePath;
12
+ var discovery = require("./discovery");
13
+ var overridePath = overrideName && discovery.explicitEntry(process.env, overrideName, false);
14
+ if (overridePath !== undefined && overrideName) return overridePath;
14
15
  try {
15
16
  var command = process.platform === "win32" ? "where" : "which";
16
17
  var out = execFileSync(command, [binaryName], {
@@ -18,7 +19,8 @@ function findOnPath(binaryName, overrideName) {
18
19
  encoding: "utf8",
19
20
  stdio: ["pipe", "pipe", "pipe"],
20
21
  });
21
- return out.trim().split(/\r?\n/)[0] || null;
22
+ var resolved = out.trim().split(/\r?\n/)[0] || null;
23
+ return discovery.validEntry(resolved, false) ? resolved : null;
22
24
  } catch (e) {
23
25
  return null;
24
26
  }
@@ -50,7 +52,7 @@ function fetchOpenCodeResolvedConfig(binaryPath, cwd, env) {
50
52
  return new Promise(function(resolve, reject) {
51
53
  execFile(binaryPath, ["debug", "config"], {
52
54
  cwd: cwd || process.cwd(),
53
- env: Object.assign({}, process.env, env || {}),
55
+ env: env ? Object.assign({}, env) : process.env,
54
56
  timeout: 30000,
55
57
  maxBuffer: 4 * 1024 * 1024,
56
58
  }, function(err, stdout) {
@@ -141,7 +143,7 @@ var ACP_AGENT_PROFILES = {
141
143
  });
142
144
  },
143
145
  buildProcessOptions: function(ctx, base) {
144
- var existing = (base.env && base.env.OPENCODE_CONFIG_CONTENT) || process.env.OPENCODE_CONFIG_CONTENT;
146
+ var existing = base.env ? base.env.OPENCODE_CONFIG_CONTENT : process.env.OPENCODE_CONFIG_CONTENT;
145
147
  var config = {};
146
148
  if (existing) config = JSON.parse(existing);
147
149
  var agent = Object.assign({}, config.agent || {});
@@ -3,19 +3,7 @@ var childProcess = require("child_process");
3
3
  var readline = require("readline");
4
4
  var skillDiscovery = require("../skill-discovery");
5
5
 
6
- function findBinary() {
7
- if (process.env.ANTIGRAVITY_CLI_PATH) return process.env.ANTIGRAVITY_CLI_PATH;
8
- try {
9
- var command = process.platform === "win32" ? "where" : "which";
10
- return childProcess.execFileSync(command, ["agy"], {
11
- encoding: "utf8",
12
- timeout: 3000,
13
- stdio: ["pipe", "pipe", "pipe"],
14
- }).trim().split(/\r?\n/)[0] || null;
15
- } catch (e) {
16
- return null;
17
- }
18
- }
6
+ var findBinary = require("../providers/antigravity-executable").resolve;
19
7
 
20
8
  function modelValue(model) {
21
9
  if (typeof model === "string") return model;
@@ -427,7 +415,8 @@ function createAntigravityAdapter(opts) {
427
415
  var adapter = {
428
416
  vendor: "antigravity",
429
417
  init: async function(initOpts) {
430
- if (!binaryPath) binaryPath = findBinary();
418
+ if (opts.linuxUser || initOpts && initOpts.linuxUser) throw new Error("Antigravity does not support mapped OS-user execution.");
419
+ if (!binaryPath) binaryPath = findBinary({ env: initOpts && initOpts.env || opts.env || process.env });
431
420
  if (!binaryPath) throw new Error("Antigravity CLI binary not found: agy");
432
421
  var fetched = opts._fetchModels ? await opts._fetchModels(binaryPath, cwd) : await fetchModels(binaryPath, cwd);
433
422
  if (fetched && fetched.length) cachedModels = fetched;
@@ -0,0 +1,9 @@
1
+ // Init-free provider transport obligations, shared by the registry and adapter.
2
+ module.exports = {
3
+ questionInput: function(name, input) { return name === "AskUserQuestion" ? input : null; },
4
+ toolTransport: "sdk-mcp",
5
+ catalogLifetime: "query",
6
+ permissionModes: ["auto"],
7
+ mcpPermissionOverrides: true,
8
+ interruptionMessage: "Interrupted · What should Claude do instead?",
9
+ };