synabun 2.0.7 → 2.0.9

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 (346) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +1 -1
  3. package/hooks/claude-code/post-plan.mjs +6 -30
  4. package/hooks/claude-code/session-start.mjs +1 -4
  5. package/hooks/claude-code/shared.mjs +106 -72
  6. package/lib/package-processes.js +670 -0
  7. package/lib/runtime-dependencies.js +225 -0
  8. package/mcp-server/dist/services/browser-bench.d.ts +1 -1
  9. package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
  10. package/mcp-server/dist/services/browser-bench.js +1 -1
  11. package/mcp-server/dist/services/browser-bench.js.map +1 -1
  12. package/mcp-server/dist/services/categories.d.ts +35 -2
  13. package/mcp-server/dist/services/categories.d.ts.map +1 -1
  14. package/mcp-server/dist/services/categories.js +77 -33
  15. package/mcp-server/dist/services/categories.js.map +1 -1
  16. package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
  17. package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
  18. package/mcp-server/dist/services/desktop-bench.js +1 -1
  19. package/mcp-server/dist/services/desktop-bench.js.map +1 -1
  20. package/mcp-server/dist/tools/agents.d.ts +1 -1
  21. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  22. package/mcp-server/dist/tools/agents.js +1 -1
  23. package/mcp-server/dist/tools/agents.js.map +1 -1
  24. package/mcp-server/dist/tools/bluesky.js +1 -1
  25. package/mcp-server/dist/tools/bluesky.js.map +1 -1
  26. package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
  27. package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
  28. package/mcp-server/dist/tools/browser-advanced.js +1 -1
  29. package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
  30. package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
  31. package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
  32. package/mcp-server/dist/tools/browser-batch.js +1 -1
  33. package/mcp-server/dist/tools/browser-batch.js.map +1 -1
  34. package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
  35. package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
  36. package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
  37. package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
  38. package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
  39. package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
  40. package/mcp-server/dist/tools/browser-interact.js +1 -1
  41. package/mcp-server/dist/tools/browser-interact.js.map +1 -1
  42. package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
  43. package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
  44. package/mcp-server/dist/tools/browser-navigate.js +1 -1
  45. package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
  46. package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
  47. package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
  48. package/mcp-server/dist/tools/browser-observe.js +1 -1
  49. package/mcp-server/dist/tools/browser-observe.js.map +1 -1
  50. package/mcp-server/dist/tools/card-tools.d.ts +1 -1
  51. package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
  52. package/mcp-server/dist/tools/card-tools.js +1 -1
  53. package/mcp-server/dist/tools/card-tools.js.map +1 -1
  54. package/mcp-server/dist/tools/category.d.ts +1 -1
  55. package/mcp-server/dist/tools/category.d.ts.map +1 -1
  56. package/mcp-server/dist/tools/category.js +5 -1
  57. package/mcp-server/dist/tools/category.js.map +1 -1
  58. package/mcp-server/dist/tools/choice.d.ts +1 -1
  59. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  60. package/mcp-server/dist/tools/choice.js +1 -1
  61. package/mcp-server/dist/tools/choice.js.map +1 -1
  62. package/mcp-server/dist/tools/computer.d.ts +1 -1
  63. package/mcp-server/dist/tools/computer.d.ts.map +1 -1
  64. package/mcp-server/dist/tools/computer.js +1 -1
  65. package/mcp-server/dist/tools/computer.js.map +1 -1
  66. package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
  67. package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
  68. package/mcp-server/dist/tools/discord-channel.js +1 -1
  69. package/mcp-server/dist/tools/discord-channel.js.map +1 -1
  70. package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
  71. package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
  72. package/mcp-server/dist/tools/discord-guild.js +1 -1
  73. package/mcp-server/dist/tools/discord-guild.js.map +1 -1
  74. package/mcp-server/dist/tools/discord-member.d.ts +1 -1
  75. package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
  76. package/mcp-server/dist/tools/discord-member.js +1 -1
  77. package/mcp-server/dist/tools/discord-member.js.map +1 -1
  78. package/mcp-server/dist/tools/discord-message.d.ts +1 -1
  79. package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
  80. package/mcp-server/dist/tools/discord-message.js +1 -1
  81. package/mcp-server/dist/tools/discord-message.js.map +1 -1
  82. package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
  83. package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
  84. package/mcp-server/dist/tools/discord-onboarding.js +1 -1
  85. package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
  86. package/mcp-server/dist/tools/discord-role.d.ts +1 -1
  87. package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
  88. package/mcp-server/dist/tools/discord-role.js +1 -1
  89. package/mcp-server/dist/tools/discord-role.js.map +1 -1
  90. package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
  91. package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/discord-thread.js +1 -1
  93. package/mcp-server/dist/tools/discord-thread.js.map +1 -1
  94. package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
  95. package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/discord-webhook.js +1 -1
  97. package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
  98. package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
  99. package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
  100. package/mcp-server/dist/tools/fb-groups.js +1 -1
  101. package/mcp-server/dist/tools/fb-groups.js.map +1 -1
  102. package/mcp-server/dist/tools/forget.d.ts +1 -1
  103. package/mcp-server/dist/tools/forget.d.ts.map +1 -1
  104. package/mcp-server/dist/tools/forget.js +1 -1
  105. package/mcp-server/dist/tools/forget.js.map +1 -1
  106. package/mcp-server/dist/tools/git-tools.d.ts +1 -1
  107. package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
  108. package/mcp-server/dist/tools/git-tools.js +1 -1
  109. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  110. package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
  111. package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
  112. package/mcp-server/dist/tools/gsc/experience.js +1 -1
  113. package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
  114. package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
  115. package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
  116. package/mcp-server/dist/tools/gsc/indexing.js +1 -1
  117. package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
  118. package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
  119. package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
  120. package/mcp-server/dist/tools/gsc/inspect.js +1 -1
  121. package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
  122. package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
  123. package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
  124. package/mcp-server/dist/tools/gsc/navigate.js +1 -1
  125. package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
  126. package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
  127. package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
  128. package/mcp-server/dist/tools/gsc/performance.js +1 -1
  129. package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
  130. package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
  131. package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
  132. package/mcp-server/dist/tools/gsc/settings.js +1 -1
  133. package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
  134. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  135. package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
  136. package/mcp-server/dist/tools/image-tools.js +1 -1
  137. package/mcp-server/dist/tools/image-tools.js.map +1 -1
  138. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
  139. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
  140. package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
  141. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
  142. package/mcp-server/dist/tools/loop.d.ts +1 -1
  143. package/mcp-server/dist/tools/loop.d.ts.map +1 -1
  144. package/mcp-server/dist/tools/loop.js +1 -1
  145. package/mcp-server/dist/tools/loop.js.map +1 -1
  146. package/mcp-server/dist/tools/memories.d.ts +1 -1
  147. package/mcp-server/dist/tools/memories.d.ts.map +1 -1
  148. package/mcp-server/dist/tools/memories.js +1 -1
  149. package/mcp-server/dist/tools/memories.js.map +1 -1
  150. package/mcp-server/dist/tools/morelogin.d.ts +1 -1
  151. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  152. package/mcp-server/dist/tools/morelogin.js +1 -1
  153. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  154. package/mcp-server/dist/tools/profile.d.ts +1 -1
  155. package/mcp-server/dist/tools/profile.d.ts.map +1 -1
  156. package/mcp-server/dist/tools/profile.js +1 -1
  157. package/mcp-server/dist/tools/profile.js.map +1 -1
  158. package/mcp-server/dist/tools/recall.d.ts +1 -1
  159. package/mcp-server/dist/tools/recall.d.ts.map +1 -1
  160. package/mcp-server/dist/tools/recall.js +1 -1
  161. package/mcp-server/dist/tools/recall.js.map +1 -1
  162. package/mcp-server/dist/tools/reflect.d.ts +1 -1
  163. package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
  164. package/mcp-server/dist/tools/reflect.js +1 -1
  165. package/mcp-server/dist/tools/reflect.js.map +1 -1
  166. package/mcp-server/dist/tools/remember.d.ts +1 -1
  167. package/mcp-server/dist/tools/remember.d.ts.map +1 -1
  168. package/mcp-server/dist/tools/remember.js +13 -11
  169. package/mcp-server/dist/tools/remember.js.map +1 -1
  170. package/mcp-server/dist/tools/restore.d.ts +1 -1
  171. package/mcp-server/dist/tools/restore.d.ts.map +1 -1
  172. package/mcp-server/dist/tools/restore.js +1 -1
  173. package/mcp-server/dist/tools/restore.js.map +1 -1
  174. package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
  175. package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
  176. package/mcp-server/dist/tools/style-guide-tools.js +1 -1
  177. package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
  178. package/mcp-server/dist/tools/sync.d.ts +1 -1
  179. package/mcp-server/dist/tools/sync.d.ts.map +1 -1
  180. package/mcp-server/dist/tools/sync.js +1 -1
  181. package/mcp-server/dist/tools/sync.js.map +1 -1
  182. package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
  183. package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
  184. package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
  185. package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
  186. package/mcp-server/dist/tools/utils.d.ts +1 -1
  187. package/mcp-server/dist/tools/utils.d.ts.map +1 -1
  188. package/mcp-server/dist/tools/utils.js +1 -1
  189. package/mcp-server/dist/tools/utils.js.map +1 -1
  190. package/mcp-server/dist/tools/whatsapp-send-file.d.ts +1 -1
  191. package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -1
  192. package/mcp-server/dist/tools/whatsapp-send-file.js +1 -1
  193. package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -1
  194. package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
  195. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  196. package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
  197. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  198. package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
  199. package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
  200. package/mcp-server/dist/tools/youtube/analytics.js +1 -1
  201. package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
  202. package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
  203. package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
  204. package/mcp-server/dist/tools/youtube/download.js +1 -1
  205. package/mcp-server/dist/tools/youtube/download.js.map +1 -1
  206. package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
  207. package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
  208. package/mcp-server/dist/tools/youtube/media.js +1 -1
  209. package/mcp-server/dist/tools/youtube/media.js.map +1 -1
  210. package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
  211. package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
  212. package/mcp-server/dist/tools/youtube/metadata.js +1 -1
  213. package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
  214. package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
  215. package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
  216. package/mcp-server/dist/tools/youtube/navigate.js +1 -1
  217. package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
  218. package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
  219. package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
  220. package/mcp-server/dist/tools/youtube/playlist.js +1 -1
  221. package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
  222. package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
  223. package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
  224. package/mcp-server/dist/tools/youtube/schedule.js +1 -1
  225. package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
  226. package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
  227. package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
  228. package/mcp-server/dist/tools/youtube/source.js +1 -1
  229. package/mcp-server/dist/tools/youtube/source.js.map +1 -1
  230. package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
  231. package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
  232. package/mcp-server/dist/tools/youtube/upload.js +4 -9
  233. package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
  234. package/mcp-server/dist/tui.js +16 -4
  235. package/mcp-server/dist/tui.js.map +1 -1
  236. package/mcp-server/package-lock.json +3 -3
  237. package/mcp-server/package.json +3 -3
  238. package/mcp-server/src/services/browser-bench.ts +1 -1
  239. package/mcp-server/src/services/categories.ts +77 -32
  240. package/mcp-server/src/services/desktop-bench.ts +1 -1
  241. package/mcp-server/src/tools/agents.ts +1 -1
  242. package/mcp-server/src/tools/bluesky.ts +1 -1
  243. package/mcp-server/src/tools/browser-advanced.ts +1 -1
  244. package/mcp-server/src/tools/browser-batch.ts +1 -1
  245. package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
  246. package/mcp-server/src/tools/browser-interact.ts +1 -1
  247. package/mcp-server/src/tools/browser-navigate.ts +1 -1
  248. package/mcp-server/src/tools/browser-observe.ts +1 -1
  249. package/mcp-server/src/tools/card-tools.ts +1 -1
  250. package/mcp-server/src/tools/category.ts +6 -1
  251. package/mcp-server/src/tools/choice.ts +1 -1
  252. package/mcp-server/src/tools/computer.ts +1 -1
  253. package/mcp-server/src/tools/discord-channel.ts +1 -1
  254. package/mcp-server/src/tools/discord-guild.ts +1 -1
  255. package/mcp-server/src/tools/discord-member.ts +1 -1
  256. package/mcp-server/src/tools/discord-message.ts +1 -1
  257. package/mcp-server/src/tools/discord-onboarding.ts +1 -1
  258. package/mcp-server/src/tools/discord-role.ts +1 -1
  259. package/mcp-server/src/tools/discord-thread.ts +1 -1
  260. package/mcp-server/src/tools/discord-webhook.ts +1 -1
  261. package/mcp-server/src/tools/fb-groups.ts +1 -1
  262. package/mcp-server/src/tools/forget.ts +1 -1
  263. package/mcp-server/src/tools/git-tools.ts +1 -1
  264. package/mcp-server/src/tools/gsc/experience.ts +1 -1
  265. package/mcp-server/src/tools/gsc/indexing.ts +1 -1
  266. package/mcp-server/src/tools/gsc/inspect.ts +1 -1
  267. package/mcp-server/src/tools/gsc/navigate.ts +1 -1
  268. package/mcp-server/src/tools/gsc/performance.ts +1 -1
  269. package/mcp-server/src/tools/gsc/settings.ts +1 -1
  270. package/mcp-server/src/tools/image-tools.ts +1 -1
  271. package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
  272. package/mcp-server/src/tools/loop.ts +1 -1
  273. package/mcp-server/src/tools/memories.ts +1 -1
  274. package/mcp-server/src/tools/morelogin.ts +1 -1
  275. package/mcp-server/src/tools/profile.ts +1 -1
  276. package/mcp-server/src/tools/recall.ts +1 -1
  277. package/mcp-server/src/tools/reflect.ts +1 -1
  278. package/mcp-server/src/tools/remember.ts +13 -12
  279. package/mcp-server/src/tools/restore.ts +1 -1
  280. package/mcp-server/src/tools/style-guide-tools.ts +1 -1
  281. package/mcp-server/src/tools/sync.ts +1 -1
  282. package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
  283. package/mcp-server/src/tools/utils.ts +1 -1
  284. package/mcp-server/src/tools/whatsapp-send-file.ts +1 -1
  285. package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
  286. package/mcp-server/src/tools/youtube/analytics.ts +1 -1
  287. package/mcp-server/src/tools/youtube/download.ts +1 -1
  288. package/mcp-server/src/tools/youtube/media.ts +1 -1
  289. package/mcp-server/src/tools/youtube/metadata.ts +1 -1
  290. package/mcp-server/src/tools/youtube/navigate.ts +1 -1
  291. package/mcp-server/src/tools/youtube/playlist.ts +1 -1
  292. package/mcp-server/src/tools/youtube/schedule.ts +1 -1
  293. package/mcp-server/src/tools/youtube/source.ts +1 -1
  294. package/mcp-server/src/tools/youtube/upload.ts +4 -12
  295. package/mcp-server/src/tui.ts +22 -9
  296. package/neural-interface/i18n/en.json +18 -0
  297. package/neural-interface/i18n/pt-BR.json +18 -0
  298. package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
  299. package/neural-interface/lib/agent-sandbox-setting.js +57 -0
  300. package/neural-interface/lib/assistant-api.js +19 -0
  301. package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
  302. package/neural-interface/lib/assistant-runtime.js +5 -1
  303. package/neural-interface/lib/codex-account-auth.js +4 -2
  304. package/neural-interface/lib/codex-accounts.js +14 -1
  305. package/neural-interface/lib/codex-settings-schema.js +5 -3
  306. package/neural-interface/lib/exec-loop-command.js +3 -1
  307. package/neural-interface/lib/install-details.js +23 -5
  308. package/neural-interface/lib/native-loop-providers.js +6 -1
  309. package/neural-interface/lib/provider-panel-terminal-auth.js +3 -2
  310. package/neural-interface/lib/session-indexer.js +3 -1
  311. package/neural-interface/lib/session-title-generator.js +2 -0
  312. package/neural-interface/package-lock.json +2 -2
  313. package/neural-interface/package.json +1 -1
  314. package/neural-interface/public/shared/account-menu.js +4 -1
  315. package/neural-interface/public/shared/account-usage.js +62 -2
  316. package/neural-interface/public/shared/account-view.js +2 -1
  317. package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
  318. package/neural-interface/public/shared/assistant/asst-api.js +7 -0
  319. package/neural-interface/public/shared/assistant/asst-brain-picker.js +232 -75
  320. package/neural-interface/public/shared/assistant/asst-menu.js +204 -77
  321. package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
  322. package/neural-interface/public/shared/assistant/asst-panel.js +39 -2
  323. package/neural-interface/public/shared/assistant/asst-styles.js +66 -17
  324. package/neural-interface/public/shared/cdx/cdx-panel.js +1 -1
  325. package/neural-interface/public/shared/cdx/cdx-styles.js +45 -5
  326. package/neural-interface/public/shared/cdx/cdx-tabs.js +3 -0
  327. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -1
  328. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +4 -1
  329. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +51 -2
  330. package/neural-interface/public/shared/showcase-privacy.js +2 -1
  331. package/neural-interface/public/shared/styles.css +3 -1
  332. package/neural-interface/public/shared/ui-claude-panel.js +50 -4
  333. package/neural-interface/public/shared/ui-explorer.js +2 -0
  334. package/neural-interface/public/shared/ui-sync.js +2 -0
  335. package/neural-interface/public/shared/ui-update.js +4 -2
  336. package/neural-interface/scripts/rebuild-pty.js +14 -2
  337. package/neural-interface/server.js +180 -86
  338. package/npm-shrinkwrap.json +4424 -0
  339. package/package.json +54 -2
  340. package/postinstall.js +61 -47
  341. package/preuninstall.js +8 -35
  342. package/setup.js +76 -44
  343. package/skills/synabun/modules/idea.md +1 -1
  344. package/skills/synabun/modules/schedule.md +1 -1
  345. package/updater.cmd +2 -2
  346. package/updater.mjs +97 -3
