synabun 1.3.0 → 2.0.0

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 (1163) hide show
  1. package/CHANGELOG.md +205 -662
  2. package/LICENSE-COMMERCIAL.md +33 -0
  3. package/NOTICE +17 -0
  4. package/README.md +175 -853
  5. package/THIRD-PARTY-LICENSES.md +136 -0
  6. package/benchmarks/browser-live-results.json +79 -0
  7. package/benchmarks/browser-v2-results.json +258 -0
  8. package/benchmarks/fixtures/browser/README.md +57 -0
  9. package/benchmarks/fixtures/browser/page-state.json +132 -0
  10. package/benchmarks/fixtures/browser/social.json +92 -0
  11. package/benchmarks/fixtures/browser/target.json +319 -0
  12. package/benchmarks/fixtures/desktop/README.md +58 -0
  13. package/benchmarks/fixtures/desktop/abstention.json +59 -0
  14. package/benchmarks/fixtures/desktop/adversarial.json +22 -0
  15. package/benchmarks/fixtures/desktop/forbidden.json +93 -0
  16. package/benchmarks/fixtures/desktop/generate.mjs +1023 -0
  17. package/benchmarks/fixtures/desktop/target.json +136 -0
  18. package/bin/synabun.js +30 -0
  19. package/docs/whatsapp.md +325 -0
  20. package/hooks/claude-code/post-plan.mjs +613 -391
  21. package/hooks/claude-code/post-remember.mjs +246 -122
  22. package/hooks/claude-code/pre-compact.mjs +171 -110
  23. package/hooks/claude-code/pre-task.mjs +133 -0
  24. package/hooks/claude-code/pre-websearch.mjs +15 -4
  25. package/hooks/claude-code/prompt-origin.mjs +94 -0
  26. package/hooks/claude-code/prompt-submit.mjs +1244 -861
  27. package/hooks/claude-code/session-start.mjs +114 -156
  28. package/hooks/claude-code/shared.mjs +1228 -368
  29. package/hooks/claude-code/state.mjs +167 -0
  30. package/hooks/claude-code/stop.mjs +515 -140
  31. package/hooks/claude-code/subagent-start.mjs +154 -0
  32. package/hooks/claude-code/subagent-stop.mjs +102 -0
  33. package/hooks/claude-code/task-gate.mjs +150 -0
  34. package/launcher.mjs +40 -0
  35. package/lib/claude-hooks.js +137 -0
  36. package/lib/claude-usage-audit.js +141 -0
  37. package/lib/client-config-repair.js +145 -0
  38. package/lib/data-home-migration.js +502 -0
  39. package/lib/desktop-pwa.js +206 -0
  40. package/lib/external-tools.js +221 -0
  41. package/lib/first-launch-protection.js +245 -0
  42. package/lib/packaged-runtime.js +110 -0
  43. package/lib/paths.d.ts +21 -0
  44. package/lib/paths.js +103 -0
  45. package/lib/start-launcher.js +1309 -0
  46. package/mcp-server/dist/config.d.ts +22 -0
  47. package/mcp-server/dist/config.d.ts.map +1 -0
  48. package/mcp-server/dist/config.js +109 -0
  49. package/mcp-server/dist/config.js.map +1 -0
  50. package/mcp-server/dist/http.d.ts +30 -0
  51. package/mcp-server/dist/http.d.ts.map +1 -0
  52. package/mcp-server/dist/http.js +276 -0
  53. package/mcp-server/dist/http.js.map +1 -0
  54. package/mcp-server/dist/index.d.ts +48 -0
  55. package/mcp-server/dist/index.d.ts.map +1 -0
  56. package/mcp-server/dist/index.js +538 -0
  57. package/mcp-server/dist/index.js.map +1 -0
  58. package/mcp-server/dist/preload-http.d.ts +3 -0
  59. package/mcp-server/dist/preload-http.d.ts.map +1 -0
  60. package/mcp-server/dist/preload-http.js +28 -0
  61. package/mcp-server/dist/preload-http.js.map +1 -0
  62. package/mcp-server/dist/preload.d.ts +3 -0
  63. package/mcp-server/dist/preload.d.ts.map +1 -0
  64. package/mcp-server/dist/preload.js +32 -0
  65. package/mcp-server/dist/preload.js.map +1 -0
  66. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts +19 -0
  67. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts.map +1 -0
  68. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js +403 -0
  69. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js.map +1 -0
  70. package/mcp-server/dist/scripts/setup-embeddings.d.ts +3 -0
  71. package/mcp-server/dist/scripts/setup-embeddings.d.ts.map +1 -0
  72. package/mcp-server/dist/scripts/setup-embeddings.js +15 -0
  73. package/mcp-server/dist/scripts/setup-embeddings.js.map +1 -0
  74. package/mcp-server/dist/services/assistant-judgments.d.ts +79 -0
  75. package/mcp-server/dist/services/assistant-judgments.d.ts.map +1 -0
  76. package/mcp-server/dist/services/assistant-judgments.js +128 -0
  77. package/mcp-server/dist/services/assistant-judgments.js.map +1 -0
  78. package/mcp-server/dist/services/browser-assist-gate.d.ts +314 -0
  79. package/mcp-server/dist/services/browser-assist-gate.d.ts.map +1 -0
  80. package/mcp-server/dist/services/browser-assist-gate.js +344 -0
  81. package/mcp-server/dist/services/browser-assist-gate.js.map +1 -0
  82. package/mcp-server/dist/services/browser-assist.d.ts +104 -0
  83. package/mcp-server/dist/services/browser-assist.d.ts.map +1 -0
  84. package/mcp-server/dist/services/browser-assist.js +282 -0
  85. package/mcp-server/dist/services/browser-assist.js.map +1 -0
  86. package/mcp-server/dist/services/browser-bench.d.ts +772 -0
  87. package/mcp-server/dist/services/browser-bench.d.ts.map +1 -0
  88. package/mcp-server/dist/services/browser-bench.js +424 -0
  89. package/mcp-server/dist/services/browser-bench.js.map +1 -0
  90. package/mcp-server/dist/services/browser-judgments.d.ts +196 -0
  91. package/mcp-server/dist/services/browser-judgments.d.ts.map +1 -0
  92. package/mcp-server/dist/services/browser-judgments.js +363 -0
  93. package/mcp-server/dist/services/browser-judgments.js.map +1 -0
  94. package/mcp-server/dist/services/browser-risk.d.ts +166 -0
  95. package/mcp-server/dist/services/browser-risk.d.ts.map +1 -0
  96. package/mcp-server/dist/services/browser-risk.js +458 -0
  97. package/mcp-server/dist/services/browser-risk.js.map +1 -0
  98. package/mcp-server/dist/services/categories.d.ts +61 -0
  99. package/mcp-server/dist/services/categories.d.ts.map +1 -0
  100. package/mcp-server/dist/services/categories.js +377 -0
  101. package/mcp-server/dist/services/categories.js.map +1 -0
  102. package/mcp-server/dist/services/codex-config-heal.d.ts +49 -0
  103. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -0
  104. package/mcp-server/dist/services/codex-config-heal.js +346 -0
  105. package/mcp-server/dist/services/codex-config-heal.js.map +1 -0
  106. package/mcp-server/dist/services/desktop-assist-gate.d.ts +198 -0
  107. package/mcp-server/dist/services/desktop-assist-gate.d.ts.map +1 -0
  108. package/mcp-server/dist/services/desktop-assist-gate.js +202 -0
  109. package/mcp-server/dist/services/desktop-assist-gate.js.map +1 -0
  110. package/mcp-server/dist/services/desktop-assist.d.ts +104 -0
  111. package/mcp-server/dist/services/desktop-assist.d.ts.map +1 -0
  112. package/mcp-server/dist/services/desktop-assist.js +266 -0
  113. package/mcp-server/dist/services/desktop-assist.js.map +1 -0
  114. package/mcp-server/dist/services/desktop-bench.d.ts +553 -0
  115. package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -0
  116. package/mcp-server/dist/services/desktop-bench.js +311 -0
  117. package/mcp-server/dist/services/desktop-bench.js.map +1 -0
  118. package/mcp-server/dist/services/desktop-client.d.ts +23 -0
  119. package/mcp-server/dist/services/desktop-client.d.ts.map +1 -0
  120. package/mcp-server/dist/services/desktop-client.js +79 -0
  121. package/mcp-server/dist/services/desktop-client.js.map +1 -0
  122. package/mcp-server/dist/services/desktop-judgments.d.ts +125 -0
  123. package/mcp-server/dist/services/desktop-judgments.d.ts.map +1 -0
  124. package/mcp-server/dist/services/desktop-judgments.js +177 -0
  125. package/mcp-server/dist/services/desktop-judgments.js.map +1 -0
  126. package/mcp-server/dist/services/desktop-risk.d.ts +283 -0
  127. package/mcp-server/dist/services/desktop-risk.d.ts.map +1 -0
  128. package/mcp-server/dist/services/desktop-risk.js +605 -0
  129. package/mcp-server/dist/services/desktop-risk.js.map +1 -0
  130. package/mcp-server/dist/services/discord.d.ts +112 -0
  131. package/mcp-server/dist/services/discord.d.ts.map +1 -0
  132. package/mcp-server/dist/services/discord.js +477 -0
  133. package/mcp-server/dist/services/discord.js.map +1 -0
  134. package/mcp-server/dist/services/edit-stale.d.ts +81 -0
  135. package/mcp-server/dist/services/edit-stale.d.ts.map +1 -0
  136. package/mcp-server/dist/services/edit-stale.js +358 -0
  137. package/mcp-server/dist/services/edit-stale.js.map +1 -0
  138. package/mcp-server/dist/services/embedding-service.d.ts +16 -0
  139. package/mcp-server/dist/services/embedding-service.d.ts.map +1 -0
  140. package/mcp-server/dist/services/embedding-service.js +126 -0
  141. package/mcp-server/dist/services/embedding-service.js.map +1 -0
  142. package/mcp-server/dist/services/embedding-worker.d.ts +2 -0
  143. package/mcp-server/dist/services/embedding-worker.d.ts.map +1 -0
  144. package/mcp-server/dist/services/embedding-worker.js +52 -0
  145. package/mcp-server/dist/services/embedding-worker.js.map +1 -0
  146. package/mcp-server/dist/services/fb-regions.d.ts +71 -0
  147. package/mcp-server/dist/services/fb-regions.d.ts.map +1 -0
  148. package/mcp-server/dist/services/fb-regions.js +211 -0
  149. package/mcp-server/dist/services/fb-regions.js.map +1 -0
  150. package/mcp-server/dist/services/file-checksums.d.ts +22 -0
  151. package/mcp-server/dist/services/file-checksums.d.ts.map +1 -0
  152. package/mcp-server/dist/services/file-checksums.js +55 -0
  153. package/mcp-server/dist/services/file-checksums.js.map +1 -0
  154. package/mcp-server/dist/services/file-excerpt.d.ts +24 -0
  155. package/mcp-server/dist/services/file-excerpt.d.ts.map +1 -0
  156. package/mcp-server/dist/services/file-excerpt.js +65 -0
  157. package/mcp-server/dist/services/file-excerpt.js.map +1 -0
  158. package/mcp-server/dist/services/identity.d.ts +124 -0
  159. package/mcp-server/dist/services/identity.d.ts.map +1 -0
  160. package/mcp-server/dist/services/identity.js +241 -0
  161. package/mcp-server/dist/services/identity.js.map +1 -0
  162. package/mcp-server/dist/services/local-embeddings.d.ts +2 -0
  163. package/mcp-server/dist/services/local-embeddings.d.ts.map +1 -0
  164. package/mcp-server/dist/services/local-embeddings.js +3 -0
  165. package/mcp-server/dist/services/local-embeddings.js.map +1 -0
  166. package/mcp-server/dist/services/memory-client.d.ts +4 -0
  167. package/mcp-server/dist/services/memory-client.d.ts.map +1 -0
  168. package/mcp-server/dist/services/memory-client.js +27 -0
  169. package/mcp-server/dist/services/memory-client.js.map +1 -0
  170. package/mcp-server/dist/services/memory-judge-backfill.d.ts +135 -0
  171. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -0
  172. package/mcp-server/dist/services/memory-judge-backfill.js +510 -0
  173. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -0
  174. package/mcp-server/dist/services/memory-judgments.d.ts +362 -0
  175. package/mcp-server/dist/services/memory-judgments.d.ts.map +1 -0
  176. package/mcp-server/dist/services/memory-judgments.js +674 -0
  177. package/mcp-server/dist/services/memory-judgments.js.map +1 -0
  178. package/mcp-server/dist/services/memory-maintenance.d.ts +108 -0
  179. package/mcp-server/dist/services/memory-maintenance.d.ts.map +1 -0
  180. package/mcp-server/dist/services/memory-maintenance.js +403 -0
  181. package/mcp-server/dist/services/memory-maintenance.js.map +1 -0
  182. package/mcp-server/dist/services/memory-retrieval.d.ts +66 -0
  183. package/mcp-server/dist/services/memory-retrieval.d.ts.map +1 -0
  184. package/mcp-server/dist/services/memory-retrieval.js +412 -0
  185. package/mcp-server/dist/services/memory-retrieval.js.map +1 -0
  186. package/mcp-server/dist/services/memory-schema.d.ts +16 -0
  187. package/mcp-server/dist/services/memory-schema.d.ts.map +1 -0
  188. package/mcp-server/dist/services/memory-schema.js +282 -0
  189. package/mcp-server/dist/services/memory-schema.js.map +1 -0
  190. package/mcp-server/dist/services/memory-sessions.d.ts +24 -0
  191. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -0
  192. package/mcp-server/dist/services/memory-sessions.js +110 -0
  193. package/mcp-server/dist/services/memory-sessions.js.map +1 -0
  194. package/mcp-server/dist/services/memory-triage.d.ts +60 -0
  195. package/mcp-server/dist/services/memory-triage.d.ts.map +1 -0
  196. package/mcp-server/dist/services/memory-triage.js +189 -0
  197. package/mcp-server/dist/services/memory-triage.js.map +1 -0
  198. package/mcp-server/dist/services/memory-verification.d.ts +24 -0
  199. package/mcp-server/dist/services/memory-verification.d.ts.map +1 -0
  200. package/mcp-server/dist/services/memory-verification.js +92 -0
  201. package/mcp-server/dist/services/memory-verification.js.map +1 -0
  202. package/mcp-server/dist/services/memory-writer.d.ts +26 -0
  203. package/mcp-server/dist/services/memory-writer.d.ts.map +1 -0
  204. package/mcp-server/dist/services/memory-writer.js +126 -0
  205. package/mcp-server/dist/services/memory-writer.js.map +1 -0
  206. package/mcp-server/dist/services/neural-interface.d.ts +439 -0
  207. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -0
  208. package/mcp-server/dist/services/neural-interface.js +1135 -0
  209. package/mcp-server/dist/services/neural-interface.js.map +1 -0
  210. package/mcp-server/dist/services/profiles.d.ts +120 -0
  211. package/mcp-server/dist/services/profiles.d.ts.map +1 -0
  212. package/mcp-server/dist/services/profiles.js +387 -0
  213. package/mcp-server/dist/services/profiles.js.map +1 -0
  214. package/mcp-server/dist/services/secret-gate.d.ts +29 -0
  215. package/mcp-server/dist/services/secret-gate.d.ts.map +1 -0
  216. package/mcp-server/dist/services/secret-gate.js +43 -0
  217. package/mcp-server/dist/services/secret-gate.js.map +1 -0
  218. package/mcp-server/dist/services/server-instructions.d.ts +10 -0
  219. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -0
  220. package/mcp-server/dist/services/server-instructions.js +101 -0
  221. package/mcp-server/dist/services/server-instructions.js.map +1 -0
  222. package/mcp-server/dist/services/sqlite.d.ts +235 -0
  223. package/mcp-server/dist/services/sqlite.d.ts.map +1 -0
  224. package/mcp-server/dist/services/sqlite.js +1185 -0
  225. package/mcp-server/dist/services/sqlite.js.map +1 -0
  226. package/mcp-server/dist/services/typesafe-bench.d.ts +99 -0
  227. package/mcp-server/dist/services/typesafe-bench.d.ts.map +1 -0
  228. package/mcp-server/dist/services/typesafe-bench.js +218 -0
  229. package/mcp-server/dist/services/typesafe-bench.js.map +1 -0
  230. package/mcp-server/dist/services/typesafe-config.d.ts +342 -0
  231. package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -0
  232. package/mcp-server/dist/services/typesafe-config.js +746 -0
  233. package/mcp-server/dist/services/typesafe-config.js.map +1 -0
  234. package/mcp-server/dist/services/typesafe.d.ts +213 -0
  235. package/mcp-server/dist/services/typesafe.d.ts.map +1 -0
  236. package/mcp-server/dist/services/typesafe.js +330 -0
  237. package/mcp-server/dist/services/typesafe.js.map +1 -0
  238. package/mcp-server/dist/services/vector-cache.d.ts +68 -0
  239. package/mcp-server/dist/services/vector-cache.d.ts.map +1 -0
  240. package/mcp-server/dist/services/vector-cache.js +271 -0
  241. package/mcp-server/dist/services/vector-cache.js.map +1 -0
  242. package/mcp-server/dist/services/whiteboard-geometry.d.ts +305 -0
  243. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -0
  244. package/mcp-server/dist/services/whiteboard-geometry.js +666 -0
  245. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -0
  246. package/mcp-server/dist/tools/agents.d.ts +212 -0
  247. package/mcp-server/dist/tools/agents.d.ts.map +1 -0
  248. package/mcp-server/dist/tools/agents.js +407 -0
  249. package/mcp-server/dist/tools/agents.js.map +1 -0
  250. package/mcp-server/dist/tools/bluesky.d.ts +39 -0
  251. package/mcp-server/dist/tools/bluesky.d.ts.map +1 -0
  252. package/mcp-server/dist/tools/bluesky.js +1144 -0
  253. package/mcp-server/dist/tools/bluesky.js.map +1 -0
  254. package/mcp-server/dist/tools/browser-advanced.d.ts +58 -0
  255. package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -0
  256. package/mcp-server/dist/tools/browser-advanced.js +106 -0
  257. package/mcp-server/dist/tools/browser-advanced.js.map +1 -0
  258. package/mcp-server/dist/tools/browser-batch.d.ts +99 -0
  259. package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -0
  260. package/mcp-server/dist/tools/browser-batch.js +187 -0
  261. package/mcp-server/dist/tools/browser-batch.js.map +1 -0
  262. package/mcp-server/dist/tools/browser-cheatsheet.d.ts +21 -0
  263. package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -0
  264. package/mcp-server/dist/tools/browser-cheatsheet.js +144 -0
  265. package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -0
  266. package/mcp-server/dist/tools/browser-interact.d.ts +239 -0
  267. package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -0
  268. package/mcp-server/dist/tools/browser-interact.js +300 -0
  269. package/mcp-server/dist/tools/browser-interact.js.map +1 -0
  270. package/mcp-server/dist/tools/browser-navigate.d.ts +90 -0
  271. package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -0
  272. package/mcp-server/dist/tools/browser-navigate.js +142 -0
  273. package/mcp-server/dist/tools/browser-navigate.js.map +1 -0
  274. package/mcp-server/dist/tools/browser-observe.d.ts +561 -0
  275. package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -0
  276. package/mcp-server/dist/tools/browser-observe.js +2009 -0
  277. package/mcp-server/dist/tools/browser-observe.js.map +1 -0
  278. package/mcp-server/dist/tools/browser.d.ts +34 -0
  279. package/mcp-server/dist/tools/browser.d.ts.map +1 -0
  280. package/mcp-server/dist/tools/browser.js +112 -0
  281. package/mcp-server/dist/tools/browser.js.map +1 -0
  282. package/mcp-server/dist/tools/card-tools.d.ts +82 -0
  283. package/mcp-server/dist/tools/card-tools.d.ts.map +1 -0
  284. package/mcp-server/dist/tools/card-tools.js +137 -0
  285. package/mcp-server/dist/tools/card-tools.js.map +1 -0
  286. package/mcp-server/dist/tools/card.d.ts +8 -0
  287. package/mcp-server/dist/tools/card.d.ts.map +1 -0
  288. package/mcp-server/dist/tools/card.js +16 -0
  289. package/mcp-server/dist/tools/card.js.map +1 -0
  290. package/mcp-server/dist/tools/category.d.ts +32 -0
  291. package/mcp-server/dist/tools/category.d.ts.map +1 -0
  292. package/mcp-server/dist/tools/category.js +290 -0
  293. package/mcp-server/dist/tools/category.js.map +1 -0
  294. package/mcp-server/dist/tools/choice.d.ts +160 -0
  295. package/mcp-server/dist/tools/choice.d.ts.map +1 -0
  296. package/mcp-server/dist/tools/choice.js +80 -0
  297. package/mcp-server/dist/tools/choice.js.map +1 -0
  298. package/mcp-server/dist/tools/computer.d.ts +71 -0
  299. package/mcp-server/dist/tools/computer.d.ts.map +1 -0
  300. package/mcp-server/dist/tools/computer.js +174 -0
  301. package/mcp-server/dist/tools/computer.js.map +1 -0
  302. package/mcp-server/dist/tools/discord-channel.d.ts +44 -0
  303. package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -0
  304. package/mcp-server/dist/tools/discord-channel.js +236 -0
  305. package/mcp-server/dist/tools/discord-channel.js.map +1 -0
  306. package/mcp-server/dist/tools/discord-guild.d.ts +20 -0
  307. package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -0
  308. package/mcp-server/dist/tools/discord-guild.js +138 -0
  309. package/mcp-server/dist/tools/discord-guild.js.map +1 -0
  310. package/mcp-server/dist/tools/discord-member.d.ts +26 -0
  311. package/mcp-server/dist/tools/discord-member.d.ts.map +1 -0
  312. package/mcp-server/dist/tools/discord-member.js +122 -0
  313. package/mcp-server/dist/tools/discord-member.js.map +1 -0
  314. package/mcp-server/dist/tools/discord-message.d.ts +36 -0
  315. package/mcp-server/dist/tools/discord-message.d.ts.map +1 -0
  316. package/mcp-server/dist/tools/discord-message.js +184 -0
  317. package/mcp-server/dist/tools/discord-message.js.map +1 -0
  318. package/mcp-server/dist/tools/discord-onboarding.d.ts +32 -0
  319. package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -0
  320. package/mcp-server/dist/tools/discord-onboarding.js +179 -0
  321. package/mcp-server/dist/tools/discord-onboarding.js.map +1 -0
  322. package/mcp-server/dist/tools/discord-role.d.ts +34 -0
  323. package/mcp-server/dist/tools/discord-role.d.ts.map +1 -0
  324. package/mcp-server/dist/tools/discord-role.js +178 -0
  325. package/mcp-server/dist/tools/discord-role.js.map +1 -0
  326. package/mcp-server/dist/tools/discord-thread.d.ts +28 -0
  327. package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -0
  328. package/mcp-server/dist/tools/discord-thread.js +88 -0
  329. package/mcp-server/dist/tools/discord-thread.js.map +1 -0
  330. package/mcp-server/dist/tools/discord-webhook.d.ts +32 -0
  331. package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -0
  332. package/mcp-server/dist/tools/discord-webhook.js +154 -0
  333. package/mcp-server/dist/tools/discord-webhook.js.map +1 -0
  334. package/mcp-server/dist/tools/discord.d.ts +7 -0
  335. package/mcp-server/dist/tools/discord.d.ts.map +1 -0
  336. package/mcp-server/dist/tools/discord.js +25 -0
  337. package/mcp-server/dist/tools/discord.js.map +1 -0
  338. package/mcp-server/dist/tools/fb-groups.d.ts +98 -0
  339. package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -0
  340. package/mcp-server/dist/tools/fb-groups.js +369 -0
  341. package/mcp-server/dist/tools/fb-groups.js.map +1 -0
  342. package/mcp-server/dist/tools/forget.d.ts +14 -0
  343. package/mcp-server/dist/tools/forget.d.ts.map +1 -0
  344. package/mcp-server/dist/tools/forget.js +26 -0
  345. package/mcp-server/dist/tools/forget.js.map +1 -0
  346. package/mcp-server/dist/tools/git-tools.d.ts +24 -0
  347. package/mcp-server/dist/tools/git-tools.d.ts.map +1 -0
  348. package/mcp-server/dist/tools/git-tools.js +107 -0
  349. package/mcp-server/dist/tools/git-tools.js.map +1 -0
  350. package/mcp-server/dist/tools/git.d.ts +7 -0
  351. package/mcp-server/dist/tools/git.d.ts.map +1 -0
  352. package/mcp-server/dist/tools/git.js +11 -0
  353. package/mcp-server/dist/tools/git.js.map +1 -0
  354. package/mcp-server/dist/tools/gsc/experience.d.ts +135 -0
  355. package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -0
  356. package/mcp-server/dist/tools/gsc/experience.js +351 -0
  357. package/mcp-server/dist/tools/gsc/experience.js.map +1 -0
  358. package/mcp-server/dist/tools/gsc/helpers.d.ts +78 -0
  359. package/mcp-server/dist/tools/gsc/helpers.d.ts.map +1 -0
  360. package/mcp-server/dist/tools/gsc/helpers.js +258 -0
  361. package/mcp-server/dist/tools/gsc/helpers.js.map +1 -0
  362. package/mcp-server/dist/tools/gsc/indexing.d.ts +121 -0
  363. package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -0
  364. package/mcp-server/dist/tools/gsc/indexing.js +357 -0
  365. package/mcp-server/dist/tools/gsc/indexing.js.map +1 -0
  366. package/mcp-server/dist/tools/gsc/inspect.d.ts +78 -0
  367. package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -0
  368. package/mcp-server/dist/tools/gsc/inspect.js +321 -0
  369. package/mcp-server/dist/tools/gsc/inspect.js.map +1 -0
  370. package/mcp-server/dist/tools/gsc/navigate.d.ts +44 -0
  371. package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -0
  372. package/mcp-server/dist/tools/gsc/navigate.js +197 -0
  373. package/mcp-server/dist/tools/gsc/navigate.js.map +1 -0
  374. package/mcp-server/dist/tools/gsc/performance.d.ts +84 -0
  375. package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -0
  376. package/mcp-server/dist/tools/gsc/performance.js +274 -0
  377. package/mcp-server/dist/tools/gsc/performance.js.map +1 -0
  378. package/mcp-server/dist/tools/gsc/settings.d.ts +153 -0
  379. package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -0
  380. package/mcp-server/dist/tools/gsc/settings.js +425 -0
  381. package/mcp-server/dist/tools/gsc/settings.js.map +1 -0
  382. package/mcp-server/dist/tools/gsc.d.ts +7 -0
  383. package/mcp-server/dist/tools/gsc.d.ts.map +1 -0
  384. package/mcp-server/dist/tools/gsc.js +51 -0
  385. package/mcp-server/dist/tools/gsc.js.map +1 -0
  386. package/mcp-server/dist/tools/image-tools.d.ts +24 -0
  387. package/mcp-server/dist/tools/image-tools.d.ts.map +1 -0
  388. package/mcp-server/dist/tools/image-tools.js +80 -0
  389. package/mcp-server/dist/tools/image-tools.js.map +1 -0
  390. package/mcp-server/dist/tools/image.d.ts +10 -0
  391. package/mcp-server/dist/tools/image.d.ts.map +1 -0
  392. package/mcp-server/dist/tools/image.js +14 -0
  393. package/mcp-server/dist/tools/image.js.map +1 -0
  394. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +97 -0
  395. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -0
  396. package/mcp-server/dist/tools/leonardo-browser-tools.js +228 -0
  397. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -0
  398. package/mcp-server/dist/tools/leonardo.d.ts +13 -0
  399. package/mcp-server/dist/tools/leonardo.d.ts.map +1 -0
  400. package/mcp-server/dist/tools/leonardo.js +21 -0
  401. package/mcp-server/dist/tools/leonardo.js.map +1 -0
  402. package/mcp-server/dist/tools/loop.d.ts +30 -0
  403. package/mcp-server/dist/tools/loop.d.ts.map +1 -0
  404. package/mcp-server/dist/tools/loop.js +401 -0
  405. package/mcp-server/dist/tools/loop.js.map +1 -0
  406. package/mcp-server/dist/tools/memories.d.ts +56 -0
  407. package/mcp-server/dist/tools/memories.d.ts.map +1 -0
  408. package/mcp-server/dist/tools/memories.js +171 -0
  409. package/mcp-server/dist/tools/memories.js.map +1 -0
  410. package/mcp-server/dist/tools/morelogin.d.ts +24 -0
  411. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -0
  412. package/mcp-server/dist/tools/morelogin.js +79 -0
  413. package/mcp-server/dist/tools/morelogin.js.map +1 -0
  414. package/mcp-server/dist/tools/profile.d.ts +17 -0
  415. package/mcp-server/dist/tools/profile.d.ts.map +1 -0
  416. package/mcp-server/dist/tools/profile.js +114 -0
  417. package/mcp-server/dist/tools/profile.js.map +1 -0
  418. package/mcp-server/dist/tools/recall.d.ts +71 -0
  419. package/mcp-server/dist/tools/recall.d.ts.map +1 -0
  420. package/mcp-server/dist/tools/recall.js +147 -0
  421. package/mcp-server/dist/tools/recall.js.map +1 -0
  422. package/mcp-server/dist/tools/reflect.d.ts +56 -0
  423. package/mcp-server/dist/tools/reflect.d.ts.map +1 -0
  424. package/mcp-server/dist/tools/reflect.js +157 -0
  425. package/mcp-server/dist/tools/reflect.js.map +1 -0
  426. package/mcp-server/dist/tools/remember.d.ts +62 -0
  427. package/mcp-server/dist/tools/remember.d.ts.map +1 -0
  428. package/mcp-server/dist/tools/remember.js +201 -0
  429. package/mcp-server/dist/tools/remember.js.map +1 -0
  430. package/mcp-server/dist/tools/response.d.ts +23 -0
  431. package/mcp-server/dist/tools/response.d.ts.map +1 -0
  432. package/mcp-server/dist/tools/response.js +24 -0
  433. package/mcp-server/dist/tools/response.js.map +1 -0
  434. package/mcp-server/dist/tools/restore.d.ts +14 -0
  435. package/mcp-server/dist/tools/restore.d.ts.map +1 -0
  436. package/mcp-server/dist/tools/restore.js +23 -0
  437. package/mcp-server/dist/tools/restore.js.map +1 -0
  438. package/mcp-server/dist/tools/style-guide-tools.d.ts +51 -0
  439. package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -0
  440. package/mcp-server/dist/tools/style-guide-tools.js +231 -0
  441. package/mcp-server/dist/tools/style-guide-tools.js.map +1 -0
  442. package/mcp-server/dist/tools/style-guide.d.ts +8 -0
  443. package/mcp-server/dist/tools/style-guide.d.ts.map +1 -0
  444. package/mcp-server/dist/tools/style-guide.js +12 -0
  445. package/mcp-server/dist/tools/style-guide.js.map +1 -0
  446. package/mcp-server/dist/tools/sync.d.ts +20 -0
  447. package/mcp-server/dist/tools/sync.d.ts.map +1 -0
  448. package/mcp-server/dist/tools/sync.js +156 -0
  449. package/mcp-server/dist/tools/sync.js.map +1 -0
  450. package/mcp-server/dist/tools/tictactoe-tools.d.ts +18 -0
  451. package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -0
  452. package/mcp-server/dist/tools/tictactoe-tools.js +78 -0
  453. package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -0
  454. package/mcp-server/dist/tools/tictactoe.d.ts +7 -0
  455. package/mcp-server/dist/tools/tictactoe.d.ts.map +1 -0
  456. package/mcp-server/dist/tools/tictactoe.js +11 -0
  457. package/mcp-server/dist/tools/tictactoe.js.map +1 -0
  458. package/mcp-server/dist/tools/utils.d.ts +19 -0
  459. package/mcp-server/dist/tools/utils.d.ts.map +1 -0
  460. package/mcp-server/dist/tools/utils.js +54 -0
  461. package/mcp-server/dist/tools/utils.js.map +1 -0
  462. package/mcp-server/dist/tools/whiteboard-format.d.ts +88 -0
  463. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -0
  464. package/mcp-server/dist/tools/whiteboard-format.js +337 -0
  465. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -0
  466. package/mcp-server/dist/tools/whiteboard-tools.d.ts +326 -0
  467. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -0
  468. package/mcp-server/dist/tools/whiteboard-tools.js +222 -0
  469. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -0
  470. package/mcp-server/dist/tools/whiteboard.d.ts +8 -0
  471. package/mcp-server/dist/tools/whiteboard.d.ts.map +1 -0
  472. package/mcp-server/dist/tools/whiteboard.js +16 -0
  473. package/mcp-server/dist/tools/whiteboard.js.map +1 -0
  474. package/mcp-server/dist/tools/youtube/analytics.d.ts +46 -0
  475. package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -0
  476. package/mcp-server/dist/tools/youtube/analytics.js +83 -0
  477. package/mcp-server/dist/tools/youtube/analytics.js.map +1 -0
  478. package/mcp-server/dist/tools/youtube/dedup.d.ts +35 -0
  479. package/mcp-server/dist/tools/youtube/dedup.d.ts.map +1 -0
  480. package/mcp-server/dist/tools/youtube/dedup.js +56 -0
  481. package/mcp-server/dist/tools/youtube/dedup.js.map +1 -0
  482. package/mcp-server/dist/tools/youtube/download.d.ts +31 -0
  483. package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -0
  484. package/mcp-server/dist/tools/youtube/download.js +30 -0
  485. package/mcp-server/dist/tools/youtube/download.js.map +1 -0
  486. package/mcp-server/dist/tools/youtube/helpers.d.ts +66 -0
  487. package/mcp-server/dist/tools/youtube/helpers.d.ts.map +1 -0
  488. package/mcp-server/dist/tools/youtube/helpers.js +143 -0
  489. package/mcp-server/dist/tools/youtube/helpers.js.map +1 -0
  490. package/mcp-server/dist/tools/youtube/media.d.ts +43 -0
  491. package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -0
  492. package/mcp-server/dist/tools/youtube/media.js +97 -0
  493. package/mcp-server/dist/tools/youtube/media.js.map +1 -0
  494. package/mcp-server/dist/tools/youtube/metadata.d.ts +33 -0
  495. package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -0
  496. package/mcp-server/dist/tools/youtube/metadata.js +106 -0
  497. package/mcp-server/dist/tools/youtube/metadata.js.map +1 -0
  498. package/mcp-server/dist/tools/youtube/navigate.d.ts +30 -0
  499. package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -0
  500. package/mcp-server/dist/tools/youtube/navigate.js +71 -0
  501. package/mcp-server/dist/tools/youtube/navigate.js.map +1 -0
  502. package/mcp-server/dist/tools/youtube/playlist.d.ts +29 -0
  503. package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -0
  504. package/mcp-server/dist/tools/youtube/playlist.js +128 -0
  505. package/mcp-server/dist/tools/youtube/playlist.js.map +1 -0
  506. package/mcp-server/dist/tools/youtube/schedule.d.ts +31 -0
  507. package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -0
  508. package/mcp-server/dist/tools/youtube/schedule.js +147 -0
  509. package/mcp-server/dist/tools/youtube/schedule.js.map +1 -0
  510. package/mcp-server/dist/tools/youtube/source.d.ts +36 -0
  511. package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -0
  512. package/mcp-server/dist/tools/youtube/source.js +85 -0
  513. package/mcp-server/dist/tools/youtube/source.js.map +1 -0
  514. package/mcp-server/dist/tools/youtube/upload.d.ts +53 -0
  515. package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -0
  516. package/mcp-server/dist/tools/youtube/upload.js +255 -0
  517. package/mcp-server/dist/tools/youtube/upload.js.map +1 -0
  518. package/mcp-server/dist/tools/youtube.d.ts +12 -0
  519. package/mcp-server/dist/tools/youtube.d.ts.map +1 -0
  520. package/mcp-server/dist/tools/youtube.js +38 -0
  521. package/mcp-server/dist/tools/youtube.js.map +1 -0
  522. package/mcp-server/dist/tui.d.ts +3 -0
  523. package/mcp-server/dist/tui.d.ts.map +1 -0
  524. package/mcp-server/dist/tui.js +806 -0
  525. package/mcp-server/dist/tui.js.map +1 -0
  526. package/mcp-server/dist/types.d.ts +77 -0
  527. package/mcp-server/dist/types.d.ts.map +1 -0
  528. package/mcp-server/dist/types.js +2 -0
  529. package/mcp-server/dist/types.js.map +1 -0
  530. package/mcp-server/package-lock.json +4798 -0
  531. package/mcp-server/package.json +55 -38
  532. package/mcp-server/run.mjs +12 -2
  533. package/mcp-server/src/config.ts +48 -3
  534. package/mcp-server/src/http.ts +296 -93
  535. package/mcp-server/src/index.ts +546 -203
  536. package/mcp-server/src/preload-http.ts +19 -18
  537. package/mcp-server/src/preload.ts +19 -18
  538. package/mcp-server/src/scripts/setup-embeddings.ts +9 -0
  539. package/mcp-server/src/services/assistant-judgments.ts +157 -0
  540. package/mcp-server/src/services/browser-assist-gate.ts +383 -0
  541. package/mcp-server/src/services/browser-assist.ts +267 -0
  542. package/mcp-server/src/services/browser-bench.ts +477 -0
  543. package/mcp-server/src/services/browser-judgments.ts +414 -0
  544. package/mcp-server/src/services/browser-risk.ts +484 -0
  545. package/mcp-server/src/services/categories.ts +36 -19
  546. package/mcp-server/src/services/codex-config-heal.ts +403 -0
  547. package/mcp-server/src/services/desktop-assist-gate.ts +251 -0
  548. package/mcp-server/src/services/desktop-assist.ts +308 -0
  549. package/mcp-server/src/services/desktop-bench.ts +372 -0
  550. package/mcp-server/src/services/desktop-client.ts +76 -0
  551. package/mcp-server/src/services/desktop-judgments.ts +218 -0
  552. package/mcp-server/src/services/desktop-risk.ts +743 -0
  553. package/mcp-server/src/services/edit-stale.ts +299 -0
  554. package/mcp-server/src/services/embedding-service.ts +108 -0
  555. package/mcp-server/src/services/embedding-worker.ts +46 -0
  556. package/mcp-server/src/services/fb-regions.ts +221 -0
  557. package/mcp-server/src/services/file-checksums.ts +26 -9
  558. package/mcp-server/src/services/file-excerpt.ts +59 -0
  559. package/mcp-server/src/services/identity.ts +291 -0
  560. package/mcp-server/src/services/local-embeddings.ts +2 -77
  561. package/mcp-server/src/services/memory-client.ts +23 -0
  562. package/mcp-server/src/services/memory-judge-backfill.ts +462 -0
  563. package/mcp-server/src/services/memory-judgments.ts +901 -0
  564. package/mcp-server/src/services/memory-maintenance.ts +360 -0
  565. package/mcp-server/src/services/memory-retrieval.ts +349 -0
  566. package/mcp-server/src/services/memory-schema.ts +280 -0
  567. package/mcp-server/src/services/memory-sessions.ts +87 -0
  568. package/mcp-server/src/services/memory-triage.ts +182 -0
  569. package/mcp-server/src/services/memory-verification.ts +68 -0
  570. package/mcp-server/src/services/memory-writer.ts +125 -0
  571. package/mcp-server/src/services/neural-interface.ts +1217 -73
  572. package/mcp-server/src/services/profiles.ts +428 -0
  573. package/mcp-server/src/services/secret-gate.ts +52 -0
  574. package/mcp-server/src/services/server-instructions.ts +122 -0
  575. package/mcp-server/src/services/sqlite.ts +1456 -823
  576. package/mcp-server/src/services/typesafe-bench.ts +247 -0
  577. package/mcp-server/src/services/typesafe-config.ts +790 -0
  578. package/mcp-server/src/services/typesafe.ts +390 -0
  579. package/mcp-server/src/services/vector-cache.ts +255 -0
  580. package/mcp-server/src/services/whiteboard-geometry.ts +711 -0
  581. package/mcp-server/src/tools/agents.ts +539 -0
  582. package/mcp-server/src/tools/bluesky.ts +1186 -0
  583. package/mcp-server/src/tools/browser-advanced.ts +15 -6
  584. package/mcp-server/src/tools/browser-batch.ts +178 -0
  585. package/mcp-server/src/tools/browser-cheatsheet.ts +155 -0
  586. package/mcp-server/src/tools/browser-interact.ts +362 -255
  587. package/mcp-server/src/tools/browser-navigate.ts +164 -77
  588. package/mcp-server/src/tools/browser-observe.ts +2222 -1330
  589. package/mcp-server/src/tools/browser.ts +181 -107
  590. package/mcp-server/src/tools/card.ts +7 -5
  591. package/mcp-server/src/tools/choice.ts +103 -0
  592. package/mcp-server/src/tools/computer.ts +190 -0
  593. package/mcp-server/src/tools/discord.ts +10 -23
  594. package/mcp-server/src/tools/fb-groups.ts +387 -0
  595. package/mcp-server/src/tools/forget.ts +1 -1
  596. package/mcp-server/src/tools/git.ts +3 -1
  597. package/mcp-server/src/tools/gsc/experience.ts +440 -0
  598. package/mcp-server/src/tools/gsc/helpers.ts +288 -0
  599. package/mcp-server/src/tools/gsc/indexing.ts +495 -0
  600. package/mcp-server/src/tools/gsc/inspect.ts +391 -0
  601. package/mcp-server/src/tools/gsc/navigate.ts +236 -0
  602. package/mcp-server/src/tools/gsc/performance.ts +352 -0
  603. package/mcp-server/src/tools/gsc/settings.ts +564 -0
  604. package/mcp-server/src/tools/gsc.ts +95 -0
  605. package/mcp-server/src/tools/image.ts +3 -1
  606. package/mcp-server/src/tools/leonardo-browser-tools.ts +47 -37
  607. package/mcp-server/src/tools/leonardo.ts +7 -5
  608. package/mcp-server/src/tools/loop.ts +118 -25
  609. package/mcp-server/src/tools/memories.ts +65 -5
  610. package/mcp-server/src/tools/morelogin.ts +81 -0
  611. package/mcp-server/src/tools/profile.ts +122 -0
  612. package/mcp-server/src/tools/recall.ts +105 -261
  613. package/mcp-server/src/tools/reflect.ts +171 -145
  614. package/mcp-server/src/tools/remember.ts +223 -115
  615. package/mcp-server/src/tools/style-guide-tools.ts +250 -0
  616. package/mcp-server/src/tools/style-guide.ts +16 -0
  617. package/mcp-server/src/tools/sync.ts +66 -9
  618. package/mcp-server/src/tools/tictactoe.ts +3 -1
  619. package/mcp-server/src/tools/utils.ts +22 -0
  620. package/mcp-server/src/tools/whiteboard-format.ts +394 -0
  621. package/mcp-server/src/tools/whiteboard-tools.ts +191 -183
  622. package/mcp-server/src/tools/whiteboard.ts +7 -5
  623. package/mcp-server/src/tools/youtube/analytics.ts +106 -0
  624. package/mcp-server/src/tools/youtube/dedup.ts +57 -0
  625. package/mcp-server/src/tools/youtube/download.ts +41 -0
  626. package/mcp-server/src/tools/youtube/helpers.ts +183 -0
  627. package/mcp-server/src/tools/youtube/media.ts +109 -0
  628. package/mcp-server/src/tools/youtube/metadata.ts +112 -0
  629. package/mcp-server/src/tools/youtube/navigate.ts +81 -0
  630. package/mcp-server/src/tools/youtube/playlist.ts +134 -0
  631. package/mcp-server/src/tools/youtube/schedule.ts +158 -0
  632. package/mcp-server/src/tools/youtube/source.ts +101 -0
  633. package/mcp-server/src/tools/youtube/upload.ts +296 -0
  634. package/mcp-server/src/tools/youtube.ts +47 -0
  635. package/mcp-server/src/tui.ts +8 -9
  636. package/neural-interface/games/TicTacToe/1.svg +1 -0
  637. package/neural-interface/games/TicTacToe/2.svg +1 -0
  638. package/neural-interface/games/TicTacToe/3.svg +1 -0
  639. package/neural-interface/games/TicTacToe/4.svg +1 -0
  640. package/neural-interface/games/TicTacToe/5.svg +1 -0
  641. package/neural-interface/games/TicTacToe/6.svg +1 -0
  642. package/neural-interface/games/TicTacToe/7.svg +1 -0
  643. package/neural-interface/games/TicTacToe/8.svg +1 -0
  644. package/neural-interface/games/TicTacToe/9.svg +1 -0
  645. package/neural-interface/games/TicTacToe/Board.svg +1 -0
  646. package/neural-interface/games/TicTacToe/Circle.svg +1 -0
  647. package/neural-interface/games/TicTacToe/Cross.svg +1 -0
  648. package/neural-interface/i18n/en.json +7022 -0
  649. package/neural-interface/i18n/pt-BR.json +7026 -0
  650. package/neural-interface/lib/assistant-api.js +1005 -0
  651. package/neural-interface/lib/assistant-attachments.js +121 -0
  652. package/neural-interface/lib/assistant-brains/claude.js +207 -0
  653. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +43 -0
  654. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +56 -0
  655. package/neural-interface/lib/assistant-brains/codex.js +213 -0
  656. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +47 -0
  657. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +62 -0
  658. package/neural-interface/lib/assistant-brains/opencode.js +320 -0
  659. package/neural-interface/lib/assistant-budget.js +318 -0
  660. package/neural-interface/lib/assistant-catalog.js +731 -0
  661. package/neural-interface/lib/assistant-clarify.js +664 -0
  662. package/neural-interface/lib/assistant-config.js +232 -0
  663. package/neural-interface/lib/assistant-dispatch.js +2744 -0
  664. package/neural-interface/lib/assistant-envelope.js +582 -0
  665. package/neural-interface/lib/assistant-evidence.js +236 -0
  666. package/neural-interface/lib/assistant-hidden-models.js +272 -0
  667. package/neural-interface/lib/assistant-jev.js +117 -0
  668. package/neural-interface/lib/assistant-judgments.js +111 -0
  669. package/neural-interface/lib/assistant-media.js +335 -0
  670. package/neural-interface/lib/assistant-memory.js +398 -0
  671. package/neural-interface/lib/assistant-persona.js +444 -0
  672. package/neural-interface/lib/assistant-plan-permissions.js +448 -0
  673. package/neural-interface/lib/assistant-playbooks/design.md +87 -0
  674. package/neural-interface/lib/assistant-playbooks.js +72 -0
  675. package/neural-interface/lib/assistant-pricing.js +159 -0
  676. package/neural-interface/lib/assistant-route-gate-codex.js +163 -0
  677. package/neural-interface/lib/assistant-route-gate.js +212 -0
  678. package/neural-interface/lib/assistant-router.js +1324 -0
  679. package/neural-interface/lib/assistant-runtime.js +3337 -0
  680. package/neural-interface/lib/assistant-task-prompt.js +472 -0
  681. package/neural-interface/lib/assistant-usage.js +1688 -0
  682. package/neural-interface/lib/augmented-path.js +70 -0
  683. package/neural-interface/lib/automation-storage-migration.js +54 -0
  684. package/neural-interface/lib/backup-service.js +851 -0
  685. package/neural-interface/lib/backup-zip-reader.js +262 -0
  686. package/neural-interface/lib/browser-assist-api.js +41 -0
  687. package/neural-interface/lib/browser-console.js +176 -0
  688. package/neural-interface/lib/browser-execution.js +241 -0
  689. package/neural-interface/lib/browser-extraction.js +191 -0
  690. package/neural-interface/lib/browser-language.js +83 -0
  691. package/neural-interface/lib/browser-screenshot.js +399 -0
  692. package/neural-interface/lib/browser-semantic-context.js +639 -0
  693. package/neural-interface/lib/browser-snapshots.js +192 -0
  694. package/neural-interface/lib/browser-tab-recovery.js +119 -0
  695. package/neural-interface/lib/browser-targets.js +70 -0
  696. package/neural-interface/lib/browser-tool-policy.js +926 -0
  697. package/neural-interface/lib/claude-accounts.js +230 -0
  698. package/neural-interface/lib/claude-agent-bridge.js +3203 -0
  699. package/neural-interface/lib/claude-bypass-policy.js +99 -0
  700. package/neural-interface/lib/claude-executable.js +241 -0
  701. package/neural-interface/lib/claude-history.js +429 -0
  702. package/neural-interface/lib/claude-model-catalog.js +444 -0
  703. package/neural-interface/lib/claude-panel-requests.js +165 -0
  704. package/neural-interface/lib/claude-panel-session.js +272 -0
  705. package/neural-interface/lib/claude-permission-rules.js +153 -0
  706. package/neural-interface/lib/claude-session-cleanup.js +71 -0
  707. package/neural-interface/lib/claude-session-list.js +82 -0
  708. package/neural-interface/lib/claude-session-ops.js +140 -0
  709. package/neural-interface/lib/claude-settings-view.js +51 -0
  710. package/neural-interface/lib/claude-skin-connect.js +79 -0
  711. package/neural-interface/lib/claude-stall-policy.js +7 -0
  712. package/neural-interface/lib/claude-temporary.js +435 -0
  713. package/neural-interface/lib/cli-update-planner.js +312 -0
  714. package/neural-interface/lib/codex-capabilities.d.ts +41 -0
  715. package/neural-interface/lib/codex-capabilities.js +148 -0
  716. package/neural-interface/lib/codex-collaboration-mode.js +17 -0
  717. package/neural-interface/lib/codex-compat-rpc.js +241 -0
  718. package/neural-interface/lib/codex-mcp-approvals.js +56 -0
  719. package/neural-interface/lib/codex-mcp-apps.js +47 -0
  720. package/neural-interface/lib/codex-model-context.js +202 -0
  721. package/neural-interface/lib/codex-plan-store.js +71 -0
  722. package/neural-interface/lib/codex-request-journal.js +242 -0
  723. package/neural-interface/lib/codex-runtime-path.js +213 -0
  724. package/neural-interface/lib/codex-session-catalog.js +231 -0
  725. package/neural-interface/lib/codex-session-settings.js +46 -0
  726. package/neural-interface/lib/codex-sidepanel-permissions.js +110 -0
  727. package/neural-interface/lib/codex-thread-history.js +165 -0
  728. package/neural-interface/lib/codex-user-verification.js +34 -0
  729. package/neural-interface/lib/codex-writer-lifecycle.js +152 -0
  730. package/neural-interface/lib/confined-fs.js +256 -0
  731. package/neural-interface/lib/db.js +922 -0
  732. package/neural-interface/lib/design-md.js +9 -0
  733. package/neural-interface/lib/desktop/api.js +92 -0
  734. package/neural-interface/lib/desktop/audit.js +62 -0
  735. package/neural-interface/lib/desktop/build.js +423 -0
  736. package/neural-interface/lib/desktop/config.js +606 -0
  737. package/neural-interface/lib/desktop/coords.js +76 -0
  738. package/neural-interface/lib/desktop/fake-helper.js +1192 -0
  739. package/neural-interface/lib/desktop/frames.js +77 -0
  740. package/neural-interface/lib/desktop/grants.js +84 -0
  741. package/neural-interface/lib/desktop/guards.js +170 -0
  742. package/neural-interface/lib/desktop/helper/SynabunDesktop.swift +3056 -0
  743. package/neural-interface/lib/desktop/lease.js +51 -0
  744. package/neural-interface/lib/desktop/manager.js +545 -0
  745. package/neural-interface/lib/desktop/press-contexts.js +103 -0
  746. package/neural-interface/lib/desktop/protocol.js +495 -0
  747. package/neural-interface/lib/desktop/service.js +1202 -0
  748. package/neural-interface/lib/effort-levels.js +148 -0
  749. package/neural-interface/lib/event-loop-monitor.js +67 -0
  750. package/neural-interface/lib/exec-loop-command.js +209 -0
  751. package/neural-interface/lib/folder-picker.ps1 +77 -0
  752. package/neural-interface/lib/http-guards.js +287 -0
  753. package/neural-interface/lib/jsonl-lines.js +94 -0
  754. package/neural-interface/lib/loop-logger.js +127 -0
  755. package/neural-interface/lib/mcp-client-config.js +133 -0
  756. package/neural-interface/lib/mcp-installer.js +487 -0
  757. package/neural-interface/lib/mcp-profile-refresh-coordinator.js +78 -0
  758. package/neural-interface/lib/mcp-profile-servers.js +120 -0
  759. package/neural-interface/lib/memo-cache.js +84 -0
  760. package/neural-interface/lib/memory-api.js +758 -0
  761. package/neural-interface/lib/memory-map-api.js +1150 -0
  762. package/neural-interface/lib/memory-map-layout.js +872 -0
  763. package/neural-interface/lib/memory-map-worker.js +165 -0
  764. package/neural-interface/lib/memory-session-capture.js +81 -0
  765. package/neural-interface/lib/memory-timers.js +62 -0
  766. package/neural-interface/lib/morelogin.js +301 -0
  767. package/neural-interface/lib/native-binary-runtime.js +382 -0
  768. package/neural-interface/lib/native-loop-goal.js +33 -0
  769. package/neural-interface/lib/native-loop-providers.js +1002 -0
  770. package/neural-interface/lib/native-loop-runtime.js +747 -0
  771. package/neural-interface/lib/offline-page.js +54 -0
  772. package/neural-interface/lib/opencode-hidden-models.js +113 -0
  773. package/neural-interface/lib/opencode-history.js +253 -0
  774. package/neural-interface/lib/opencode-runtime-config.js +58 -0
  775. package/neural-interface/lib/opencode-v2-client.js +486 -0
  776. package/neural-interface/lib/opencode-v2-ws-requests.js +955 -0
  777. package/neural-interface/lib/path-confine.js +213 -0
  778. package/neural-interface/lib/plugin-installer.js +264 -0
  779. package/neural-interface/lib/project-storage.js +766 -0
  780. package/neural-interface/lib/pty-host/core.js +603 -0
  781. package/neural-interface/lib/pty-host/flow.js +43 -0
  782. package/neural-interface/lib/pty-host/host.js +47 -0
  783. package/neural-interface/lib/pty-host/manager.js +360 -0
  784. package/neural-interface/lib/pty-host/protocol.js +81 -0
  785. package/neural-interface/lib/pty-host/snapshot.js +133 -0
  786. package/neural-interface/lib/remote-policy.js +582 -0
  787. package/neural-interface/lib/rulesets/api.js +175 -0
  788. package/neural-interface/lib/rulesets/fs-safe.js +245 -0
  789. package/neural-interface/lib/rulesets/installer.js +1453 -0
  790. package/neural-interface/lib/rulesets/json-edit.js +186 -0
  791. package/neural-interface/lib/rulesets/lock.js +170 -0
  792. package/neural-interface/lib/rulesets/managed-text.js +314 -0
  793. package/neural-interface/lib/rulesets/normalise.js +24 -0
  794. package/neural-interface/lib/rulesets/render.js +84 -0
  795. package/neural-interface/lib/schedule-launch-intent.js +40 -0
  796. package/neural-interface/lib/session-cache-builder.js +524 -0
  797. package/neural-interface/lib/session-chunker.js +344 -0
  798. package/neural-interface/lib/session-indexer.js +327 -0
  799. package/neural-interface/lib/session-title-generator.js +232 -0
  800. package/neural-interface/lib/skill-prompt-bridge.js +11 -0
  801. package/neural-interface/lib/style-guide/api.js +375 -0
  802. package/neural-interface/lib/style-guide/color.js +352 -0
  803. package/neural-interface/lib/style-guide/export-css.js +99 -0
  804. package/neural-interface/lib/style-guide/export-dtcg.js +209 -0
  805. package/neural-interface/lib/style-guide/export-tailwind.js +102 -0
  806. package/neural-interface/lib/style-guide/fonts.json +227 -0
  807. package/neural-interface/lib/style-guide/import.js +1268 -0
  808. package/neural-interface/lib/style-guide/pointers.js +103 -0
  809. package/neural-interface/lib/style-guide/presets.js +232 -0
  810. package/neural-interface/lib/style-guide/render-design-md.js +319 -0
  811. package/neural-interface/lib/style-guide/schema.js +848 -0
  812. package/neural-interface/lib/style-guide/security.js +43 -0
  813. package/neural-interface/lib/style-guide/store.js +491 -0
  814. package/neural-interface/lib/style-guide/summary.js +106 -0
  815. package/neural-interface/lib/style-guide/tokens.js +170 -0
  816. package/neural-interface/lib/synabun-update-plan.js +324 -0
  817. package/neural-interface/lib/synabun-version.js +179 -0
  818. package/neural-interface/lib/system-restore.js +99 -0
  819. package/neural-interface/lib/terminal-env.js +86 -0
  820. package/neural-interface/lib/ui-blob-store.js +106 -0
  821. package/neural-interface/lib/vector-cache.js +2 -0
  822. package/neural-interface/lib/virtual-socket.js +60 -0
  823. package/neural-interface/lib/whatsapp/api.js +146 -0
  824. package/neural-interface/lib/whatsapp/auth-store.js +389 -0
  825. package/neural-interface/lib/whatsapp/baileys-adapter.js +457 -0
  826. package/neural-interface/lib/whatsapp/brain.js +128 -0
  827. package/neural-interface/lib/whatsapp/bridge.js +1499 -0
  828. package/neural-interface/lib/whatsapp/cards.js +519 -0
  829. package/neural-interface/lib/whatsapp/commands.js +92 -0
  830. package/neural-interface/lib/whatsapp/config.js +291 -0
  831. package/neural-interface/lib/whatsapp/connector/entry.mjs +25 -0
  832. package/neural-interface/lib/whatsapp/connector/manifest.json +6 -0
  833. package/neural-interface/lib/whatsapp/connector/npm-shrinkwrap.json +717 -0
  834. package/neural-interface/lib/whatsapp/connector/package.json +8 -0
  835. package/neural-interface/lib/whatsapp/fake-baileys.js +444 -0
  836. package/neural-interface/lib/whatsapp/format.js +552 -0
  837. package/neural-interface/lib/whatsapp/host-core.js +1225 -0
  838. package/neural-interface/lib/whatsapp/host.js +119 -0
  839. package/neural-interface/lib/whatsapp/identity.js +288 -0
  840. package/neural-interface/lib/whatsapp/inbound.js +149 -0
  841. package/neural-interface/lib/whatsapp/installer.js +562 -0
  842. package/neural-interface/lib/whatsapp/manager.js +638 -0
  843. package/neural-interface/lib/whatsapp/paths.js +81 -0
  844. package/neural-interface/lib/whatsapp/protocol.js +327 -0
  845. package/neural-interface/lib/whatsapp/qr-svg.js +57 -0
  846. package/neural-interface/lib/whatsapp/redact.js +130 -0
  847. package/neural-interface/lib/whatsapp/service.js +1305 -0
  848. package/neural-interface/lib/whatsapp/vendor/qrcodegen.js +848 -0
  849. package/neural-interface/package-lock.json +4431 -0
  850. package/neural-interface/package.json +58 -27
  851. package/neural-interface/public/apple-touch-icon.png +0 -0
  852. package/neural-interface/public/category-logos/synabun.png +0 -0
  853. package/neural-interface/public/claude.svg +1 -0
  854. package/neural-interface/public/favicon-16x16.png +0 -0
  855. package/neural-interface/public/favicon-32x32.png +0 -0
  856. package/neural-interface/public/icon-192.png +0 -0
  857. package/neural-interface/public/icon-512.png +0 -0
  858. package/neural-interface/public/index.html +32 -182
  859. package/neural-interface/public/index2d.html +2 -2
  860. package/neural-interface/public/install-app.html +31 -0
  861. package/neural-interface/public/logo-synabun.png +0 -0
  862. package/neural-interface/public/logoHD.png +0 -0
  863. package/neural-interface/public/manifest.json +2 -0
  864. package/neural-interface/public/mcp.svg +4 -0
  865. package/neural-interface/public/offline.html +670 -299
  866. package/neural-interface/public/onboarding.html +804 -161
  867. package/neural-interface/public/opencode-logo-dark-square.svg +1 -0
  868. package/neural-interface/public/shared/agent-runtime-options.js +596 -0
  869. package/neural-interface/public/shared/api.js +339 -28
  870. package/neural-interface/public/shared/assistant/asst-accounts.js +318 -0
  871. package/neural-interface/public/shared/assistant/asst-agents-dock.js +296 -0
  872. package/neural-interface/public/shared/assistant/asst-api.js +270 -0
  873. package/neural-interface/public/shared/assistant/asst-brain-picker.js +744 -0
  874. package/neural-interface/public/shared/assistant/asst-budget.js +333 -0
  875. package/neural-interface/public/shared/assistant/asst-composer.js +656 -0
  876. package/neural-interface/public/shared/assistant/asst-computer.js +803 -0
  877. package/neural-interface/public/shared/assistant/asst-control.js +1018 -0
  878. package/neural-interface/public/shared/assistant/asst-hosts.js +262 -0
  879. package/neural-interface/public/shared/assistant/asst-mascot.js +313 -0
  880. package/neural-interface/public/shared/assistant/asst-menu.js +375 -0
  881. package/neural-interface/public/shared/assistant/asst-panel.js +1845 -0
  882. package/neural-interface/public/shared/assistant/asst-rack-styles.js +586 -0
  883. package/neural-interface/public/shared/assistant/asst-render.js +3305 -0
  884. package/neural-interface/public/shared/assistant/asst-route.js +1653 -0
  885. package/neural-interface/public/shared/assistant/asst-roving.js +75 -0
  886. package/neural-interface/public/shared/assistant/asst-sanitize.js +117 -0
  887. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +488 -0
  888. package/neural-interface/public/shared/assistant/asst-sidepanel.js +675 -0
  889. package/neural-interface/public/shared/assistant/asst-slash.js +258 -0
  890. package/neural-interface/public/shared/assistant/asst-state.js +727 -0
  891. package/neural-interface/public/shared/assistant/asst-styles.js +1686 -0
  892. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +1017 -0
  893. package/neural-interface/public/shared/assistant/asst-usage.js +444 -0
  894. package/neural-interface/public/shared/assistant/asst-ws.js +175 -0
  895. package/neural-interface/public/shared/automation-context.js +75 -0
  896. package/neural-interface/public/shared/blob-store.js +99 -0
  897. package/neural-interface/public/shared/cdx/cdx-capabilities.js +118 -0
  898. package/neural-interface/public/shared/cdx/cdx-cards.js +37 -0
  899. package/neural-interface/public/shared/cdx/cdx-commands.js +171 -0
  900. package/neural-interface/public/shared/cdx/cdx-context-menu.js +402 -0
  901. package/neural-interface/public/shared/cdx/cdx-context-model.js +220 -0
  902. package/neural-interface/public/shared/cdx/cdx-features.js +408 -0
  903. package/neural-interface/public/shared/cdx/cdx-icons.js +89 -0
  904. package/neural-interface/public/shared/cdx/cdx-mcp-app-host.js +414 -0
  905. package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.html +6 -0
  906. package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.js +56 -0
  907. package/neural-interface/public/shared/cdx/cdx-mcp-app.js +178 -0
  908. package/neural-interface/public/shared/cdx/cdx-model-catalog.js +120 -0
  909. package/neural-interface/public/shared/cdx/cdx-output-model.js +261 -0
  910. package/neural-interface/public/shared/cdx/cdx-output.js +382 -0
  911. package/neural-interface/public/shared/cdx/cdx-panel.js +1372 -0
  912. package/neural-interface/public/shared/cdx/cdx-plan.js +266 -0
  913. package/neural-interface/public/shared/cdx/cdx-protocol.js +682 -0
  914. package/neural-interface/public/shared/cdx/cdx-render.js +3381 -0
  915. package/neural-interface/public/shared/cdx/cdx-requests.js +1136 -0
  916. package/neural-interface/public/shared/cdx/cdx-styles.js +3251 -0
  917. package/neural-interface/public/shared/cdx/cdx-tabs.js +7992 -0
  918. package/neural-interface/public/shared/cdx/cdx-ws.js +363 -0
  919. package/neural-interface/public/shared/cli-status.js +169 -0
  920. package/neural-interface/public/shared/command-runner-model.js +30 -0
  921. package/neural-interface/public/shared/constants.js +22 -5
  922. package/neural-interface/public/shared/cp/cp-agents.js +186 -0
  923. package/neural-interface/public/shared/cp/cp-bash.js +252 -0
  924. package/neural-interface/public/shared/cp/cp-compose.js +159 -0
  925. package/neural-interface/public/shared/cp/cp-context-menu.js +309 -0
  926. package/neural-interface/public/shared/cp/cp-context-model.js +157 -0
  927. package/neural-interface/public/shared/cp/cp-context-window.js +80 -0
  928. package/neural-interface/public/shared/cp/cp-ctx.js +11 -0
  929. package/neural-interface/public/shared/cp/cp-diff.js +255 -0
  930. package/neural-interface/public/shared/cp/cp-event-rows.js +637 -0
  931. package/neural-interface/public/shared/cp/cp-events.js +846 -0
  932. package/neural-interface/public/shared/cp/cp-markdown.js +104 -0
  933. package/neural-interface/public/shared/cp/cp-permission-model.js +905 -0
  934. package/neural-interface/public/shared/cp/cp-permissions.js +626 -0
  935. package/neural-interface/public/shared/cp/cp-rehydrate.js +113 -0
  936. package/neural-interface/public/shared/cp/cp-restore.js +224 -0
  937. package/neural-interface/public/shared/cp/cp-session-model.js +338 -0
  938. package/neural-interface/public/shared/cp/cp-session-settings.js +254 -0
  939. package/neural-interface/public/shared/cp/cp-sessions.js +227 -0
  940. package/neural-interface/public/shared/cp/cp-statusline.js +153 -0
  941. package/neural-interface/public/shared/cp/cp-styles.js +349 -0
  942. package/neural-interface/public/shared/cp/cp-tasks-model.js +282 -0
  943. package/neural-interface/public/shared/cp/cp-tasks.js +107 -0
  944. package/neural-interface/public/shared/cp/cp-temporary-view.js +56 -0
  945. package/neural-interface/public/shared/cp/cp-temporary.js +231 -0
  946. package/neural-interface/public/shared/cp/cp-tool-cards.js +326 -0
  947. package/neural-interface/public/shared/cp/cp-tool-results.js +618 -0
  948. package/neural-interface/public/shared/cp/cp-usage-model.js +124 -0
  949. package/neural-interface/public/shared/graph-activity.js +68 -0
  950. package/neural-interface/public/shared/html-shell.js +116 -17
  951. package/neural-interface/public/shared/i18n.js +132 -34
  952. package/neural-interface/public/shared/node-positions-store.js +44 -0
  953. package/neural-interface/public/shared/ocp-hidden-models.js +116 -0
  954. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +355 -0
  955. package/neural-interface/public/shared/ocp-v2/ocp-v2-autoaccept-button.js +35 -0
  956. package/neural-interface/public/shared/ocp-v2/ocp-v2-automation-ownership.js +72 -0
  957. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +280 -0
  958. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +67 -0
  959. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +179 -0
  960. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes.js +164 -0
  961. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +725 -0
  962. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +75 -0
  963. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +1204 -0
  964. package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm-logic.js +117 -0
  965. package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm.js +59 -0
  966. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-gauge.js +252 -0
  967. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +478 -0
  968. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +179 -0
  969. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +233 -0
  970. package/neural-interface/public/shared/ocp-v2/ocp-v2-icons.js +30 -0
  971. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +1065 -0
  972. package/neural-interface/public/shared/ocp-v2/ocp-v2-mention-hints.js +182 -0
  973. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +655 -0
  974. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +2636 -0
  975. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +601 -0
  976. package/neural-interface/public/shared/ocp-v2/ocp-v2-profile-inheritance.js +78 -0
  977. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +649 -0
  978. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +35 -0
  979. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +357 -0
  980. package/neural-interface/public/shared/ocp-v2/ocp-v2-render-logic.js +189 -0
  981. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1869 -0
  982. package/neural-interface/public/shared/ocp-v2/ocp-v2-select.js +42 -0
  983. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +117 -0
  984. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +1714 -0
  985. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +468 -0
  986. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-widgets.js +63 -0
  987. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +366 -0
  988. package/neural-interface/public/shared/ocp-v2/ocp-v2-settings-link.js +19 -0
  989. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +343 -0
  990. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +746 -0
  991. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +347 -0
  992. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +338 -0
  993. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +3543 -0
  994. package/neural-interface/public/shared/ocp-v2/ocp-v2-subagents-logic.js +482 -0
  995. package/neural-interface/public/shared/ocp-v2/ocp-v2-tools-logic.js +351 -0
  996. package/neural-interface/public/shared/ocp-v2/ocp-v2-tools.js +168 -0
  997. package/neural-interface/public/shared/ocp-v2/ocp-v2-variantpicker.js +315 -0
  998. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +545 -0
  999. package/neural-interface/public/shared/provider-icons.js +30 -0
  1000. package/neural-interface/public/shared/pwa-install-page.js +34 -0
  1001. package/neural-interface/public/shared/pwa-install.css +12 -0
  1002. package/neural-interface/public/shared/pwa-install.js +28 -0
  1003. package/neural-interface/public/shared/session-title.js +100 -0
  1004. package/neural-interface/public/shared/settings/settings-ia.js +389 -0
  1005. package/neural-interface/public/shared/settings/settings-kit.js +234 -0
  1006. package/neural-interface/public/shared/settings/settings-rules.js +160 -0
  1007. package/neural-interface/public/shared/settings/settings-search.js +463 -0
  1008. package/neural-interface/public/shared/settings/settings-shell.js +570 -0
  1009. package/neural-interface/public/shared/start-bridge.js +583 -0
  1010. package/neural-interface/public/shared/state.js +5 -0
  1011. package/neural-interface/public/shared/storage.js +50 -7
  1012. package/neural-interface/public/shared/styleguide/sg-agents.js +42 -0
  1013. package/neural-interface/public/shared/styleguide/sg-brand.js +4 -0
  1014. package/neural-interface/public/shared/styleguide/sg-color-client.js +388 -0
  1015. package/neural-interface/public/shared/styleguide/sg-colors.js +151 -0
  1016. package/neural-interface/public/shared/styleguide/sg-components.js +35 -0
  1017. package/neural-interface/public/shared/styleguide/sg-history.js +41 -0
  1018. package/neural-interface/public/shared/styleguide/sg-icons-logo.js +38 -0
  1019. package/neural-interface/public/shared/styleguide/sg-imagery.js +4 -0
  1020. package/neural-interface/public/shared/styleguide/sg-import-export.js +48 -0
  1021. package/neural-interface/public/shared/styleguide/sg-kit.js +284 -0
  1022. package/neural-interface/public/shared/styleguide/sg-labels.js +318 -0
  1023. package/neural-interface/public/shared/styleguide/sg-layout.js +4 -0
  1024. package/neural-interface/public/shared/styleguide/sg-motion.js +5 -0
  1025. package/neural-interface/public/shared/styleguide/sg-panel.js +237 -0
  1026. package/neural-interface/public/shared/styleguide/sg-preview.js +138 -0
  1027. package/neural-interface/public/shared/styleguide/sg-rules.js +9 -0
  1028. package/neural-interface/public/shared/styleguide/sg-shape.js +24 -0
  1029. package/neural-interface/public/shared/styleguide/sg-state.js +132 -0
  1030. package/neural-interface/public/shared/styleguide/sg-typography.js +125 -0
  1031. package/neural-interface/public/shared/styles.css +8614 -1477
  1032. package/neural-interface/public/shared/synabun-mascot.js +1625 -0
  1033. package/neural-interface/public/shared/synabun-ticker.js +376 -0
  1034. package/neural-interface/public/shared/term-ready.js +307 -0
  1035. package/neural-interface/public/shared/term-renderer.js +343 -0
  1036. package/neural-interface/public/shared/ui-assistant-panel.js +10 -0
  1037. package/neural-interface/public/shared/ui-assistant.js +77 -0
  1038. package/neural-interface/public/shared/ui-automation-studio.js +5105 -3573
  1039. package/neural-interface/public/shared/ui-claude-panel.js +11685 -6333
  1040. package/neural-interface/public/shared/ui-codex-panel.js +12 -0
  1041. package/neural-interface/public/shared/ui-command-runner.js +251 -468
  1042. package/neural-interface/public/shared/ui-cost-widget.js +55 -34
  1043. package/neural-interface/public/shared/ui-detail.js +77 -14
  1044. package/neural-interface/public/shared/ui-explorer.js +360 -181
  1045. package/neural-interface/public/shared/ui-file-explorer.js +485 -107
  1046. package/neural-interface/public/shared/ui-help.js +2 -2
  1047. package/neural-interface/public/shared/ui-image-gallery.js +45 -21
  1048. package/neural-interface/public/shared/ui-judgments.js +1346 -0
  1049. package/neural-interface/public/shared/ui-keybinds.js +3 -2
  1050. package/neural-interface/public/shared/ui-link.js +105 -51
  1051. package/neural-interface/public/shared/ui-loading.js +222 -11
  1052. package/neural-interface/public/shared/ui-memory-maintenance.js +111 -0
  1053. package/neural-interface/public/shared/ui-menubar.js +100 -31
  1054. package/neural-interface/public/shared/ui-native-loop-router-state.js +94 -0
  1055. package/neural-interface/public/shared/ui-native-loop-router.js +493 -0
  1056. package/neural-interface/public/shared/ui-native-window-id.js +7 -0
  1057. package/neural-interface/public/shared/ui-navbar.js +357 -222
  1058. package/neural-interface/public/shared/ui-notifications.js +58 -12
  1059. package/neural-interface/public/shared/ui-opencode-panel-v2.js +17 -0
  1060. package/neural-interface/public/shared/ui-panels.js +15 -7
  1061. package/neural-interface/public/shared/ui-resume.js +823 -653
  1062. package/neural-interface/public/shared/ui-schedule-queue.js +172 -0
  1063. package/neural-interface/public/shared/ui-schedules-studio.js +1882 -0
  1064. package/neural-interface/public/shared/ui-scroll-follow.js +194 -0
  1065. package/neural-interface/public/shared/ui-sessions.js +789 -34
  1066. package/neural-interface/public/shared/ui-settings.js +5774 -2194
  1067. package/neural-interface/public/shared/ui-sidepanel-layout.js +109 -0
  1068. package/neural-interface/public/shared/ui-sidepanel-runtime.js +19 -0
  1069. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +40 -0
  1070. package/neural-interface/public/shared/ui-sidepanel-sessions.js +221 -0
  1071. package/neural-interface/public/shared/ui-sidepanel-state.js +131 -0
  1072. package/neural-interface/public/shared/ui-sidepanel-tray.js +547 -0
  1073. package/neural-interface/public/shared/ui-sidepanel-windows.js +387 -0
  1074. package/neural-interface/public/shared/ui-skills.js +18 -32
  1075. package/neural-interface/public/shared/ui-styleguide.js +35 -0
  1076. package/neural-interface/public/shared/ui-sync.js +87 -0
  1077. package/neural-interface/public/shared/ui-terminal.js +7863 -6385
  1078. package/neural-interface/public/shared/ui-tool-updates.js +292 -0
  1079. package/neural-interface/public/shared/ui-tooltip.js +156 -15
  1080. package/neural-interface/public/shared/ui-tutorial-draw.js +119 -683
  1081. package/neural-interface/public/shared/ui-tutorial-layout.js +135 -0
  1082. package/neural-interface/public/shared/ui-tutorial-steps.js +59 -2209
  1083. package/neural-interface/public/shared/ui-tutorial.css +102 -0
  1084. package/neural-interface/public/shared/ui-tutorial.js +557 -1076
  1085. package/neural-interface/public/shared/ui-update.js +420 -68
  1086. package/neural-interface/public/shared/ui-whatsapp.js +941 -0
  1087. package/neural-interface/public/shared/ui-whiteboard.js +1076 -233
  1088. package/neural-interface/public/shared/ui-workspaces.js +2 -1
  1089. package/neural-interface/public/shared/utils.js +58 -0
  1090. package/neural-interface/public/shared/vterm-buffer.js +15 -5
  1091. package/neural-interface/public/shared/whatsapp/wa-phone.js +65 -0
  1092. package/neural-interface/public/shared/whatsapp/wa-view.js +411 -0
  1093. package/neural-interface/public/sidepanel-session.html +18 -0
  1094. package/neural-interface/public/sw.js +10 -2
  1095. package/neural-interface/public/synabun.png +0 -0
  1096. package/neural-interface/public/variant/2d/graph.js +1707 -1635
  1097. package/neural-interface/public/variant/2d/lasso.js +2 -1
  1098. package/neural-interface/public/variant/2d/layout.js +595 -594
  1099. package/neural-interface/public/variant/2d/main.js +557 -521
  1100. package/neural-interface/public/variant/2d/settings-gfx.js +18 -24
  1101. package/neural-interface/public/variant/3d/main.js +517 -500
  1102. package/neural-interface/public/variant/3d/map-controls.js +144 -0
  1103. package/neural-interface/public/variant/3d/map-data.js +251 -0
  1104. package/neural-interface/public/variant/3d/map-labels.js +241 -0
  1105. package/neural-interface/public/variant/3d/map-pick.js +90 -0
  1106. package/neural-interface/public/variant/3d/map-renderer.js +521 -0
  1107. package/neural-interface/public/variant/3d/map-shaders.js +158 -0
  1108. package/neural-interface/public/variant/3d/map-view.js +618 -0
  1109. package/neural-interface/public/vendor/three/manifest.json +3 -0
  1110. package/neural-interface/public/vendor/three/three-0.169.0.min.js +3844 -0
  1111. package/neural-interface/public/vendor/xterm/manifest.json +3 -0
  1112. package/neural-interface/public/vendor/xterm/xterm-6.0.0.css +285 -0
  1113. package/neural-interface/public/vendor/xterm/xterm-6.0.0.min.js +192 -0
  1114. package/neural-interface/scripts/build-vendor.mjs +64 -0
  1115. package/neural-interface/scripts/codex-protocol-fixture.mjs +83 -0
  1116. package/neural-interface/scripts/rebuild-pty.js +39 -22
  1117. package/neural-interface/scripts/vendor-three-entry.js +24 -0
  1118. package/neural-interface/scripts/vendor-xterm-entry.js +8 -0
  1119. package/neural-interface/server.js +33983 -15000
  1120. package/neural-interface/skins/default/skin.css +90 -0
  1121. package/neural-interface/skins/default/skin.json +8 -0
  1122. package/neural-interface/templates/rulesets/README.md +9 -0
  1123. package/neural-interface/templates/rulesets/claude.md +3 -0
  1124. package/neural-interface/templates/rulesets/codex.md +2 -0
  1125. package/neural-interface/templates/rulesets/coexistence.md +6 -0
  1126. package/neural-interface/templates/rulesets/core.md +26 -0
  1127. package/neural-interface/templates/rulesets/cursor.md +2 -0
  1128. package/neural-interface/templates/rulesets/gemini.md +2 -0
  1129. package/neural-interface/templates/rulesets/legacy-hashes.json +227 -0
  1130. package/neural-interface/templates/rulesets/manifest.json +12 -0
  1131. package/neural-interface/templates/rulesets/opencode.md +2 -0
  1132. package/package.json +131 -53
  1133. package/postinstall.js +55 -26
  1134. package/preuninstall.js +187 -0
  1135. package/scripts/restore-data-home-from-backup.mjs +239 -0
  1136. package/setup.js +872 -260
  1137. package/skills/leonardo/SKILL.md +19 -10
  1138. package/skills/leonardo/modules/image-prompter.md +18 -12
  1139. package/skills/leonardo/modules/video-prompter.md +19 -13
  1140. package/skills/synabun/SKILL.md +209 -185
  1141. package/skills/synabun/icon.png +0 -0
  1142. package/skills/synabun/modules/audit.md +380 -374
  1143. package/skills/synabun/modules/changelog.md +15 -6
  1144. package/skills/synabun/modules/idea.md +148 -144
  1145. package/skills/synabun/modules/memorize.md +13 -4
  1146. package/skills/synabun/modules/schedule.md +198 -0
  1147. package/skills/synabun/synabunicon.png +0 -0
  1148. package/updater.cmd +31 -0
  1149. package/updater.mjs +382 -0
  1150. package/updater.sh +29 -0
  1151. package/hooks/claude-code/test-user-learning.mjs +0 -531
  1152. package/neural-interface/public/claude-chat.css +0 -878
  1153. package/neural-interface/public/claude-chat.html +0 -92
  1154. package/neural-interface/public/claude-chat.js +0 -1168
  1155. package/neural-interface/public/index-legacy.html +0 -14677
  1156. package/neural-interface/public/index2d-legacy.html +0 -8193
  1157. package/neural-interface/public/shared/html-term-renderer.js +0 -1022
  1158. package/neural-interface/public/variant/3d/background.js +0 -884
  1159. package/neural-interface/public/variant/3d/camera.js +0 -661
  1160. package/neural-interface/public/variant/3d/gfx.js +0 -116
  1161. package/neural-interface/public/variant/3d/graph.js +0 -2399
  1162. package/neural-interface/public/variant/3d/settings-gfx.js +0 -228
  1163. package/neural-interface/templates/CLAUDE-template.md +0 -211
