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
@@ -0,0 +1,955 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // OpenCode V2 — sidepanel WebSocket requests as pure functions
3
+ //
4
+ // server.js owns the socket, the isolated serves and the native-run guards; a
5
+ // request body lives here as `(msg, deps) => reply` so node:test can drive it
6
+ // with a fake client. `handleOpencodeV2Request` returns false for a type it
7
+ // does not own, and the caller falls through to its own switch.
8
+ //
9
+ // deps (all supplied by handleOpencodeV2Ws):
10
+ // send(data) write one JSON message to this socket
11
+ // shared the shared-serve client (opencode-v2-client).
12
+ // SDK calls added for the panel are under
13
+ // `client.extra.<group>.<method>`
14
+ // bound(sessionId) the serve currently hosting the session's
15
+ // turn, else the shared client; never spawns
16
+ // turn(sessionId, mcpProfile) the session's dedicated serve; may spawn it
17
+ // proxy(method, path, body, timeoutMs, baseUrl) raw HTTP to a serve
18
+ // baseUrlFor(sessionId) base URL of the serve hosting the session
19
+ // directoryQuery(cwd) `?directory=…` or ''
20
+ // isTurnActive(sessionId) true while a turn is running or starting
21
+ // turnScope(sessionId) the bookkeeping message:send does around a
22
+ // turn: aborts the previous prompt of this
23
+ // socket, marks the session active. Returns
24
+ // { signal, end() }; end() must always run
25
+ // persistMcp(name, config) write one MCP server into the OpenCode
26
+ // config file; starts nothing. Throws on failure
27
+ //
28
+ // The panel must work against a server that predates a request type, so the
29
+ // server says what it understands: `capabilities` in init:result and one
30
+ // `capabilities` message after identify. The panel shows a feature that needs
31
+ // a type only when that type is listed.
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+
34
+ import { readFileSync } from 'node:fs';
35
+ import { dirname, join } from 'node:path';
36
+ import { fileURLToPath } from 'node:url';
37
+ import { compactOrSummarize, lastModelOf } from './opencode-v2-client.js';
38
+
39
+ export { lastModelOf };
40
+
41
+ // Types answered by the switch in server.js.
42
+ export const OPENCODE_V2_WS_INLINE_TYPES = Object.freeze([
43
+ 'init', 'identify',
44
+ 'session:list', 'session:create', 'session:get', 'session:update', 'session:delete', 'session:messages',
45
+ 'mcp:profile:get', 'mcp:profile:set',
46
+ 'message:send', 'message:abort',
47
+ 'question:list', 'question:reject',
48
+ ]);
49
+
50
+ const failure = (status, error, extra = {}) => ({ ok: false, status, error, ...extra });
51
+
52
+ const sessionIdOf = (msg) => (typeof msg?.sessionId === 'string' ? msg.sessionId.trim() : '');
53
+ // The id every per-session resolver gets: the canonical one, or nothing.
54
+ const sessionKeyOf = (msg) => sessionIdOf(msg) || undefined;
55
+ const directoryOf = (msg) => (typeof msg?.cwd === 'string' && msg.cwd.trim() ? msg.cwd.trim() : undefined);
56
+
57
+ // ── One session id per request ──────────────────────────────────────────────
58
+ // The native-run and history guards in server.js look a session up by id, and
59
+ // so does every SDK call. They must look up the same string: an id that is
60
+ // trimmed for the SDK but not for the guard (" ses_x ") walks past the guard.
61
+ // So the id is made canonical once, in place, before anything reads it, and an
62
+ // id that is not a plain token is refused outright.
63
+ const SESSION_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
64
+
65
+ /**
66
+ * Canonicalise `msg.sessionId` in place. Returns null when the message may go
67
+ * on, or the failure to answer with. An absent or empty id becomes `undefined`.
68
+ * A `body` (session:create / session:update) loses any session id of its own:
69
+ * the one that was checked is the only one a call may use.
70
+ */
71
+ export function canonicalizeOpencodeV2Message(msg) {
72
+ if (!msg || typeof msg !== 'object') return failure(400, 'malformed request');
73
+ const raw = msg.sessionId;
74
+ if (raw === undefined || raw === null) {
75
+ msg.sessionId = undefined;
76
+ } else if (typeof raw !== 'string') {
77
+ return failure(400, 'sessionId must be a string');
78
+ } else {
79
+ const trimmed = raw.trim();
80
+ if (!trimmed) msg.sessionId = undefined;
81
+ else if (!SESSION_ID_RE.test(trimmed)) return failure(400, 'sessionId is not a valid session id');
82
+ else msg.sessionId = trimmed;
83
+ }
84
+ if (msg.body && typeof msg.body === 'object' && !Array.isArray(msg.body)) {
85
+ delete msg.body.sessionID;
86
+ delete msg.body.sessionId;
87
+ }
88
+ return null;
89
+ }
90
+
91
+ /**
92
+ * Everything that must hold before a request is answered, in one place so it
93
+ * can be tested: a canonical session id, no write while history is being
94
+ * cleared, and the native-automation ownership rules. Returns null to let the
95
+ * request through, or `{ status, error }`.
96
+ * ctx: { historyClearing, historyWriteTypes, nativeMutationTypes,
97
+ * protectedRunFor(sessionId), ownsRun(run) }
98
+ */
99
+ export function guardOpencodeV2Request(msg, ctx = {}) {
100
+ const malformed = canonicalizeOpencodeV2Message(msg);
101
+ if (malformed) return { status: malformed.status, error: malformed.error };
102
+ const type = msg.type;
103
+ if (ctx.historyClearing && ctx.historyWriteTypes?.has(type)) {
104
+ return { status: 409, error: 'OpenCode history is being cleared' };
105
+ }
106
+ const protectedRun = msg.sessionId ? ctx.protectedRunFor?.(msg.sessionId) : null;
107
+ if (protectedRun && !ctx.ownsRun?.(protectedRun)) {
108
+ return { status: 409, error: 'Native automation session is owned by another window' };
109
+ }
110
+ if (protectedRun && ctx.nativeMutationTypes?.has(type)) {
111
+ return { status: 409, error: 'Stop the native automation before modifying its session' };
112
+ }
113
+ return null;
114
+ }
115
+
116
+ // v2.session.context answers `{ data: [...] }` since 1.18; older serves sent the
117
+ // bare array.
118
+ export function contextRows(data) {
119
+ if (Array.isArray(data)) return data;
120
+ if (Array.isArray(data?.data)) return data.data;
121
+ return [];
122
+ }
123
+
124
+ // session.status answers a map of the sessions that are NOT idle on that serve.
125
+ export function statusForSession(map, sessionId) {
126
+ const entry = map && typeof map === 'object' ? map[sessionId] : null;
127
+ return entry && typeof entry.type === 'string' ? entry : { type: 'idle' };
128
+ }
129
+
130
+ function modelOf(value) {
131
+ const providerID = typeof value?.providerID === 'string' ? value.providerID.trim() : '';
132
+ const modelID = typeof value?.modelID === 'string' ? value.modelID.trim() : '';
133
+ return providerID && modelID ? { providerID, modelID } : null;
134
+ }
135
+
136
+ // session.compact with the session.summarize fallback (see compactOrSummarize).
137
+ async function compactSession(msg, deps) {
138
+ const client = await deps.turn(sessionKeyOf(msg), msg.mcpProfile);
139
+ try {
140
+ return await compactOrSummarize(client, {
141
+ sessionID: sessionIdOf(msg), directory: directoryOf(msg), model: modelOf(msg.model),
142
+ });
143
+ } catch (err) {
144
+ // "Pick a model first" is an answer for the user, not a server error.
145
+ if (err?.status === 400) return failure(400, err.message);
146
+ throw err;
147
+ }
148
+ }
149
+
150
+ const PERMISSION_REPLIES = new Set(['once', 'always', 'reject']);
151
+
152
+ async function permissionReply(msg, deps) {
153
+ const requestID = String(msg.permissionId || msg.requestId || '').trim();
154
+ const reply = String(msg.response || '');
155
+ if (!requestID) return failure(400, 'permission id is required');
156
+ if (!PERMISSION_REPLIES.has(reply)) return failure(400, `unknown permission reply: ${reply || '(empty)'}`);
157
+ // The rejection reason is shown to the model; only a rejection carries one.
158
+ const message = reply === 'reject' && typeof msg.message === 'string' && msg.message.trim()
159
+ ? msg.message.trim().slice(0, 2000)
160
+ : undefined;
161
+ const client = deps.bound(sessionKeyOf(msg));
162
+ const directory = directoryOf(msg);
163
+ try {
164
+ const r = await client.permission.reply({ requestID, reply, message, directory });
165
+ return { status: r.status, data: r.data };
166
+ } catch (err) {
167
+ // A request raised under the serve's default scope does not match a reply
168
+ // sent with ?directory=. One retry without it; nothing else is a real route
169
+ // (the old /respond and bare-id fallbacks answered with the web UI's HTML).
170
+ if (err?.status !== 404 || !directory) throw err;
171
+ const r = await client.permission.reply({ requestID, reply, message });
172
+ return { status: r.status, data: r.data };
173
+ }
174
+ }
175
+
176
+ async function questionReply(msg, deps) {
177
+ const requestID = String(msg.requestId || msg.requestID || '').trim();
178
+ if (!requestID) return failure(400, 'question request id is required');
179
+ const body = { answers: Array.isArray(msg.answers) ? msg.answers : [] };
180
+ const path = `/question/${encodeURIComponent(requestID)}/reply${deps.directoryQuery(msg.cwd)}`;
181
+ const r = await deps.proxy('POST', path, body, 10000, deps.baseUrlFor(sessionKeyOf(msg)));
182
+ // Any unknown route on `opencode serve` answers 200 with the web UI; a reply
183
+ // that comes back as a document did not reach the question API.
184
+ if (typeof r.data === 'string' && /^\s*<(?:!doctype|html)/i.test(r.data)) {
185
+ return failure(502, 'OpenCode did not accept the question reply');
186
+ }
187
+ return { status: r.status, data: r.data };
188
+ }
189
+
190
+ async function permissionList(msg, deps) {
191
+ const r = await deps.bound(sessionKeyOf(msg)).extra.permission.list({ directory: directoryOf(msg) });
192
+ return { status: r.status, data: Array.isArray(r.data) ? r.data : [] };
193
+ }
194
+
195
+ // Rules OpenCode saved from "Always allow" (v2.permission.saved). They are
196
+ // stored per project, so the shared serve answers.
197
+ async function permissionSavedList(msg, deps) {
198
+ const projectID = typeof msg.projectID === 'string' && msg.projectID.trim() ? msg.projectID.trim() : '';
199
+ const query = projectID ? `?projectID=${encodeURIComponent(projectID)}` : '';
200
+ const r = await deps.proxy('GET', `/api/permission/saved${query}`, null, 10000, deps.baseUrlFor(null));
201
+ if (r.status >= 400) return failure(r.status, proxyErrorText(r.data, 'Could not list saved approvals'));
202
+ const rows = Array.isArray(r.data?.data) ? r.data.data : (Array.isArray(r.data) ? r.data : []);
203
+ return { status: r.status, data: rows };
204
+ }
205
+
206
+ async function permissionSavedRemove(msg, deps) {
207
+ const id = String(msg.savedId || '').trim();
208
+ if (!id) return failure(400, 'saved approval id is required');
209
+ const r = await deps.proxy('DELETE', `/api/permission/saved/${encodeURIComponent(id)}`, null, 10000, deps.baseUrlFor(null));
210
+ if (r.status >= 400) return failure(r.status, proxyErrorText(r.data, 'Could not remove the saved approval'));
211
+ return { status: r.status, data: true };
212
+ }
213
+
214
+ // A raw proxy answer is the parsed body: `{ name, data: { message } }`,
215
+ // `{ _tag, message }` or text.
216
+ function proxyErrorText(body, fallback) {
217
+ if (typeof body === 'string') return /^\s*</.test(body) ? fallback : (body.trim().slice(0, 500) || fallback);
218
+ return body?.message || body?.data?.message || body?.error || fallback;
219
+ }
220
+
221
+ // The model's todo list for the session (the todowrite tool keeps it).
222
+ async function sessionTodo(msg, deps) {
223
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.todo({ sessionID: sessionIdOf(msg), directory: directoryOf(msg) });
224
+ return { status: r.status, data: Array.isArray(r.data) ? r.data : [] };
225
+ }
226
+
227
+ async function sessionStatus(msg, deps) {
228
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.status({ directory: directoryOf(msg) });
229
+ return { status: r.status, data: { status: statusForSession(r.data, sessionIdOf(msg)) } };
230
+ }
231
+
232
+ // What the relay forwards to panels. OpenCode 1.18 mirrors every bus event as
233
+ // a `sync` envelope ({ type: 'sync', syncEvent }); the panel acts on the bus
234
+ // event itself, so the mirror is dropped. Everything else passes.
235
+ export function shouldRelayOpencodeV2Message(data) {
236
+ return !(data?.type === 'event' && data.eventType === 'sync');
237
+ }
238
+
239
+ // Body of `POST /mcp` for a server SynaBun describes as { command, args, env }
240
+ // or { url, headers }. OpenCode takes McpLocalConfig (`type: 'local'`, the
241
+ // command as one array, `environment`) or McpRemoteConfig; `type: 'stdio'` with
242
+ // a string command is answered 400.
243
+ export function buildOpencodeRuntimeMcpConfig(config = {}) {
244
+ if (config.type === 'local' || config.type === 'remote') return { ...config };
245
+ if (typeof config.url === 'string' && config.url) {
246
+ return {
247
+ type: 'remote',
248
+ url: config.url,
249
+ ...(config.headers && typeof config.headers === 'object' ? { headers: config.headers } : {}),
250
+ enabled: config.enabled !== false,
251
+ };
252
+ }
253
+ // Every word goes through as it is: an argument may be empty or carry
254
+ // spaces on purpose, and what is registered must be what was typed.
255
+ const head = Array.isArray(config.command) ? config.command : [config.command];
256
+ const command = [...head, ...(Array.isArray(config.args) ? config.args : [])]
257
+ .filter((part) => typeof part === 'string');
258
+ const environment = config.environment || config.env;
259
+ return {
260
+ type: 'local',
261
+ command,
262
+ ...(environment && typeof environment === 'object' ? { environment } : {}),
263
+ enabled: config.enabled !== false,
264
+ };
265
+ }
266
+
267
+ // ── Session list (read straight from OpenCode's SQLite) ─────────────────────
268
+ // The SDK's session.list only answers for the serve's own project; the panel
269
+ // lists every project, so server.js reads the `session` table. The query and
270
+ // the row mapping live here so they can be tested against a real table.
271
+ export const SESSION_LIST_MAX = 500;
272
+
273
+ /**
274
+ * options: { search, archived, roots, limit }
275
+ * archived false (default) → live sessions; true → archived ones only
276
+ * roots true → no sub-agent sessions (parent_id IS NULL)
277
+ * search case-insensitive match on title, slug or directory
278
+ * Un-archiving writes time_archived = 0, so "live" is NULL or 0.
279
+ */
280
+ export function buildSessionListQuery(options = {}) {
281
+ const where = [];
282
+ const params = [];
283
+ where.push(options.archived === true
284
+ ? '(s.time_archived IS NOT NULL AND s.time_archived != 0)'
285
+ : '(s.time_archived IS NULL OR s.time_archived = 0)');
286
+ if (options.roots === true) where.push('s.parent_id IS NULL');
287
+ const search = typeof options.search === 'string' ? options.search.trim().slice(0, 200) : '';
288
+ if (search) {
289
+ const like = `%${search.replace(/[\\%_]/g, (ch) => `\\${ch}`)}%`;
290
+ where.push("(s.title LIKE ? ESCAPE '\\' OR s.slug LIKE ? ESCAPE '\\' OR s.directory LIKE ? ESCAPE '\\')");
291
+ params.push(like, like, like);
292
+ }
293
+ const requested = Number(options.limit);
294
+ const limit = Number.isInteger(requested) && requested > 0 ? Math.min(requested, SESSION_LIST_MAX) : null;
295
+ const sql = `
296
+ SELECT s.id, s.title, s.directory, s.slug, s.project_id, s.parent_id, s.share_url,
297
+ s.time_created, s.time_updated, s.time_archived,
298
+ (SELECT COUNT(*) FROM message m WHERE m.session_id = s.id) AS message_count
299
+ FROM session s
300
+ WHERE ${where.join(' AND ')}
301
+ ORDER BY s.time_updated DESC${limit ? '\n LIMIT ?' : ''}
302
+ `;
303
+ if (limit) params.push(limit);
304
+ return { sql, params };
305
+ }
306
+
307
+ const epochMs = (value) => (value ? Math.floor(new Date(value).getTime()) || 0 : 0);
308
+
309
+ export function mapSessionListRow(row) {
310
+ const out = {
311
+ id: row.id,
312
+ title: row.title || '',
313
+ slug: row.slug || '',
314
+ directory: row.directory || '',
315
+ projectID: row.project_id || '',
316
+ messageCount: row.message_count || 0,
317
+ time: { created: epochMs(row.time_created), updated: epochMs(row.time_updated) },
318
+ };
319
+ if (row.parent_id) out.parentID = row.parent_id;
320
+ if (row.share_url) out.share = { url: row.share_url };
321
+ const archived = epochMs(row.time_archived);
322
+ if (archived) out.time.archived = archived;
323
+ return out;
324
+ }
325
+
326
+ // ── Session lifecycle (revert, fork, share, children, delete message) ───────
327
+
328
+ const messageIdOf = (msg) => (typeof msg?.messageID === 'string' && msg.messageID.trim()
329
+ ? msg.messageID.trim()
330
+ : (typeof msg?.messageId === 'string' ? msg.messageId.trim() : ''));
331
+
332
+ // Reverting or deleting under a running turn would pull the transcript out
333
+ // from under the model.
334
+ function refuseWhileRunning(msg, deps, what) {
335
+ return deps.isTurnActive?.(sessionIdOf(msg))
336
+ ? failure(409, `Stop the running turn before you ${what}.`)
337
+ : null;
338
+ }
339
+
340
+ async function sessionRevert(msg, deps) {
341
+ const busy = refuseWhileRunning(msg, deps, 'revert');
342
+ if (busy) return busy;
343
+ const messageID = messageIdOf(msg);
344
+ if (!messageID) return failure(400, 'messageID is required');
345
+ const partID = typeof msg.partID === 'string' && msg.partID.trim() ? msg.partID.trim() : undefined;
346
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.revert({
347
+ sessionID: sessionIdOf(msg), messageID, partID, directory: directoryOf(msg),
348
+ });
349
+ return { status: r.status, data: r.data };
350
+ }
351
+
352
+ async function sessionUnrevert(msg, deps) {
353
+ const busy = refuseWhileRunning(msg, deps, 'restore');
354
+ if (busy) return busy;
355
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.unrevert({ sessionID: sessionIdOf(msg), directory: directoryOf(msg) });
356
+ return { status: r.status, data: r.data };
357
+ }
358
+
359
+ async function sessionFork(msg, deps) {
360
+ const r = await deps.shared.extra.session.fork({
361
+ sessionID: sessionIdOf(msg), messageID: messageIdOf(msg) || undefined, directory: directoryOf(msg),
362
+ });
363
+ return { status: r.status, data: r.data };
364
+ }
365
+
366
+ async function sessionChildren(msg, deps) {
367
+ const r = await deps.shared.extra.session.children({ sessionID: sessionIdOf(msg), directory: directoryOf(msg) });
368
+ return { status: r.status, data: Array.isArray(r.data) ? r.data : [] };
369
+ }
370
+
371
+ async function messageDelete(msg, deps) {
372
+ const busy = refuseWhileRunning(msg, deps, 'delete a message');
373
+ if (busy) return busy;
374
+ const messageID = messageIdOf(msg);
375
+ if (!messageID) return failure(400, 'messageID is required');
376
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.deleteMessage({
377
+ sessionID: sessionIdOf(msg), messageID, directory: directoryOf(msg),
378
+ });
379
+ return { status: r.status, data: r.data };
380
+ }
381
+
382
+ // OpenCode's `share` setting: manual (default), auto, or disabled.
383
+ export function sharePolicyOf(config) {
384
+ const value = config?.share;
385
+ if (value === 'disabled' || value === 'auto' || value === 'manual') return value;
386
+ return 'manual';
387
+ }
388
+
389
+ async function readSharePolicy(msg, deps) {
390
+ const r = await deps.shared.extra.config.get({ directory: directoryOf(msg) });
391
+ return sharePolicyOf(r.data);
392
+ }
393
+
394
+ async function sessionSharePolicy(msg, deps) {
395
+ return { status: 200, data: { share: await readSharePolicy(msg, deps) } };
396
+ }
397
+
398
+ // Publishes the transcript at a public opencode URL. The panel confirms with
399
+ // the user every time; the server refuses when the config forbids sharing.
400
+ async function sessionShare(msg, deps) {
401
+ if (await readSharePolicy(msg, deps) === 'disabled') {
402
+ return failure(403, 'Sharing is disabled in the OpenCode config.');
403
+ }
404
+ const r = await deps.shared.extra.session.share({ sessionID: sessionIdOf(msg), directory: directoryOf(msg) });
405
+ return { status: r.status, data: r.data };
406
+ }
407
+
408
+ async function sessionUnshare(msg, deps) {
409
+ const r = await deps.shared.extra.session.unshare({ sessionID: sessionIdOf(msg), directory: directoryOf(msg) });
410
+ return { status: r.status, data: r.data };
411
+ }
412
+
413
+ // ── Composer: slash commands, shell, file search ────────────────────────────
414
+
415
+ /** What the slash menu needs of a Command; the template can be 16 KB and is not sent. */
416
+ export function commandRow(cmd) {
417
+ if (!cmd || typeof cmd.name !== 'string' || !cmd.name) return null;
418
+ const out = { name: cmd.name, description: typeof cmd.description === 'string' ? cmd.description : '' };
419
+ out.source = ['command', 'mcp', 'skill'].includes(cmd.source) ? cmd.source : 'command';
420
+ if (typeof cmd.agent === 'string' && cmd.agent) out.agent = cmd.agent;
421
+ if (cmd.subtask === true) out.subtask = true;
422
+ if (Array.isArray(cmd.hints) && cmd.hints.length) out.hints = cmd.hints.filter((h) => typeof h === 'string').slice(0, 8);
423
+ return out;
424
+ }
425
+
426
+ // Commands depend on the project (.opencode/command, project skills), so the
427
+ // list is asked for the session's directory.
428
+ async function commandList(msg, deps) {
429
+ const r = await deps.shared.extra.command.list({ directory: directoryOf(msg) });
430
+ return { status: r.status, data: (Array.isArray(r.data) ? r.data : []).map(commandRow).filter(Boolean) };
431
+ }
432
+
433
+ // A model string for session.command / session.shell: `provider/model`.
434
+ function modelRef(value) {
435
+ const model = modelOf(value);
436
+ return model ? `${model.providerID}/${model.modelID}` : undefined;
437
+ }
438
+
439
+ // Run something that occupies the session like a prompt does: on the
440
+ // session's dedicated serve, inside the same turn bookkeeping as message:send.
441
+ async function withTurn(msg, deps, run) {
442
+ const scope = deps.turnScope(sessionIdOf(msg));
443
+ try {
444
+ const client = await deps.turn(sessionKeyOf(msg), msg.mcpProfile);
445
+ const r = await run(client, scope.signal ? { signal: scope.signal } : undefined);
446
+ return { status: r.status, data: r.data };
447
+ } finally {
448
+ scope.end();
449
+ }
450
+ }
451
+
452
+ // session.command: run a slash command (a command file, a skill, an MCP prompt).
453
+ async function commandRun(msg, deps) {
454
+ const command = typeof msg.command === 'string' ? msg.command.trim().replace(/^\//, '') : '';
455
+ if (!command) return failure(400, 'command is required');
456
+ const parts = Array.isArray(msg.parts) && msg.parts.length ? msg.parts : undefined;
457
+ return withTurn(msg, deps, (client, options) => client.extra.session.command({
458
+ sessionID: sessionIdOf(msg),
459
+ command,
460
+ arguments: typeof msg.arguments === 'string' ? msg.arguments : '',
461
+ agent: typeof msg.agent === 'string' && msg.agent ? msg.agent : undefined,
462
+ model: modelRef(msg.model),
463
+ variant: typeof msg.variant === 'string' && msg.variant ? msg.variant : undefined,
464
+ parts,
465
+ directory: directoryOf(msg),
466
+ }, options));
467
+ }
468
+
469
+ // session.shell: run one shell command in the session, with no model call.
470
+ // The panel sends this only from its shell mode, which nothing but the user
471
+ // typing "!" into an empty composer can enter.
472
+ async function sessionShell(msg, deps) {
473
+ const command = typeof msg.command === 'string' ? msg.command.trim() : '';
474
+ if (!command) return failure(400, 'command is required');
475
+ if (command.length > 20000) return failure(400, 'command is too long');
476
+ return withTurn(msg, deps, (client, options) => client.extra.session.shell({
477
+ sessionID: sessionIdOf(msg),
478
+ command,
479
+ agent: typeof msg.agent === 'string' && msg.agent ? msg.agent : 'build',
480
+ model: modelOf(msg.model) || undefined,
481
+ directory: directoryOf(msg),
482
+ }, options));
483
+ }
484
+
485
+ export const FIND_FILES_LIMIT = 50;
486
+
487
+ // find.files: fuzzy file (and directory) search for @ mentions.
488
+ async function findFiles(msg, deps) {
489
+ const query = typeof msg.query === 'string' ? msg.query.trim().slice(0, 200) : '';
490
+ const r = await deps.shared.extra.find.files({
491
+ query,
492
+ dirs: msg.dirs === false ? 'false' : 'true',
493
+ limit: FIND_FILES_LIMIT,
494
+ directory: directoryOf(msg),
495
+ });
496
+ const rows = (Array.isArray(r.data) ? r.data : []).filter((p) => typeof p === 'string' && p);
497
+ return { status: r.status, data: rows.slice(0, FIND_FILES_LIMIT) };
498
+ }
499
+
500
+ // A file:// URI as a filesystem path; anything else is not a project file.
501
+ function pathOfFileUri(uri) {
502
+ if (typeof uri !== 'string' || !uri.startsWith('file://')) return '';
503
+ try { return decodeURIComponent(new URL(uri).pathname); } catch { return ''; }
504
+ }
505
+
506
+ /** A workspace symbol as the @ picker takes it: `{ name, kind, path, range }`. */
507
+ export function symbolRow(symbol) {
508
+ const name = typeof symbol?.name === 'string' ? symbol.name.trim() : '';
509
+ const path = pathOfFileUri(symbol?.location?.uri);
510
+ if (!name || !path) return null;
511
+ const point = (p) => ({ line: Number(p?.line) || 0, character: Number(p?.character) || 0 });
512
+ const range = symbol.location.range || {};
513
+ return {
514
+ name: name.slice(0, 200),
515
+ kind: Number(symbol.kind) || 0,
516
+ path,
517
+ range: { start: point(range.start), end: point(range.end) },
518
+ };
519
+ }
520
+
521
+ // find.symbols: workspace symbols from the language servers of the serve that
522
+ // runs this session (they start when the session reads a file of that language).
523
+ async function findSymbols(msg, deps) {
524
+ const query = typeof msg.query === 'string' ? msg.query.trim().slice(0, 200) : '';
525
+ if (!query) return { status: 200, data: [] };
526
+ const r = await deps.bound(sessionKeyOf(msg)).extra.find.symbols({ query, directory: directoryOf(msg) });
527
+ const rows = (Array.isArray(r.data) ? r.data : []).map(symbolRow).filter(Boolean);
528
+ return { status: r.status, data: rows.slice(0, FIND_FILES_LIMIT) };
529
+ }
530
+
531
+ export const RESOURCE_LIST_LIMIT = 200;
532
+
533
+ /** experimental.resource.list answers `{ [key]: McpResource }`; the picker takes rows. */
534
+ export function resourceRows(map) {
535
+ if (!map || typeof map !== 'object' || Array.isArray(map)) return [];
536
+ return Object.values(map)
537
+ .filter((r) => r && typeof r.uri === 'string' && r.uri && typeof r.client === 'string' && r.client)
538
+ .map((r) => ({
539
+ name: String(r.name || r.uri).slice(0, 200),
540
+ uri: r.uri,
541
+ client: r.client,
542
+ description: typeof r.description === 'string' ? r.description.slice(0, 300) : '',
543
+ mimeType: typeof r.mimeType === 'string' ? r.mimeType : '',
544
+ }))
545
+ .sort((a, b) => a.client.localeCompare(b.client) || a.name.localeCompare(b.name))
546
+ .slice(0, RESOURCE_LIST_LIMIT);
547
+ }
548
+
549
+ // Resources of the MCP servers connected to the serve hosting this session.
550
+ async function resourceList(msg, deps) {
551
+ const r = await deps.proxy('GET', `/experimental/resource${deps.directoryQuery(msg.cwd)}`, null, 10000, deps.baseUrlFor(sessionKeyOf(msg)));
552
+ if (r.status >= 400) return failure(r.status, proxyErrorText(r.data, 'Could not list MCP resources'));
553
+ return { status: r.status, data: resourceRows(r.data) };
554
+ }
555
+
556
+ /** v2.reference.list answers `{ location, data: ReferenceInfo[] }`; hidden ones are left out. */
557
+ export function referenceRows(body) {
558
+ const list = Array.isArray(body?.data) ? body.data : (Array.isArray(body) ? body : []);
559
+ return list
560
+ .filter((r) => r && typeof r.name === 'string' && r.name && r.hidden !== true)
561
+ .map((r) => ({
562
+ name: r.name,
563
+ path: typeof r.path === 'string' ? r.path : '',
564
+ description: typeof r.description === 'string' ? r.description : '',
565
+ }));
566
+ }
567
+
568
+ // References live under /api and take the directory as a location.
569
+ function referencePath(directory) {
570
+ return directory
571
+ ? `/api/reference?directory=${encodeURIComponent(directory)}&location%5Bdirectory%5D=${encodeURIComponent(directory)}`
572
+ : '/api/reference';
573
+ }
574
+
575
+ async function referenceList(msg, deps) {
576
+ const r = await deps.proxy('GET', referencePath(directoryOf(msg)), null, 10000, deps.baseUrlFor(sessionKeyOf(msg)));
577
+ if (r.status >= 400 || typeof r.data === 'string') return { status: 200, data: [] };
578
+ return { status: r.status, data: referenceRows(r.data) };
579
+ }
580
+
581
+ /** What the agent toggle needs of an Agent; the prompt and permission ruleset stay behind. */
582
+ export function agentRow(agent) {
583
+ if (!agent || typeof agent.name !== 'string' || !agent.name) return null;
584
+ return {
585
+ name: agent.name,
586
+ mode: typeof agent.mode === 'string' ? agent.mode : '',
587
+ description: typeof agent.description === 'string' ? agent.description : '',
588
+ hidden: agent.hidden === true,
589
+ color: typeof agent.color === 'string' ? agent.color : '',
590
+ };
591
+ }
592
+
593
+ // Agents depend on the project (.opencode/agent), so they are asked per directory.
594
+ async function agentList(msg, deps) {
595
+ const r = await deps.shared.extra.app.agents({ directory: directoryOf(msg) });
596
+ return { status: r.status, data: (Array.isArray(r.data) ? r.data : []).map(agentRow).filter(Boolean) };
597
+ }
598
+
599
+ // ── Changes and VCS ─────────────────────────────────────────────────────────
600
+
601
+ export const FILE_DIFF_MAX_FILES = 300;
602
+ export const FILE_DIFF_MAX_PATCH_CHARS = 200_000;
603
+
604
+ /**
605
+ * File diffs as the panel takes them: `{ file, patch, additions, deletions,
606
+ * status }`. `file` and `patch` are optional in the SDK (SnapshotFileDiff);
607
+ * a huge patch is cut and marked so one generated file cannot flood the socket.
608
+ */
609
+ export function capFileDiffs(list) {
610
+ const rows = (Array.isArray(list) ? list : []).filter((row) => row && typeof row === 'object');
611
+ return rows.slice(0, FILE_DIFF_MAX_FILES).map((row) => {
612
+ const patch = typeof row.patch === 'string' ? row.patch : '';
613
+ const out = {
614
+ file: typeof row.file === 'string' ? row.file : '',
615
+ patch: patch.length > FILE_DIFF_MAX_PATCH_CHARS ? patch.slice(0, FILE_DIFF_MAX_PATCH_CHARS) : patch,
616
+ additions: Number(row.additions) || 0,
617
+ deletions: Number(row.deletions) || 0,
618
+ };
619
+ if (typeof row.status === 'string') out.status = row.status;
620
+ if (patch.length > FILE_DIFF_MAX_PATCH_CHARS) out.patchTruncated = true;
621
+ return out;
622
+ });
623
+ }
624
+
625
+ // What the session changed (snapshot based), optionally only one message's turn.
626
+ async function sessionDiff(msg, deps) {
627
+ const r = await deps.bound(sessionKeyOf(msg)).extra.session.diff({
628
+ sessionID: sessionIdOf(msg), messageID: messageIdOf(msg) || undefined, directory: directoryOf(msg),
629
+ });
630
+ return { status: r.status, data: capFileDiffs(r.data) };
631
+ }
632
+
633
+ async function vcsGet(msg, deps) {
634
+ const r = await deps.shared.extra.vcs.get({ directory: directoryOf(msg) });
635
+ return { status: r.status, data: { branch: r.data?.branch || '', defaultBranch: r.data?.default_branch || '' } };
636
+ }
637
+
638
+ async function vcsStatus(msg, deps) {
639
+ const r = await deps.shared.extra.vcs.status({ directory: directoryOf(msg) });
640
+ return { status: r.status, data: capFileDiffs(r.data).map(({ patch, ...row }) => row) };
641
+ }
642
+
643
+ // mode 'git': the working tree against HEAD. 'branch': against the default branch.
644
+ async function vcsDiff(msg, deps) {
645
+ const mode = msg.mode === 'branch' ? 'branch' : 'git';
646
+ const r = await deps.shared.extra.vcs.diff({ mode, directory: directoryOf(msg) });
647
+ return { status: r.status, data: capFileDiffs(r.data) };
648
+ }
649
+
650
+ // ── Worktrees ───────────────────────────────────────────────────────────────
651
+
652
+ // worktree.create answers a Worktree { name, branch, directory }; worktree.list
653
+ // answers the directories only (confirmed on 1.18.34).
654
+ function worktreeRow(w) {
655
+ const directory = typeof w === 'string' ? w : (w && typeof w.directory === 'string' ? w.directory : '');
656
+ if (!directory) return null;
657
+ const leaf = directory.split(/[\\/]/).filter(Boolean).pop() || directory;
658
+ return {
659
+ name: typeof w === 'object' && w.name ? String(w.name) : leaf,
660
+ branch: typeof w === 'object' && typeof w.branch === 'string' ? w.branch : '',
661
+ directory,
662
+ };
663
+ }
664
+
665
+ async function worktreeList(msg, deps) {
666
+ if (!directoryOf(msg)) return failure(400, 'cwd is required');
667
+ const r = await deps.shared.extra.worktree.list({ directory: directoryOf(msg) });
668
+ return { status: r.status, data: (Array.isArray(r.data) ? r.data : []).map(worktreeRow).filter(Boolean) };
669
+ }
670
+
671
+ async function worktreeCreate(msg, deps) {
672
+ if (!directoryOf(msg)) return failure(400, 'cwd is required');
673
+ const name = typeof msg.name === 'string' ? msg.name.trim() : '';
674
+ if (name && !/^[A-Za-z0-9][\w.-]{0,63}$/.test(name)) {
675
+ return failure(400, 'A worktree name may use letters, digits, ".", "_" and "-".');
676
+ }
677
+ const r = await deps.shared.extra.worktree.create({
678
+ directory: directoryOf(msg),
679
+ worktreeCreateInput: name ? { name } : {},
680
+ });
681
+ const row = worktreeRow(r.data);
682
+ if (!row) return failure(502, 'OpenCode did not return the new worktree.');
683
+ return { status: r.status, data: row };
684
+ }
685
+
686
+ // Removing deletes a directory, so only one OpenCode itself lists as a worktree
687
+ // of this project is accepted.
688
+ async function worktreeRemove(msg, deps) {
689
+ const cwd = directoryOf(msg);
690
+ const target = typeof msg.directory === 'string' ? msg.directory.trim() : '';
691
+ if (!cwd || !target) return failure(400, 'cwd and directory are required');
692
+ const listed = await deps.shared.extra.worktree.list({ directory: cwd });
693
+ const known = (Array.isArray(listed.data) ? listed.data : []).some((w) => worktreeRow(w)?.directory === target);
694
+ if (!known) return failure(404, 'That directory is not a worktree of this project.');
695
+ const r = await deps.shared.extra.worktree.remove({ directory: cwd, worktreeRemoveInput: { directory: target } });
696
+ return { status: r.status, data: true };
697
+ }
698
+
699
+ // ── Environment: MCP servers, LSP, formatters ───────────────────────────────
700
+
701
+ // SynaBun's own MCP entry is pinned by the runtime (profile, terminal identity,
702
+ // browser ownership): the panel shows it but may not switch it.
703
+ export const MANAGED_MCP_NAMES = Object.freeze(['SynaBun']);
704
+ const isManagedMcpName = (name) => MANAGED_MCP_NAMES.some((managed) => managed.toLowerCase() === String(name).trim().toLowerCase());
705
+
706
+ const MCP_STATUSES = new Set(['connected', 'disabled', 'failed', 'needs_auth', 'needs_client_registration']);
707
+
708
+ /** mcp.status answers `{ [name]: McpStatus }`; the panel takes sorted rows. */
709
+ export function mcpRows(statusMap) {
710
+ const map = statusMap && typeof statusMap === 'object' && !Array.isArray(statusMap) ? statusMap : {};
711
+ return Object.entries(map)
712
+ .map(([name, value]) => {
713
+ const row = {
714
+ name,
715
+ status: MCP_STATUSES.has(value?.status) ? value.status : 'failed',
716
+ managed: MANAGED_MCP_NAMES.includes(name),
717
+ };
718
+ if (typeof value?.error === 'string' && value.error) row.error = value.error.slice(0, 500);
719
+ return row;
720
+ })
721
+ .sort((a, b) => Number(b.managed) - Number(a.managed) || a.name.localeCompare(b.name));
722
+ }
723
+
724
+ const mcpNameOf = (msg) => (typeof msg?.name === 'string' ? msg.name.trim() : '');
725
+
726
+ // The MCP servers of the serve that runs this session's turns.
727
+ async function mcpStatus(msg, deps) {
728
+ const r = await deps.bound(sessionKeyOf(msg)).mcp.status({ directory: directoryOf(msg) });
729
+ return { status: r.status, data: mcpRows(r.data) };
730
+ }
731
+
732
+ async function mcpSwitch(msg, deps, connect) {
733
+ const name = mcpNameOf(msg);
734
+ if (!name) return failure(400, 'MCP server name is required');
735
+ if (isManagedMcpName(name)) return failure(403, `${name} is managed by SynaBun and cannot be switched from the panel.`);
736
+ const client = deps.bound(sessionKeyOf(msg));
737
+ const params = { name, directory: directoryOf(msg) };
738
+ const r = connect ? await client.mcp.connect(params) : await client.mcp.disconnect(params);
739
+ const after = await client.mcp.status({ directory: directoryOf(msg) }).catch(() => null);
740
+ return { status: r.status, data: after ? mcpRows(after.data) : [] };
741
+ }
742
+
743
+ // OAuth for a remote MCP server: OpenCode opens the browser itself and waits
744
+ // for the callback, so the request can take minutes.
745
+ async function mcpAuthenticate(msg, deps) {
746
+ const name = mcpNameOf(msg);
747
+ if (!name) return failure(400, 'MCP server name is required');
748
+ if (isManagedMcpName(name)) return failure(403, `${name} is managed by SynaBun.`);
749
+ const path = `/mcp/${encodeURIComponent(name)}/auth/authenticate${deps.directoryQuery(msg.cwd)}`;
750
+ const r = await deps.proxy('POST', path, {}, 5 * 60 * 1000, deps.baseUrlFor(sessionKeyOf(msg)));
751
+ if (r.status >= 400 || typeof r.data === 'string') {
752
+ return failure(r.status >= 400 ? r.status : 502, proxyErrorText(r.data, 'Authentication did not complete'));
753
+ }
754
+ return { status: r.status, data: r.data };
755
+ }
756
+
757
+ const MCP_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/;
758
+ const stringMap = (value) => value && typeof value === 'object' && !Array.isArray(value)
759
+ && Object.values(value).every((v) => typeof v === 'string');
760
+
761
+ /**
762
+ * A server the user typed into the panel, as OpenCode's `POST /mcp` takes it.
763
+ * `{ command, args?, env? }` → McpLocalConfig, `{ url, headers? }` → McpRemoteConfig.
764
+ * Resolves `{ ok: true, config }` or `{ ok: false, error }`.
765
+ *
766
+ * This validates; it does not rewrite. The executable has to be there, and the
767
+ * command and its arguments have to be text. Past that every word is passed on
768
+ * exactly as it came: an empty argument stays an argument, leading and
769
+ * trailing spaces stay. The config that is registered is also the one that is
770
+ * saved (mcpAdd), so a later serve starts the server with the same argv.
771
+ */
772
+ export function runtimeMcpConfigFor(input) {
773
+ if (!input || typeof input !== 'object') return { ok: false, error: 'A command or a URL is required.' };
774
+ const env = input.environment ?? input.env;
775
+ if (env != null && !stringMap(env)) return { ok: false, error: 'Environment variables must be text.' };
776
+ if (input.headers != null && !stringMap(input.headers)) return { ok: false, error: 'Headers must be text.' };
777
+ if (typeof input.url === 'string' && input.url.trim()) {
778
+ let url;
779
+ try { url = new URL(input.url.trim()); } catch { return { ok: false, error: 'That is not a valid URL.' }; }
780
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') return { ok: false, error: 'An MCP server URL must be http or https.' };
781
+ return { ok: true, config: buildOpencodeRuntimeMcpConfig({ url: url.toString(), headers: input.headers || undefined }) };
782
+ }
783
+ if (input.args != null && !Array.isArray(input.args)) return { ok: false, error: 'Arguments must be a list.' };
784
+ const command = [...(Array.isArray(input.command) ? input.command : [input.command]), ...(input.args || [])];
785
+ if (command[0] === undefined || command[0] === null) return { ok: false, error: 'A command or a URL is required.' };
786
+ if (!command.every((part) => typeof part === 'string')) return { ok: false, error: 'The command and its arguments must be text.' };
787
+ if (!command[0].trim()) return { ok: false, error: 'A command or a URL is required.' };
788
+ return { ok: true, config: buildOpencodeRuntimeMcpConfig({ command, env: env || undefined }) };
789
+ }
790
+
791
+ // mcp.add: register one more MCP server on the serve that runs this session.
792
+ // It lasts as long as that serve. With `persist: true` the same config is then
793
+ // written to the OpenCode config (deps.persistMcp), so later serves start with
794
+ // it. That write starts nothing: the server runs once, where it was registered.
795
+ // (The Settings route, POST /api/opencode/mcp, also registers on the shared
796
+ // serve; a panel that saved through it started a command-based server twice.)
797
+ // A server that did not start is never saved: a typo must not end up in the config.
798
+ async function mcpAdd(msg, deps) {
799
+ const name = mcpNameOf(msg);
800
+ if (!name) return failure(400, 'MCP server name is required');
801
+ if (isManagedMcpName(name)) return failure(403, `${name} is managed by SynaBun and cannot be changed from the panel.`);
802
+ if (!MCP_NAME_RE.test(name)) return failure(400, 'A server name may use letters, digits, ".", "_" and "-".');
803
+ const built = runtimeMcpConfigFor(msg.config);
804
+ if (!built.ok) return failure(400, built.error);
805
+ const r = await deps.bound(sessionKeyOf(msg)).extra.mcp.add({ name, config: built.config, directory: directoryOf(msg) });
806
+ const rows = mcpRows(r.data);
807
+ const reply = { status: r.status, data: rows };
808
+ if (msg.persist !== true) return reply;
809
+ const row = rows.find((entry) => entry.name === name);
810
+ if (r.status >= 400 || !row || row.status === 'failed') return { ...reply, saved: false };
811
+ if (typeof deps.persistMcp !== 'function') return { ...reply, saved: false, saveError: 'This server cannot save MCP servers.' };
812
+ try {
813
+ await deps.persistMcp(name, built.config);
814
+ return { ...reply, saved: true };
815
+ } catch (err) {
816
+ return { ...reply, saved: false, saveError: err?.message || String(err) };
817
+ }
818
+ }
819
+
820
+ const listOr = (value) => (Array.isArray(value) ? value : []);
821
+
822
+ // Language servers and formatters of the session's serve. Each read is
823
+ // independent: one that fails is reported as an empty list.
824
+ async function envStatus(msg, deps) {
825
+ const client = deps.bound(sessionKeyOf(msg));
826
+ const directory = directoryOf(msg);
827
+ const [lsp, formatter, reference] = await Promise.all([
828
+ client.extra.lsp.status({ directory }).catch(() => null),
829
+ client.extra.formatter.status({ directory }).catch(() => null),
830
+ deps.proxy('GET', referencePath(directory), null, 10000, deps.baseUrlFor(sessionKeyOf(msg))).catch(() => null),
831
+ ]);
832
+ return {
833
+ status: 200,
834
+ data: {
835
+ references: reference?.status === 200 ? referenceRows(reference.data) : [],
836
+ lsp: listOr(lsp?.data).map((s) => ({ id: String(s?.id || ''), name: String(s?.name || s?.id || ''), root: String(s?.root || ''), status: String(s?.status || '') })),
837
+ formatter: listOr(formatter?.data).map((f) => ({ name: String(f?.name || ''), extensions: listOr(f?.extensions).filter((e) => typeof e === 'string'), enabled: f?.enabled !== false })),
838
+ },
839
+ };
840
+ }
841
+
842
+ // type → { run, session? }. `session: true` rejects a request without sessionId.
843
+ const HANDLERS = {
844
+ 'session:context': {
845
+ session: true,
846
+ run: async (msg, deps) => {
847
+ const r = await deps.shared.session.context({ sessionID: sessionIdOf(msg) });
848
+ return { status: r.status, data: contextRows(r.data) };
849
+ },
850
+ },
851
+ 'session:compact': { session: true, run: compactSession },
852
+ 'session:status': { session: true, run: sessionStatus },
853
+ 'session:todo': { session: true, run: sessionTodo },
854
+ 'permission:reply': { run: permissionReply },
855
+ 'permission:list': { run: permissionList },
856
+ 'permission:saved:list': { run: permissionSavedList },
857
+ 'permission:saved:remove': { run: permissionSavedRemove },
858
+ 'question:reply': { run: questionReply },
859
+ 'session:revert': { session: true, mutates: true, run: sessionRevert },
860
+ 'session:unrevert': { session: true, mutates: true, run: sessionUnrevert },
861
+ 'session:fork': { session: true, mutates: true, run: sessionFork },
862
+ 'session:children': { session: true, run: sessionChildren },
863
+ 'session:share': { session: true, mutates: true, run: sessionShare },
864
+ 'session:unshare': { session: true, mutates: true, run: sessionUnshare },
865
+ 'session:share:policy': { run: sessionSharePolicy },
866
+ 'message:delete': { session: true, mutates: true, run: messageDelete },
867
+ 'command:list': { run: commandList },
868
+ 'command:run': { session: true, mutates: true, run: commandRun },
869
+ 'session:shell': { session: true, mutates: true, run: sessionShell },
870
+ 'find:files': { run: findFiles },
871
+ 'find:symbols': { run: findSymbols },
872
+ 'resource:list': { run: resourceList },
873
+ 'reference:list': { run: referenceList },
874
+ 'agent:list': { run: agentList },
875
+ 'session:diff': { session: true, run: sessionDiff },
876
+ 'vcs:get': { run: vcsGet },
877
+ 'vcs:status': { run: vcsStatus },
878
+ 'vcs:diff': { run: vcsDiff },
879
+ 'worktree:list': { run: worktreeList },
880
+ 'worktree:create': { run: worktreeCreate },
881
+ 'worktree:remove': { run: worktreeRemove },
882
+ 'mcp:status': { run: mcpStatus },
883
+ 'mcp:connect': { session: true, mutates: true, run: (msg, deps) => mcpSwitch(msg, deps, true) },
884
+ 'mcp:disconnect': { session: true, mutates: true, run: (msg, deps) => mcpSwitch(msg, deps, false) },
885
+ 'mcp:authenticate': { session: true, mutates: true, run: mcpAuthenticate },
886
+ 'mcp:add': { session: true, mutates: true, run: mcpAdd },
887
+ 'env:status': { run: envStatus },
888
+ };
889
+
890
+ // Types added here that change a session. server.js adds them to its
891
+ // native-run and history-clear guard sets, which key on the type name.
892
+ export const OPENCODE_V2_WS_MUTATION_TYPES = Object.freeze(
893
+ Object.keys(HANDLERS).filter((type) => HANDLERS[type].mutates),
894
+ );
895
+
896
+ export const OPENCODE_V2_WS_MODULE_TYPES = Object.freeze(Object.keys(HANDLERS));
897
+
898
+ // Behaviours of an existing type that an older server lacks. Listed next to
899
+ // the types so the panel can gate on them the same way; never a request type.
900
+ export const OPENCODE_V2_WS_FEATURES = Object.freeze([
901
+ 'feature:permission-reply-message', // permission:reply forwards a rejection reason
902
+ 'feature:compact-summarize', // session:compact falls back to session.summarize
903
+ 'feature:session-list-filters', // session:list takes search / archived / roots / limit, rows carry parentID
904
+ 'feature:mcp-add-persist', // mcp:add with persist:true saves the server without starting it a second time
905
+ ]);
906
+
907
+ // The version of the @opencode-ai/sdk this server talks to OpenCode through,
908
+ // for the panel's Versions rows ('' when its package.json cannot be read).
909
+ let _sdkVersion;
910
+ export function opencodeSdkVersion() {
911
+ if (_sdkVersion !== undefined) return _sdkVersion;
912
+ _sdkVersion = '';
913
+ try {
914
+ let dir = dirname(fileURLToPath(import.meta.resolve('@opencode-ai/sdk/v2')));
915
+ for (let i = 0; i < 6 && dir !== dirname(dir); i += 1, dir = dirname(dir)) {
916
+ let pkg = null;
917
+ try { pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')); } catch { /* not the package root */ }
918
+ if (pkg?.name === '@opencode-ai/sdk') { _sdkVersion = String(pkg.version || ''); break; }
919
+ }
920
+ } catch { /* stays '' */ }
921
+ return _sdkVersion;
922
+ }
923
+
924
+ // Everything this server answers, for the panel's feature gating.
925
+ export function opencodeV2WsCapabilities() {
926
+ return [...OPENCODE_V2_WS_INLINE_TYPES, ...OPENCODE_V2_WS_MODULE_TYPES, ...OPENCODE_V2_WS_FEATURES];
927
+ }
928
+
929
+ export function ownsOpencodeV2Request(type) {
930
+ return Object.prototype.hasOwnProperty.call(HANDLERS, type);
931
+ }
932
+
933
+ /** Answer `msg` when its type lives here. Resolves true when it was handled. */
934
+ export async function handleOpencodeV2Request(msg, deps) {
935
+ const type = msg?.type;
936
+ if (!ownsOpencodeV2Request(type)) return false;
937
+ const handler = HANDLERS[type];
938
+ const reply = (body) => deps.send({ type: `${type}:result`, id: msg.id, ...body });
939
+ // server.js has done this already; a caller that has not gets the same id rules.
940
+ const malformed = canonicalizeOpencodeV2Message(msg);
941
+ if (malformed) {
942
+ reply(malformed);
943
+ return true;
944
+ }
945
+ if (handler.session && !sessionIdOf(msg)) {
946
+ reply(failure(400, 'sessionId is required'));
947
+ return true;
948
+ }
949
+ try {
950
+ reply(await handler.run(msg, deps));
951
+ } catch (err) {
952
+ reply(failure(err?.status || 500, err?.message || String(err), err?.tag ? { tag: err.tag } : {}));
953
+ }
954
+ return true;
955
+ }