@@ -1108,13 +1108,21 @@ export function injectAssistantStyles() {
1108
1108
  /* Fields (toolbar and composer): glyph · seam · value ▾ */
1109
1109
  .asst-dd { flex: 0 1 auto; justify-content: flex-start; max-width: calc(18ch + 60px); }
1110
1110
  .asst-dd .asst-dd-label { min-width: 0; max-width: 18ch; overflow: hidden; text-overflow: ellipsis; }
1111
- .asst-dd-model .asst-dd-label.asst-model-account-label { display: flex; gap: 4px; max-width: 34ch; }
1112
- .asst-model-account-label :is(.asst-model-name, .asst-model-account) { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1113
- .asst-model-account-label .asst-model-name { flex: 1 1 auto; }
1114
- .asst-model-account-label .asst-model-account { flex: 0 1 auto; min-width: 4ch; max-width: 12ch; }
1115
- .asst-model-account-label .asst-model-mode { flex-shrink: 0; }
1116
- /* A display name ("Sonnet 5", a project) is sans; a raw model id (opus[1m]) is mono. */
1117
- .asst-dd.asst-dd-model[data-raw] .asst-dd-label { font-family: var(--asst-mono); font-weight: 400; }
1111
+ /* The model chip: name · context tag · account cue · API (asst-model-chip.js). The picker
1112
+ draws the longest form that fits the row, so no part shrinks or ends in an ellipsis; the
1113
+ cue and the API badge are the account menu's avatar and badge at the row's xs size. */
1114
+ .asst-dd.asst-dd-model { max-width: calc(30ch + 60px); }
1115
+ .asst-dd-model .asst-dd-label.asst-model-label { display: inline-flex; align-items: center; gap: 4px; max-width: none; }
1116
+ .asst-model-label > * { flex: none; }
1117
+ .asst-model-label > [hidden] { display: none; }
1118
+ .asst-model-tag { color: var(--asst-text-3); font-family: var(--asst-mono); font-size: 10.5px; font-weight: 400; }
1119
+ .asst-model-label > .asst-acct-avatar { flex: 0 0 auto; min-width: 16px; width: auto; height: 16px; padding: 0 4px; font-size: 10px; }
1120
+ .asst-model-label > .asst-acct-avatar[data-tone="warn"] { box-shadow: inset 0 0 0 1px var(--asst-pill-warn-ring); color: var(--asst-warn); }
1121
+ .asst-model-label > .asst-acct-badge { margin: 0; }
1122
+ /* Even the shortest form does not fit (a row narrower than 320px that cannot wrap): the name gives. */
1123
+ .asst-dd-model[data-squeezed] .asst-model-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1124
+ /* A display name ("Sonnet 5", a project) is sans; a raw model id (opus) is mono. */
1125
+ .asst-dd.asst-dd-model[data-raw] .asst-model-name { font-family: var(--asst-mono); font-weight: 400; }
1118
1126
  .asst-dd-caret {
1119
1127
  display: inline-flex;
1120
1128
  flex-shrink: 0;
@@ -1420,8 +1428,9 @@ export function injectAssistantStyles() {
1420
1428
  z-index: 100030; /* above modals (100020): the routes editor opens model menus */
1421
1429
  display: flex;
1422
1430
  flex-direction: column;
1423
- min-width: 200px;
1424
- max-width: min(380px, calc(100vw - 16px));
1431
+ /* --asst-dd-room: the width of the box the menu stays inside, less its margins (asst-menu.js positionMenu). */
1432
+ min-width: min(200px, var(--asst-dd-room, 200px));
1433
+ max-width: min(380px, calc(100vw - 16px), var(--asst-dd-room, 100vw));
1425
1434
  max-height: 380px;
1426
1435
  overflow: hidden;
1427
1436
  padding: 4px;
@@ -1468,6 +1477,8 @@ export function injectAssistantStyles() {
1468
1477
  .asst-dd-item-desc { color: var(--asst-text-3); font-size: 11px; }
1469
1478
  /* Test density: each level's description is a sentence, so it wraps instead of truncating. */
1470
1479
  .asst-tests-menu .asst-dd-item-desc { white-space: normal; }
1480
+ /* Admin sandbox (permission menu): its note is a sentence too. */
1481
+ .asst-dd-item.asst-admin-sandbox-item .asst-dd-item-desc { white-space: normal; }
1471
1482
  .asst-dd-item-tag { flex-shrink: 0; margin-left: auto; color: var(--asst-text-3); font-size: 11px; }
1472
1483
  .asst-dd-kbd { flex-shrink: 0; margin-left: auto; color: var(--asst-text-3); font-family: var(--asst-mono); font-size: 10.5px; }
1473
1484
  .asst-dd-sep { flex-shrink: 0; height: 1px; margin: 4px 6px; background: var(--asst-line); }
@@ -1497,6 +1508,45 @@ export function injectAssistantStyles() {
1497
1508
  .asst-dd-input::placeholder { color: var(--asst-text-3); }
1498
1509
  .asst-dd-filter { margin: 2px 0 4px; }
1499
1510
  .asst-dd-empty { padding: 8px 10px; color: var(--asst-text-3); }
1511
+ /* A footer stays under a scrolling list; a button row is one line of compact items. */
1512
+ .asst-dd-foot { flex-shrink: 0; margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--asst-line); }
1513
+ .asst-dd-btnrow { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
1514
+ .asst-dd-btnrow-label { flex: 1 1 auto; min-width: 0; padding: 5px 10px; color: var(--asst-text-2); overflow-wrap: anywhere; }
1515
+ .asst-dd-btnrow .asst-dd-item { flex: 0 1 auto; width: auto; }
1516
+
1517
+ /* ── Account menu (asst-account-menu.js) ────────────────────────
1518
+ Every account once: initial · name ✓ · plan or credential badge, then who it is and its
1519
+ usage in full (lines wrap, nothing is cut). Kept inside the panel by asst-menu.js. The
1520
+ composer's Model menu lists the same rows: the rules follow the rows' own classes. */
1521
+ .asst-dd-item.asst-acct-item { gap: 8px; padding: 6px 8px; }
1522
+ :is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice))[data-checked="1"] { background: var(--asst-fill-1); }
1523
+ :is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice)):is(:hover, .focused) { background: var(--asst-fill-2); }
1524
+ .asst-acct-avatar { display: inline-flex; flex: 0 0 24px; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-2); color: var(--asst-text-2); font-size: 11px; font-weight: 600; line-height: 1; }
1525
+ .asst-acct-avatar svg { width: 14px; height: 14px; }
1526
+ .asst-acct-main { display: flex; flex: 1 1 auto; flex-direction: column; gap: 1px; min-width: 0; }
1527
+ /* A long name wraps; its check and badge stay on its first line. */
1528
+ .asst-acct-head { display: flex; align-items: flex-start; gap: 6px; min-width: 0; }
1529
+ .asst-acct-name { min-width: 0; font-weight: 500; overflow-wrap: anywhere; }
1530
+ .asst-acct-check { display: inline-flex; flex: none; margin-top: 3px; color: var(--asst-text); }
1531
+ .asst-acct-check svg { width: 12px; height: 12px; }
1532
+ .asst-acct-badge { flex: none; margin: 1px 0 0 auto; padding: 0 var(--asst-pill-px-xs); border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-1); box-shadow: inset 0 0 0 1px var(--asst-line); color: var(--asst-text-2); font-size: 10.5px; font-weight: 500; line-height: 16px; white-space: nowrap; }
1533
+ .asst-acct-line { color: var(--asst-text-3); font-size: 11px; line-height: 1.35; overflow-wrap: anywhere; }
1534
+ .asst-dd-item:is(:hover, .focused) .asst-acct-line:not([data-tone="warn"]) { color: var(--asst-text-2); }
1535
+ :is(.asst-acct-badge, .asst-acct-line, .asst-acct-value-text)[data-tone="warn"] { color: var(--asst-warn); }
1536
+ /* The note under the accounts lines up with their names. */
1537
+ .asst-dd-info.asst-acct-note { padding: 3px 8px 5px 40px; font-size: 11px; }
1538
+ .asst-dd-item.asst-acct-value { gap: 6px; }
1539
+ /* Footer rows read "label … value": the label muted, as the button row's. */
1540
+ .asst-acct-value-label { flex: 1 1 auto; min-width: 0; color: var(--asst-text-2); overflow-wrap: anywhere; }
1541
+ .asst-acct-value-text { flex: 0 1 auto; min-width: 0; text-align: right; overflow-wrap: anywhere; }
1542
+ .asst-acct-next { display: inline-flex; flex: none; color: var(--asst-text-3); }
1543
+ .asst-acct-next svg { width: 12px; height: 12px; }
1544
+ .asst-dd-item.asst-acct-back { gap: 6px; color: var(--asst-text-2); }
1545
+ .asst-dd-item.asst-acct-choice { gap: 4px; padding: 5px 8px; }
1546
+ .asst-dd-btnrow[data-id="manage-row"] .asst-dd-item { flex: 1 1 0; }
1547
+ @media (pointer: coarse) {
1548
+ :is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice), .asst-dd-btnrow[data-id="manage-row"] .asst-dd-item) { min-height: 44px; }
1549
+ }
1500
1550
 