@@ -1,10 +1,22 @@
1
1
  // ═══════════════════════════════════════════
2
- // SynaBun — Session Monitor Window
3
- // Real-time view of active Claude Code sessions, agents, loops, and leak detection.
4
- // Proper draggable/resizable window with tabbed sections.
2
+ // SynaBun — Notifications Drawer
3
+ // Centralised notification window: pending updates (SynaBun core, CLI tools,
4
+ // SynaBun's rules), active sessions, agents, loops,
5
+ // and leak detection. Proper draggable/resizable window with tabbed sections.
6
+ //
7
+ // Note: CSS classes, DOM IDs, and event names use the legacy `session-monitor`
8
+ // / `sm-*` prefix for backward compat with the rest of the app.
5
9
  // ═══════════════════════════════════════════
6
10
 
7
11
  import { emit, on } from './state.js';
12
+ import { getSynabunUpdateData, openSynabunUpdateModal, forceCheckSynabunUpdate } from './ui-update.js';
13
+ import { getToolUpdateData, runToolUpdate, TOOL_LABELS } from './ui-tool-updates.js';
14
+ import { openSettingsModal } from './ui-settings.js';
15
+ import { getProviderMeta } from './provider-icons.js';
16
+ import { sendToPanel as sendToClaudePanel, isClaudePanelOpen } from './ui-claude-panel.js';
17
+ import { toggleCodexPanel, isCodexPanelOpen } from './cdx/cdx-panel.js';
18
+ import { openOpencodeWithPrompt } from './ui-opencode-panel-v2.js';
19
+ import { fetchRulesStatus, installAllRules, ackRulesNotice } from './api.js';
8
20
 