1501
1551
  /* ── Modals (help, accounts, model routes) ──────────────────────── */
1502
1552
  .asst-modal-overlay {
@@ -1723,7 +1773,7 @@ export function injectAssistantStyles() {
1723
1773
  .asst-routes-catalog-note { padding: 8px; color: var(--asst-warn); font-size: 12px; line-height: 1.45; background: var(--asst-fill-1); border-radius: var(--asst-pill-r-xs); }
1724
1774
  .asst-routes-modal .asst-routes-error { flex-wrap: wrap; }
1725
1775
  .asst-routes-modal .asst-routes-error span { min-width: 0; overflow-wrap: anywhere; }
1726
- .asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) { max-width: min(440px, calc(100vw - 16px)); font-family: inherit; font-size: 12px; }
1776
+ .asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) { max-width: min(440px, calc(100vw - 16px), var(--asst-dd-room, 100vw)); font-family: inherit; font-size: 12px; }
1727
1777
  .asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item { height: var(--asst-pill-h-sm); min-height: var(--asst-pill-h-sm); padding: 0 8px; border-radius: var(--asst-pill-r-xs); }
1728
1778
  .asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-main { flex-direction: row; align-items: center; gap: 8px; }
1729
1779
  .asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-label { flex-shrink: 0; max-width: 60%; }
@@ -1827,8 +1877,9 @@ export function injectAssistantStyles() {
1827
1877
  density is its gauge alone. A capsule that runs out of
1828
1878
  room drops its label half first and stays a glyph (its words remain in
1829
1879
  aria-label and the tooltip): route mode and Computer ≤960px, the mode
1830
- ≤540px, every composer field but the model ≤440px. Model, history, new
1831
- and "⋯" never hide; whatever hides stays in "⋯". A toolbar placed
1880
+ ≤540px, every composer field but the model ≤440px, where the model
1881
+ drops its caret and keeps its name (its form fits the row: see the
1882
+ model chip above). Model, history, new and "⋯" never hide; whatever hides stays in "⋯". A toolbar placed
1832
1883
  outside the root (the sidepanel header) is out of reach of these rules:
1833
1884
  its host sizes it (asst-sidepanel-styles.js).
1834
1885
  Glyph only is the same three rules everywhere (see Capsules): the
@@ -1854,13 +1905,13 @@ export function injectAssistantStyles() {
1854
1905
  .asst-composer-brain .asst-dd.asst-dd-mode { display: grid; place-content: center; place-items: center; padding: 0; }
1855
1906
  .asst-composer-brain .asst-dd.asst-dd-mode > :is(.asst-dd-label, .asst-dd-caret) { display: none; }
1856
1907
  .asst-composer-brain .asst-dd.asst-dd-mode > .asst-icon:not([hidden]) { margin: 0; padding: 0 var(--cap-glyph-pad); box-shadow: none; }
1857
- .asst-dd-model .asst-dd-label { max-width: 14ch; }
1858
1908
  .asst-route-badge { display: none; }
1859
1909
  }
1860
1910
  @container asst (max-width: 440px) {
1861
1911
  .asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) { display: grid; place-content: center; place-items: center; padding: 0; }
1862
1912
  .asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) > :is(.asst-dd-label, .asst-dd-caret) { display: none; }