9
21
  // ── State ──
10
22
  let ws = null;
@@ -12,10 +24,31 @@ let reconnectTimer = null;
12
24
  let sessions = [];
13
25
  let leaks = [];
14
26
  let agents = [];
27
+ let loops = [];
28
+ let staleLoopCount = 0;
15
29
  let _panel = null;
16
30
  let _backdrop = null;
17
- let _activeTab = 'sessions'; // 'sessions' | 'agents' | 'leaks'
31
+ let _activeTab = 'updates'; // 'updates' | 'sessions' | 'agents' | 'loops' | 'leaks'
18
32
  let isVisible = false;
33
+ let _stalledTickerTimer = null;
34
+
35
+ // ── Pending-Remember picker state ──
36
+ const PROVIDER_LABELS = { claude: 'Claude Code', codex: 'Codex', opencode: 'OpenCode' };
37
+ let _prPicker = { open: false, provider: 'claude', model: '', modelsByProvider: {}, loading: null };
38
+
39
+ // ── Notifications state ──
40
+ // SynaBun's rules, as GET /api/setup/rules reports them (lib/rulesets/installer.js).
41
+ // null until it answers and on a server without the route: the drawer then
42
+ // simply has no rules items. The server holds what was acknowledged.
43
+ const RULES_HOSTS = {
44
+ claude: { label: 'Claude Code', provider: 'claude-code', section: 'setup-claude' },
45
+ codex: { label: 'Codex', provider: 'codex', section: 'setup-codex' },
46
+ opencode: { label: 'OpenCode', provider: 'opencode', section: 'setup-opencode' },
47
+ gemini: { label: 'Gemini', provider: 'gemini', section: 'setup-gemini' },
48
+ };
49
+ // The host states that need the user: each one opens Settings > Setup.
50
+ const RULES_ATTENTION = { outdated: 'Update available', modified: 'Edited copy', conflict: 'Needs repair' };
51
+ let _rulesStatus = null;
19
52
 
20
53
  // ── Icons ──
21
54
  const ICON_TERMINAL = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1.5" y="2" width="13" height="12" rx="2"/><path d="M4.5 6l2.5 2-2.5 2M8.5 10h3"/></svg>';
@@ -30,6 +63,11 @@ const ICON_AGENT = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" s
30
63
  const ICON_STOP = '<svg viewBox="0 0 16 16" fill="currentColor"><rect x="4" y="4" width="8" height="8" rx="1"/></svg>';
31
64
  const ICON_SESSIONS = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1.5" y="2" width="13" height="10" rx="2"/><path d="M5.5 14h5M8 12v2"/></svg>';
32
65
  const ICON_LEAKS = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2v3M8 11v3"/><path d="M4 5l1.5 2M10.5 9L12 11"/><path d="M2 8h3M11 8h3"/><path d="M4 11l1.5-2M10.5 7L12 5"/></svg>';
66
+ const ICON_LOOP = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 5a5.5 5.5 0 00-10 0v3M2 11a5.5 5.5 0 0010 0V8"/><path d="M12 5l2 0 0-2M4 11l-2 0 0 2"/></svg>';
67
+ const ICON_BELL = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 13h10l-1.2-1.5a3 3 0 01-.6-1.8V7a3.2 3.2 0 00-6.4 0v2.7a3 3 0 01-.6 1.8L3 13z"/><path d="M6.5 13.5a1.5 1.5 0 003 0"/></svg>';
68
+ const ICON_RULESET = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 2.5h7l3 3V13a.5.5 0 01-.5.5h-9A.5.5 0 013 13V3a.5.5 0 010-.5z"/><path d="M9.5 2.5V6h3"/><path d="M5.5 8.5h5M5.5 10.5h5M5.5 12h3"/></svg>';
69
+ const ICON_PACKAGE = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4.5L8 1.5l6 3v7L8 14.5 2 11.5v-7z"/><path d="M2 4.5L8 7.5l6-3M8 7.5v7"/></svg>';
70
+ const ICON_UP_ARROW = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M8 13V3M4 7l4-4 4 4"/></svg>';
33
71
 