1863
1913
  .asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) > .asst-icon:not([hidden]) { margin: 0; padding: 0 var(--cap-glyph-pad); box-shadow: none; }
1914
+ .asst-composer-brain .asst-dd.asst-dd-model > .asst-dd-caret { display: none; }
1864
1915
  }
1865
1916
  @container asst (max-width: 400px) {
1866
1917
  .asst-root > * { --asst-inline: 6px; }
@@ -1871,16 +1922,14 @@ export function injectAssistantStyles() {
1871
1922
  .asst-dd.asst-empty-control-btn { flex: 1 1 auto; justify-content: flex-start; max-width: none; }
1872
1923
  .asst-empty-control-btn .asst-dd-label { flex: 1 1 auto; max-width: none; text-align: start; }
1873
1924
  .asst-msg.msg-user .asst-msg-content { max-width: 92%; }
1874
- .asst-dd-model .asst-dd-label { max-width: 9ch; }
1875
1925
  .asst-route-opt-sub { display: none; }
1876
1926
  .asst-run-main { flex-wrap: wrap; row-gap: 2px; }
1877
1927
  .asst-run-title { flex-basis: 100%; }
1878
1928
  }
1879
1929
  @container asst (max-width: 320px) {
1880
1930
  .asst-bar-group[data-group="computer"] { display: none !important; }
1881
- /* The model keeps a readable name (at least 5ch): the composer row wraps instead of truncating it. */
1882
- .asst-dd-model .asst-dd-label { min-width: 5ch; max-width: 14ch; }
1883
- /* A tighter gap keeps attach · model · effort · variant · mode · tests · send on one row at 320px. */
1931
+ /* A tighter gap keeps attach · model · effort · variant · mode · tests · send on one row at 320px;
1932
+ narrower, the row wraps rather than cut the model chip. */
1884
1933
  .asst-composer-actions { flex-wrap: wrap; gap: 6px 4px; }
1885
1934
  .asst-composer-brain { flex-wrap: wrap; gap: 6px 4px; }
1886
1935
  }
@@ -261,7 +261,7 @@ function buildPanel() {
261
261
  panel.innerHTML = `
262
262
  <div class="cxp-resize-handle"></div>
263
263
  <div class="cxp-header">
264
- <button class="cxp-session-btn" id="cxp-session-btn" type="button">
264
+ <button class="cxp-session-btn" id="cxp-session-btn" type="button" title="${esc(_sessionLabel)}">
265
265
  <span class="cxp-session-label" id="cxp-session-label">${esc(_sessionLabel)}</span>
266
266
  <span class="cxp-dd-arrow">&#x25BE;</span>
267
267
  </button>
@@ -168,7 +168,15 @@ export function injectStyles() {
168
168
  align-items: center;
169
169
  background: var(--cxp-surface-1);
170
170
  z-index: 3;
171
- }
171
+ /* A query container measured in controls: 1em is one header button (24px
172
+ docked, the window's control size when detached, which follows the font
173
+ scale), so the thresholds at the end of this section hold at any scale.
174
+ Nothing in the row inherits it; the session menu takes the panel's back. */
175
+ container: cxp-header / inline-size;
176
+ font-size: 24px;
177
+ }
178
+ .sp-sidepanel.sp-floating > .cxp-header { font-size: var(--fw-header-control-size); }
179
+ .cxp-header > .cxp-session-menu { font-size: 1rem; }
172
180
  .cxp-session-btn {
173
181
  background: var(--cxp-surface-1);
174
182
  border: none;
@@ -182,10 +190,14 @@ export function injectStyles() {
182
190
  padding: 5px 10px;
183
191
  border-radius: var(--cxp-radius-md) 0 0 var(--cxp-radius-md);
184
192
  transition: background var(--cxp-dur-fast), color var(--cxp-dur-fast);
185
- max-width: 100%;
193
+ /* The session name keeps a readable 88px (about 8 characters, or its own
194
+ width if shorter) and gives way first above that: it grows only into the
195
+ room the pencil and the actions leave, so a long name never pushes them.
196
+ Narrower, the container queries let it go down to 32px (the caret). */
197
+ flex: 1 0 88px;
198
+ min-width: 32px;
199
+ max-width: max-content;
186
200
  overflow: hidden;
187
- flex-shrink: 1;
188
- min-width: 0;
189
201
  }
190
202
  .cxp-session-btn:hover {
191
203
  background: var(--cxp-surface-2);
@@ -231,6 +243,8 @@ export function injectStyles() {
231
243
  cursor: pointer;
232
244
  transition: background var(--cxp-dur-fast), color var(--cxp-dur-fast);
233
245
  flex-shrink: 0;
246
+ /* The actions' own gap, kept when the name fills the row. */
247
+ margin-right: 3px;
234
248
  }
235
249
  .cxp-header-rename:hover:not(:disabled) {
236
250
  color: var(--cxp-text);
@@ -256,8 +270,34 @@ export function injectStyles() {
256
270
  margin-left: auto;
257
271
  flex-shrink: 0;
258
272
  }
259
- /* The header account menu's trigger (account-menu.js) gives way before the session name does. */
273
+ /* The header buttons never shrink. The account menu's trigger (account-menu.js)
274
+ is the one piece of the actions that gives way, once the session name is at
275
+ its readable 88px, down to its compact 64px, and truncates. */
276
+ .cxp-actions > * { flex-shrink: 0; }
260
277
  .cxp-actions:has(> .acct-menu-trigger) { flex-shrink: 1; min-width: 0; }
278
+ .cxp-actions > .acct-menu-trigger { flex-shrink: 1; }
279
+ /* Narrow headers, in order: the trigger stays at its compact 64px and the name
280
+ goes from 88px down to its caret; then the trigger is hidden (the cog's
281
+ Account row still opens its menu). Room counted in controls (em) plus px:
282
+ docked, the pencil and six buttons are 7em with 21px of gaps; detached, the
283
+ move handle makes 8em, the window's 6px gaps 39px, the name's floor is 1em.
284
+ Thresholds: name + 64px trigger + that row. */
285
+ @container cxp-header (width < calc(7em + 173px)) {
286
+ .codex-panel:not(.sp-floating) > .cxp-header .cxp-session-btn { flex: 1 1 0; }
287
+ .codex-panel:not(.sp-floating) > .cxp-header > .cxp-actions { flex-shrink: 0; }
288
+ .codex-panel:not(.sp-floating) > .cxp-header .acct-menu-trigger { flex: 0 0 64px; width: 64px; }
289
+ }
290
+ @container cxp-header (width < calc(7em + 117px)) {
291
+ .codex-panel:not(.sp-floating) > .cxp-header .acct-menu-trigger { display: none; }
292
+ }
293
+ @container cxp-header (width < calc(8em + 191px)) {
294
+ .codex-panel.sp-floating > .cxp-header .cxp-session-btn { flex: 1 1 0; }
295
+ .codex-panel.sp-floating > .cxp-header > .cxp-actions { flex-shrink: 0; }
296
+ .codex-panel.sp-floating > .cxp-header .acct-menu-trigger { flex: 0 0 64px; width: 64px; }
297
+ }
298
+ @container cxp-header (width < calc(9em + 103px)) {
299
+ .codex-panel.sp-floating > .cxp-header .acct-menu-trigger { display: none; }
300
+ }
261
301
  .cxp-btn {
262
302
  width: 24px;
263
303
  height: 24px;
@@ -2437,6 +2437,9 @@ export function setSessionLabel(label, { persist = true } = {}) {
2437
2437
  if (isActiveTab(_boundTab)) {
2438
2438
  const labelEl = panelEl('#cxp-session-label');
2439
2439
  if (labelEl) labelEl.replaceChildren(document.createTextNode(_sessionLabel));
2440
+ // The whole name, for when the header shows only part of it.
2441
+ const sessionBtn = panelEl('#cxp-session-btn');
2442
+ if (sessionBtn) sessionBtn.title = _sessionLabel;
2440
2443
  syncLegacyState();
2441
2444
  }
2442
2445
  updateTrayPillLabel();
@@ -419,9 +419,12 @@ export function createChildPanel({
419
419
  _statusEl.removeAttribute('data-tooltip');
420
420
  }
421
421
  }
422
+ const title = sessionTitleFor(store);
422
423
  if (_titleEl && !_titleEl.querySelector('.ocpv2-rename-input')) {
423
- _titleEl.textContent = sessionTitleFor(store);
424
+ _titleEl.textContent = title;
424
425
  }
426
+ // The whole name, for when the header shows only part of it.
427
+ if (_titleEl?.parentElement) _titleEl.parentElement.title = title;
425
428
  if (_renameBtn) _renameBtn.disabled = !s.sessionId;
426
429
  renderCrumbs();
427
430
  renderPill();
@@ -671,10 +671,13 @@ function syncHeader() {
671
671
  // The footer row gives the text only the room that is left: the tooltip
672
672
  // says it in full when just the dot fits.
673
673
  _statusEl.setAttribute('data-tooltip', status.text);
674
+ const title = sessionTitleFor(s);
674
675
  // Skip label update while user is mid-rename (input is mounted in the label).
675
676
  if (_sessionLabelEl && !_sessionLabelEl.querySelector('.ocpv2-rename-input')) {
676
- _sessionLabelEl.textContent = sessionTitleFor(s);
677
+ _sessionLabelEl.textContent = title;
677
678
  }
679
+ // The whole name, for when the header shows only part of it.
680
+ if (_sessionBtnEl) _sessionBtnEl.title = title;
678
681
  if (_renameBtnEl) {
679
682
  _renameBtnEl.disabled = !s.sessionId;
680
683
  }
@@ -98,8 +98,12 @@ const CSS = `
98
98
  padding: 5px 10px;
99
99
  border-radius: 8px 0 0 8px;
100
100
  transition: background 0.15s, color 0.15s;
101
- max-width: 100%;
102
- min-width: 0;
101
+ /* The session name gives way first: it starts from nothing and takes only
102
+ the room the pencil and the actions leave, up to its own width, so a long
103
+ name can never push them. 32px keeps the caret in view. */
104
+ flex: 1 1 0;
105
+ min-width: 32px;
106
+ max-width: max-content;
103
107
  overflow: hidden;
104
108
  }
105
109
  .ocpv2-session-btn:hover {
@@ -135,6 +139,7 @@ const CSS = `
135
139
  .ocpv2-rename-input:focus { border-color: rgba(100,160,255,0.5); }
136
140
  .ocpv2-rename-input::placeholder { color: rgba(255,255,255,0.3); }
137
141
  .ocpv2-session-btn .ocpv2-dd-arrow {
142
+ flex-shrink: 0;
138
143
  font-size: 9px;
139
144
  padding: 4px 6px;
140
145
  margin: -4px -6px -4px 0;
@@ -164,6 +169,8 @@ const CSS = `
164
169
  -webkit-tap-highlight-color: transparent;
165
170
  touch-action: manipulation;
166
171
  flex-shrink: 0;
172
+ /* The actions' own gap, kept when the name fills the row. */
173
+ margin-right: 3px;
167
174
  }
168
175
  .ocpv2-header-rename:hover:not(:disabled) {
169
176
  color: rgba(100,160,255,0.95);
@@ -359,6 +366,8 @@ const CSS = `
359
366
  margin-left: auto;
360
367
  flex-shrink: 0;
361
368
  }
369
+ /* The header buttons never shrink, whatever the session name's length. */
370
+ .ocpv2-actions > * { flex-shrink: 0; }
362
371
  .ocpv2-btn {
363
372
  display: flex;
364
373
  align-items: center;
@@ -2718,16 +2727,56 @@ const CHILD_CSS = `
2718
2727
  set inline via --right-panel-offset-{owner}. */
2719
2728
  border: 0.5px dashed rgba(180, 200, 255, 0.18);
2720
2729
  }
2730
+ /* A query container measured in controls: 1em is one header button (24px
2731
+ docked, the window's control size when detached, which follows the font
2732
+ scale), so the thresholds below hold at any scale. Nothing in this row
2733
+ inherits it: the crumbs and the title set their own sizes. */
2734
+ .ocpv2-panel-child > .ocpv2-header {
2735
+ container: ocpv2-child-header / inline-size;
2736
+ font-size: 24px;
2737
+ }
2738
+ .ocpv2-panel-child.sp-floating > .ocpv2-header { font-size: var(--fw-header-control-size); }
2739
+ /* The sub-agent's name keeps a readable 88px (or its own width if shorter):
2740
+ the chain of parents gives way first. */
2741
+ .ocpv2-panel-child .ocpv2-session-btn { flex: 1 0 88px; }
2742
+ /* The chain of parents: at most 40% of the row, and it gives way before the
2743
+ name. When it is cut, it is cut from the left, so the nearest parent (the
2744
+ last crumb, which keeps its own width, at most 140px) stays readable. */
2721
2745
  .ocpv2-panel-child .ocpv2-child-crumbs {
2722
2746
  display: inline-flex;
2723
2747
  align-items: center;
2748
+ justify-content: flex-end;
2724
2749
  gap: 3px;
2725
2750
  min-width: 0;
2751
+ max-width: 40%;
2726
2752
  flex-shrink: 1;
2727
2753
  overflow: hidden;
2728
2754
  margin-right: 6px;
2729
2755
  }
2730
2756
  .ocpv2-panel-child .ocpv2-child-crumbs:empty { display: none; }
2757
+ .ocpv2-panel-child .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 0; }
2758
+ /* Narrow headers, in order: with less than 140px for the chain, only the
2759
+ nearest parent shows, truncated; with less than 64px, the chain is hidden
2760
+ and the name goes down to its caret. Room counted in controls (em) plus px:
2761
+ docked, the pencil and six buttons are 7em with 18px of gaps; detached, the
2762
+ move handle makes 8em and the window's 6px gaps 42px. Thresholds: the
2763
+ name's 88px + the chain's 6px margin + 140px or 64px + that row. */
2764
+ @container ocpv2-child-header (width < calc(7em + 252px)) {
2765
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs > :not(:last-child) { display: none; }
2766
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 1; min-width: 0; }
2767
+ }
2768
+ @container ocpv2-child-header (width < calc(7em + 176px)) {
2769
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs { display: none; }
2770
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-session-btn { flex: 1 1 0; }
2771
+ }
2772
+ @container ocpv2-child-header (width < calc(8em + 276px)) {
2773
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs > :not(:last-child) { display: none; }
2774
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 1; min-width: 0; }
2775
+ }
2776
+ @container ocpv2-child-header (width < calc(8em + 200px)) {
2777
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs { display: none; }
2778
+ .ocpv2-panel-child.sp-floating .ocpv2-session-btn { flex: 1 1 0; }
2779
+ }
2731
2780
  .ocpv2-panel-child .ocpv2-child-crumb-sep {
2732
2781
  flex-shrink: 0;
2733
2782
  color: rgba(180, 200, 255, 0.4);
@@ -69,7 +69,8 @@ export const WHOLESALE_SELECTORS = [
69
69
  '.resume-project-badge', '.resume-branch',
70
70
  // Account emails and names
71
71
  '.acct-menu-trigger-name', '.acct-menu-item-name', '.acct-menu-item-id', '.acct-menu-avatar', '.acct-menu-note', '.acct-menu-v',
72
- '.asst-account-label', '.asst-account-sub', '.asst-account-cred', '.asst-model-account', '.as-launch-account-name',
72
+ '.asst-account-label', '.asst-account-sub', '.asst-account-cred', '.as-launch-account-name',
73
+ '.asst-acct-name', '.asst-acct-line', '.asst-acct-avatar', '.asst-acct-value-text',
73
74
  '.invite-key-box', '.invite-url-text', '.invite-key-status',
74
75
  // Toast text
75
76
  '.notif-toast-msg', '.term-toast', '#fe-toast', '.as-toast', '.ss-toast', '.cc-toast', '.asp-toast',
@@ -26727,7 +26727,9 @@
26727
26727
  body .term-float-tab.term-float-tab > .term-float-tab-header .term-float-tab-title { font-size: var(--fs-xs); }
26728
26728
  body :is(.sched-header-icon, .sm-header-icon, .ig-icon),
26729
26729
  body :is(.sched-header-icon, .sm-header-icon, .ig-icon) svg { width: 16px; height: 16px; }
26730
- body .sp-sidepanel.sp-floating > :is(.cp-header, .cxp-header, .ocpv2-header, .asp-header) { flex-wrap: wrap; }
26730
+ /* The Claude Code, Codex and OpenCode headers stay one row: their session name gives way
26731
+ instead (the panels' own header styles). */
26732
+ body .sp-sidepanel.sp-floating > .asp-header { flex-wrap: wrap; }
26731
26733
 
26732
26734
  body .term-float-tab-title { flex: 1 1 100px; }
26733
26735
  body .term-float-tab-actions { flex-wrap: wrap; max-width: 100%; }
@@ -1905,10 +1905,44 @@ function injectStyles() {
1905
1905
  background: rgba(22, 22, 26, 0.95);
1906
1906
  z-index: 3;
1907
1907
  box-shadow: var(--shadow-sm), 0 0 0 1px rgba(255,255,255,0.06);
1908
- }
1908
+ /* A query container measured in controls: 1em is one header button (24px docked, the
1909
+ window's control size when detached, which follows the font scale), so the thresholds
1910
+ below hold at any scale. Nothing in the row inherits it; the session menu takes the
1911
+ panel's back. */
1912
+ container: cp-header / inline-size;
1913
+ font-size: 24px;
1914
+ }
1915
+ .sp-sidepanel.sp-floating > .cp-header { font-size: var(--fw-header-control-size); }
1916
+ .cp-header > .cp-session-menu { font-size: 1rem; }
1909
1917
  .cp-header-actions {
1910
1918
  display: flex; align-items: center; gap: 3px; margin-left: auto; flex-shrink: 0;
1911
1919
  }
1920
+ /* The header buttons never shrink. The account menu's trigger (account-menu.js) is the one
1921
+ piece of the actions that gives way, once the session name is at its readable 88px, down to
1922
+ its compact 64px, and truncates. */
1923
+ .cp-header-actions > * { flex-shrink: 0; }
1924
+ .cp-header-actions:has(> .acct-menu-trigger) { flex-shrink: 1; min-width: 0; }
1925
+ .cp-header-actions > .acct-menu-trigger { flex-shrink: 1; }
1926
+ /* Narrow headers, in order: the trigger stays at its compact 64px and the name goes from 88px
1927
+ down to its caret; then the trigger is hidden. Room counted in controls (em) plus px: docked,
1928
+ the pencil and six buttons are 7em with 21px of gaps; detached, the move handle makes 8em,
1929
+ the window's 6px gaps 39px, the name's floor is 1em. Thresholds: name + 64px trigger + that row. */
1930
+ @container cp-header (width < calc(7em + 173px)) {
1931
+ .claude-panel:not(.sp-floating) > .cp-header .cp-session-btn { flex: 1 1 0; }
1932
+ .claude-panel:not(.sp-floating) > .cp-header > .cp-header-actions { flex-shrink: 0; }
1933
+ .claude-panel:not(.sp-floating) > .cp-header .acct-menu-trigger { flex: 0 0 64px; width: 64px; }
1934
+ }
1935
+ @container cp-header (width < calc(7em + 117px)) {
1936
+ .claude-panel:not(.sp-floating) > .cp-header .acct-menu-trigger { display: none; }
1937
+ }
1938
+ @container cp-header (width < calc(8em + 191px)) {
1939
+ .claude-panel.sp-floating > .cp-header .cp-session-btn { flex: 1 1 0; }
1940
+ .claude-panel.sp-floating > .cp-header > .cp-header-actions { flex-shrink: 0; }
1941
+ .claude-panel.sp-floating > .cp-header .acct-menu-trigger { flex: 0 0 64px; width: 64px; }
1942
+ }
1943
+ @container cp-header (width < calc(9em + 103px)) {
1944
+ .claude-panel.sp-floating > .cp-header .acct-menu-trigger { display: none; }
1945
+ }
1912
1946
  .cp-header-btn {
1913
1947
  display: flex; align-items: center; justify-content: center;
1914
1948
  width: 24px; height: 24px; border-radius: 7px;
@@ -1934,14 +1968,18 @@ function injectStyles() {
1934
1968
  font-size: 11px; font-family: 'JetBrains Mono', monospace;
1935
1969
  cursor: pointer; padding: 5px 10px; border-radius: 8px 0 0 8px;
1936
1970
  transition: background 0.15s, color 0.15s;
1937
- max-width: 100%; overflow: hidden;
1971
+ /* The session name keeps a readable 88px (about 8 characters, or its own width if shorter)
1972
+ and gives way first above that: it grows only into the room the pencil and the actions
1973
+ leave, so a long name never pushes them. Narrower, the container queries above let it go
1974
+ down to 32px (the caret). */
1975
+ flex: 1 0 88px; min-width: 32px; max-width: max-content; overflow: hidden;
1938
1976
  }
1939
1977
  .cp-session-btn:hover { background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.75); }
1940
1978
  .cp-session-btn .cp-session-label {
1941
- overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1979
+ min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1942
1980
  }
1943
1981
  .cp-session-btn .cp-dd-arrow {
1944
- font-size: 9px; padding: 4px 6px; margin: -4px -6px -4px 0;
1982
+ flex-shrink: 0; font-size: 9px; padding: 4px 6px; margin: -4px -6px -4px 0;
1945
1983
  border-radius: 0 6px 6px 0; cursor: pointer;
1946
1984
  transition: background 0.15s, color 0.2s, transform 0.2s;
1947
1985
  }
@@ -1956,6 +1994,7 @@ function injectStyles() {
1956
1994
  -webkit-tap-highlight-color: transparent;
1957
1995
  touch-action: manipulation;
1958
1996
  flex-shrink: 0;
1997
+ margin-right: 3px; /* the actions' own gap, kept when the name fills the row */
1959
1998
  }
1960
1999
  .cp-header-rename-btn:hover { color: rgba(100,160,255,0.95); background: rgba(100,160,255,0.14); }
1961
2000
  .cp-header-rename-btn:active { transform: scale(0.92); transition-duration: 0.06s; }
@@ -11605,6 +11644,13 @@ function wireEvents() {
11605
11644
  const $sessMenu = _panel.querySelector('#cp-session-menu');
11606
11645
  const $sessLabel = _panel.querySelector('.cp-session-label');
11607
11646
  let _sessClickTimer = null;
11647
+ // The whole name as the chip's tooltip, for when the header shows only part of it. The label is
11648
+ // written from many places (switch, rename, title, reset), so it follows the label itself.
11649
+ const syncSessionTooltip = () => {
11650
+ if (!$sessLabel.querySelector('.cp-rename-input')) $sessBtn.title = $sessLabel.textContent;
11651
+ };
11652
+ syncSessionTooltip();
11653
+ new MutationObserver(syncSessionTooltip).observe($sessLabel, { childList: true, characterData: true, subtree: true });
11608
11654
 
11609
11655
  $sessBtn.addEventListener('click', (e) => {
11610
11656
  // Block menu toggle while rename input is active
@@ -1441,6 +1441,8 @@ export function initExplorer() {
1441
1441
  if (selectAllBtn) {
1442
1442
  selectAllBtn.addEventListener('click', () => {
1443
1443
  Object.keys(state.categoryMetadata).forEach(c => state.activeCategories.add(c));
1444
+ // and the categories memories use without a registered one ("uncategorized" included), as the sidebar does
1445
+ (state.allNodes || []).forEach(n => { if (n.payload?.category) state.activeCategories.add(n.payload.category); });
1444
1446
  cancelScheduledRemoval();
1445
1447
  emit('graph:refresh');
1446
1448
  emit('categories-changed');
@@ -129,6 +129,8 @@ const SYNC_HANDLERS = {
129
129
  'assistant:desktop': (msg) => emit('sync:assistant:desktop', msg),
130
130
  'assistant:desktop-setup': (msg) => emit('sync:assistant:desktop-setup', msg),
131
131
  'assistant:routing-changed': (msg) => emit('sync:assistant:routing-changed', msg),
132
+ // Admin sandbox (lib/agent-sandbox-setting.js): the one global value changed in some window
133
+ 'agents:admin-sandbox-changed': (msg) => emit('sync:agents:admin-sandbox-changed', msg),
132
134
 
133
135
  // WhatsApp Link — states and counters only (never a QR, code, number or text); Settings → WhatsApp re-reads /api/whatsapp/status
134
136
  'whatsapp:status': (msg) => emit('sync:whatsapp:status', msg),
@@ -1076,12 +1076,14 @@ function openUpdateModal() {
1076
1076
  failure.code = code;
1077
1077
  throw failure;
1078
1078
  }
1079
- await res.json();
1079
+ const launched = await res.json();
1080
+ // On Windows the updater also stops the SynaBun MCP servers AI clients started (updater.mjs).
1081
+ const onWindows = launched?.platform === 'win32';
1080
1082
 
1081
1083
  icon.className = 'update-backup-icon';
1082
1084
  icon.textContent = '✓';
1083
1085
  icon.style.color = '#34c759';
1084
- text.innerHTML = `<strong>Updater terminal launched</strong><span class="update-run-detail">SynaBun is shutting down so npm can replace the package. Watch the terminal for install progress; SynaBun will relaunch automatically when it finishes.</span><span class="update-run-hint">If no terminal window appears, run <code>${esc(installPlan.displayCommand || 'npm i -g synabun@latest')}</code> manually.</span>`;
1086
+ text.innerHTML = `<strong>Updater terminal launched</strong><span class="update-run-detail">SynaBun is shutting down so npm can replace the package. Watch the terminal for install progress; SynaBun will relaunch automatically when it finishes.</span>${onWindows ? '<span class="update-run-detail">It also stops the SynaBun MCP servers your AI clients started. Reconnect them afterwards (in Claude Code: /mcp).</span>' : ''}<span class="update-run-hint">If no terminal window appears, ${onWindows ? 'close your AI clients, then ' : ''}run <code>${esc(installPlan.displayCommand || 'npm i -g synabun@latest')}</code> manually.</span>`;
1085
1087
  runBtn.innerHTML = 'Updater running…';
1086
1088
 
1087
1089
  // Server is shutting down. Optionally redirect to a friendly offline
@@ -16,10 +16,16 @@ import { resolve, dirname } from 'node:path';
16
16
  import { fileURLToPath } from 'node:url';
17
17
  import { ensureVendoredExecutables } from '../lib/native-binary-runtime.js';
18
18
  import { pruneExternalTools } from '../../lib/external-tools.js';
19
+ import { findInstalled } from '../../lib/runtime-dependencies.js';
19
20
 
20
21
  const __dirname = dirname(fileURLToPath(import.meta.url));
21
22
  const neuralRoot = resolve(__dirname, '..');
22
- const ptyDir = resolve(neuralRoot, 'node_modules', 'node-pty');
23
+ const packageRoot = resolve(neuralRoot, '..');
24
+ // node-pty where Node finds it from the Neural Interface: the package root's
25
+ // node_modules after `npm i -g synabun`, neural-interface/node_modules in a
26
+ // development checkout or a desktop build.
27
+ const ptyDir = findInstalled(neuralRoot, 'node-pty', { stopAt: packageRoot })?.path
28
+ || resolve(neuralRoot, 'node_modules', 'node-pty');
23
29
 
24
30
  // Step 0: Claude Code, Codex, OpenCode and Gemini CLI are installed by the user,
25
31
  // never by SynaBun. The lockfile holds none of them; an `npm install` that
@@ -40,7 +46,13 @@ for (const item of pruneExternalTools(resolve(neuralRoot, 'node_modules')).remov
40
46
  // linux dirs that do not exist here while missing ones that do). The sweep
41
47
  // below enumerates instead.
42
48
  function sweepVendoredBinaries(label) {
43
- const sweep = ensureVendoredExecutables({ root: neuralRoot, log: console.log });
49
+ // Both node_modules an install can have: the package root's and the Neural Interface's own.
50
+ const sweep = { repaired: [], failed: [] };
51
+ for (const root of new Set([neuralRoot, packageRoot])) {
52
+ const found = ensureVendoredExecutables({ root, log: console.log });
53
+ sweep.repaired.push(...found.repaired);
54
+ sweep.failed.push(...found.failed);
55
+ }
44
56
  for (const failure of sweep.failed) {
45
57
  console.warn(`[rebuild-pty] ${failure.path} is not launchable (${failure.state}).`
46
58
  + (failure.repairCommand ? ` Try: ${failure.repairCommand}` : ''));