34
72
  const TYPE_ICONS = { terminal: ICON_TERMINAL, floating: ICON_FLOATING, sidepanel: ICON_SIDEPANEL, external: ICON_EXTERNAL };
35
73
  const TYPE_LABELS = { terminal: 'Terminal', floating: 'Floating', sidepanel: 'Side Panel', external: 'External' };
@@ -51,6 +89,9 @@ function handleWsMessage(msg) {
51
89
  case 'session:init':
52
90
  sessions = msg.sessions || [];
53
91
  leaks = msg.leaks || [];
92
+ loops = msg.loops || [];
93
+ staleLoopCount = msg.staleCount || 0;
94
+ emitLoopsUpdate();
54
95
  fetch('/api/agents').then(r => r.json()).then(r => { agents = r.agents || []; render(); }).catch(() => render());
55
96
  return;
56
97
  case 'session:registered': {
@@ -68,9 +109,19 @@ function handleWsMessage(msg) {
68
109
  leaks = msg.leaks || [];
69
110
  render();
70
111
  break;
112
+ case 'session:loops':
113
+ loops = msg.loops || [];
114
+ staleLoopCount = msg.staleCount || 0;
115
+ emitLoopsUpdate();
116
+ render();
117
+ break;
71
118
  }
72
119
  }
73
120
 
121
+ function emitLoopsUpdate() {
122
+ emit('loops:updated', { staleCount: staleLoopCount, total: loops.length });
123
+ }
124
+
74
125
  // ── Panel HTML ──
75
126
 
76
127
  function buildPanelHTML() {
@@ -79,6 +130,13 @@ function buildPanelHTML() {
79
130
  const infoCount = leaks.filter(l => l.severity === 'info').length;
80
131
  const leakTotal = critCount + warnCount + infoCount;
81
132
  const runningAgents = agents.filter(a => a.status === 'running').length;
133
+ const updateCount = computeUpdates().length;
134
+ const updatesBadge = updateCount > 0
135
+ ? `<span class="sm-tab-count sm-tab-count-warning">${updateCount}</span>`
136
+ : `<span class="sm-tab-count">0</span>`;
137
+
138
+ const tabActive = (name) => _activeTab === name ? ' active' : '';
139
+ const headerCls = 'sm-header drag-handle';
82
140
 
83
141
  return `
84
142
  <div class="resize-handle resize-handle-t" data-resize="t"></div>
@@ -90,33 +148,46 @@ function buildPanelHTML() {
90
148
  <div class="resize-handle resize-handle-bl" data-resize="bl"></div>
91
149
  <div class="resize-handle resize-handle-br" data-resize="br"></div>
92
150
 
93
- <div class="sm-header drag-handle" data-drag="session-monitor-panel">
151
+ <div class="${headerCls}" data-drag="session-monitor-panel">
94
152
  <div class="sm-header-left">
95
- <h3>Session Monitor</h3>
96
- <span class="sm-header-badge" id="sm-session-count">${sessions.length} sessions</span>
97
- ${critCount > 0 ? `<span class="sm-header-badge sm-badge-critical">${critCount} critical</span>` : ''}
153
+ <div class="sm-header-icon" aria-hidden="true">
154
+ ${ICON_BELL}
155
+ </div>
156
+ <div class="sm-header-titlewrap">
157
+ <h3>Notifications</h3>
158
+ </div>
98
159
  </div>
99
160
  <div class="sm-header-actions">
100
161
  <button class="sm-header-btn" id="sm-refresh" title="Refresh">${ICON_REFRESH}</button>
101
162
  <button class="backdrop-toggle-btn" id="sm-backdrop-toggle" data-tooltip="Toggle backdrop">
102
163
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
103
164
  </button>
104
- <button class="sm-close" id="sm-close">&times;</button>
165
+ <button class="sm-close" id="sm-close" title="Close">&times;</button>
105
166
  </div>
106
167
  </div>
107
168
 
108
- <div class="sm-tabs" id="sm-tabs">
109
- <button class="sm-tab active" data-tab="sessions">
169
+ <div class="sm-tabs" id="sm-tabs" role="tablist">
170
+ <button class="sm-tab${tabActive('updates')}" data-tab="updates" role="tab">
171
+ ${ICON_BELL}
172
+ <span>Updates</span>
173
+ ${updatesBadge}
174
+ </button>
175
+ <button class="sm-tab${tabActive('sessions')}" data-tab="sessions" role="tab">
110
176
  ${ICON_SESSIONS}
111
177
  <span>Sessions</span>
112
178
  <span class="sm-tab-count">${sessions.length}</span>
113
179
  </button>
114
- <button class="sm-tab" data-tab="agents">
180
+ <button class="sm-tab${tabActive('agents')}" data-tab="agents" role="tab">
115
181
  ${ICON_AGENT}
116
182
  <span>Agents</span>
117
183
  ${runningAgents > 0 ? `<span class="sm-tab-count sm-tab-count-active">${runningAgents}</span>` : `<span class="sm-tab-count">${agents.length}</span>`}
118
184
  </button>
119
- <button class="sm-tab" data-tab="leaks">
185
+ <button class="sm-tab${tabActive('loops')}" data-tab="loops" role="tab">
186
+ ${ICON_LOOP}
187
+ <span>Loops</span>
188
+ ${staleLoopCount > 0 ? `<span class="sm-tab-count sm-tab-count-warning">${loops.length}</span>` : `<span class="sm-tab-count">${loops.length}</span>`}
189
+ </button>
190
+ <button class="sm-tab${tabActive('leaks')}" data-tab="leaks" role="tab">
120
191
  ${ICON_LEAKS}
121
192
  <span>Health</span>
122
193
  ${critCount > 0 ? `<span class="sm-tab-count sm-tab-count-critical">${leakTotal}</span>` : warnCount > 0 ? `<span class="sm-tab-count sm-tab-count-warning">${leakTotal}</span>` : `<span class="sm-tab-count">${leakTotal}</span>`}
@@ -127,6 +198,263 @@ function buildPanelHTML() {
127
198
  `;
128
199
  }
129
200
 
201
+ // Acknowledge every dismissable update in one shot. Used by the "Dismiss all"
202
+ // action in the Updates tab. Only the rules notice can be dismissed.
203
+ function markAllUpdatesRead() {
204
+ if (computeUpdates().some(it => it.dismissable)) dismissRulesNotice();
205
+ else if (_panel) render();
206
+ }
207
+
208
+ // ── Notifications engine ──
209
+
210
+ // Build the notification list from SynaBun core update data, CLI tool update
211
+ // data and the rules status. Each item is shown in the Updates tab.
212
+ // SynaBun and CLI updates show whenever available (not dismissable). Of the
213
+ // rules items only the notice can be dismissed; the server remembers that.
214
+ function computeUpdates() {
215
+ const items = [];
216
+
217
+ // SynaBun core
218
+ const synabun = getSynabunUpdateData();
219
+ if (synabun?.updateAvailable) {
220
+ items.push({
221
+ kind: 'synabun',
222
+ key: 'synabun',
223
+ title: 'SynaBun',
224
+ subtitle: `v${synabun.current} → v${synabun.latest}`,
225
+ meta: synabun.source ? `Source: ${synabun.source}` : '',
226
+ action: 'Open updater',
227
+ severity: 'normal',
228
+ });
229
+ }
230
+
231
+ // CLI tools
232
+ const toolsData = getToolUpdateData();
233
+ if (toolsData?.tools) {
234
+ for (const [key, info] of Object.entries(toolsData.tools)) {
235
+ if (!info?.updateAvailable) continue;
236
+ items.push({
237
+ kind: 'tool',
238
+ key,
239
+ title: TOOL_LABELS[key] || key,
240
+ subtitle: `v${info.installed} → v${info.latest}`,
241
+ meta: info.canUpdate ? '' : `Update via ${info.installSource || 'your installer'}`,
242
+ action: info.canUpdate ? 'Run update' : 'How to update',
243
+ severity: 'normal',
244
+ });
245
+ }
246
+ }
247
+
248
+ // SynaBun rules: at most one notice, then one item per tool that needs attention.
249
+ if (_rulesStatus?.hosts) {
250
+ const names = (hosts) => (hosts || []).map(h => RULES_HOSTS[h]?.label || h).join(', ');
251
+ const notice = _rulesStatus.notice;
252
+ if (notice?.kind === 'offer-install' && notice.hosts?.length) {
253
+ items.push({
254
+ kind: 'ruleset',
255
+ key: 'offer-install',
256
+ hosts: notice.hosts,
257
+ title: 'Install SynaBun rules',
258
+ subtitle: names(notice.hosts),
259
+ meta: 'SynaBun can put its rules where these tools load them for every project, and keep them up to date.',
260
+ action: 'Install',
261
+ dismissable: true,
262
+ severity: 'normal',
263
+ });
264
+ } else if (notice?.kind === 'updated') {
265
+ items.push({
266
+ kind: 'ruleset',
267
+ key: 'updated',
268
+ hosts: notice.hosts || [],
269
+ title: 'SynaBun rules updated',
270
+ subtitle: notice.from && notice.to ? `v${notice.from} \u2192 v${notice.to}` : (notice.to ? `v${notice.to}` : 'Updated'),
271
+ meta: notice.hosts?.length ? `Updated for ${names(notice.hosts)}` : '',
272
+ section: 'setup-rules',
273
+ action: 'Open Setup',
274
+ dismissable: true,
275
+ severity: 'normal',
276
+ });
277
+ }
278
+ for (const [host, info] of Object.entries(_rulesStatus.hosts)) {
279
+ const what = RULES_ATTENTION[info?.state];
280
+ if (!what || !RULES_HOSTS[host]) continue;
281
+ items.push({
282
+ kind: 'ruleset',
283
+ key: `host:${host}`,
284
+ host,
285
+ title: `${RULES_HOSTS[host].label} rules`,
286
+ subtitle: what,
287
+ meta: info.state === 'outdated' ? (_rulesStatus.version ? `Version ${_rulesStatus.version} is available` : '')
288
+ : info.state === 'modified' ? 'This copy was edited, so SynaBun no longer updates it'
289
+ : (info.error || info.detail || ''),
290
+ path: info.path || '',
291
+ section: RULES_HOSTS[host].section,
292
+ action: 'Open Setup',
293
+ dismissable: false,
294
+ severity: 'normal',
295
+ });
296
+ }
297
+ }
298
+
299
+ return items;
300
+ }
301
+
302
+ function emitNotificationsUpdate() {
303
+ emit('notifications:updated', { unreadCount: computeUpdates().length });
304
+ }
305
+
306
+ async function refreshRulesStatus() {
307
+ _rulesStatus = await fetchRulesStatus();
308
+ emitNotificationsUpdate();
309
+ }
310
+
311
+ // Settings > Setup re-reads the status after every rules action and passes it on.
312
+ on('rules:changed', (status) => {
313
+ _rulesStatus = status?.ok ? status : null;
314
+ emitNotificationsUpdate();
315
+ if (_panel) render();
316
+ });
317
+
318
+ function openRulesSetup(section) {
319
+ if (_panel) closePanel();
320
+ const sections = [...new Set(['setup-rules', section].filter(Boolean))];
321
+ openSettingsModal({ tab: 'ai-connections', expand: sections, highlight: [section || 'setup-rules'], scrollTo: section || 'setup-rules' });
322
+ }
323
+
324
+ // "Install" on the offer: install for the offered tools, then acknowledge the
325
+ // notice so it is not offered again. When a tool refuses (an edited copy, a
326
+ // CLI that is gone) Setup shows which one and why.
327
+ async function installOfferedRules(item) {
328
+ let refused = false;
329
+ try {
330
+ const result = await installAllRules(item.hosts);
331
+ refused = result?.ok === false;
332
+ await ackRulesNotice();
333
+ } catch {
334
+ refused = true;
335
+ }
336
+ await refreshRulesStatus();
337
+ if (refused) openRulesSetup('setup-rules');
338
+ else if (_panel) render();
339
+ }
340
+
341
+ async function dismissRulesNotice() {
342
+ try { await ackRulesNotice(); } catch { /* still there next time */ }
343
+ await refreshRulesStatus();
344
+ if (_panel) render();
345
+ }
346
+
347
+ function handleUpdateAction(item) {
348
+ if (!item) return;
349
+ if (item.kind === 'synabun') {
350
+ if (_panel) closePanel();
351
+ openSynabunUpdateModal();
352
+ return;
353
+ }
354
+ if (item.kind === 'tool') {
355
+ runToolUpdate(item.key);
356
+ if (_panel) render();
357
+ return;
358
+ }
359
+ if (item.kind === 'ruleset') {
360
+ if (item.key === 'offer-install') installOfferedRules(item);
361
+ else openRulesSetup(item.section);
362
+ }
363
+ }
364
+
365
+ function handleUpdateAck(item) {
366
+ if (!item) return;
367
+ if (item.kind === 'ruleset') {
368
+ if (item.dismissable) dismissRulesNotice();
369
+ return;
370
+ }
371
+ handleUpdateAction(item);
372
+ if (_panel) render();
373
+ }
374
+
375
+ function renderUpdatesTab() {
376
+ const items = computeUpdates();
377
+ if (items.length === 0) {
378
+ return `<div class="sm-empty-state">
379
+ <div class="sm-empty-icon sm-empty-ok">${ICON_BELL}</div>
380
+ <div class="sm-empty-title">All caught up</div>
381
+ <div class="sm-empty-desc">No new updates. We'll let you know when SynaBun, CLI tools or SynaBun's rules need attention.</div>
382
+ </div>`;
383
+ }
384
+
385
+ // Group by kind for cleaner sections
386
+ const groups = [
387
+ { id: 'synabun', label: 'SynaBun', items: items.filter(i => i.kind === 'synabun') },
388
+ { id: 'tool', label: 'CLI tools', items: items.filter(i => i.kind === 'tool') },
389
+ { id: 'ruleset', label: 'Rules', items: items.filter(i => i.kind === 'ruleset') },
390
+ ];
391
+
392
+ let html = '';
393
+ // Only show Dismiss all when there is something dismissable (the rules notice)
394
+ const dismissableCount = items.filter(i => i.dismissable).length;
395
+ if (dismissableCount > 0) {
396
+ html += `<div class="sm-actionbar">
397
+ <span class="sm-actionbar-label">${dismissableCount} rules notice${dismissableCount === 1 ? '' : 's'} to dismiss</span>
398
+ <button class="sm-btn sm-btn-ghost" id="sm-updates-mark-all">Dismiss all</button>
399
+ </div>`;
400
+ }
401
+ for (const g of groups) {
402
+ if (g.items.length === 0) continue;
403
+ html += `<div class="sm-section-label">${esc(g.label)} <span class="sm-section-count">${g.items.length}</span></div>`;
404
+ html += '<div class="sm-list">';
405
+ for (let i = 0; i < g.items.length; i++) {
406
+ html += renderUpdateCard(g.items[i], `${g.id}-${i}`);
407
+ }
408
+ html += '</div>';
409
+ }
410
+ return html;
411
+ }
412
+
413
+ function renderUpdateCard(item, idx) {
414
+ let icon;
415
+ let providerColor;
416
+ if (item.kind === 'synabun') {
417
+ const meta = getProviderMeta('synabun');
418
+ icon = meta.icon;
419
+ providerColor = meta.color;
420
+ } else if (item.kind === 'tool') {
421
+ const meta = getProviderMeta(item.key);
422
+ icon = meta.icon;
423
+ providerColor = meta.color;
424
+ } else {
425
+ // A tool's own icon for its item; SynaBun's for the notice that covers several tools.
426
+ const meta = getProviderMeta(RULES_HOSTS[item.host]?.provider || 'synabun');
427
+ icon = meta.icon;
428
+ providerColor = meta.color;
429
+ }
430
+ const kindLabel = item.kind === 'synabun' ? 'SynaBun'
431
+ : item.kind === 'tool' ? 'CLI tool'
432
+ : 'Rules';
433
+ let html = `<div class="sm-card sm-card-update" data-update-idx="${esc(idx)}">`;
434
+ html += `<div class="sm-update-row">`;
435
+ html += `<div class="sm-update-icon" aria-hidden="true" style="color:${providerColor}">${icon}</div>`;
436
+ html += `<div class="sm-update-content">`;
437
+ html += `<div class="sm-update-kicker">${esc(kindLabel)}</div>`;
438
+ html += `<div class="sm-update-line">`;
439
+ html += `<span class="sm-update-title">${esc(item.title)}</span>`;
440
+ html += `<span class="sm-update-version">${esc(item.subtitle)}</span>`;
441
+ html += `</div>`;
442
+ if (item.meta) {
443
+ html += `<div class="sm-update-meta">${esc(item.meta)}</div>`;
444
+ }
445
+ if (item.kind === 'ruleset' && item.path) {
446
+ html += `<div class="sm-update-meta sm-update-meta-target"><span class="sm-update-meta-key">File</span><span class="sm-update-meta-val mono">${esc(item.path)}</span></div>`;
447
+ }
448
+ html += `</div>`;
449
+ html += `<div class="sm-update-actions">`;
450
+ if (item.dismissable) { html += `<button class="sm-btn sm-btn-ghost" data-update-ack="${esc(idx)}" title="Dismiss">Dismiss</button>`; }
451
+ html += `<button class="sm-btn sm-btn-primary" data-update-action="${esc(idx)}">${esc(item.action)}</button>`;
452
+ html += `</div>`;
453
+ html += `</div>`;
454
+ html += `</div>`;
455
+ return html;
456
+ }
457
+
130
458
  // ── Tab renderers ──
131
459
 
132
460
  function renderSessionsTab() {
@@ -163,7 +491,7 @@ function renderSessionsTab() {
163
491
  if (s.cwd) html += `<div class="sm-card-row"><span class="sm-card-key">CWD</span><span class="sm-card-val mono" title="${esc(s.cwd)}">${esc(shortPath(s.cwd))}</span></div>`;
164
492
  html += `</div>`;
165
493
  if (hasLeaks) {
166
- html += `<div class="sm-card-warning">Has associated leaks</div>`;
494
+ html += `<div class="sm-card-note-warning">Has associated leaks</div>`;
167
495
  }
168
496
  html += `</div>`;
169
497
  }
@@ -238,6 +566,7 @@ function renderLeaksTab() {
238
566
  const criticalLeaks = leaks.filter(l => l.severity === 'critical');
239
567
  const warningLeaks = leaks.filter(l => l.severity === 'warning');
240
568
  const infoLeaks = leaks.filter(l => l.severity === 'info');
569
+ const cleanableLeaks = leaks.filter(l => l.type === 'orphaned-state' || l.type === 'stale-precompact');
241
570
 
242
571
  if (leaks.length === 0) {
243
572
  return `<div class="sm-empty-state">
@@ -268,8 +597,26 @@ function renderLeaksTab() {
268
597
  html += '<div class="sm-list">';
269
598
  for (const l of infoLeaks) html += renderLeakCard(l);
270
599
  html += '</div>';
600
+ }
601
+
602
+ const pendingRememberLeaks = leaks.filter(l =>
603
+ l.type === 'orphaned-state' && l.file && l.file.includes('pending-remember')
604
+ );
605
+
606
+ if (pendingRememberLeaks.length > 0) {
607
+ if (!_prPicker.open) {
608
+ html += `<div class="sm-cleanup-bar">
609
+ <span>${pendingRememberLeaks.length} pending remember${pendingRememberLeaks.length > 1 ? 's' : ''} — pick a provider/model to summarize each session into a memory</span>
610
+ <button class="sm-btn sm-btn-cleanup" id="sm-process-pending-remembers-btn">✨ Run Pending Remembers</button>
611
+ </div>`;
612
+ } else {
613
+ html += renderPendingRememberPicker();
614
+ }
615
+ }
616
+
617
+ if (cleanableLeaks.length > 0) {
271
618
  html += `<div class="sm-cleanup-bar">
272
- <span>${infoLeaks.length} orphaned file${infoLeaks.length > 1 ? 's' : ''} can be cleaned up</span>
619
+ <span>${cleanableLeaks.length} stale flag${cleanableLeaks.length > 1 ? 's' : ''} can be cleaned up</span>
273
620
  <button class="sm-btn sm-btn-cleanup" id="sm-cleanup-btn">${ICON_CLEANUP} Clean All</button>
274
621
  </div>`;
275
622
  }
@@ -301,6 +648,97 @@ function renderLeakCard(l) {
301
648
  return html;
302
649
  }
303
650
 
651
+ function renderLoopsTab() {
652
+ if (loops.length === 0) {
653
+ return `<div class="sm-empty-state">
654
+ <div class="sm-empty-icon">${ICON_LOOP}</div>
655
+ <div class="sm-empty-title">No loops</div>
656
+ <div class="sm-empty-desc">Active and recent loop runs will appear here.</div>
657
+ </div>`;
658
+ }
659
+
660
+ const totalCount = loops.length;
661
+ const stale = loops.filter(l => l.state === 'stale-inactive').length;
662
+
663
+ let html = '<div class="sm-list">';
664
+ for (const l of loops) html += renderLoopCard(l);
665
+ html += '</div>';
666
+
667
+ html += `<div class="sm-loops-actionbar">
668
+ <span class="sm-loops-summary">${totalCount} loop${totalCount === 1 ? '' : 's'} · ${stale} stale</span>
669
+ <span class="sm-loops-actions">
670
+ <button class="sm-btn sm-btn-cleanup" id="sm-loops-clear-stale" ${stale === 0 ? 'disabled' : ''}>${ICON_CLEANUP} Clear stale</button>
671
+ <button class="sm-btn sm-btn-stop" id="sm-loops-clear-all">${ICON_STOP} Clear all</button>
672
+ </span>
673
+ </div>`;
674
+ return html;
675
+ }
676
+
677
+ function loopStateLabel(state) {
678
+ switch (state) {
679
+ case 'active': return 'Running';
680
+ case 'finished': return 'Finished';
681
+ case 'orphaned-pty': return 'Orphaned';
682
+ case 'stale-inactive': return 'Stale';
683
+ default: return state;
684
+ }
685
+ }
686
+
687
+ function loopStateClass(state) {
688
+ switch (state) {
689
+ case 'active': return 'sm-loop-running';
690
+ case 'finished': return 'sm-loop-finished';
691
+ case 'orphaned-pty': return 'sm-loop-orphan';
692
+ case 'stale-inactive': return 'sm-loop-stale';
693
+ default: return '';
694
+ }
695
+ }
696
+
697
+ function formatStalled(stalledMs) {
698
+ if (!stalledMs || stalledMs < 1000) return '0s';
699
+ const s = Math.floor(stalledMs / 1000);
700
+ if (s < 60) return `${s}s`;
701
+ const m = Math.floor(s / 60);
702
+ const rem = s % 60;
703
+ if (m < 60) return rem ? `${m}m ${rem}s` : `${m}m`;
704
+ const h = Math.floor(m / 60);
705
+ return `${h}h ${m % 60}m`;
706
+ }
707
+
708
+ function renderLoopCard(l) {
709
+ const stateCls = loopStateClass(l.state);
710
+ const stateLabel = loopStateLabel(l.state);
711
+ const showStalled = l.state === 'active';
712
+ // Live-tick adjustment: WS may be a few seconds old, so add elapsed since fetch
713
+ const stalledMs = (l.stalledMs || 0) + (Date.now() - (l._fetchedAt || Date.now()));
714
+ const stalledHot = showStalled && stalledMs >= 5 * 60 * 1000;
715
+ const iter = `${l.currentIteration || 0}/${l.totalIterations || 0}`;
716
+ const taskPreview = l.task ? (l.task.length > 80 ? l.task.slice(0, 80) + '…' : l.task) : '';
717
+ const startedAge = l.startedAt ? formatAge(new Date(l.startedAt).getTime()) : '?';
718
+ const tsidShort = l.terminalSessionId ? l.terminalSessionId.slice(0, 8) : '—';
719
+
720
+ let html = `<div class="sm-card ${stateCls}">`;
721
+ html += `<div class="sm-card-header">`;
722
+ html += `<span class="sm-loop-badge ${stateCls}">${esc(stateLabel)}</span>`;
723
+ html += `<span class="sm-loop-iter">${iter}</span>`;
724
+ html += `<span class="sm-card-spacer"></span>`;
725
+ if (l.state === 'active' || l.state === 'orphaned-pty' || l.state === 'finished') {
726
+ html += `<button class="sm-btn sm-btn-stop" data-loop-stop="${esc(l.terminalSessionId || '')}" data-session="${esc(l.sessionId)}" title="Stop loop">${ICON_STOP} Stop</button>`;
727
+ }
728
+ html += `</div>`;
729
+ html += `<div class="sm-card-details">`;
730
+ if (showStalled) {
731
+ html += `<div class="sm-card-row"><span class="sm-card-key">Stalled</span><span class="sm-card-val sm-loop-stalled${stalledHot ? ' sm-loop-stalled-hot' : ''}" data-stalled-ms="${l.stalledMs || 0}" data-fetched-at="${l._fetchedAt || Date.now()}">${formatStalled(stalledMs)}</span></div>`;
732
+ }
733
+ if (taskPreview) html += `<div class="sm-card-row"><span class="sm-card-key">Task</span><span class="sm-card-val" title="${esc(l.task)}">${esc(taskPreview)}</span></div>`;
734
+ html += `<div class="sm-card-row"><span class="sm-card-key">Started</span><span class="sm-card-val">${startedAge} ago</span></div>`;
735
+ html += `<div class="sm-card-row"><span class="sm-card-key">Terminal</span><span class="sm-card-val mono">${esc(tsidShort)} <span class="sm-pulse-${l.terminalAlive ? 'active' : 'dead'}"></span></span></div>`;
736
+ html += `<div class="sm-card-row"><span class="sm-card-key">Session</span><span class="sm-card-val mono">${esc(l.sessionId.slice(0, 8))}</span></div>`;
737
+ html += `</div>`;
738
+ html += `</div>`;
739
+ return html;
740
+ }
741
+
304
742
  // ── Master render ──
305
743
 
306
744
  function render() {
@@ -308,10 +746,6 @@ function render() {
308
746
  const body = _panel.querySelector('#sm-body');
309
747
  if (!body) return;
310
748
 
311
- // Update header badges
312
- const countBadge = _panel.querySelector('#sm-session-count');
313
- if (countBadge) countBadge.textContent = `${sessions.length} session${sessions.length !== 1 ? 's' : ''}`;
314
-
315
749
  // Update tab counts
316
750
  const critCount = leaks.filter(l => l.severity === 'critical').length;
317
751
  const warnCount = leaks.filter(l => l.severity === 'warning').length;
@@ -328,21 +762,56 @@ function render() {
328
762
  } else if (tabName === 'agents') {
329
763
  countEl.textContent = runningAgents > 0 ? runningAgents : agents.length;
330
764
  countEl.className = `sm-tab-count${runningAgents > 0 ? ' sm-tab-count-active' : ''}`;
765
+ } else if (tabName === 'loops') {
766
+ countEl.textContent = loops.length;
767
+ countEl.className = `sm-tab-count${staleLoopCount > 0 ? ' sm-tab-count-warning' : ''}`;
331
768
  } else if (tabName === 'leaks') {
332
769
  countEl.textContent = leakTotal;
333
770
  countEl.className = `sm-tab-count${critCount > 0 ? ' sm-tab-count-critical' : warnCount > 0 ? ' sm-tab-count-warning' : ''}`;
334
771
  }
335
772
  });
336
773
 
774
+ // Update tabs that depend on Updates count too
775
+ const updatesTab = _panel.querySelector('.sm-tab[data-tab="updates"]');
776
+ if (updatesTab) {
777
+ const c = updatesTab.querySelector('.sm-tab-count');
778
+ if (c) {
779
+ const updateCount = computeUpdates().length;
780
+ c.textContent = updateCount;
781
+ c.className = `sm-tab-count${updateCount > 0 ? ' sm-tab-count-warning' : ''}`;
782
+ }
783
+ }
784
+
337
785
  // Render active tab content
338
786
  let html = '';
339
787
  switch (_activeTab) {
788
+ case 'updates': html = renderUpdatesTab(); break;
340
789
  case 'sessions': html = renderSessionsTab(); break;
341
790
  case 'agents': html = renderAgentsTab(); break;
791
+ case 'loops': html = renderLoopsTab(); break;
342
792
  case 'leaks': html = renderLeaksTab(); break;
343
793
  }
344
794
  body.innerHTML = html;
345
795
 
796
+ // Wire updates-tab actions (cache items so action/ack handlers stay in sync
797
+ // with what was rendered, even if computeUpdates() shifts mid-tick)
798
+ if (_activeTab === 'updates') {
799
+ const renderedItems = computeUpdates();
800
+ const findItem = (idx) => {
801
+ const [groupId, n] = String(idx || '').split('-');
802
+ const filtered = renderedItems.filter(it => it.kind === groupId);
803
+ return filtered[Number(n)];
804
+ };
805
+ body.querySelectorAll('[data-update-action]').forEach(btn => {
806
+ btn.addEventListener('click', () => handleUpdateAction(findItem(btn.dataset.updateAction)));
807
+ });
808
+ body.querySelectorAll('[data-update-ack]').forEach(btn => {
809
+ btn.addEventListener('click', () => handleUpdateAck(findItem(btn.dataset.updateAck)));
810
+ });
811
+ const markAllBtn = body.querySelector('#sm-updates-mark-all');
812
+ if (markAllBtn) markAllBtn.addEventListener('click', markAllUpdatesRead);
813
+ }
814
+
346
815
  // Wire event listeners
347
816
  body.querySelectorAll('[data-agent-stop]').forEach(btn => {
348
817
  btn.addEventListener('click', () => stopAgent(btn.dataset.agentStop));
@@ -352,24 +821,123 @@ function render() {
352
821
  });
353
822
  const cleanupBtn = body.querySelector('#sm-cleanup-btn');
354
823
  if (cleanupBtn) cleanupBtn.addEventListener('click', cleanupOrphans);
824
+ const processPendingBtn = body.querySelector('#sm-process-pending-remembers-btn');
825
+ if (processPendingBtn) processPendingBtn.addEventListener('click', openPendingRememberPicker);
826
+ body.querySelectorAll('[data-pr-provider]').forEach(b =>
827
+ b.addEventListener('click', () => selectPendingRememberProvider(b.dataset.prProvider))
828
+ );
829
+ const prModel = body.querySelector('#sm-pr-model');
830
+ if (prModel) prModel.addEventListener('change', () => {
831
+ _prPicker.model = prModel.value;
832
+ const runBtn = body.querySelector('#sm-pr-run');
833
+ if (runBtn) runBtn.disabled = !_prPicker.model;
834
+ });
835
+ const prCancel = body.querySelector('#sm-pr-cancel');
836
+ if (prCancel) prCancel.addEventListener('click', cancelPendingRememberPicker);
837
+ const prRun = body.querySelector('#sm-pr-run');
838
+ if (prRun) prRun.addEventListener('click', runPendingRemembers);
839
+
840
+ // Wire loops-tab actions
841
+ body.querySelectorAll('[data-loop-stop]').forEach(btn => {
842
+ btn.addEventListener('click', () => stopLoop(btn.dataset.loopStop, btn.dataset.session));
843
+ });
844
+ const loopsClearStaleBtn = body.querySelector('#sm-loops-clear-stale');
845
+ if (loopsClearStaleBtn) loopsClearStaleBtn.addEventListener('click', clearStaleLoops);
846
+ const loopsClearAllBtn = body.querySelector('#sm-loops-clear-all');
847
+ if (loopsClearAllBtn) loopsClearAllBtn.addEventListener('click', clearAllLoops);
848
+
849
+ // Stalled timer ticker — only active while the Loops tab is visible
850
+ if (_activeTab === 'loops') startStalledTicker();
851
+ else stopStalledTicker();
852
+ }
853
+
854
+ function startStalledTicker() {
855
+ if (_stalledTickerTimer) return;
856
+ _stalledTickerTimer = setInterval(() => {
857
+ if (!_panel || _activeTab !== 'loops') { stopStalledTicker(); return; }
858
+ if (document.hidden) return;
859
+ const cells = _panel.querySelectorAll('.sm-loop-stalled');
860
+ const now = Date.now();
861
+ cells.forEach(cell => {
862
+ const baseMs = parseInt(cell.dataset.stalledMs || '0', 10);
863
+ const fetchedAt = parseInt(cell.dataset.fetchedAt || `${now}`, 10);
864
+ const ms = baseMs + (now - fetchedAt);
865
+ cell.textContent = formatStalled(ms);
866
+ cell.classList.toggle('sm-loop-stalled-hot', ms >= 5 * 60 * 1000);
867
+ });
868
+ }, 1000);
869
+ }
870
+
871
+ function stopStalledTicker() {
872
+ if (_stalledTickerTimer) {
873
+ clearInterval(_stalledTickerTimer);
874
+ _stalledTickerTimer = null;
875
+ }
355
876
  }
356
877
 
357
878
  // ── Actions ──
358
879
 
359
880
  async function refreshSessions() {
360
881
  try {
361
- const [sessRes, leakRes, agentRes] = await Promise.all([
882
+ const [sessRes, leakRes, agentRes, loopRes] = await Promise.all([
362
883
  fetch('/api/sessions/active').then(r => r.json()),
363
884
  fetch('/api/sessions/leaks').then(r => r.json()),
364
885
  fetch('/api/agents').then(r => r.json()).catch(() => ({ agents: [] })),
886
+ fetch('/api/loop/list').then(r => r.json()).catch(() => ({ loops: [], staleCount: 0 })),
365
887
  ]);
366
888
  sessions = sessRes.sessions || [];
367
889
  leaks = leakRes.leaks || [];
368
890
  agents = agentRes.agents || [];
891
+ const fetchedAt = Date.now();
892
+ loops = (loopRes.loops || []).map(l => ({ ...l, _fetchedAt: fetchedAt }));
893
+ staleLoopCount = loopRes.staleCount || 0;
894
+ emitLoopsUpdate();
895
+ // Refresh notification feed alongside session/loop data
896
+ refreshRulesStatus().then(() => render()).catch(() => {});
897
+ forceCheckSynabunUpdate().then(() => render()).catch(() => {});
369
898
  render();
370
899
  } catch {}
371
900
  }
372
901
 
902
+ async function stopLoop(terminalSessionId, sessionId) {
903
+ try {
904
+ if (!terminalSessionId) {
905
+ // Loop file with no terminal — just delete it via cleanup endpoint flow:
906
+ // mark inactive on the server side by hitting cleanup after the fact is
907
+ // not possible (cleanup needs active=false). For orphan-pty without a
908
+ // terminal id, fall through to /api/loop/stop with no body would kill all
909
+ // — so instead just refresh; the stale broadcast will catch it.
910
+ await refreshSessions();
911
+ return;
912
+ }
913
+ await fetch('/api/loop/stop', {
914
+ method: 'POST',
915
+ headers: { 'Content-Type': 'application/json' },
916
+ body: JSON.stringify({ terminalSessionId }),
917
+ });
918
+ await refreshSessions();
919
+ } catch {}
920
+ }
921
+
922
+ async function clearStaleLoops() {
923
+ try {
924
+ const res = await fetch('/api/loop/cleanup', { method: 'POST' }).then(r => r.json());
925
+ if (res?.ok) await refreshSessions();
926
+ } catch {}
927
+ }
928
+
929
+ async function clearAllLoops() {
930
+ if (!confirm('Stop and delete ALL loops, including running ones? This will kill their PTY sessions and close their browser tabs.')) return;
931
+ try {
932
+ await fetch('/api/loop/stop', {
933
+ method: 'POST',
934
+ headers: { 'Content-Type': 'application/json' },
935
+ body: JSON.stringify({}),
936
+ });
937
+ await refreshSessions();
938
+ } catch {}
939
+ }
940
+
373
941
  async function stopAgent(agentId) {
374
942
  try {
375
943
  await fetch(`/api/agents/${agentId}/stop`, { method: 'POST' });
@@ -395,6 +963,158 @@ async function cleanupOrphans() {
395
963
  } catch {}
396
964
  }
397
965
 
966
+ function renderPendingRememberPicker() {
967
+ const provider = _prPicker.provider;
968
+ const models = _prPicker.modelsByProvider[provider] || [];
969
+ const loading = _prPicker.loading === provider;
970
+
971
+ const providerBtns = ['claude', 'codex', 'opencode'].map(p => `
972
+ <button class="sm-btn sm-pr-prov${p === provider ? ' active' : ''}" data-pr-provider="${p}">
973
+ ${esc(PROVIDER_LABELS[p])}
974
+ </button>
975
+ `).join('');
976
+
977
+ let modelOptions = '<option value="">— select model —</option>';
978
+ if (loading) modelOptions = '<option value="">Loading…</option>';
979
+ else if (models.length === 0) modelOptions = '<option value="">No models found</option>';
980
+ else {
981
+ modelOptions += models.map(m =>
982
+ `<option value="${esc(m.id)}"${m.id === _prPicker.model ? ' selected' : ''}>${esc(m.label || m.id)}</option>`
983
+ ).join('');
984
+ }
985
+
986
+ return `<div class="sm-cleanup-bar sm-pr-picker">
987
+ <div class="sm-pr-row">
988
+ <span class="sm-pr-label">Provider</span>
989
+ <span class="sm-pr-providers">${providerBtns}</span>
990
+ </div>
991
+ <div class="sm-pr-row">
992
+ <span class="sm-pr-label">Model</span>
993
+ <select id="sm-pr-model" class="sm-pr-select"${loading || models.length === 0 ? ' disabled' : ''}>${modelOptions}</select>
994
+ </div>
995
+ <div class="sm-pr-row sm-pr-actions">
996
+ <button class="sm-btn" id="sm-pr-cancel">Cancel</button>
997
+ <button class="sm-btn sm-btn-cleanup" id="sm-pr-run"${(!_prPicker.model || loading) ? ' disabled' : ''}>Run on ${esc(PROVIDER_LABELS[provider])}</button>
998
+ </div>
999
+ </div>`;
1000
+ }
1001
+
1002
+ async function loadProviderModels(provider) {
1003
+ if (_prPicker.modelsByProvider[provider]) return _prPicker.modelsByProvider[provider];
1004
+ _prPicker.loading = provider;
1005
+ render();
1006
+ try {
1007
+ let models = [];
1008
+ if (provider === 'claude') {
1009
+ const r = await fetch('/api/claude/config').then(r => r.json());
1010
+ models = (r?.models || []).map(m => ({ id: m.id, label: m.label || m.id }));
1011
+ } else if (provider === 'opencode') {
1012
+ const r = await fetch('/api/opencode/providers/full').then(r => r.json()).catch(() => null);
1013
+ const provs = r?.providers || r?.data || r || [];
1014
+ const flat = [];
1015
+ for (const p of (Array.isArray(provs) ? provs : Object.values(provs || {}))) {
1016
+ const pid = p?.id || p?.name || '';
1017
+ const ms = p?.models || {};
1018
+ const list = Array.isArray(ms) ? ms : Object.values(ms);
1019
+ for (const m of list) {
1020
+ const mid = m?.id || m?.name;
1021
+ if (!mid) continue;
1022
+ const id = pid ? `${pid}/${mid}` : mid;
1023
+ flat.push({ id, label: `${pid ? pid + ' · ' : ''}${m?.name || mid}` });
1024
+ }
1025
+ }
1026
+ models = flat;
1027
+ } else if (provider === 'codex') {
1028
+ // Codex models come from the running CLI (WebSocket). Provide a sensible static list.
1029
+ models = [
1030
+ { id: 'gpt-5-codex', label: 'gpt-5-codex' },
1031
+ { id: 'gpt-5', label: 'gpt-5' },
1032
+ { id: 'o4', label: 'o4' },
1033
+ { id: 'o4-mini', label: 'o4-mini' },
1034
+ ];
1035
+ }
1036
+ _prPicker.modelsByProvider[provider] = models;
1037
+ return models;
1038
+ } catch (err) {
1039
+ console.warn(`[pending-remember] model load failed for ${provider}:`, err);
1040
+ _prPicker.modelsByProvider[provider] = [];
1041
+ return [];
1042
+ } finally {
1043
+ if (_prPicker.loading === provider) _prPicker.loading = null;
1044
+ }
1045
+ }
1046
+
1047
+ async function openPendingRememberPicker() {
1048
+ _prPicker.open = true;
1049
+ if (!_prPicker.provider) _prPicker.provider = 'claude';
1050
+ render();
1051
+ await loadProviderModels(_prPicker.provider);
1052
+ render();
1053
+ }
1054
+
1055
+ function cancelPendingRememberPicker() {
1056
+ _prPicker.open = false;
1057
+ _prPicker.model = '';
1058
+ render();
1059
+ }
1060
+
1061
+ async function selectPendingRememberProvider(provider) {
1062
+ if (!provider || provider === _prPicker.provider) return;
1063
+ _prPicker.provider = provider;
1064
+ _prPicker.model = '';
1065
+ render();
1066
+ await loadProviderModels(provider);
1067
+ render();
1068
+ }
1069
+
1070
+ async function runPendingRemembers() {
1071
+ const provider = _prPicker.provider;
1072
+ const model = _prPicker.model;
1073
+ if (!provider || !model) return;
1074
+ const runBtn = _panel?.querySelector('#sm-pr-run');
1075
+ if (runBtn) { runBtn.disabled = true; runBtn.textContent = 'Loading prompt…'; }
1076
+ try {
1077
+ const res = await fetch('/api/sessions/pending-remember-prompt').then(r => r.json());
1078
+ if (!res?.ok) {
1079
+ alert(res?.error || 'Failed to build prompt');
1080
+ if (runBtn) { runBtn.disabled = false; runBtn.textContent = `Run on ${PROVIDER_LABELS[provider]}`; }
1081
+ return;
1082
+ }
1083
+ if (!res.prompt) {
1084
+ alert(res.message || 'No pending remembers to process.');
1085
+ cancelPendingRememberPicker();
1086
+ return;
1087
+ }
1088
+
1089
+ if (provider === 'claude') {
1090
+ try { localStorage.setItem('claudePanel:lastModel', model); } catch {}
1091
+ await sendToClaudePanel(res.prompt, { newTab: true, tabLabel: 'Pending remembers', autoSubmit: true });
1092
+ } else if (provider === 'opencode') {
1093
+ try { localStorage.setItem('ocp:lastModel', model); } catch {}
1094
+ await openOpencodeWithPrompt(res.prompt, { autoSend: true });
1095
+ } else if (provider === 'codex') {
1096
+ try { localStorage.setItem('cxp:model', model); } catch {}
1097
+ if (!isCodexPanelOpen()) await toggleCodexPanel();
1098
+ // Codex auto-send is unreliable from outside the panel — populate the input
1099
+ // and let the user click send. Best-effort.
1100
+ setTimeout(() => {
1101
+ const input = document.querySelector('#cxp-input');
1102
+ if (input) {
1103
+ input.value = res.prompt;
1104
+ input.dispatchEvent(new Event('input', { bubbles: true }));
1105
+ input.focus();
1106
+ }
1107
+ }, 200);
1108
+ }
1109
+
1110
+ cancelPendingRememberPicker();
1111
+ closePanel();
1112
+ } catch (err) {
1113
+ alert('Failed: ' + (err?.message || err));
1114
+ if (runBtn) { runBtn.disabled = false; runBtn.textContent = `Run on ${PROVIDER_LABELS[provider]}`; }
1115
+ }
1116
+ }
1117
+
398
1118
  // ── Helpers ──
399
1119
 
400
1120
  function esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }
@@ -430,6 +1150,10 @@ function openPanel() {
430
1150
  // Backdrop click disabled — close only via ESC or close button
431
1151
  document.body.appendChild(_backdrop);
432
1152
 
1153
+ // Default to Updates tab when there's something to act on, otherwise
1154
+ // Sessions (the historical default).
1155
+ _activeTab = computeUpdates().length > 0 ? 'updates' : 'sessions';
1156
+
433
1157
  _panel = document.createElement('div');
434
1158
  _panel.className = 'session-monitor-panel glass resizable';
435
1159
  _panel.id = 'session-monitor-panel';
@@ -437,8 +1161,8 @@ function openPanel() {
437
1161
  document.body.appendChild(_panel);
438
1162
 
439
1163
  // Center at default size
440
- _panel.style.left = Math.max(20, (window.innerWidth - 640) / 2) + 'px';
441
- _panel.style.top = Math.max(48, (window.innerHeight - 480) / 2) + 'px';
1164
+ _panel.style.left = Math.max(20, (window.innerWidth - 680) / 2) + 'px';
1165
+ _panel.style.top = Math.max(48, (window.innerHeight - 520) / 2) + 'px';
442
1166
 
443
1167
  wirePanel();
444
1168
  isVisible = true;
@@ -459,11 +1183,12 @@ function openPanel() {
459
1183
 
460
1184
  function closePanel() {
461
1185
  if (!_panel) return;
1186
+ stopStalledTicker();
462
1187
  if (_backdrop) { _backdrop.remove(); _backdrop = null; }
463
1188
  _panel.remove();
464
1189
  _panel = null;
465
1190
  isVisible = false;
466
- _activeTab = 'sessions';
1191
+ _activeTab = 'updates';
467
1192
  emit('session-monitor:closed');
468
1193
  }
469
1194
 
@@ -508,17 +1233,47 @@ export function toggleSessionMonitor() {
508
1233
  else openPanel();
509
1234
  }
510
1235
 
511
- // Widget mode for claude-chat skin
512
- export function mountSessionWidget(container) {
513
- const widget = document.createElement('div');
514
- widget.className = 'session-widget';
515
- widget.innerHTML = `<div class="sm-body" id="sm-body"></div>`;
516
- container.appendChild(widget);
517
- _panel = widget;
518
- _activeTab = 'sessions';
519
- isVisible = true;
520
- connectWs();
521
- return widget;
1236
+ // Open the Notifications drawer and switch directly to the Loops tab. Used by the
1237
+ // titlebar stale-loops alert button.
1238
+ export function openLoopsTab() {
1239
+ if (!_panel) openPanel();
1240
+ _activeTab = 'loops';
1241
+ if (_panel) {
1242
+ _panel.querySelectorAll('.sm-tab').forEach(t => t.classList.toggle('active', t.dataset.tab === 'loops'));
1243
+ render();
1244
+ }
1245
+ }
1246
+
1247
+ // Bootstrap fetch: populate badge state without opening the Notifications
1248
+ // drawer. Called from ui-navbar.js on init so the alert dot can show on app
1249
+ // load.
1250
+ export async function fetchLoopsForBadge() {
1251
+ try {
1252
+ const res = await fetch('/api/loop/list').then(r => r.json());
1253
+ loops = res.loops || [];
1254
+ staleLoopCount = res.staleCount || 0;
1255
+ emitLoopsUpdate();
1256
+ } catch {}
1257
+ }
1258
+
1259
+ // Bootstrap fetch for Updates badge — reads the rules status and emits the
1260
+ // notifications:updated event so the navbar can show its count without the
1261
+ // drawer ever being opened.
1262
+ export async function fetchNotificationsForBadge() {
1263
+ await refreshRulesStatus();
1264
+ // Also re-emit on next tick so ui-update / ui-tool-updates have a chance to
1265
+ // populate their cached state before the count is computed for the badge.
1266
+ setTimeout(() => emitNotificationsUpdate(), 1500);
1267
+ }
1268
+
1269
+ // Open the Notifications drawer directly to the Updates tab.
1270
+ export function openUpdatesTab() {
1271
+ if (!_panel) openPanel();
1272
+ _activeTab = 'updates';
1273
+ if (_panel) {
1274
+ _panel.querySelectorAll('.sm-tab').forEach(t => t.classList.toggle('active', t.dataset.tab === 'updates'));
1275
+ render();
1276
+ }
522
1277
  }
523
1278
 
524
1279
  // Kept for backwards compat