synabun 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1163) hide show
  1. package/CHANGELOG.md +205 -662
  2. package/LICENSE-COMMERCIAL.md +33 -0
  3. package/NOTICE +17 -0
  4. package/README.md +175 -853
  5. package/THIRD-PARTY-LICENSES.md +136 -0
  6. package/benchmarks/browser-live-results.json +79 -0
  7. package/benchmarks/browser-v2-results.json +258 -0
  8. package/benchmarks/fixtures/browser/README.md +57 -0
  9. package/benchmarks/fixtures/browser/page-state.json +132 -0
  10. package/benchmarks/fixtures/browser/social.json +92 -0
  11. package/benchmarks/fixtures/browser/target.json +319 -0
  12. package/benchmarks/fixtures/desktop/README.md +58 -0
  13. package/benchmarks/fixtures/desktop/abstention.json +59 -0
  14. package/benchmarks/fixtures/desktop/adversarial.json +22 -0
  15. package/benchmarks/fixtures/desktop/forbidden.json +93 -0
  16. package/benchmarks/fixtures/desktop/generate.mjs +1023 -0
  17. package/benchmarks/fixtures/desktop/target.json +136 -0
  18. package/bin/synabun.js +30 -0
  19. package/docs/whatsapp.md +325 -0
  20. package/hooks/claude-code/post-plan.mjs +613 -391
  21. package/hooks/claude-code/post-remember.mjs +246 -122
  22. package/hooks/claude-code/pre-compact.mjs +171 -110
  23. package/hooks/claude-code/pre-task.mjs +133 -0
  24. package/hooks/claude-code/pre-websearch.mjs +15 -4
  25. package/hooks/claude-code/prompt-origin.mjs +94 -0
  26. package/hooks/claude-code/prompt-submit.mjs +1244 -861
  27. package/hooks/claude-code/session-start.mjs +114 -156
  28. package/hooks/claude-code/shared.mjs +1228 -368
  29. package/hooks/claude-code/state.mjs +167 -0
  30. package/hooks/claude-code/stop.mjs +515 -140
  31. package/hooks/claude-code/subagent-start.mjs +154 -0
  32. package/hooks/claude-code/subagent-stop.mjs +102 -0
  33. package/hooks/claude-code/task-gate.mjs +150 -0
  34. package/launcher.mjs +40 -0
  35. package/lib/claude-hooks.js +137 -0
  36. package/lib/claude-usage-audit.js +141 -0
  37. package/lib/client-config-repair.js +145 -0
  38. package/lib/data-home-migration.js +502 -0
  39. package/lib/desktop-pwa.js +206 -0
  40. package/lib/external-tools.js +221 -0
  41. package/lib/first-launch-protection.js +245 -0
  42. package/lib/packaged-runtime.js +110 -0
  43. package/lib/paths.d.ts +21 -0
  44. package/lib/paths.js +103 -0
  45. package/lib/start-launcher.js +1309 -0
  46. package/mcp-server/dist/config.d.ts +22 -0
  47. package/mcp-server/dist/config.d.ts.map +1 -0
  48. package/mcp-server/dist/config.js +109 -0
  49. package/mcp-server/dist/config.js.map +1 -0
  50. package/mcp-server/dist/http.d.ts +30 -0
  51. package/mcp-server/dist/http.d.ts.map +1 -0
  52. package/mcp-server/dist/http.js +276 -0
  53. package/mcp-server/dist/http.js.map +1 -0
  54. package/mcp-server/dist/index.d.ts +48 -0
  55. package/mcp-server/dist/index.d.ts.map +1 -0
  56. package/mcp-server/dist/index.js +538 -0
  57. package/mcp-server/dist/index.js.map +1 -0
  58. package/mcp-server/dist/preload-http.d.ts +3 -0
  59. package/mcp-server/dist/preload-http.d.ts.map +1 -0
  60. package/mcp-server/dist/preload-http.js +28 -0
  61. package/mcp-server/dist/preload-http.js.map +1 -0
  62. package/mcp-server/dist/preload.d.ts +3 -0
  63. package/mcp-server/dist/preload.d.ts.map +1 -0
  64. package/mcp-server/dist/preload.js +32 -0
  65. package/mcp-server/dist/preload.js.map +1 -0
  66. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts +19 -0
  67. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.d.ts.map +1 -0
  68. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js +403 -0
  69. package/mcp-server/dist/scripts/migrate-qdrant-to-sqlite.js.map +1 -0
  70. package/mcp-server/dist/scripts/setup-embeddings.d.ts +3 -0
  71. package/mcp-server/dist/scripts/setup-embeddings.d.ts.map +1 -0
  72. package/mcp-server/dist/scripts/setup-embeddings.js +15 -0
  73. package/mcp-server/dist/scripts/setup-embeddings.js.map +1 -0
  74. package/mcp-server/dist/services/assistant-judgments.d.ts +79 -0
  75. package/mcp-server/dist/services/assistant-judgments.d.ts.map +1 -0
  76. package/mcp-server/dist/services/assistant-judgments.js +128 -0
  77. package/mcp-server/dist/services/assistant-judgments.js.map +1 -0
  78. package/mcp-server/dist/services/browser-assist-gate.d.ts +314 -0
  79. package/mcp-server/dist/services/browser-assist-gate.d.ts.map +1 -0
  80. package/mcp-server/dist/services/browser-assist-gate.js +344 -0
  81. package/mcp-server/dist/services/browser-assist-gate.js.map +1 -0
  82. package/mcp-server/dist/services/browser-assist.d.ts +104 -0
  83. package/mcp-server/dist/services/browser-assist.d.ts.map +1 -0
  84. package/mcp-server/dist/services/browser-assist.js +282 -0
  85. package/mcp-server/dist/services/browser-assist.js.map +1 -0
  86. package/mcp-server/dist/services/browser-bench.d.ts +772 -0
  87. package/mcp-server/dist/services/browser-bench.d.ts.map +1 -0
  88. package/mcp-server/dist/services/browser-bench.js +424 -0
  89. package/mcp-server/dist/services/browser-bench.js.map +1 -0
  90. package/mcp-server/dist/services/browser-judgments.d.ts +196 -0
  91. package/mcp-server/dist/services/browser-judgments.d.ts.map +1 -0
  92. package/mcp-server/dist/services/browser-judgments.js +363 -0
  93. package/mcp-server/dist/services/browser-judgments.js.map +1 -0
  94. package/mcp-server/dist/services/browser-risk.d.ts +166 -0
  95. package/mcp-server/dist/services/browser-risk.d.ts.map +1 -0
  96. package/mcp-server/dist/services/browser-risk.js +458 -0
  97. package/mcp-server/dist/services/browser-risk.js.map +1 -0
  98. package/mcp-server/dist/services/categories.d.ts +61 -0
  99. package/mcp-server/dist/services/categories.d.ts.map +1 -0
  100. package/mcp-server/dist/services/categories.js +377 -0
  101. package/mcp-server/dist/services/categories.js.map +1 -0
  102. package/mcp-server/dist/services/codex-config-heal.d.ts +49 -0
  103. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -0
  104. package/mcp-server/dist/services/codex-config-heal.js +346 -0
  105. package/mcp-server/dist/services/codex-config-heal.js.map +1 -0
  106. package/mcp-server/dist/services/desktop-assist-gate.d.ts +198 -0
  107. package/mcp-server/dist/services/desktop-assist-gate.d.ts.map +1 -0
  108. package/mcp-server/dist/services/desktop-assist-gate.js +202 -0
  109. package/mcp-server/dist/services/desktop-assist-gate.js.map +1 -0
  110. package/mcp-server/dist/services/desktop-assist.d.ts +104 -0
  111. package/mcp-server/dist/services/desktop-assist.d.ts.map +1 -0
  112. package/mcp-server/dist/services/desktop-assist.js +266 -0
  113. package/mcp-server/dist/services/desktop-assist.js.map +1 -0
  114. package/mcp-server/dist/services/desktop-bench.d.ts +553 -0
  115. package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -0
  116. package/mcp-server/dist/services/desktop-bench.js +311 -0
  117. package/mcp-server/dist/services/desktop-bench.js.map +1 -0
  118. package/mcp-server/dist/services/desktop-client.d.ts +23 -0
  119. package/mcp-server/dist/services/desktop-client.d.ts.map +1 -0
  120. package/mcp-server/dist/services/desktop-client.js +79 -0
  121. package/mcp-server/dist/services/desktop-client.js.map +1 -0
  122. package/mcp-server/dist/services/desktop-judgments.d.ts +125 -0
  123. package/mcp-server/dist/services/desktop-judgments.d.ts.map +1 -0
  124. package/mcp-server/dist/services/desktop-judgments.js +177 -0
  125. package/mcp-server/dist/services/desktop-judgments.js.map +1 -0
  126. package/mcp-server/dist/services/desktop-risk.d.ts +283 -0
  127. package/mcp-server/dist/services/desktop-risk.d.ts.map +1 -0
  128. package/mcp-server/dist/services/desktop-risk.js +605 -0
  129. package/mcp-server/dist/services/desktop-risk.js.map +1 -0
  130. package/mcp-server/dist/services/discord.d.ts +112 -0
  131. package/mcp-server/dist/services/discord.d.ts.map +1 -0
  132. package/mcp-server/dist/services/discord.js +477 -0
  133. package/mcp-server/dist/services/discord.js.map +1 -0
  134. package/mcp-server/dist/services/edit-stale.d.ts +81 -0
  135. package/mcp-server/dist/services/edit-stale.d.ts.map +1 -0
  136. package/mcp-server/dist/services/edit-stale.js +358 -0
  137. package/mcp-server/dist/services/edit-stale.js.map +1 -0
  138. package/mcp-server/dist/services/embedding-service.d.ts +16 -0
  139. package/mcp-server/dist/services/embedding-service.d.ts.map +1 -0
  140. package/mcp-server/dist/services/embedding-service.js +126 -0
  141. package/mcp-server/dist/services/embedding-service.js.map +1 -0
  142. package/mcp-server/dist/services/embedding-worker.d.ts +2 -0
  143. package/mcp-server/dist/services/embedding-worker.d.ts.map +1 -0
  144. package/mcp-server/dist/services/embedding-worker.js +52 -0
  145. package/mcp-server/dist/services/embedding-worker.js.map +1 -0
  146. package/mcp-server/dist/services/fb-regions.d.ts +71 -0
  147. package/mcp-server/dist/services/fb-regions.d.ts.map +1 -0
  148. package/mcp-server/dist/services/fb-regions.js +211 -0
  149. package/mcp-server/dist/services/fb-regions.js.map +1 -0
  150. package/mcp-server/dist/services/file-checksums.d.ts +22 -0
  151. package/mcp-server/dist/services/file-checksums.d.ts.map +1 -0
  152. package/mcp-server/dist/services/file-checksums.js +55 -0
  153. package/mcp-server/dist/services/file-checksums.js.map +1 -0
  154. package/mcp-server/dist/services/file-excerpt.d.ts +24 -0
  155. package/mcp-server/dist/services/file-excerpt.d.ts.map +1 -0
  156. package/mcp-server/dist/services/file-excerpt.js +65 -0
  157. package/mcp-server/dist/services/file-excerpt.js.map +1 -0
  158. package/mcp-server/dist/services/identity.d.ts +124 -0
  159. package/mcp-server/dist/services/identity.d.ts.map +1 -0
  160. package/mcp-server/dist/services/identity.js +241 -0
  161. package/mcp-server/dist/services/identity.js.map +1 -0
  162. package/mcp-server/dist/services/local-embeddings.d.ts +2 -0
  163. package/mcp-server/dist/services/local-embeddings.d.ts.map +1 -0
  164. package/mcp-server/dist/services/local-embeddings.js +3 -0
  165. package/mcp-server/dist/services/local-embeddings.js.map +1 -0
  166. package/mcp-server/dist/services/memory-client.d.ts +4 -0
  167. package/mcp-server/dist/services/memory-client.d.ts.map +1 -0
  168. package/mcp-server/dist/services/memory-client.js +27 -0
  169. package/mcp-server/dist/services/memory-client.js.map +1 -0
  170. package/mcp-server/dist/services/memory-judge-backfill.d.ts +135 -0
  171. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -0
  172. package/mcp-server/dist/services/memory-judge-backfill.js +510 -0
  173. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -0
  174. package/mcp-server/dist/services/memory-judgments.d.ts +362 -0
  175. package/mcp-server/dist/services/memory-judgments.d.ts.map +1 -0
  176. package/mcp-server/dist/services/memory-judgments.js +674 -0
  177. package/mcp-server/dist/services/memory-judgments.js.map +1 -0
  178. package/mcp-server/dist/services/memory-maintenance.d.ts +108 -0
  179. package/mcp-server/dist/services/memory-maintenance.d.ts.map +1 -0
  180. package/mcp-server/dist/services/memory-maintenance.js +403 -0
  181. package/mcp-server/dist/services/memory-maintenance.js.map +1 -0
  182. package/mcp-server/dist/services/memory-retrieval.d.ts +66 -0
  183. package/mcp-server/dist/services/memory-retrieval.d.ts.map +1 -0
  184. package/mcp-server/dist/services/memory-retrieval.js +412 -0
  185. package/mcp-server/dist/services/memory-retrieval.js.map +1 -0
  186. package/mcp-server/dist/services/memory-schema.d.ts +16 -0
  187. package/mcp-server/dist/services/memory-schema.d.ts.map +1 -0
  188. package/mcp-server/dist/services/memory-schema.js +282 -0
  189. package/mcp-server/dist/services/memory-schema.js.map +1 -0
  190. package/mcp-server/dist/services/memory-sessions.d.ts +24 -0
  191. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -0
  192. package/mcp-server/dist/services/memory-sessions.js +110 -0
  193. package/mcp-server/dist/services/memory-sessions.js.map +1 -0
  194. package/mcp-server/dist/services/memory-triage.d.ts +60 -0
  195. package/mcp-server/dist/services/memory-triage.d.ts.map +1 -0
  196. package/mcp-server/dist/services/memory-triage.js +189 -0
  197. package/mcp-server/dist/services/memory-triage.js.map +1 -0
  198. package/mcp-server/dist/services/memory-verification.d.ts +24 -0
  199. package/mcp-server/dist/services/memory-verification.d.ts.map +1 -0
  200. package/mcp-server/dist/services/memory-verification.js +92 -0
  201. package/mcp-server/dist/services/memory-verification.js.map +1 -0
  202. package/mcp-server/dist/services/memory-writer.d.ts +26 -0
  203. package/mcp-server/dist/services/memory-writer.d.ts.map +1 -0
  204. package/mcp-server/dist/services/memory-writer.js +126 -0
  205. package/mcp-server/dist/services/memory-writer.js.map +1 -0
  206. package/mcp-server/dist/services/neural-interface.d.ts +439 -0
  207. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -0
  208. package/mcp-server/dist/services/neural-interface.js +1135 -0
  209. package/mcp-server/dist/services/neural-interface.js.map +1 -0
  210. package/mcp-server/dist/services/profiles.d.ts +120 -0
  211. package/mcp-server/dist/services/profiles.d.ts.map +1 -0
  212. package/mcp-server/dist/services/profiles.js +387 -0
  213. package/mcp-server/dist/services/profiles.js.map +1 -0
  214. package/mcp-server/dist/services/secret-gate.d.ts +29 -0
  215. package/mcp-server/dist/services/secret-gate.d.ts.map +1 -0
  216. package/mcp-server/dist/services/secret-gate.js +43 -0
  217. package/mcp-server/dist/services/secret-gate.js.map +1 -0
  218. package/mcp-server/dist/services/server-instructions.d.ts +10 -0
  219. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -0
  220. package/mcp-server/dist/services/server-instructions.js +101 -0
  221. package/mcp-server/dist/services/server-instructions.js.map +1 -0
  222. package/mcp-server/dist/services/sqlite.d.ts +235 -0
  223. package/mcp-server/dist/services/sqlite.d.ts.map +1 -0
  224. package/mcp-server/dist/services/sqlite.js +1185 -0
  225. package/mcp-server/dist/services/sqlite.js.map +1 -0
  226. package/mcp-server/dist/services/typesafe-bench.d.ts +99 -0
  227. package/mcp-server/dist/services/typesafe-bench.d.ts.map +1 -0
  228. package/mcp-server/dist/services/typesafe-bench.js +218 -0
  229. package/mcp-server/dist/services/typesafe-bench.js.map +1 -0
  230. package/mcp-server/dist/services/typesafe-config.d.ts +342 -0
  231. package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -0
  232. package/mcp-server/dist/services/typesafe-config.js +746 -0
  233. package/mcp-server/dist/services/typesafe-config.js.map +1 -0
  234. package/mcp-server/dist/services/typesafe.d.ts +213 -0
  235. package/mcp-server/dist/services/typesafe.d.ts.map +1 -0
  236. package/mcp-server/dist/services/typesafe.js +330 -0
  237. package/mcp-server/dist/services/typesafe.js.map +1 -0
  238. package/mcp-server/dist/services/vector-cache.d.ts +68 -0
  239. package/mcp-server/dist/services/vector-cache.d.ts.map +1 -0
  240. package/mcp-server/dist/services/vector-cache.js +271 -0
  241. package/mcp-server/dist/services/vector-cache.js.map +1 -0
  242. package/mcp-server/dist/services/whiteboard-geometry.d.ts +305 -0
  243. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -0
  244. package/mcp-server/dist/services/whiteboard-geometry.js +666 -0
  245. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -0
  246. package/mcp-server/dist/tools/agents.d.ts +212 -0
  247. package/mcp-server/dist/tools/agents.d.ts.map +1 -0
  248. package/mcp-server/dist/tools/agents.js +407 -0
  249. package/mcp-server/dist/tools/agents.js.map +1 -0
  250. package/mcp-server/dist/tools/bluesky.d.ts +39 -0
  251. package/mcp-server/dist/tools/bluesky.d.ts.map +1 -0
  252. package/mcp-server/dist/tools/bluesky.js +1144 -0
  253. package/mcp-server/dist/tools/bluesky.js.map +1 -0
  254. package/mcp-server/dist/tools/browser-advanced.d.ts +58 -0
  255. package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -0
  256. package/mcp-server/dist/tools/browser-advanced.js +106 -0
  257. package/mcp-server/dist/tools/browser-advanced.js.map +1 -0
  258. package/mcp-server/dist/tools/browser-batch.d.ts +99 -0
  259. package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -0
  260. package/mcp-server/dist/tools/browser-batch.js +187 -0
  261. package/mcp-server/dist/tools/browser-batch.js.map +1 -0
  262. package/mcp-server/dist/tools/browser-cheatsheet.d.ts +21 -0
  263. package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -0
  264. package/mcp-server/dist/tools/browser-cheatsheet.js +144 -0
  265. package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -0
  266. package/mcp-server/dist/tools/browser-interact.d.ts +239 -0
  267. package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -0
  268. package/mcp-server/dist/tools/browser-interact.js +300 -0
  269. package/mcp-server/dist/tools/browser-interact.js.map +1 -0
  270. package/mcp-server/dist/tools/browser-navigate.d.ts +90 -0
  271. package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -0
  272. package/mcp-server/dist/tools/browser-navigate.js +142 -0
  273. package/mcp-server/dist/tools/browser-navigate.js.map +1 -0
  274. package/mcp-server/dist/tools/browser-observe.d.ts +561 -0
  275. package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -0
  276. package/mcp-server/dist/tools/browser-observe.js +2009 -0
  277. package/mcp-server/dist/tools/browser-observe.js.map +1 -0
  278. package/mcp-server/dist/tools/browser.d.ts +34 -0
  279. package/mcp-server/dist/tools/browser.d.ts.map +1 -0
  280. package/mcp-server/dist/tools/browser.js +112 -0
  281. package/mcp-server/dist/tools/browser.js.map +1 -0
  282. package/mcp-server/dist/tools/card-tools.d.ts +82 -0
  283. package/mcp-server/dist/tools/card-tools.d.ts.map +1 -0
  284. package/mcp-server/dist/tools/card-tools.js +137 -0
  285. package/mcp-server/dist/tools/card-tools.js.map +1 -0
  286. package/mcp-server/dist/tools/card.d.ts +8 -0
  287. package/mcp-server/dist/tools/card.d.ts.map +1 -0
  288. package/mcp-server/dist/tools/card.js +16 -0
  289. package/mcp-server/dist/tools/card.js.map +1 -0
  290. package/mcp-server/dist/tools/category.d.ts +32 -0
  291. package/mcp-server/dist/tools/category.d.ts.map +1 -0
  292. package/mcp-server/dist/tools/category.js +290 -0
  293. package/mcp-server/dist/tools/category.js.map +1 -0
  294. package/mcp-server/dist/tools/choice.d.ts +160 -0
  295. package/mcp-server/dist/tools/choice.d.ts.map +1 -0
  296. package/mcp-server/dist/tools/choice.js +80 -0
  297. package/mcp-server/dist/tools/choice.js.map +1 -0
  298. package/mcp-server/dist/tools/computer.d.ts +71 -0
  299. package/mcp-server/dist/tools/computer.d.ts.map +1 -0
  300. package/mcp-server/dist/tools/computer.js +174 -0
  301. package/mcp-server/dist/tools/computer.js.map +1 -0
  302. package/mcp-server/dist/tools/discord-channel.d.ts +44 -0
  303. package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -0
  304. package/mcp-server/dist/tools/discord-channel.js +236 -0
  305. package/mcp-server/dist/tools/discord-channel.js.map +1 -0
  306. package/mcp-server/dist/tools/discord-guild.d.ts +20 -0
  307. package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -0
  308. package/mcp-server/dist/tools/discord-guild.js +138 -0
  309. package/mcp-server/dist/tools/discord-guild.js.map +1 -0
  310. package/mcp-server/dist/tools/discord-member.d.ts +26 -0
  311. package/mcp-server/dist/tools/discord-member.d.ts.map +1 -0
  312. package/mcp-server/dist/tools/discord-member.js +122 -0
  313. package/mcp-server/dist/tools/discord-member.js.map +1 -0
  314. package/mcp-server/dist/tools/discord-message.d.ts +36 -0
  315. package/mcp-server/dist/tools/discord-message.d.ts.map +1 -0
  316. package/mcp-server/dist/tools/discord-message.js +184 -0
  317. package/mcp-server/dist/tools/discord-message.js.map +1 -0
  318. package/mcp-server/dist/tools/discord-onboarding.d.ts +32 -0
  319. package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -0
  320. package/mcp-server/dist/tools/discord-onboarding.js +179 -0
  321. package/mcp-server/dist/tools/discord-onboarding.js.map +1 -0
  322. package/mcp-server/dist/tools/discord-role.d.ts +34 -0
  323. package/mcp-server/dist/tools/discord-role.d.ts.map +1 -0
  324. package/mcp-server/dist/tools/discord-role.js +178 -0
  325. package/mcp-server/dist/tools/discord-role.js.map +1 -0
  326. package/mcp-server/dist/tools/discord-thread.d.ts +28 -0
  327. package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -0
  328. package/mcp-server/dist/tools/discord-thread.js +88 -0
  329. package/mcp-server/dist/tools/discord-thread.js.map +1 -0
  330. package/mcp-server/dist/tools/discord-webhook.d.ts +32 -0
  331. package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -0
  332. package/mcp-server/dist/tools/discord-webhook.js +154 -0
  333. package/mcp-server/dist/tools/discord-webhook.js.map +1 -0
  334. package/mcp-server/dist/tools/discord.d.ts +7 -0
  335. package/mcp-server/dist/tools/discord.d.ts.map +1 -0
  336. package/mcp-server/dist/tools/discord.js +25 -0
  337. package/mcp-server/dist/tools/discord.js.map +1 -0
  338. package/mcp-server/dist/tools/fb-groups.d.ts +98 -0
  339. package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -0
  340. package/mcp-server/dist/tools/fb-groups.js +369 -0
  341. package/mcp-server/dist/tools/fb-groups.js.map +1 -0
  342. package/mcp-server/dist/tools/forget.d.ts +14 -0
  343. package/mcp-server/dist/tools/forget.d.ts.map +1 -0
  344. package/mcp-server/dist/tools/forget.js +26 -0
  345. package/mcp-server/dist/tools/forget.js.map +1 -0
  346. package/mcp-server/dist/tools/git-tools.d.ts +24 -0
  347. package/mcp-server/dist/tools/git-tools.d.ts.map +1 -0
  348. package/mcp-server/dist/tools/git-tools.js +107 -0
  349. package/mcp-server/dist/tools/git-tools.js.map +1 -0
  350. package/mcp-server/dist/tools/git.d.ts +7 -0
  351. package/mcp-server/dist/tools/git.d.ts.map +1 -0
  352. package/mcp-server/dist/tools/git.js +11 -0
  353. package/mcp-server/dist/tools/git.js.map +1 -0
  354. package/mcp-server/dist/tools/gsc/experience.d.ts +135 -0
  355. package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -0
  356. package/mcp-server/dist/tools/gsc/experience.js +351 -0
  357. package/mcp-server/dist/tools/gsc/experience.js.map +1 -0
  358. package/mcp-server/dist/tools/gsc/helpers.d.ts +78 -0
  359. package/mcp-server/dist/tools/gsc/helpers.d.ts.map +1 -0
  360. package/mcp-server/dist/tools/gsc/helpers.js +258 -0
  361. package/mcp-server/dist/tools/gsc/helpers.js.map +1 -0
  362. package/mcp-server/dist/tools/gsc/indexing.d.ts +121 -0
  363. package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -0
  364. package/mcp-server/dist/tools/gsc/indexing.js +357 -0
  365. package/mcp-server/dist/tools/gsc/indexing.js.map +1 -0
  366. package/mcp-server/dist/tools/gsc/inspect.d.ts +78 -0
  367. package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -0
  368. package/mcp-server/dist/tools/gsc/inspect.js +321 -0
  369. package/mcp-server/dist/tools/gsc/inspect.js.map +1 -0
  370. package/mcp-server/dist/tools/gsc/navigate.d.ts +44 -0
  371. package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -0
  372. package/mcp-server/dist/tools/gsc/navigate.js +197 -0
  373. package/mcp-server/dist/tools/gsc/navigate.js.map +1 -0
  374. package/mcp-server/dist/tools/gsc/performance.d.ts +84 -0
  375. package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -0
  376. package/mcp-server/dist/tools/gsc/performance.js +274 -0
  377. package/mcp-server/dist/tools/gsc/performance.js.map +1 -0
  378. package/mcp-server/dist/tools/gsc/settings.d.ts +153 -0
  379. package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -0
  380. package/mcp-server/dist/tools/gsc/settings.js +425 -0
  381. package/mcp-server/dist/tools/gsc/settings.js.map +1 -0
  382. package/mcp-server/dist/tools/gsc.d.ts +7 -0
  383. package/mcp-server/dist/tools/gsc.d.ts.map +1 -0
  384. package/mcp-server/dist/tools/gsc.js +51 -0
  385. package/mcp-server/dist/tools/gsc.js.map +1 -0
  386. package/mcp-server/dist/tools/image-tools.d.ts +24 -0
  387. package/mcp-server/dist/tools/image-tools.d.ts.map +1 -0
  388. package/mcp-server/dist/tools/image-tools.js +80 -0
  389. package/mcp-server/dist/tools/image-tools.js.map +1 -0
  390. package/mcp-server/dist/tools/image.d.ts +10 -0
  391. package/mcp-server/dist/tools/image.d.ts.map +1 -0
  392. package/mcp-server/dist/tools/image.js +14 -0
  393. package/mcp-server/dist/tools/image.js.map +1 -0
  394. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +97 -0
  395. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -0
  396. package/mcp-server/dist/tools/leonardo-browser-tools.js +228 -0
  397. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -0
  398. package/mcp-server/dist/tools/leonardo.d.ts +13 -0
  399. package/mcp-server/dist/tools/leonardo.d.ts.map +1 -0
  400. package/mcp-server/dist/tools/leonardo.js +21 -0
  401. package/mcp-server/dist/tools/leonardo.js.map +1 -0
  402. package/mcp-server/dist/tools/loop.d.ts +30 -0
  403. package/mcp-server/dist/tools/loop.d.ts.map +1 -0
  404. package/mcp-server/dist/tools/loop.js +401 -0
  405. package/mcp-server/dist/tools/loop.js.map +1 -0
  406. package/mcp-server/dist/tools/memories.d.ts +56 -0
  407. package/mcp-server/dist/tools/memories.d.ts.map +1 -0
  408. package/mcp-server/dist/tools/memories.js +171 -0
  409. package/mcp-server/dist/tools/memories.js.map +1 -0
  410. package/mcp-server/dist/tools/morelogin.d.ts +24 -0
  411. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -0
  412. package/mcp-server/dist/tools/morelogin.js +79 -0
  413. package/mcp-server/dist/tools/morelogin.js.map +1 -0
  414. package/mcp-server/dist/tools/profile.d.ts +17 -0
  415. package/mcp-server/dist/tools/profile.d.ts.map +1 -0
  416. package/mcp-server/dist/tools/profile.js +114 -0
  417. package/mcp-server/dist/tools/profile.js.map +1 -0
  418. package/mcp-server/dist/tools/recall.d.ts +71 -0
  419. package/mcp-server/dist/tools/recall.d.ts.map +1 -0
  420. package/mcp-server/dist/tools/recall.js +147 -0
  421. package/mcp-server/dist/tools/recall.js.map +1 -0
  422. package/mcp-server/dist/tools/reflect.d.ts +56 -0
  423. package/mcp-server/dist/tools/reflect.d.ts.map +1 -0
  424. package/mcp-server/dist/tools/reflect.js +157 -0
  425. package/mcp-server/dist/tools/reflect.js.map +1 -0
  426. package/mcp-server/dist/tools/remember.d.ts +62 -0
  427. package/mcp-server/dist/tools/remember.d.ts.map +1 -0
  428. package/mcp-server/dist/tools/remember.js +201 -0
  429. package/mcp-server/dist/tools/remember.js.map +1 -0
  430. package/mcp-server/dist/tools/response.d.ts +23 -0
  431. package/mcp-server/dist/tools/response.d.ts.map +1 -0
  432. package/mcp-server/dist/tools/response.js +24 -0
  433. package/mcp-server/dist/tools/response.js.map +1 -0
  434. package/mcp-server/dist/tools/restore.d.ts +14 -0
  435. package/mcp-server/dist/tools/restore.d.ts.map +1 -0
  436. package/mcp-server/dist/tools/restore.js +23 -0
  437. package/mcp-server/dist/tools/restore.js.map +1 -0
  438. package/mcp-server/dist/tools/style-guide-tools.d.ts +51 -0
  439. package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -0
  440. package/mcp-server/dist/tools/style-guide-tools.js +231 -0
  441. package/mcp-server/dist/tools/style-guide-tools.js.map +1 -0
  442. package/mcp-server/dist/tools/style-guide.d.ts +8 -0
  443. package/mcp-server/dist/tools/style-guide.d.ts.map +1 -0
  444. package/mcp-server/dist/tools/style-guide.js +12 -0
  445. package/mcp-server/dist/tools/style-guide.js.map +1 -0
  446. package/mcp-server/dist/tools/sync.d.ts +20 -0
  447. package/mcp-server/dist/tools/sync.d.ts.map +1 -0
  448. package/mcp-server/dist/tools/sync.js +156 -0
  449. package/mcp-server/dist/tools/sync.js.map +1 -0
  450. package/mcp-server/dist/tools/tictactoe-tools.d.ts +18 -0
  451. package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -0
  452. package/mcp-server/dist/tools/tictactoe-tools.js +78 -0
  453. package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -0
  454. package/mcp-server/dist/tools/tictactoe.d.ts +7 -0
  455. package/mcp-server/dist/tools/tictactoe.d.ts.map +1 -0
  456. package/mcp-server/dist/tools/tictactoe.js +11 -0
  457. package/mcp-server/dist/tools/tictactoe.js.map +1 -0
  458. package/mcp-server/dist/tools/utils.d.ts +19 -0
  459. package/mcp-server/dist/tools/utils.d.ts.map +1 -0
  460. package/mcp-server/dist/tools/utils.js +54 -0
  461. package/mcp-server/dist/tools/utils.js.map +1 -0
  462. package/mcp-server/dist/tools/whiteboard-format.d.ts +88 -0
  463. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -0
  464. package/mcp-server/dist/tools/whiteboard-format.js +337 -0
  465. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -0
  466. package/mcp-server/dist/tools/whiteboard-tools.d.ts +326 -0
  467. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -0
  468. package/mcp-server/dist/tools/whiteboard-tools.js +222 -0
  469. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -0
  470. package/mcp-server/dist/tools/whiteboard.d.ts +8 -0
  471. package/mcp-server/dist/tools/whiteboard.d.ts.map +1 -0
  472. package/mcp-server/dist/tools/whiteboard.js +16 -0
  473. package/mcp-server/dist/tools/whiteboard.js.map +1 -0
  474. package/mcp-server/dist/tools/youtube/analytics.d.ts +46 -0
  475. package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -0
  476. package/mcp-server/dist/tools/youtube/analytics.js +83 -0
  477. package/mcp-server/dist/tools/youtube/analytics.js.map +1 -0
  478. package/mcp-server/dist/tools/youtube/dedup.d.ts +35 -0
  479. package/mcp-server/dist/tools/youtube/dedup.d.ts.map +1 -0
  480. package/mcp-server/dist/tools/youtube/dedup.js +56 -0
  481. package/mcp-server/dist/tools/youtube/dedup.js.map +1 -0
  482. package/mcp-server/dist/tools/youtube/download.d.ts +31 -0
  483. package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -0
  484. package/mcp-server/dist/tools/youtube/download.js +30 -0
  485. package/mcp-server/dist/tools/youtube/download.js.map +1 -0
  486. package/mcp-server/dist/tools/youtube/helpers.d.ts +66 -0
  487. package/mcp-server/dist/tools/youtube/helpers.d.ts.map +1 -0
  488. package/mcp-server/dist/tools/youtube/helpers.js +143 -0
  489. package/mcp-server/dist/tools/youtube/helpers.js.map +1 -0
  490. package/mcp-server/dist/tools/youtube/media.d.ts +43 -0
  491. package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -0
  492. package/mcp-server/dist/tools/youtube/media.js +97 -0
  493. package/mcp-server/dist/tools/youtube/media.js.map +1 -0
  494. package/mcp-server/dist/tools/youtube/metadata.d.ts +33 -0
  495. package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -0
  496. package/mcp-server/dist/tools/youtube/metadata.js +106 -0
  497. package/mcp-server/dist/tools/youtube/metadata.js.map +1 -0
  498. package/mcp-server/dist/tools/youtube/navigate.d.ts +30 -0
  499. package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -0
  500. package/mcp-server/dist/tools/youtube/navigate.js +71 -0
  501. package/mcp-server/dist/tools/youtube/navigate.js.map +1 -0
  502. package/mcp-server/dist/tools/youtube/playlist.d.ts +29 -0
  503. package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -0
  504. package/mcp-server/dist/tools/youtube/playlist.js +128 -0
  505. package/mcp-server/dist/tools/youtube/playlist.js.map +1 -0
  506. package/mcp-server/dist/tools/youtube/schedule.d.ts +31 -0
  507. package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -0
  508. package/mcp-server/dist/tools/youtube/schedule.js +147 -0
  509. package/mcp-server/dist/tools/youtube/schedule.js.map +1 -0
  510. package/mcp-server/dist/tools/youtube/source.d.ts +36 -0
  511. package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -0
  512. package/mcp-server/dist/tools/youtube/source.js +85 -0
  513. package/mcp-server/dist/tools/youtube/source.js.map +1 -0
  514. package/mcp-server/dist/tools/youtube/upload.d.ts +53 -0
  515. package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -0
  516. package/mcp-server/dist/tools/youtube/upload.js +255 -0
  517. package/mcp-server/dist/tools/youtube/upload.js.map +1 -0
  518. package/mcp-server/dist/tools/youtube.d.ts +12 -0
  519. package/mcp-server/dist/tools/youtube.d.ts.map +1 -0
  520. package/mcp-server/dist/tools/youtube.js +38 -0
  521. package/mcp-server/dist/tools/youtube.js.map +1 -0
  522. package/mcp-server/dist/tui.d.ts +3 -0
  523. package/mcp-server/dist/tui.d.ts.map +1 -0
  524. package/mcp-server/dist/tui.js +806 -0
  525. package/mcp-server/dist/tui.js.map +1 -0
  526. package/mcp-server/dist/types.d.ts +77 -0
  527. package/mcp-server/dist/types.d.ts.map +1 -0
  528. package/mcp-server/dist/types.js +2 -0
  529. package/mcp-server/dist/types.js.map +1 -0
  530. package/mcp-server/package-lock.json +4798 -0
  531. package/mcp-server/package.json +55 -38
  532. package/mcp-server/run.mjs +12 -2
  533. package/mcp-server/src/config.ts +48 -3
  534. package/mcp-server/src/http.ts +296 -93
  535. package/mcp-server/src/index.ts +546 -203
  536. package/mcp-server/src/preload-http.ts +19 -18
  537. package/mcp-server/src/preload.ts +19 -18
  538. package/mcp-server/src/scripts/setup-embeddings.ts +9 -0
  539. package/mcp-server/src/services/assistant-judgments.ts +157 -0
  540. package/mcp-server/src/services/browser-assist-gate.ts +383 -0
  541. package/mcp-server/src/services/browser-assist.ts +267 -0
  542. package/mcp-server/src/services/browser-bench.ts +477 -0
  543. package/mcp-server/src/services/browser-judgments.ts +414 -0
  544. package/mcp-server/src/services/browser-risk.ts +484 -0
  545. package/mcp-server/src/services/categories.ts +36 -19
  546. package/mcp-server/src/services/codex-config-heal.ts +403 -0
  547. package/mcp-server/src/services/desktop-assist-gate.ts +251 -0
  548. package/mcp-server/src/services/desktop-assist.ts +308 -0
  549. package/mcp-server/src/services/desktop-bench.ts +372 -0
  550. package/mcp-server/src/services/desktop-client.ts +76 -0
  551. package/mcp-server/src/services/desktop-judgments.ts +218 -0
  552. package/mcp-server/src/services/desktop-risk.ts +743 -0
  553. package/mcp-server/src/services/edit-stale.ts +299 -0
  554. package/mcp-server/src/services/embedding-service.ts +108 -0
  555. package/mcp-server/src/services/embedding-worker.ts +46 -0
  556. package/mcp-server/src/services/fb-regions.ts +221 -0
  557. package/mcp-server/src/services/file-checksums.ts +26 -9
  558. package/mcp-server/src/services/file-excerpt.ts +59 -0
  559. package/mcp-server/src/services/identity.ts +291 -0
  560. package/mcp-server/src/services/local-embeddings.ts +2 -77
  561. package/mcp-server/src/services/memory-client.ts +23 -0
  562. package/mcp-server/src/services/memory-judge-backfill.ts +462 -0
  563. package/mcp-server/src/services/memory-judgments.ts +901 -0
  564. package/mcp-server/src/services/memory-maintenance.ts +360 -0
  565. package/mcp-server/src/services/memory-retrieval.ts +349 -0
  566. package/mcp-server/src/services/memory-schema.ts +280 -0
  567. package/mcp-server/src/services/memory-sessions.ts +87 -0
  568. package/mcp-server/src/services/memory-triage.ts +182 -0
  569. package/mcp-server/src/services/memory-verification.ts +68 -0
  570. package/mcp-server/src/services/memory-writer.ts +125 -0
  571. package/mcp-server/src/services/neural-interface.ts +1217 -73
  572. package/mcp-server/src/services/profiles.ts +428 -0
  573. package/mcp-server/src/services/secret-gate.ts +52 -0
  574. package/mcp-server/src/services/server-instructions.ts +122 -0
  575. package/mcp-server/src/services/sqlite.ts +1456 -823
  576. package/mcp-server/src/services/typesafe-bench.ts +247 -0
  577. package/mcp-server/src/services/typesafe-config.ts +790 -0
  578. package/mcp-server/src/services/typesafe.ts +390 -0
  579. package/mcp-server/src/services/vector-cache.ts +255 -0
  580. package/mcp-server/src/services/whiteboard-geometry.ts +711 -0
  581. package/mcp-server/src/tools/agents.ts +539 -0
  582. package/mcp-server/src/tools/bluesky.ts +1186 -0
  583. package/mcp-server/src/tools/browser-advanced.ts +15 -6
  584. package/mcp-server/src/tools/browser-batch.ts +178 -0
  585. package/mcp-server/src/tools/browser-cheatsheet.ts +155 -0
  586. package/mcp-server/src/tools/browser-interact.ts +362 -255
  587. package/mcp-server/src/tools/browser-navigate.ts +164 -77
  588. package/mcp-server/src/tools/browser-observe.ts +2222 -1330
  589. package/mcp-server/src/tools/browser.ts +181 -107
  590. package/mcp-server/src/tools/card.ts +7 -5
  591. package/mcp-server/src/tools/choice.ts +103 -0
  592. package/mcp-server/src/tools/computer.ts +190 -0
  593. package/mcp-server/src/tools/discord.ts +10 -23
  594. package/mcp-server/src/tools/fb-groups.ts +387 -0
  595. package/mcp-server/src/tools/forget.ts +1 -1
  596. package/mcp-server/src/tools/git.ts +3 -1
  597. package/mcp-server/src/tools/gsc/experience.ts +440 -0
  598. package/mcp-server/src/tools/gsc/helpers.ts +288 -0
  599. package/mcp-server/src/tools/gsc/indexing.ts +495 -0
  600. package/mcp-server/src/tools/gsc/inspect.ts +391 -0
  601. package/mcp-server/src/tools/gsc/navigate.ts +236 -0
  602. package/mcp-server/src/tools/gsc/performance.ts +352 -0
  603. package/mcp-server/src/tools/gsc/settings.ts +564 -0
  604. package/mcp-server/src/tools/gsc.ts +95 -0
  605. package/mcp-server/src/tools/image.ts +3 -1
  606. package/mcp-server/src/tools/leonardo-browser-tools.ts +47 -37
  607. package/mcp-server/src/tools/leonardo.ts +7 -5
  608. package/mcp-server/src/tools/loop.ts +118 -25
  609. package/mcp-server/src/tools/memories.ts +65 -5
  610. package/mcp-server/src/tools/morelogin.ts +81 -0
  611. package/mcp-server/src/tools/profile.ts +122 -0
  612. package/mcp-server/src/tools/recall.ts +105 -261
  613. package/mcp-server/src/tools/reflect.ts +171 -145
  614. package/mcp-server/src/tools/remember.ts +223 -115
  615. package/mcp-server/src/tools/style-guide-tools.ts +250 -0
  616. package/mcp-server/src/tools/style-guide.ts +16 -0
  617. package/mcp-server/src/tools/sync.ts +66 -9
  618. package/mcp-server/src/tools/tictactoe.ts +3 -1
  619. package/mcp-server/src/tools/utils.ts +22 -0
  620. package/mcp-server/src/tools/whiteboard-format.ts +394 -0
  621. package/mcp-server/src/tools/whiteboard-tools.ts +191 -183
  622. package/mcp-server/src/tools/whiteboard.ts +7 -5
  623. package/mcp-server/src/tools/youtube/analytics.ts +106 -0
  624. package/mcp-server/src/tools/youtube/dedup.ts +57 -0
  625. package/mcp-server/src/tools/youtube/download.ts +41 -0
  626. package/mcp-server/src/tools/youtube/helpers.ts +183 -0
  627. package/mcp-server/src/tools/youtube/media.ts +109 -0
  628. package/mcp-server/src/tools/youtube/metadata.ts +112 -0
  629. package/mcp-server/src/tools/youtube/navigate.ts +81 -0
  630. package/mcp-server/src/tools/youtube/playlist.ts +134 -0
  631. package/mcp-server/src/tools/youtube/schedule.ts +158 -0
  632. package/mcp-server/src/tools/youtube/source.ts +101 -0
  633. package/mcp-server/src/tools/youtube/upload.ts +296 -0
  634. package/mcp-server/src/tools/youtube.ts +47 -0
  635. package/mcp-server/src/tui.ts +8 -9
  636. package/neural-interface/games/TicTacToe/1.svg +1 -0
  637. package/neural-interface/games/TicTacToe/2.svg +1 -0
  638. package/neural-interface/games/TicTacToe/3.svg +1 -0
  639. package/neural-interface/games/TicTacToe/4.svg +1 -0
  640. package/neural-interface/games/TicTacToe/5.svg +1 -0
  641. package/neural-interface/games/TicTacToe/6.svg +1 -0
  642. package/neural-interface/games/TicTacToe/7.svg +1 -0
  643. package/neural-interface/games/TicTacToe/8.svg +1 -0
  644. package/neural-interface/games/TicTacToe/9.svg +1 -0
  645. package/neural-interface/games/TicTacToe/Board.svg +1 -0
  646. package/neural-interface/games/TicTacToe/Circle.svg +1 -0
  647. package/neural-interface/games/TicTacToe/Cross.svg +1 -0
  648. package/neural-interface/i18n/en.json +7022 -0
  649. package/neural-interface/i18n/pt-BR.json +7026 -0
  650. package/neural-interface/lib/assistant-api.js +1005 -0
  651. package/neural-interface/lib/assistant-attachments.js +121 -0
  652. package/neural-interface/lib/assistant-brains/claude.js +207 -0
  653. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +43 -0
  654. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +56 -0
  655. package/neural-interface/lib/assistant-brains/codex.js +213 -0
  656. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +47 -0
  657. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +62 -0
  658. package/neural-interface/lib/assistant-brains/opencode.js +320 -0
  659. package/neural-interface/lib/assistant-budget.js +318 -0
  660. package/neural-interface/lib/assistant-catalog.js +731 -0
  661. package/neural-interface/lib/assistant-clarify.js +664 -0
  662. package/neural-interface/lib/assistant-config.js +232 -0
  663. package/neural-interface/lib/assistant-dispatch.js +2744 -0
  664. package/neural-interface/lib/assistant-envelope.js +582 -0
  665. package/neural-interface/lib/assistant-evidence.js +236 -0
  666. package/neural-interface/lib/assistant-hidden-models.js +272 -0
  667. package/neural-interface/lib/assistant-jev.js +117 -0
  668. package/neural-interface/lib/assistant-judgments.js +111 -0
  669. package/neural-interface/lib/assistant-media.js +335 -0
  670. package/neural-interface/lib/assistant-memory.js +398 -0
  671. package/neural-interface/lib/assistant-persona.js +444 -0
  672. package/neural-interface/lib/assistant-plan-permissions.js +448 -0
  673. package/neural-interface/lib/assistant-playbooks/design.md +87 -0
  674. package/neural-interface/lib/assistant-playbooks.js +72 -0
  675. package/neural-interface/lib/assistant-pricing.js +159 -0
  676. package/neural-interface/lib/assistant-route-gate-codex.js +163 -0
  677. package/neural-interface/lib/assistant-route-gate.js +212 -0
  678. package/neural-interface/lib/assistant-router.js +1324 -0
  679. package/neural-interface/lib/assistant-runtime.js +3337 -0
  680. package/neural-interface/lib/assistant-task-prompt.js +472 -0
  681. package/neural-interface/lib/assistant-usage.js +1688 -0
  682. package/neural-interface/lib/augmented-path.js +70 -0
  683. package/neural-interface/lib/automation-storage-migration.js +54 -0
  684. package/neural-interface/lib/backup-service.js +851 -0
  685. package/neural-interface/lib/backup-zip-reader.js +262 -0
  686. package/neural-interface/lib/browser-assist-api.js +41 -0
  687. package/neural-interface/lib/browser-console.js +176 -0
  688. package/neural-interface/lib/browser-execution.js +241 -0
  689. package/neural-interface/lib/browser-extraction.js +191 -0
  690. package/neural-interface/lib/browser-language.js +83 -0
  691. package/neural-interface/lib/browser-screenshot.js +399 -0
  692. package/neural-interface/lib/browser-semantic-context.js +639 -0
  693. package/neural-interface/lib/browser-snapshots.js +192 -0
  694. package/neural-interface/lib/browser-tab-recovery.js +119 -0
  695. package/neural-interface/lib/browser-targets.js +70 -0
  696. package/neural-interface/lib/browser-tool-policy.js +926 -0
  697. package/neural-interface/lib/claude-accounts.js +230 -0
  698. package/neural-interface/lib/claude-agent-bridge.js +3203 -0
  699. package/neural-interface/lib/claude-bypass-policy.js +99 -0
  700. package/neural-interface/lib/claude-executable.js +241 -0
  701. package/neural-interface/lib/claude-history.js +429 -0
  702. package/neural-interface/lib/claude-model-catalog.js +444 -0
  703. package/neural-interface/lib/claude-panel-requests.js +165 -0
  704. package/neural-interface/lib/claude-panel-session.js +272 -0
  705. package/neural-interface/lib/claude-permission-rules.js +153 -0
  706. package/neural-interface/lib/claude-session-cleanup.js +71 -0
  707. package/neural-interface/lib/claude-session-list.js +82 -0
  708. package/neural-interface/lib/claude-session-ops.js +140 -0
  709. package/neural-interface/lib/claude-settings-view.js +51 -0
  710. package/neural-interface/lib/claude-skin-connect.js +79 -0
  711. package/neural-interface/lib/claude-stall-policy.js +7 -0
  712. package/neural-interface/lib/claude-temporary.js +435 -0
  713. package/neural-interface/lib/cli-update-planner.js +312 -0
  714. package/neural-interface/lib/codex-capabilities.d.ts +41 -0
  715. package/neural-interface/lib/codex-capabilities.js +148 -0
  716. package/neural-interface/lib/codex-collaboration-mode.js +17 -0
  717. package/neural-interface/lib/codex-compat-rpc.js +241 -0
  718. package/neural-interface/lib/codex-mcp-approvals.js +56 -0
  719. package/neural-interface/lib/codex-mcp-apps.js +47 -0
  720. package/neural-interface/lib/codex-model-context.js +202 -0
  721. package/neural-interface/lib/codex-plan-store.js +71 -0
  722. package/neural-interface/lib/codex-request-journal.js +242 -0
  723. package/neural-interface/lib/codex-runtime-path.js +213 -0
  724. package/neural-interface/lib/codex-session-catalog.js +231 -0
  725. package/neural-interface/lib/codex-session-settings.js +46 -0
  726. package/neural-interface/lib/codex-sidepanel-permissions.js +110 -0
  727. package/neural-interface/lib/codex-thread-history.js +165 -0
  728. package/neural-interface/lib/codex-user-verification.js +34 -0
  729. package/neural-interface/lib/codex-writer-lifecycle.js +152 -0
  730. package/neural-interface/lib/confined-fs.js +256 -0
  731. package/neural-interface/lib/db.js +922 -0
  732. package/neural-interface/lib/design-md.js +9 -0
  733. package/neural-interface/lib/desktop/api.js +92 -0
  734. package/neural-interface/lib/desktop/audit.js +62 -0
  735. package/neural-interface/lib/desktop/build.js +423 -0
  736. package/neural-interface/lib/desktop/config.js +606 -0
  737. package/neural-interface/lib/desktop/coords.js +76 -0
  738. package/neural-interface/lib/desktop/fake-helper.js +1192 -0
  739. package/neural-interface/lib/desktop/frames.js +77 -0
  740. package/neural-interface/lib/desktop/grants.js +84 -0
  741. package/neural-interface/lib/desktop/guards.js +170 -0
  742. package/neural-interface/lib/desktop/helper/SynabunDesktop.swift +3056 -0
  743. package/neural-interface/lib/desktop/lease.js +51 -0
  744. package/neural-interface/lib/desktop/manager.js +545 -0
  745. package/neural-interface/lib/desktop/press-contexts.js +103 -0
  746. package/neural-interface/lib/desktop/protocol.js +495 -0
  747. package/neural-interface/lib/desktop/service.js +1202 -0
  748. package/neural-interface/lib/effort-levels.js +148 -0
  749. package/neural-interface/lib/event-loop-monitor.js +67 -0
  750. package/neural-interface/lib/exec-loop-command.js +209 -0
  751. package/neural-interface/lib/folder-picker.ps1 +77 -0
  752. package/neural-interface/lib/http-guards.js +287 -0
  753. package/neural-interface/lib/jsonl-lines.js +94 -0
  754. package/neural-interface/lib/loop-logger.js +127 -0
  755. package/neural-interface/lib/mcp-client-config.js +133 -0
  756. package/neural-interface/lib/mcp-installer.js +487 -0
  757. package/neural-interface/lib/mcp-profile-refresh-coordinator.js +78 -0
  758. package/neural-interface/lib/mcp-profile-servers.js +120 -0
  759. package/neural-interface/lib/memo-cache.js +84 -0
  760. package/neural-interface/lib/memory-api.js +758 -0
  761. package/neural-interface/lib/memory-map-api.js +1150 -0
  762. package/neural-interface/lib/memory-map-layout.js +872 -0
  763. package/neural-interface/lib/memory-map-worker.js +165 -0
  764. package/neural-interface/lib/memory-session-capture.js +81 -0
  765. package/neural-interface/lib/memory-timers.js +62 -0
  766. package/neural-interface/lib/morelogin.js +301 -0
  767. package/neural-interface/lib/native-binary-runtime.js +382 -0
  768. package/neural-interface/lib/native-loop-goal.js +33 -0
  769. package/neural-interface/lib/native-loop-providers.js +1002 -0
  770. package/neural-interface/lib/native-loop-runtime.js +747 -0
  771. package/neural-interface/lib/offline-page.js +54 -0
  772. package/neural-interface/lib/opencode-hidden-models.js +113 -0
  773. package/neural-interface/lib/opencode-history.js +253 -0
  774. package/neural-interface/lib/opencode-runtime-config.js +58 -0
  775. package/neural-interface/lib/opencode-v2-client.js +486 -0
  776. package/neural-interface/lib/opencode-v2-ws-requests.js +955 -0
  777. package/neural-interface/lib/path-confine.js +213 -0
  778. package/neural-interface/lib/plugin-installer.js +264 -0
  779. package/neural-interface/lib/project-storage.js +766 -0
  780. package/neural-interface/lib/pty-host/core.js +603 -0
  781. package/neural-interface/lib/pty-host/flow.js +43 -0
  782. package/neural-interface/lib/pty-host/host.js +47 -0
  783. package/neural-interface/lib/pty-host/manager.js +360 -0
  784. package/neural-interface/lib/pty-host/protocol.js +81 -0
  785. package/neural-interface/lib/pty-host/snapshot.js +133 -0
  786. package/neural-interface/lib/remote-policy.js +582 -0
  787. package/neural-interface/lib/rulesets/api.js +175 -0
  788. package/neural-interface/lib/rulesets/fs-safe.js +245 -0
  789. package/neural-interface/lib/rulesets/installer.js +1453 -0
  790. package/neural-interface/lib/rulesets/json-edit.js +186 -0
  791. package/neural-interface/lib/rulesets/lock.js +170 -0
  792. package/neural-interface/lib/rulesets/managed-text.js +314 -0
  793. package/neural-interface/lib/rulesets/normalise.js +24 -0
  794. package/neural-interface/lib/rulesets/render.js +84 -0
  795. package/neural-interface/lib/schedule-launch-intent.js +40 -0
  796. package/neural-interface/lib/session-cache-builder.js +524 -0
  797. package/neural-interface/lib/session-chunker.js +344 -0
  798. package/neural-interface/lib/session-indexer.js +327 -0
  799. package/neural-interface/lib/session-title-generator.js +232 -0
  800. package/neural-interface/lib/skill-prompt-bridge.js +11 -0
  801. package/neural-interface/lib/style-guide/api.js +375 -0
  802. package/neural-interface/lib/style-guide/color.js +352 -0
  803. package/neural-interface/lib/style-guide/export-css.js +99 -0
  804. package/neural-interface/lib/style-guide/export-dtcg.js +209 -0
  805. package/neural-interface/lib/style-guide/export-tailwind.js +102 -0
  806. package/neural-interface/lib/style-guide/fonts.json +227 -0
  807. package/neural-interface/lib/style-guide/import.js +1268 -0
  808. package/neural-interface/lib/style-guide/pointers.js +103 -0
  809. package/neural-interface/lib/style-guide/presets.js +232 -0
  810. package/neural-interface/lib/style-guide/render-design-md.js +319 -0
  811. package/neural-interface/lib/style-guide/schema.js +848 -0
  812. package/neural-interface/lib/style-guide/security.js +43 -0
  813. package/neural-interface/lib/style-guide/store.js +491 -0
  814. package/neural-interface/lib/style-guide/summary.js +106 -0
  815. package/neural-interface/lib/style-guide/tokens.js +170 -0
  816. package/neural-interface/lib/synabun-update-plan.js +324 -0
  817. package/neural-interface/lib/synabun-version.js +179 -0
  818. package/neural-interface/lib/system-restore.js +99 -0
  819. package/neural-interface/lib/terminal-env.js +86 -0
  820. package/neural-interface/lib/ui-blob-store.js +106 -0
  821. package/neural-interface/lib/vector-cache.js +2 -0
  822. package/neural-interface/lib/virtual-socket.js +60 -0
  823. package/neural-interface/lib/whatsapp/api.js +146 -0
  824. package/neural-interface/lib/whatsapp/auth-store.js +389 -0
  825. package/neural-interface/lib/whatsapp/baileys-adapter.js +457 -0
  826. package/neural-interface/lib/whatsapp/brain.js +128 -0
  827. package/neural-interface/lib/whatsapp/bridge.js +1499 -0
  828. package/neural-interface/lib/whatsapp/cards.js +519 -0
  829. package/neural-interface/lib/whatsapp/commands.js +92 -0
  830. package/neural-interface/lib/whatsapp/config.js +291 -0
  831. package/neural-interface/lib/whatsapp/connector/entry.mjs +25 -0
  832. package/neural-interface/lib/whatsapp/connector/manifest.json +6 -0
  833. package/neural-interface/lib/whatsapp/connector/npm-shrinkwrap.json +717 -0
  834. package/neural-interface/lib/whatsapp/connector/package.json +8 -0
  835. package/neural-interface/lib/whatsapp/fake-baileys.js +444 -0
  836. package/neural-interface/lib/whatsapp/format.js +552 -0
  837. package/neural-interface/lib/whatsapp/host-core.js +1225 -0
  838. package/neural-interface/lib/whatsapp/host.js +119 -0
  839. package/neural-interface/lib/whatsapp/identity.js +288 -0
  840. package/neural-interface/lib/whatsapp/inbound.js +149 -0
  841. package/neural-interface/lib/whatsapp/installer.js +562 -0
  842. package/neural-interface/lib/whatsapp/manager.js +638 -0
  843. package/neural-interface/lib/whatsapp/paths.js +81 -0
  844. package/neural-interface/lib/whatsapp/protocol.js +327 -0
  845. package/neural-interface/lib/whatsapp/qr-svg.js +57 -0
  846. package/neural-interface/lib/whatsapp/redact.js +130 -0
  847. package/neural-interface/lib/whatsapp/service.js +1305 -0
  848. package/neural-interface/lib/whatsapp/vendor/qrcodegen.js +848 -0
  849. package/neural-interface/package-lock.json +4431 -0
  850. package/neural-interface/package.json +58 -27
  851. package/neural-interface/public/apple-touch-icon.png +0 -0
  852. package/neural-interface/public/category-logos/synabun.png +0 -0
  853. package/neural-interface/public/claude.svg +1 -0
  854. package/neural-interface/public/favicon-16x16.png +0 -0
  855. package/neural-interface/public/favicon-32x32.png +0 -0
  856. package/neural-interface/public/icon-192.png +0 -0
  857. package/neural-interface/public/icon-512.png +0 -0
  858. package/neural-interface/public/index.html +32 -182
  859. package/neural-interface/public/index2d.html +2 -2
  860. package/neural-interface/public/install-app.html +31 -0
  861. package/neural-interface/public/logo-synabun.png +0 -0
  862. package/neural-interface/public/logoHD.png +0 -0
  863. package/neural-interface/public/manifest.json +2 -0
  864. package/neural-interface/public/mcp.svg +4 -0
  865. package/neural-interface/public/offline.html +670 -299
  866. package/neural-interface/public/onboarding.html +804 -161
  867. package/neural-interface/public/opencode-logo-dark-square.svg +1 -0
  868. package/neural-interface/public/shared/agent-runtime-options.js +596 -0
  869. package/neural-interface/public/shared/api.js +339 -28
  870. package/neural-interface/public/shared/assistant/asst-accounts.js +318 -0
  871. package/neural-interface/public/shared/assistant/asst-agents-dock.js +296 -0
  872. package/neural-interface/public/shared/assistant/asst-api.js +270 -0
  873. package/neural-interface/public/shared/assistant/asst-brain-picker.js +744 -0
  874. package/neural-interface/public/shared/assistant/asst-budget.js +333 -0
  875. package/neural-interface/public/shared/assistant/asst-composer.js +656 -0
  876. package/neural-interface/public/shared/assistant/asst-computer.js +803 -0
  877. package/neural-interface/public/shared/assistant/asst-control.js +1018 -0
  878. package/neural-interface/public/shared/assistant/asst-hosts.js +262 -0
  879. package/neural-interface/public/shared/assistant/asst-mascot.js +313 -0
  880. package/neural-interface/public/shared/assistant/asst-menu.js +375 -0
  881. package/neural-interface/public/shared/assistant/asst-panel.js +1845 -0
  882. package/neural-interface/public/shared/assistant/asst-rack-styles.js +586 -0
  883. package/neural-interface/public/shared/assistant/asst-render.js +3305 -0
  884. package/neural-interface/public/shared/assistant/asst-route.js +1653 -0
  885. package/neural-interface/public/shared/assistant/asst-roving.js +75 -0
  886. package/neural-interface/public/shared/assistant/asst-sanitize.js +117 -0
  887. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +488 -0
  888. package/neural-interface/public/shared/assistant/asst-sidepanel.js +675 -0
  889. package/neural-interface/public/shared/assistant/asst-slash.js +258 -0
  890. package/neural-interface/public/shared/assistant/asst-state.js +727 -0
  891. package/neural-interface/public/shared/assistant/asst-styles.js +1686 -0
  892. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +1017 -0
  893. package/neural-interface/public/shared/assistant/asst-usage.js +444 -0
  894. package/neural-interface/public/shared/assistant/asst-ws.js +175 -0
  895. package/neural-interface/public/shared/automation-context.js +75 -0
  896. package/neural-interface/public/shared/blob-store.js +99 -0
  897. package/neural-interface/public/shared/cdx/cdx-capabilities.js +118 -0
  898. package/neural-interface/public/shared/cdx/cdx-cards.js +37 -0
  899. package/neural-interface/public/shared/cdx/cdx-commands.js +171 -0
  900. package/neural-interface/public/shared/cdx/cdx-context-menu.js +402 -0
  901. package/neural-interface/public/shared/cdx/cdx-context-model.js +220 -0
  902. package/neural-interface/public/shared/cdx/cdx-features.js +408 -0
  903. package/neural-interface/public/shared/cdx/cdx-icons.js +89 -0
  904. package/neural-interface/public/shared/cdx/cdx-mcp-app-host.js +414 -0
  905. package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.html +6 -0
  906. package/neural-interface/public/shared/cdx/cdx-mcp-app-proxy.js +56 -0
  907. package/neural-interface/public/shared/cdx/cdx-mcp-app.js +178 -0
  908. package/neural-interface/public/shared/cdx/cdx-model-catalog.js +120 -0
  909. package/neural-interface/public/shared/cdx/cdx-output-model.js +261 -0
  910. package/neural-interface/public/shared/cdx/cdx-output.js +382 -0
  911. package/neural-interface/public/shared/cdx/cdx-panel.js +1372 -0
  912. package/neural-interface/public/shared/cdx/cdx-plan.js +266 -0
  913. package/neural-interface/public/shared/cdx/cdx-protocol.js +682 -0
  914. package/neural-interface/public/shared/cdx/cdx-render.js +3381 -0
  915. package/neural-interface/public/shared/cdx/cdx-requests.js +1136 -0
  916. package/neural-interface/public/shared/cdx/cdx-styles.js +3251 -0
  917. package/neural-interface/public/shared/cdx/cdx-tabs.js +7992 -0
  918. package/neural-interface/public/shared/cdx/cdx-ws.js +363 -0
  919. package/neural-interface/public/shared/cli-status.js +169 -0
  920. package/neural-interface/public/shared/command-runner-model.js +30 -0
  921. package/neural-interface/public/shared/constants.js +22 -5
  922. package/neural-interface/public/shared/cp/cp-agents.js +186 -0
  923. package/neural-interface/public/shared/cp/cp-bash.js +252 -0
  924. package/neural-interface/public/shared/cp/cp-compose.js +159 -0
  925. package/neural-interface/public/shared/cp/cp-context-menu.js +309 -0
  926. package/neural-interface/public/shared/cp/cp-context-model.js +157 -0
  927. package/neural-interface/public/shared/cp/cp-context-window.js +80 -0
  928. package/neural-interface/public/shared/cp/cp-ctx.js +11 -0
  929. package/neural-interface/public/shared/cp/cp-diff.js +255 -0
  930. package/neural-interface/public/shared/cp/cp-event-rows.js +637 -0
  931. package/neural-interface/public/shared/cp/cp-events.js +846 -0
  932. package/neural-interface/public/shared/cp/cp-markdown.js +104 -0
  933. package/neural-interface/public/shared/cp/cp-permission-model.js +905 -0
  934. package/neural-interface/public/shared/cp/cp-permissions.js +626 -0
  935. package/neural-interface/public/shared/cp/cp-rehydrate.js +113 -0
  936. package/neural-interface/public/shared/cp/cp-restore.js +224 -0
  937. package/neural-interface/public/shared/cp/cp-session-model.js +338 -0
  938. package/neural-interface/public/shared/cp/cp-session-settings.js +254 -0
  939. package/neural-interface/public/shared/cp/cp-sessions.js +227 -0
  940. package/neural-interface/public/shared/cp/cp-statusline.js +153 -0
  941. package/neural-interface/public/shared/cp/cp-styles.js +349 -0
  942. package/neural-interface/public/shared/cp/cp-tasks-model.js +282 -0
  943. package/neural-interface/public/shared/cp/cp-tasks.js +107 -0
  944. package/neural-interface/public/shared/cp/cp-temporary-view.js +56 -0
  945. package/neural-interface/public/shared/cp/cp-temporary.js +231 -0
  946. package/neural-interface/public/shared/cp/cp-tool-cards.js +326 -0
  947. package/neural-interface/public/shared/cp/cp-tool-results.js +618 -0
  948. package/neural-interface/public/shared/cp/cp-usage-model.js +124 -0
  949. package/neural-interface/public/shared/graph-activity.js +68 -0
  950. package/neural-interface/public/shared/html-shell.js +116 -17
  951. package/neural-interface/public/shared/i18n.js +132 -34
  952. package/neural-interface/public/shared/node-positions-store.js +44 -0
  953. package/neural-interface/public/shared/ocp-hidden-models.js +116 -0
  954. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +355 -0
  955. package/neural-interface/public/shared/ocp-v2/ocp-v2-autoaccept-button.js +35 -0
  956. package/neural-interface/public/shared/ocp-v2/ocp-v2-automation-ownership.js +72 -0
  957. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +280 -0
  958. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +67 -0
  959. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +179 -0
  960. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes.js +164 -0
  961. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +725 -0
  962. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +75 -0
  963. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +1204 -0
  964. package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm-logic.js +117 -0
  965. package/neural-interface/public/shared/ocp-v2/ocp-v2-confirm.js +59 -0
  966. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-gauge.js +252 -0
  967. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +478 -0
  968. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +179 -0
  969. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +233 -0
  970. package/neural-interface/public/shared/ocp-v2/ocp-v2-icons.js +30 -0
  971. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +1065 -0
  972. package/neural-interface/public/shared/ocp-v2/ocp-v2-mention-hints.js +182 -0
  973. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +655 -0
  974. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +2636 -0
  975. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +601 -0
  976. package/neural-interface/public/shared/ocp-v2/ocp-v2-profile-inheritance.js +78 -0
  977. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +649 -0
  978. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +35 -0
  979. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +357 -0
  980. package/neural-interface/public/shared/ocp-v2/ocp-v2-render-logic.js +189 -0
  981. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1869 -0
  982. package/neural-interface/public/shared/ocp-v2/ocp-v2-select.js +42 -0
  983. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +117 -0
  984. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +1714 -0
  985. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +468 -0
  986. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-widgets.js +63 -0
  987. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +366 -0
  988. package/neural-interface/public/shared/ocp-v2/ocp-v2-settings-link.js +19 -0
  989. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +343 -0
  990. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +746 -0
  991. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +347 -0
  992. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +338 -0
  993. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +3543 -0
  994. package/neural-interface/public/shared/ocp-v2/ocp-v2-subagents-logic.js +482 -0
  995. package/neural-interface/public/shared/ocp-v2/ocp-v2-tools-logic.js +351 -0
  996. package/neural-interface/public/shared/ocp-v2/ocp-v2-tools.js +168 -0
  997. package/neural-interface/public/shared/ocp-v2/ocp-v2-variantpicker.js +315 -0
  998. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +545 -0
  999. package/neural-interface/public/shared/provider-icons.js +30 -0
  1000. package/neural-interface/public/shared/pwa-install-page.js +34 -0
  1001. package/neural-interface/public/shared/pwa-install.css +12 -0
  1002. package/neural-interface/public/shared/pwa-install.js +28 -0
  1003. package/neural-interface/public/shared/session-title.js +100 -0
  1004. package/neural-interface/public/shared/settings/settings-ia.js +389 -0
  1005. package/neural-interface/public/shared/settings/settings-kit.js +234 -0
  1006. package/neural-interface/public/shared/settings/settings-rules.js +160 -0
  1007. package/neural-interface/public/shared/settings/settings-search.js +463 -0
  1008. package/neural-interface/public/shared/settings/settings-shell.js +570 -0
  1009. package/neural-interface/public/shared/start-bridge.js +583 -0
  1010. package/neural-interface/public/shared/state.js +5 -0
  1011. package/neural-interface/public/shared/storage.js +50 -7
  1012. package/neural-interface/public/shared/styleguide/sg-agents.js +42 -0
  1013. package/neural-interface/public/shared/styleguide/sg-brand.js +4 -0
  1014. package/neural-interface/public/shared/styleguide/sg-color-client.js +388 -0
  1015. package/neural-interface/public/shared/styleguide/sg-colors.js +151 -0
  1016. package/neural-interface/public/shared/styleguide/sg-components.js +35 -0
  1017. package/neural-interface/public/shared/styleguide/sg-history.js +41 -0
  1018. package/neural-interface/public/shared/styleguide/sg-icons-logo.js +38 -0
  1019. package/neural-interface/public/shared/styleguide/sg-imagery.js +4 -0
  1020. package/neural-interface/public/shared/styleguide/sg-import-export.js +48 -0
  1021. package/neural-interface/public/shared/styleguide/sg-kit.js +284 -0
  1022. package/neural-interface/public/shared/styleguide/sg-labels.js +318 -0
  1023. package/neural-interface/public/shared/styleguide/sg-layout.js +4 -0
  1024. package/neural-interface/public/shared/styleguide/sg-motion.js +5 -0
  1025. package/neural-interface/public/shared/styleguide/sg-panel.js +237 -0
  1026. package/neural-interface/public/shared/styleguide/sg-preview.js +138 -0
  1027. package/neural-interface/public/shared/styleguide/sg-rules.js +9 -0
  1028. package/neural-interface/public/shared/styleguide/sg-shape.js +24 -0
  1029. package/neural-interface/public/shared/styleguide/sg-state.js +132 -0
  1030. package/neural-interface/public/shared/styleguide/sg-typography.js +125 -0
  1031. package/neural-interface/public/shared/styles.css +8614 -1477
  1032. package/neural-interface/public/shared/synabun-mascot.js +1625 -0
  1033. package/neural-interface/public/shared/synabun-ticker.js +376 -0
  1034. package/neural-interface/public/shared/term-ready.js +307 -0
  1035. package/neural-interface/public/shared/term-renderer.js +343 -0
  1036. package/neural-interface/public/shared/ui-assistant-panel.js +10 -0
  1037. package/neural-interface/public/shared/ui-assistant.js +77 -0
  1038. package/neural-interface/public/shared/ui-automation-studio.js +5105 -3573
  1039. package/neural-interface/public/shared/ui-claude-panel.js +11685 -6333
  1040. package/neural-interface/public/shared/ui-codex-panel.js +12 -0
  1041. package/neural-interface/public/shared/ui-command-runner.js +251 -468
  1042. package/neural-interface/public/shared/ui-cost-widget.js +55 -34
  1043. package/neural-interface/public/shared/ui-detail.js +77 -14
  1044. package/neural-interface/public/shared/ui-explorer.js +360 -181
  1045. package/neural-interface/public/shared/ui-file-explorer.js +485 -107
  1046. package/neural-interface/public/shared/ui-help.js +2 -2
  1047. package/neural-interface/public/shared/ui-image-gallery.js +45 -21
  1048. package/neural-interface/public/shared/ui-judgments.js +1346 -0
  1049. package/neural-interface/public/shared/ui-keybinds.js +3 -2
  1050. package/neural-interface/public/shared/ui-link.js +105 -51
  1051. package/neural-interface/public/shared/ui-loading.js +222 -11
  1052. package/neural-interface/public/shared/ui-memory-maintenance.js +111 -0
  1053. package/neural-interface/public/shared/ui-menubar.js +100 -31
  1054. package/neural-interface/public/shared/ui-native-loop-router-state.js +94 -0
  1055. package/neural-interface/public/shared/ui-native-loop-router.js +493 -0
  1056. package/neural-interface/public/shared/ui-native-window-id.js +7 -0
  1057. package/neural-interface/public/shared/ui-navbar.js +357 -222
  1058. package/neural-interface/public/shared/ui-notifications.js +58 -12
  1059. package/neural-interface/public/shared/ui-opencode-panel-v2.js +17 -0
  1060. package/neural-interface/public/shared/ui-panels.js +15 -7
  1061. package/neural-interface/public/shared/ui-resume.js +823 -653
  1062. package/neural-interface/public/shared/ui-schedule-queue.js +172 -0
  1063. package/neural-interface/public/shared/ui-schedules-studio.js +1882 -0
  1064. package/neural-interface/public/shared/ui-scroll-follow.js +194 -0
  1065. package/neural-interface/public/shared/ui-sessions.js +789 -34
  1066. package/neural-interface/public/shared/ui-settings.js +5774 -2194
  1067. package/neural-interface/public/shared/ui-sidepanel-layout.js +109 -0
  1068. package/neural-interface/public/shared/ui-sidepanel-runtime.js +19 -0
  1069. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +40 -0
  1070. package/neural-interface/public/shared/ui-sidepanel-sessions.js +221 -0
  1071. package/neural-interface/public/shared/ui-sidepanel-state.js +131 -0
  1072. package/neural-interface/public/shared/ui-sidepanel-tray.js +547 -0
  1073. package/neural-interface/public/shared/ui-sidepanel-windows.js +387 -0
  1074. package/neural-interface/public/shared/ui-skills.js +18 -32
  1075. package/neural-interface/public/shared/ui-styleguide.js +35 -0
  1076. package/neural-interface/public/shared/ui-sync.js +87 -0
  1077. package/neural-interface/public/shared/ui-terminal.js +7863 -6385
  1078. package/neural-interface/public/shared/ui-tool-updates.js +292 -0
  1079. package/neural-interface/public/shared/ui-tooltip.js +156 -15
  1080. package/neural-interface/public/shared/ui-tutorial-draw.js +119 -683
  1081. package/neural-interface/public/shared/ui-tutorial-layout.js +135 -0
  1082. package/neural-interface/public/shared/ui-tutorial-steps.js +59 -2209
  1083. package/neural-interface/public/shared/ui-tutorial.css +102 -0
  1084. package/neural-interface/public/shared/ui-tutorial.js +557 -1076
  1085. package/neural-interface/public/shared/ui-update.js +420 -68
  1086. package/neural-interface/public/shared/ui-whatsapp.js +941 -0
  1087. package/neural-interface/public/shared/ui-whiteboard.js +1076 -233
  1088. package/neural-interface/public/shared/ui-workspaces.js +2 -1
  1089. package/neural-interface/public/shared/utils.js +58 -0
  1090. package/neural-interface/public/shared/vterm-buffer.js +15 -5
  1091. package/neural-interface/public/shared/whatsapp/wa-phone.js +65 -0
  1092. package/neural-interface/public/shared/whatsapp/wa-view.js +411 -0
  1093. package/neural-interface/public/sidepanel-session.html +18 -0
  1094. package/neural-interface/public/sw.js +10 -2
  1095. package/neural-interface/public/synabun.png +0 -0
  1096. package/neural-interface/public/variant/2d/graph.js +1707 -1635
  1097. package/neural-interface/public/variant/2d/lasso.js +2 -1
  1098. package/neural-interface/public/variant/2d/layout.js +595 -594
  1099. package/neural-interface/public/variant/2d/main.js +557 -521
  1100. package/neural-interface/public/variant/2d/settings-gfx.js +18 -24
  1101. package/neural-interface/public/variant/3d/main.js +517 -500
  1102. package/neural-interface/public/variant/3d/map-controls.js +144 -0
  1103. package/neural-interface/public/variant/3d/map-data.js +251 -0
  1104. package/neural-interface/public/variant/3d/map-labels.js +241 -0
  1105. package/neural-interface/public/variant/3d/map-pick.js +90 -0
  1106. package/neural-interface/public/variant/3d/map-renderer.js +521 -0
  1107. package/neural-interface/public/variant/3d/map-shaders.js +158 -0
  1108. package/neural-interface/public/variant/3d/map-view.js +618 -0
  1109. package/neural-interface/public/vendor/three/manifest.json +3 -0
  1110. package/neural-interface/public/vendor/three/three-0.169.0.min.js +3844 -0
  1111. package/neural-interface/public/vendor/xterm/manifest.json +3 -0
  1112. package/neural-interface/public/vendor/xterm/xterm-6.0.0.css +285 -0
  1113. package/neural-interface/public/vendor/xterm/xterm-6.0.0.min.js +192 -0
  1114. package/neural-interface/scripts/build-vendor.mjs +64 -0
  1115. package/neural-interface/scripts/codex-protocol-fixture.mjs +83 -0
  1116. package/neural-interface/scripts/rebuild-pty.js +39 -22
  1117. package/neural-interface/scripts/vendor-three-entry.js +24 -0
  1118. package/neural-interface/scripts/vendor-xterm-entry.js +8 -0
  1119. package/neural-interface/server.js +33983 -15000
  1120. package/neural-interface/skins/default/skin.css +90 -0
  1121. package/neural-interface/skins/default/skin.json +8 -0
  1122. package/neural-interface/templates/rulesets/README.md +9 -0
  1123. package/neural-interface/templates/rulesets/claude.md +3 -0
  1124. package/neural-interface/templates/rulesets/codex.md +2 -0
  1125. package/neural-interface/templates/rulesets/coexistence.md +6 -0
  1126. package/neural-interface/templates/rulesets/core.md +26 -0
  1127. package/neural-interface/templates/rulesets/cursor.md +2 -0
  1128. package/neural-interface/templates/rulesets/gemini.md +2 -0
  1129. package/neural-interface/templates/rulesets/legacy-hashes.json +227 -0
  1130. package/neural-interface/templates/rulesets/manifest.json +12 -0
  1131. package/neural-interface/templates/rulesets/opencode.md +2 -0
  1132. package/package.json +131 -53
  1133. package/postinstall.js +55 -26
  1134. package/preuninstall.js +187 -0
  1135. package/scripts/restore-data-home-from-backup.mjs +239 -0
  1136. package/setup.js +872 -260
  1137. package/skills/leonardo/SKILL.md +19 -10
  1138. package/skills/leonardo/modules/image-prompter.md +18 -12
  1139. package/skills/leonardo/modules/video-prompter.md +19 -13
  1140. package/skills/synabun/SKILL.md +209 -185
  1141. package/skills/synabun/icon.png +0 -0
  1142. package/skills/synabun/modules/audit.md +380 -374
  1143. package/skills/synabun/modules/changelog.md +15 -6
  1144. package/skills/synabun/modules/idea.md +148 -144
  1145. package/skills/synabun/modules/memorize.md +13 -4
  1146. package/skills/synabun/modules/schedule.md +198 -0
  1147. package/skills/synabun/synabunicon.png +0 -0
  1148. package/updater.cmd +31 -0
  1149. package/updater.mjs +382 -0
  1150. package/updater.sh +29 -0
  1151. package/hooks/claude-code/test-user-learning.mjs +0 -531
  1152. package/neural-interface/public/claude-chat.css +0 -878
  1153. package/neural-interface/public/claude-chat.html +0 -92
  1154. package/neural-interface/public/claude-chat.js +0 -1168
  1155. package/neural-interface/public/index-legacy.html +0 -14677
  1156. package/neural-interface/public/index2d-legacy.html +0 -8193
  1157. package/neural-interface/public/shared/html-term-renderer.js +0 -1022
  1158. package/neural-interface/public/variant/3d/background.js +0 -884
  1159. package/neural-interface/public/variant/3d/camera.js +0 -661
  1160. package/neural-interface/public/variant/3d/gfx.js +0 -116
  1161. package/neural-interface/public/variant/3d/graph.js +0 -2399
  1162. package/neural-interface/public/variant/3d/settings-gfx.js +0 -228
  1163. package/neural-interface/templates/CLAUDE-template.md +0 -211
@@ -1,3 +1,4 @@
1
+ import { sendToFocusedSession } from './ui-sidepanel-windows.js';
1
2
  // ═══════════════════════════════════════════
2
3
  // SynaBun Neural Interface — File Explorer
3
4
  // ═══════════════════════════════════════════
@@ -8,8 +9,30 @@
8
9
  import { KEYS } from './constants.js';
9
10
  import { registerAction } from './ui-keybinds.js';
10
11
  import { storage } from './storage.js';
11
- import { sendToPanel } from './ui-claude-panel.js';
12
- import { on, emit } from './state.js';
12
+ import { sendToPanel as sendToClaudePanel } from './ui-claude-panel.js';
13
+ import { attachPathToOpencode } from './ui-opencode-panel-v2.js';
14
+ import { isCodexPanelOpen, toggleCodexPanel } from './cdx/cdx-panel.js';
15
+ import { addPathChip as addCodexPathChip } from './cdx/cdx-tabs.js';
16
+ import { on, emit, state } from './state.js';
17
+ import { debounce, rafThrottle } from './utils.js';
18
+
19
+ // Route to the most recently focused provider, even when several panels
20
+ // are visible. The provider opens if minimized and attaches its native path chip.
21
+ async function sendPathToActivePanel(filePath) {
22
+ if (sendToFocusedSession('path', filePath)) return;
23
+ const target = state.lastActivePanel || 'claude';
24
+
25
+ // The Assistant sidepanel: through the bus (a static import would close an import cycle).
26
+ if (target === 'assistant') { emit('assistant:attach-path', { path: filePath }); return; }
27
+ if (target === 'opencode') {
28
+ await attachPathToOpencode(filePath);
29
+ } else if (target === 'codex') {
30
+ if (!isCodexPanelOpen()) await toggleCodexPanel();
31
+ addCodexPathChip(filePath);
32
+ } else {
33
+ await sendToClaudePanel(filePath);
34
+ }
35
+ }
13
36
 
14
37
  const $ = (id) => document.getElementById(id);
15
38
 
@@ -39,12 +62,43 @@ let _folderColors = {}; // { "/path/to/folder": "#hex" }
39
62
  let _customIcons = null; // { extensions: {}, filenames: {} } from server
40
63
  let _planEditMode = false; // true when editing a plan file from Claude panel
41
64
  let _planEditFilePath = null; // path of the plan file being edited
65
+ let _planEditSource = null; // panel that opened the plan editor
66
+ let _planEditTabId = null; // tab id to route plan editor events back
67
+ let _planEditContract = null; // optional versioned document identity and atomic save callback
68
+ let _editorSaving = false;
69
+ let _editorOpenSequence = 0;
42
70
  let _changelogEditMode = false; // true when editing a changelog draft from Claude panel
43
71
  let _changelogEditFilePath = null; // path of the changelog draft being edited
44
72
 
45
73
  const MIN_WIDTH = 240;
46
74
  const MAX_WIDTH = 500;
47
75
 
76
+ function planEditorSourceLabel(source) {
77
+ if (source === 'codex') return 'Codex';
78
+ if (source === 'opencode') return 'OpenCode';
79
+ return 'Claude';
80
+ }
81
+
82
+ function planEditorEvent(extra = {}) {
83
+ const { planId, revision, accountId, threadId, sidepanelWindowId = null } = _planEditContract || {};
84
+ return { source: _planEditSource, tabId: _planEditTabId, planId, revision, accountId, threadId, sidepanelWindowId, ...extra };
85
+ }
86
+
87
+ function emitPlanEditorState() {
88
+ if (_planEditMode) emit('plan-editor-state', planEditorEvent({ dirty: _editorDirty, saving: _editorSaving, open: _editorOpen }));
89
+ }
90
+
91
+ function cancelPlanEditMode() {
92
+ if (!_planEditMode) return;
93
+ const event = planEditorEvent();
94
+ _planEditMode = false;
95
+ _planEditFilePath = null;
96
+ _planEditSource = null;
97
+ _planEditTabId = null;
98
+ _planEditContract = null;
99
+ emit('plan-edit-cancelled', event);
100
+ }
101
+
48
102
  // ─── SVG icons ────────────────────────
49
103
  const FOLDER_SVG = '<svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>';
50
104
  const FILE_SVG = '<svg viewBox="0 0 24 24"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><polyline points="13 2 13 7 18 7"/></svg>';
@@ -646,7 +700,13 @@ async function addProjectFlow() {
646
700
 
647
701
  // Register as a project
648
702
  const label = data.path.split(/[\\/]/).pop() || data.path;
649
- await fetch('/api/claude-code/integrations', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ target: 'project', projectPath: data.path, label }) });
703
+ const integRes = await fetch('/api/claude-code/integrations', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ target: 'project', projectPath: data.path, label }) });
704
+ const integData = await integRes.json().catch(() => ({}));
705
+
706
+ // Windows git CVE-2022-24765 safe.directory prompt — only fires when server detected the specific error.
707
+ if (integData && integData.dubiousOwnership && integData.trustPath) {
708
+ await promptTrustWorkspace(integData.trustPath);
709
+ }
650
710
 
651
711
  // Refresh projects list and select the new one
652
712
  await fetchProjects();
@@ -663,6 +723,67 @@ async function addProjectFlow() {
663
723
  }
664
724
  }
665
725
 
726
+ function promptTrustWorkspace(trustPath) {
727
+ return new Promise((resolve) => {
728
+ const existing = document.getElementById('fe-trust-modal');
729
+ if (existing) existing.remove();
730
+
731
+ const overlay = document.createElement('div');
732
+ overlay.id = 'fe-trust-modal';
733
+ overlay.className = 'fe-modal-overlay';
734
+
735
+ const modal = document.createElement('div');
736
+ modal.className = 'fe-modal fe-trust-modal';
737
+ modal.innerHTML = `
738
+ <div class="fe-modal-title">Git ownership mismatch</div>
739
+ <div class="fe-modal-body">
740
+ Git is refusing to read this workspace because it's owned by a different user account. Trusting it adds the directory to your global <code>safe.directory</code> config so Synabun's git UI can show the branch and changes.
741
+ <div class="fe-trust-path" id="fe-trust-path"></div>
742
+ </div>
743
+ <div class="fe-modal-actions">
744
+ <button class="fe-modal-btn fe-modal-cancel" id="fe-trust-skip">Skip</button>
745
+ <button class="fe-modal-btn fe-modal-confirm" id="fe-trust-confirm">Trust workspace</button>
746
+ </div>
747
+ `;
748
+ overlay.appendChild(modal);
749
+ document.body.appendChild(overlay);
750
+ modal.querySelector('#fe-trust-path').textContent = trustPath;
751
+
752
+ requestAnimationFrame(() => overlay.classList.add('fe-modal-overlay--in'));
753
+
754
+ const done = () => {
755
+ overlay.classList.remove('fe-modal-overlay--in');
756
+ setTimeout(() => overlay.remove(), 150);
757
+ document.removeEventListener('keydown', onKey);
758
+ resolve();
759
+ };
760
+ const onKey = (ev) => { if (ev.key === 'Escape') done(); };
761
+ document.addEventListener('keydown', onKey);
762
+
763
+ modal.querySelector('#fe-trust-skip').addEventListener('click', done);
764
+ overlay.addEventListener('click', (ev) => { if (ev.target === overlay) done(); });
765
+
766
+ modal.querySelector('#fe-trust-confirm').addEventListener('click', async () => {
767
+ const btn = modal.querySelector('#fe-trust-confirm');
768
+ btn.disabled = true;
769
+ btn.textContent = 'Trusting...';
770
+ try {
771
+ const res = await fetch('/api/terminal/trust-workspace', {
772
+ method: 'POST',
773
+ headers: { 'Content-Type': 'application/json' },
774
+ body: JSON.stringify({ path: trustPath }),
775
+ });
776
+ const data = await res.json();
777
+ if (data.ok) showToast('Workspace trusted');
778
+ else showToast(data.error || 'Trust failed');
779
+ } catch {
780
+ showToast('Trust failed');
781
+ }
782
+ done();
783
+ });
784
+ });
785
+ }
786
+
666
787
  function initProjectSelector() {
667
788
  const btn = $('fe-project-btn');
668
789
  const wrap = $('fe-project-selector');
@@ -715,11 +836,11 @@ async function loadDirectory(dirPath) {
715
836
  return data;
716
837
  }
717
838
 
718
- async function searchFiles(term) {
839
+ async function searchFiles(term, signal) {
719
840
  const params = new URLSearchParams({ search: term });
720
841
  // Scope search to selected project
721
842
  if (_selectedProject) params.set('path', _selectedProject.path);
722
- const res = await fetch(`/api/project-files?${params}`);
843
+ const res = await fetch(`/api/project-files?${params}`, signal ? { signal } : undefined);
723
844
  return res.json();
724
845
  }
725
846
 
@@ -750,6 +871,8 @@ function createRow(item, depth) {
750
871
  node.dataset.path = item.fullPath || item.name;
751
872
  node.dataset.type = item.type;
752
873
  node.dataset.expanded = 'false';
874
+ node.dataset.depth = depth;
875
+ node._item = item; // stashed so the delegated #fe-tree listener can recover context
753
876
 
754
877
  const row = document.createElement('div');
755
878
  row.className = 'fe-row';
@@ -811,33 +934,43 @@ function createRow(item, depth) {
811
934
  node.appendChild(children);
812
935
  }
813
936
 
814
- // Event handlers
937
+ // Row click (dir → expand/collapse; file → context menu) and right-click are
938
+ // handled by the delegated listeners on #fe-tree (see onFeTreeClick /
939
+ // onFeTreeContextMenu). The node carries data-path/data-type/data-depth and a
940
+ // stashed _item so the handler can recover the same context createRow had.
941
+
942
+ return node;
943
+ }
944
+
945
+ // Delegated tree interaction — one click + one contextmenu listener on #fe-tree,
946
+ // instead of two listeners per row re-created on every expand. Recovers the
947
+ // server item / depth / row / icon from the clicked .fe-node.
948
+ function onFeTreeClick(e) {
949
+ const nodeEl = e.target.closest('.fe-node');
950
+ if (!nodeEl) return;
951
+ const item = nodeEl._item;
952
+ if (!item) return;
953
+ const depth = Number(nodeEl.dataset.depth) || 0;
815
954
  if (item.type === 'dir') {
816
- row.addEventListener('click', () => {
817
- const isExpanded = node.dataset.expanded === 'true';
818
- if (isExpanded) {
819
- collapseDir(node, item.fullPath);
820
- } else {
821
- expandDir(node, item.fullPath, depth + 1);
822
- }
823
- });
955
+ if (nodeEl.dataset.expanded === 'true') {
956
+ collapseDir(nodeEl, item.fullPath);
957
+ } else {
958
+ expandDir(nodeEl, item.fullPath, depth + 1);
959
+ }
824
960
  } else {
825
- // Left-click opens context menu for files too
826
- row.addEventListener('click', (e) => {
827
- e.preventDefault();
828
- e.stopPropagation();
829
- showContextMenu(e, item, node, row, icon, depth);
830
- });
831
- }
832
-
833
- // Right-click context menu for both files and folders
834
- row.addEventListener('contextmenu', (e) => {
835
961
  e.preventDefault();
836
962
  e.stopPropagation();
837
- showContextMenu(e, item, node, row, icon, depth);
838
- });
963
+ showContextMenu(e, item, nodeEl, nodeEl.querySelector('.fe-row'), nodeEl.querySelector('.fe-icon'), depth);
964
+ }
965
+ }
839
966
 
840
- return node;
967
+ function onFeTreeContextMenu(e) {
968
+ const nodeEl = e.target.closest('.fe-node');
969
+ if (!nodeEl || !nodeEl._item) return;
970
+ e.preventDefault();
971
+ e.stopPropagation();
972
+ const depth = Number(nodeEl.dataset.depth) || 0;
973
+ showContextMenu(e, nodeEl._item, nodeEl, nodeEl.querySelector('.fe-row'), nodeEl.querySelector('.fe-icon'), depth);
841
974
  }
842
975
 
843
976
  // ─── Delete undo/redo stacks ─────────────
@@ -1157,7 +1290,7 @@ function showContextMenu(e, item, nodeEl, rowEl, iconEl, depth) {
1157
1290
 
1158
1291
  // ── Send to AI (both)
1159
1292
  menu.appendChild(_ctxItem(aiIcon, 'Send to AI', () => {
1160
- sendToPanel(item.fullPath);
1293
+ sendPathToActivePanel(item.fullPath);
1161
1294
  dismissCtxMenu();
1162
1295
  }));
1163
1296
 
@@ -1167,6 +1300,7 @@ function showContextMenu(e, item, nodeEl, rowEl, iconEl, depth) {
1167
1300
  // ── Edit File
1168
1301
  menu.appendChild(_ctxItem(editIcon, 'Edit File', () => {
1169
1302
  dismissCtxMenu();
1303
+ if ((_editorOpen || _planEditMode) && !closeFileEditor()) return;
1170
1304
  openFileEditor(item.fullPath);
1171
1305
  }));
1172
1306
  }
@@ -1547,11 +1681,35 @@ function updateGutter() {
1547
1681
  const textarea = $('fe-editor-textarea');
1548
1682
  if (!gutter || !textarea) return;
1549
1683
  const lines = textarea.value.split('\n').length;
1550
- const frags = [];
1551
- for (let i = 1; i <= lines; i++) frags.push(`<div>${i}</div>`);
1552
- gutter.innerHTML = frags.join('');
1684
+ // Incremental: line numbers are just 1..N, so we only add/remove the tail delta.
1685
+ // childElementCount is the source of truth (desync-proof, no layout read), and the
1686
+ // common typing case (line count unchanged) does zero DOM work.
1687
+ let have = gutter.childElementCount;
1688
+ if (have === lines) return;
1689
+ if (have < lines) {
1690
+ const frag = document.createDocumentFragment();
1691
+ for (let i = have + 1; i <= lines; i++) {
1692
+ const d = document.createElement('div');
1693
+ d.textContent = i;
1694
+ frag.appendChild(d);
1695
+ }
1696
+ gutter.appendChild(frag);
1697
+ } else {
1698
+ while (have > lines) { gutter.removeChild(gutter.lastChild); have--; }
1699
+ }
1553
1700
  }
1554
1701
 
1702
+ // Debounced heavy editor render. Re-highlighting the whole file and reconciling
1703
+ // the gutter shouldn't run on every keystroke; the colorized <pre> sits behind a
1704
+ // transparent-text textarea, so the user reads live textarea glyphs while
1705
+ // colorization catches up a beat later. Caret/line-highlight + dirty state stay
1706
+ // immediate (see the input listener). Discrete actions (undo/redo/replace) keep
1707
+ // calling updateHighlight()/updateGutter() directly for instant feedback.
1708
+ const debouncedEditorRender = debounce(() => {
1709
+ updateHighlight();
1710
+ updateGutter();
1711
+ }, 90);
1712
+
1555
1713
  function updateCursorPos() {
1556
1714
  const textarea = $('fe-editor-textarea');
1557
1715
  const el = $('fe-editor-cursor');
@@ -1570,15 +1728,70 @@ function syncGutterScroll() {
1570
1728
  if (gutter && textarea) gutter.scrollTop = textarea.scrollTop;
1571
1729
  }
1572
1730
 
1731
+ let _hlMirror = null;
1732
+ let _hlMirrorSynced = false; // false \u2192 re-copy textarea computed styles + width into the mirror
1733
+ let _hlResizeObs = null;
1734
+ const _hlMirrorProps = [
1735
+ 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'lineHeight',
1736
+ 'letterSpacing', 'wordSpacing', 'whiteSpace', 'overflowWrap',
1737
+ 'wordBreak', 'tabSize', 'paddingTop', 'paddingRight',
1738
+ 'paddingBottom', 'paddingLeft', 'boxSizing'
1739
+ ];
1740
+
1741
+ // Force the next getLineVisualTop to re-copy the textarea's computed styles into
1742
+ // the measuring mirror. Needed on word-wrap toggle, which changes wrapping without
1743
+ // changing the textarea's box size and so isn't caught by the ResizeObserver.
1744
+ function invalidateLineMirror() { _hlMirrorSynced = false; }
1745
+
1746
+ function getLineVisualTop(textarea, pos) {
1747
+ if (!_hlMirror) {
1748
+ _hlMirror = document.createElement('div');
1749
+ _hlMirror.style.position = 'absolute';
1750
+ _hlMirror.style.visibility = 'hidden';
1751
+ _hlMirror.style.pointerEvents = 'none';
1752
+ _hlMirror.style.top = '-9999px';
1753
+ _hlMirror.style.left = '0';
1754
+ _hlMirror.style.height = 'auto';
1755
+ _hlMirror.style.overflow = 'hidden';
1756
+ _hlMirror.style.border = 'none';
1757
+ document.body.appendChild(_hlMirror);
1758
+ _hlMirrorSynced = false;
1759
+ }
1760
+ // Observe the textarea so any box-size change (panel/window resize, show/hide)
1761
+ // invalidates the cached copy automatically. The textarea element is stable
1762
+ // across file opens, so this observes exactly once.
1763
+ if (typeof ResizeObserver === 'function' && _hlResizeObs?._target !== textarea) {
1764
+ _hlResizeObs?.disconnect();
1765
+ _hlResizeObs = new ResizeObserver(() => { _hlMirrorSynced = false; });
1766
+ _hlResizeObs.observe(textarea);
1767
+ _hlResizeObs._target = textarea;
1768
+ _hlMirrorSynced = false;
1769
+ }
1770
+ // The getComputedStyle read + 16 style writes was the per-caret-move hot cost;
1771
+ // copy only when stale. The marker measurement below is the one unavoidable read.
1772
+ if (!_hlMirrorSynced) {
1773
+ const cs = getComputedStyle(textarea);
1774
+ for (const p of _hlMirrorProps) _hlMirror.style[p] = cs[p];
1775
+ _hlMirror.style.width = textarea.clientWidth + 'px';
1776
+ _hlMirrorSynced = true;
1777
+ }
1778
+
1779
+ const val = textarea.value;
1780
+ const lineStart = val.lastIndexOf('\n', pos - 1) + 1;
1781
+ _hlMirror.textContent = '';
1782
+ _hlMirror.appendChild(document.createTextNode(val.substring(0, lineStart)));
1783
+ const marker = document.createElement('span');
1784
+ marker.textContent = '\u200b';
1785
+ _hlMirror.appendChild(marker);
1786
+ return marker.offsetTop;
1787
+ }
1788
+
1573
1789
  function updateLineHighlight() {
1574
1790
  const textarea = $('fe-editor-textarea');
1575
1791
  const hl = $('fe-editor-line-highlight');
1576
1792
  if (!textarea || !hl) return;
1577
- const val = textarea.value;
1578
- const pos = textarea.selectionStart;
1579
- const lineNum = val.substring(0, pos).split('\n').length - 1;
1580
- const lineH = 20;
1581
- hl.style.top = `${10 + lineNum * lineH - textarea.scrollTop}px`;
1793
+ const yPos = getLineVisualTop(textarea, textarea.selectionStart);
1794
+ hl.style.top = `${yPos - textarea.scrollTop}px`;
1582
1795
  }
1583
1796
 
1584
1797
  function updateScrollmap() {
@@ -1606,6 +1819,7 @@ function editorPushUndo(ta) {
1606
1819
  }
1607
1820
 
1608
1821
  function editorInsertText(ta, text) {
1822
+ if (_editorSaving) return;
1609
1823
  editorPushUndo(ta);
1610
1824
  const start = ta.selectionStart;
1611
1825
  const end = ta.selectionEnd;
@@ -1616,12 +1830,14 @@ function editorInsertText(ta, text) {
1616
1830
  }
1617
1831
 
1618
1832
  function editorReplaceRange(ta, from, to, text) {
1833
+ if (_editorSaving) return;
1619
1834
  editorPushUndo(ta);
1620
1835
  ta.value = ta.value.substring(0, from) + text + ta.value.substring(to);
1621
1836
  ta.dispatchEvent(new Event('input'));
1622
1837
  }
1623
1838
 
1624
1839
  function editorUndo(ta) {
1840
+ if (_editorSaving) return;
1625
1841
  if (_undoStack.length === 0) return;
1626
1842
  _redoStack.push({ value: ta.value, selStart: ta.selectionStart, selEnd: ta.selectionEnd });
1627
1843
  const state = _undoStack.pop();
@@ -1634,6 +1850,7 @@ function editorUndo(ta) {
1634
1850
  }
1635
1851
 
1636
1852
  function editorRedo(ta) {
1853
+ if (_editorSaving) return;
1637
1854
  if (_redoStack.length === 0) return;
1638
1855
  _undoStack.push({ value: ta.value, selStart: ta.selectionStart, selEnd: ta.selectionEnd });
1639
1856
  const state = _redoStack.pop();
@@ -1645,17 +1862,61 @@ function editorRedo(ta) {
1645
1862
  updateHighlight();
1646
1863
  }
1647
1864
 
1648
- async function openFileEditor(filePath) {
1865
+ function getEditorSelectionOffset(text, lineNum, columnNum = 1) {
1866
+ const content = String(text || '');
1867
+ const lines = content.split('\n');
1868
+ const targetLine = Math.min(Math.max(1, Number(lineNum) || 1), lines.length || 1);
1869
+ const targetColumn = Math.max(1, Number(columnNum) || 1);
1870
+ let pos = 0;
1871
+ for (let i = 0; i < targetLine - 1; i++) pos += lines[i].length + 1;
1872
+ pos += Math.min(targetColumn - 1, (lines[targetLine - 1] || '').length);
1873
+ return { pos, line: targetLine };
1874
+ }
1875
+
1876
+ function focusEditorLocation(lineNum, columnNum = 1) {
1877
+ const textarea = $('fe-editor-textarea');
1878
+ if (!textarea || !lineNum || lineNum < 1) return;
1879
+ const { pos, line } = getEditorSelectionOffset(textarea.value, lineNum, columnNum);
1880
+ textarea.focus();
1881
+ textarea.setSelectionRange(pos, pos);
1882
+ const yPos = getLineVisualTop(textarea, pos);
1883
+ const lineHeight = 20;
1884
+ textarea.scrollTop = Math.max(0, yPos - 5 * lineHeight);
1885
+ updateCursorPos();
1886
+ updateLineHighlight();
1887
+ syncGutterScroll();
1888
+ }
1889
+
1890
+ async function openFileEditor(filePath, opts = {}) {
1891
+ const openSequence = ++_editorOpenSequence;
1892
+ const contract = _planEditContract;
1649
1893
  try {
1894
+ const normalizedPath = String(filePath || '').replace(/\\/g, '/');
1650
1895
  const res = await fetch(`/api/file-content?path=${encodeURIComponent(filePath)}`);
1651
1896
  const data = await res.json();
1897
+ if (openSequence !== _editorOpenSequence) return;
1652
1898
  if (!res.ok) {
1899
+ const isOpencodeConfig = normalizedPath.endsWith('/.config/opencode/config.json');
1900
+ const isAllowlistMiss = res.status === 403 && data?.error === 'Path outside registered project roots';
1901
+ if (isOpencodeConfig && isAllowlistMiss) {
1902
+ showToast('Restart Synabun to apply OpenCode config editor support');
1903
+ cancelPlanEditMode();
1904
+ return;
1905
+ }
1653
1906
  showToast(data.error || 'Cannot open file');
1907
+ cancelPlanEditMode();
1654
1908
  return;
1655
1909
  }
1656
1910
 
1911
+ if (typeof contract?.expectedMarkdown === 'string'
1912
+ && String(data.content).replace(/\r\n/g, '\n') !== contract.expectedMarkdown.replace(/\r\n/g, '\n')) {
1913
+ showToast('The plan file changed. Reopen the current plan revision.');
1914
+ cancelPlanEditMode();
1915
+ return;
1916
+ }
1657
1917
  _editorOpen = true;
1658
1918
  _editorFilePath = data.path;
1919
+ if (_planEditMode) _planEditFilePath = data.path;
1659
1920
  // Normalize line endings — textarea always returns \n, server may send \r\n on Windows
1660
1921
  _editorOriginal = data.content.replace(/\r\n/g, '\n');
1661
1922
  _editorDirty = false;
@@ -1713,7 +1974,9 @@ async function openFileEditor(filePath) {
1713
1974
  if (_planEditMode) {
1714
1975
  const banner = document.createElement('div');
1715
1976
  banner.className = 'fe-plan-banner';
1716
- banner.textContent = 'Editing plan — save to send to Claude';
1977
+ banner.textContent = _planEditSource === 'codex'
1978
+ ? 'Editing plan — save to return to review'
1979
+ : `Editing plan — save to send to ${planEditorSourceLabel(_planEditSource)}`;
1717
1980
  edPanel?.prepend(banner);
1718
1981
  } else if (_changelogEditMode) {
1719
1982
  const banner = document.createElement('div');
@@ -1727,21 +1990,29 @@ async function openFileEditor(filePath) {
1727
1990
  updateCursorPos();
1728
1991
  updateEditorDirtyState();
1729
1992
  // Defer so the textarea has rendered its scroll dimensions
1730
- requestAnimationFrame(() => { updateLineHighlight(); updateScrollmap(); syncHighlightScroll(); });
1993
+ requestAnimationFrame(() => {
1994
+ if (opts?.line) focusEditorLocation(opts.line, opts.column || 1);
1995
+ updateLineHighlight();
1996
+ updateScrollmap();
1997
+ syncHighlightScroll();
1998
+ });
1731
1999
  } catch (err) {
2000
+ cancelPlanEditMode();
1732
2001
  showToast('Failed to open file');
1733
2002
  }
1734
2003
  }
1735
2004
 
1736
2005
  function closeFileEditor() {
2006
+ if (_editorSaving) return false;
1737
2007
  if (_editorDirty) {
1738
2008
  if (!confirm('Discard unsaved changes?')) return false;
1739
2009
  }
1740
2010
 
1741
2011
  // Emit cancel events before clearing flags so Claude panel can re-enable buttons
1742
- if (_planEditMode) emit('plan-edit-cancelled');
2012
+ if (_planEditMode) cancelPlanEditMode();
1743
2013
  if (_changelogEditMode) emit('changelog-edit-cancelled');
1744
2014
 
2015
+ ++_editorOpenSequence;
1745
2016
  _editorOpen = false;
1746
2017
  _editorFilePath = null;
1747
2018
  _editorOriginal = '';
@@ -1750,6 +2021,8 @@ function closeFileEditor() {
1750
2021
  _editorPreviewMode = false;
1751
2022
  _planEditMode = false;
1752
2023
  _planEditFilePath = null;
2024
+ _planEditSource = null;
2025
+ _planEditTabId = null;
1753
2026
  _changelogEditMode = false;
1754
2027
  _changelogEditFilePath = null;
1755
2028
  $('fe-editor-panel')?.querySelector('.fe-plan-banner')?.remove();
@@ -1757,6 +2030,7 @@ function closeFileEditor() {
1757
2030
  _shLines = null;
1758
2031
  _shViewStart = 0;
1759
2032
  _shViewEnd = 0;
2033
+ if (_hlMirror) { _hlMirror.remove(); _hlMirror = null; }
1760
2034
  const hlCode = $('fe-editor-highlight-code');
1761
2035
  if (hlCode) hlCode.innerHTML = '';
1762
2036
 
@@ -1778,54 +2052,75 @@ function closeFileEditor() {
1778
2052
  }
1779
2053
 
1780
2054
  async function saveFileEditor() {
1781
- if (!_editorFilePath) return;
2055
+ if (!_editorFilePath || _editorSaving) return;
1782
2056
  const textarea = $('fe-editor-textarea');
1783
2057
  if (!textarea) return;
1784
-
2058
+ const savedContent = textarea.value;
2059
+ const savedPath = _editorFilePath;
2060
+ const planEvent = _planEditMode ? planEditorEvent() : null;
2061
+ const contract = _planEditContract;
2062
+ _editorSaving = true;
2063
+ textarea.readOnly = true;
2064
+ updateEditorDirtyState();
2065
+ let saved = false;
2066
+ let result = null;
1785
2067
  try {
1786
- const res = await fetch('/api/file-content', {
1787
- method: 'POST',
1788
- headers: { 'Content-Type': 'application/json' },
1789
- body: JSON.stringify({ path: _editorFilePath, content: textarea.value })
1790
- });
1791
- const data = await res.json();
1792
- if (!res.ok) {
1793
- showToast(data.error || 'Save failed');
1794
- return;
2068
+ if (planEvent?.source === 'codex' && typeof contract?.save !== 'function') {
2069
+ throw new Error('This plan editor is missing its revision. Reopen the plan to save.');
1795
2070
  }
1796
- _editorOriginal = textarea.value;
1797
- updateEditorDirtyState();
1798
-
1799
- // Plan edit: emit saved content to Claude panel, then close editor
1800
- if (_planEditMode && _editorFilePath === _planEditFilePath) {
1801
- const savedContent = textarea.value;
1802
- const savedPath = _editorFilePath;
1803
- _planEditMode = false;
1804
- _planEditFilePath = null;
1805
- showToast('Plan saved — sending to Claude');
1806
- emit('plan-saved', { filePath: savedPath, content: savedContent });
1807
- closeFileEditor();
1808
- return;
2071
+ if (typeof contract?.save === 'function') {
2072
+ result = await contract.save({ ...planEvent, content: savedContent });
2073
+ if (!result?.ok) throw new Error(result?.reason || result?.error || 'The plan changed. Reopen the latest revision before saving.');
2074
+ } else {
2075
+ const res = await fetch('/api/file-content', {
2076
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
2077
+ body: JSON.stringify({ path: savedPath, content: savedContent }),
2078
+ });
2079
+ result = await res.json();
2080
+ if (!res.ok) throw new Error(result.error || 'Save failed');
1809
2081
  }
1810
-
1811
- // Changelog edit: emit saved content to Claude panel, then close editor
1812
- if (_changelogEditMode && _editorFilePath === _changelogEditFilePath) {
1813
- const savedContent = textarea.value;
1814
- _changelogEditMode = false;
1815
- _changelogEditFilePath = null;
1816
- showToast('Changelog saved — sending to Claude');
1817
- emit('changelog-saved', { content: savedContent });
1818
- closeFileEditor();
1819
- return;
2082
+ _editorOriginal = savedContent;
2083
+ saved = true;
2084
+ } catch (error) {
2085
+ showToast(error?.message || 'Save failed');
2086
+ if (_planEditSource === 'codex') {
2087
+ const banner = $('fe-editor-panel')?.querySelector('.fe-plan-banner');
2088
+ if (banner) banner.textContent = `${error?.message || 'Save failed'} Your edits are still open.`;
1820
2089
  }
1821
-
1822
- showToast('Saved');
1823
- } catch {
1824
- showToast('Save failed');
2090
+ } finally {
2091
+ _editorSaving = false;
2092
+ textarea.readOnly = false;
2093
+ updateEditorDirtyState();
2094
+ }
2095
+ if (!saved) return;
2096
+
2097
+ if (planEvent && _planEditMode && savedPath === _planEditFilePath) {
2098
+ _planEditMode = false;
2099
+ _planEditFilePath = null;
2100
+ _planEditSource = null;
2101
+ _planEditTabId = null;
2102
+ _planEditContract = null;
2103
+ showToast('Plan saved');
2104
+ emit('plan-saved', {
2105
+ ...planEvent, filePath: result?.path || savedPath, content: savedContent,
2106
+ persisted: typeof contract?.save === 'function', savedRevision: result?.document?.revision,
2107
+ });
2108
+ closeFileEditor();
2109
+ return;
1825
2110
  }
2111
+ if (_changelogEditMode && savedPath === _changelogEditFilePath) {
2112
+ _changelogEditMode = false;
2113
+ _changelogEditFilePath = null;
2114
+ showToast('Changelog saved — sending to Claude');
2115
+ emit('changelog-saved', { content: savedContent });
2116
+ closeFileEditor();
2117
+ return;
2118
+ }
2119
+ showToast('Saved');
1826
2120
  }
1827
2121
 
1828
2122
  function discardFileEditor() {
2123
+ if (_editorSaving) return;
1829
2124
  if (!confirm('Discard changes?')) return;
1830
2125
  const textarea = $('fe-editor-textarea');
1831
2126
  if (textarea) textarea.value = _editorOriginal;
@@ -1841,12 +2136,13 @@ function updateEditorDirtyState() {
1841
2136
 
1842
2137
  const saveBtn = $('fe-editor-save');
1843
2138
  if (saveBtn) {
1844
- saveBtn.disabled = !_editorDirty;
2139
+ saveBtn.disabled = _editorSaving || (!_editorDirty && !_planEditMode);
1845
2140
  saveBtn.classList.toggle('dirty', _editorDirty);
1846
2141
  }
1847
2142
 
1848
2143
  const discardBtn = $('fe-editor-discard');
1849
- if (discardBtn) discardBtn.disabled = !_editorDirty;
2144
+ if (discardBtn) discardBtn.disabled = _editorSaving || !_editorDirty;
2145
+ emitPlanEditorState();
1850
2146
  }
1851
2147
 
1852
2148
  // ─── Markdown rendering (same as Skills Studio) ────────────
@@ -1991,11 +2287,9 @@ function selectFindMatch(focusTextarea) {
1991
2287
  textarea.setSelectionRange(m.start, m.end);
1992
2288
  }
1993
2289
  // Scroll match into view
1994
- const text = textarea.value.substring(0, m.start);
1995
- const lineNum = text.split('\n').length;
2290
+ const yPos = getLineVisualTop(textarea, m.start);
1996
2291
  const lineHeight = 20;
1997
- const targetScroll = (lineNum - 5) * lineHeight; // a few lines above
1998
- textarea.scrollTop = Math.max(0, targetScroll);
2292
+ textarea.scrollTop = Math.max(0, yPos - 5 * lineHeight);
1999
2293
  }
2000
2294
 
2001
2295
  function updateFindCount() {
@@ -2010,6 +2304,7 @@ function updateFindCount() {
2010
2304
  }
2011
2305
 
2012
2306
  function doReplace() {
2307
+ if (_editorSaving) return;
2013
2308
  const textarea = $('fe-editor-textarea');
2014
2309
  const replaceInput = $('fe-editor-replace-input');
2015
2310
  if (!textarea || !replaceInput || _findMatches.length === 0 || _findIndex < 0) return;
@@ -2030,6 +2325,7 @@ function doReplace() {
2030
2325
  }
2031
2326
 
2032
2327
  function doReplaceAll() {
2328
+ if (_editorSaving) return;
2033
2329
  const textarea = $('fe-editor-textarea');
2034
2330
  const findInput = $('fe-editor-find-input');
2035
2331
  const replaceInput = $('fe-editor-replace-input');
@@ -2070,26 +2366,30 @@ function closeGoToLine() {
2070
2366
  }
2071
2367
 
2072
2368
  function goToLine(lineNum) {
2073
- const textarea = $('fe-editor-textarea');
2074
- if (!textarea || !lineNum || lineNum < 1) return;
2075
- const lines = textarea.value.split('\n');
2076
- const target = Math.min(lineNum, lines.length);
2077
- let pos = 0;
2078
- for (let i = 0; i < target - 1; i++) pos += lines[i].length + 1;
2079
- textarea.focus();
2080
- textarea.setSelectionRange(pos, pos);
2081
- const lineHeight = 20;
2082
- textarea.scrollTop = Math.max(0, (target - 5) * lineHeight);
2083
- updateCursorPos();
2084
- updateLineHighlight();
2085
- syncGutterScroll();
2369
+ focusEditorLocation(lineNum, 1);
2086
2370
  closeGoToLine();
2087
2371
  }
2088
2372
 
2089
2373
 
2374
+ // Append a muted "… N more (truncated)" row when the server capped a large dir,
2375
+ // so files aren't silently dropped. Styled like the inline "Loading..." indicator.
2376
+ function appendTruncationNotice(container, total, shown, depth) {
2377
+ if (!total || total <= shown) return;
2378
+ const note = document.createElement('div');
2379
+ note.style.cssText = `padding:4px 0 4px ${depth * 16 + 24}px;font-size:11px;color:rgba(255,255,255,0.3);font-family:var(--ff-mono);`;
2380
+ note.textContent = `… ${total - shown} more (truncated — narrow with search)`;
2381
+ container.appendChild(note);
2382
+ }
2383
+
2090
2384
  async function buildFileTree() {
2091
2385
  const tree = $('fe-tree');
2092
2386
  if (!tree) return;
2387
+ // Delegated listeners survive innerHTML clears, so wire them once on the container.
2388
+ if (!tree._delegated) {
2389
+ tree.addEventListener('click', onFeTreeClick);
2390
+ tree.addEventListener('contextmenu', onFeTreeContextMenu);
2391
+ tree._delegated = true;
2392
+ }
2093
2393
  tree.innerHTML = '';
2094
2394
 
2095
2395
  const data = _cache.values().next().value || await loadDirectory();
@@ -2113,6 +2413,7 @@ async function buildFileTree() {
2113
2413
  tree.appendChild(node);
2114
2414
  }
2115
2415
 
2416
+ if (data.truncated) appendTruncationNotice(tree, data.total, items.length, 0);
2116
2417
  updateCount(items.length);
2117
2418
  }
2118
2419
 
@@ -2142,6 +2443,8 @@ async function expandDir(nodeEl, dirPath, depth) {
2142
2443
  const child = createRow(item, depth);
2143
2444
  childrenEl.appendChild(child);
2144
2445
  }
2446
+
2447
+ if (data.truncated) appendTruncationNotice(childrenEl, data.total, items.length, depth);
2145
2448
  }
2146
2449
 
2147
2450
  function collapseDir(nodeEl, dirPath) {
@@ -2190,11 +2493,14 @@ function updateCount(count) {
2190
2493
  // ═══════════════════════════════════════════
2191
2494
 
2192
2495
  let _searchTimer = null;
2496
+ let _searchAbort = null;
2193
2497
 
2194
2498
  function onFilterInput(e) {
2195
2499
  _filterText = e.target.value.trim();
2196
2500
 
2197
2501
  clearTimeout(_searchTimer);
2502
+ // Cancel any in-flight search — its response is for a now-stale query.
2503
+ _searchAbort?.abort();
2198
2504
 
2199
2505
  if (_filterText.length > 2) {
2200
2506
  _searchTimer = setTimeout(async () => {
@@ -2202,7 +2508,20 @@ function onFilterInput(e) {
2202
2508
  if (!tree) return;
2203
2509
  tree.innerHTML = '<div style="padding:12px;font-size:11px;color:rgba(255,255,255,0.3);font-family:var(--ff-mono);text-align:center;">Searching...</div>';
2204
2510
 
2205
- const data = await searchFiles(_filterText);
2511
+ const controller = new AbortController();
2512
+ _searchAbort = controller;
2513
+ const queryAtRequest = _filterText;
2514
+ let data;
2515
+ try {
2516
+ data = await searchFiles(_filterText, controller.signal);
2517
+ } catch (err) {
2518
+ if (err && err.name === 'AbortError') return; // superseded by a newer search
2519
+ tree.innerHTML = '<div style="padding:12px;font-size:11px;color:rgba(255,120,120,0.6);font-family:var(--ff-mono);text-align:center;">Search failed</div>';
2520
+ updateCount(0);
2521
+ return;
2522
+ }
2523
+ // Guard against an out-of-order response landing after the query moved on.
2524
+ if (queryAtRequest !== _filterText) return;
2206
2525
  tree.innerHTML = '';
2207
2526
 
2208
2527
  if (!data || !data.items || data.items.length === 0) {
@@ -2238,10 +2557,32 @@ function initResizeHandle() {
2238
2557
  if (!handle || !panel) return;
2239
2558
 
2240
2559
  let dragging = false;
2560
+ let resizeRaf = 0;
2561
+ let pendingWidth = _width;
2562
+ let explorerWidth = 0;
2563
+
2564
+ const applyResize = () => {
2565
+ resizeRaf = 0;
2566
+ _width = pendingWidth;
2567
+ panel.style.width = `${_width}px`;
2568
+ applyFileExplorerWidth();
2569
+ };
2570
+ const scheduleResize = (width) => {
2571
+ pendingWidth = width;
2572
+ if (!resizeRaf) resizeRaf = requestAnimationFrame(applyResize);
2573
+ };
2574
+ const flushResize = () => {
2575
+ if (resizeRaf) {
2576
+ cancelAnimationFrame(resizeRaf);
2577
+ resizeRaf = 0;
2578
+ }
2579
+ applyResize();
2580
+ };
2241
2581
 
2242
2582
  handle.addEventListener('mousedown', (e) => {
2243
2583
  e.preventDefault();
2244
2584
  dragging = true;
2585
+ explorerWidth = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--explorer-width')) || 0;
2245
2586
  handle.classList.add('active');
2246
2587
  document.body.style.cursor = 'col-resize';
2247
2588
  document.body.style.userSelect = 'none';
@@ -2250,16 +2591,14 @@ function initResizeHandle() {
2250
2591
  document.addEventListener('mousemove', (e) => {
2251
2592
  if (!dragging) return;
2252
2593
  // The panel left edge starts at --explorer-width
2253
- const explorerWidth = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--explorer-width')) || 0;
2254
2594
  const newWidth = Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, e.clientX - explorerWidth));
2255
- _width = newWidth;
2256
- panel.style.width = `${_width}px`;
2257
- applyFileExplorerWidth();
2595
+ scheduleResize(newWidth);
2258
2596
  });
2259
2597
 
2260
2598
  document.addEventListener('mouseup', () => {
2261
2599
  if (!dragging) return;
2262
2600
  dragging = false;
2601
+ flushResize();
2263
2602
  handle.classList.remove('active');
2264
2603
  document.body.style.cursor = '';
2265
2604
  document.body.style.userSelect = '';
@@ -2336,19 +2675,48 @@ export function initFileExplorer() {
2336
2675
  });
2337
2676
 
2338
2677
  // ── Plan editor — open plan file from Claude panel for direct editing ──
2339
- on('open-plan-editor', ({ filePath }) => {
2678
+ on('open-plan-editor', (contract = {}) => {
2679
+ const { filePath, source = 'claude', tabId = null } = contract;
2680
+ if (!filePath) return;
2681
+ if (_planEditMode && _planEditFilePath === filePath
2682
+ && _planEditSource === source && _planEditTabId === tabId
2683
+ && _planEditContract?.planId === contract.planId && _planEditContract?.revision === contract.revision) {
2684
+ $('fe-editor-textarea')?.focus();
2685
+ return;
2686
+ }
2687
+ if ((_editorOpen || _planEditMode) && !closeFileEditor()) {
2688
+ emit('plan-edit-cancelled', { source, tabId, planId: contract.planId, revision: contract.revision, accountId: contract.accountId, threadId: contract.threadId, sidepanelWindowId: contract.sidepanelWindowId || null });
2689
+ return;
2690
+ }
2340
2691
  _planEditMode = true;
2341
2692
  _planEditFilePath = filePath;
2693
+ _planEditSource = source;
2694
+ _planEditTabId = tabId;
2695
+ _planEditContract = contract;
2342
2696
  openFileEditor(filePath);
2343
2697
  });
2344
2698
 
2345
2699
  // ── Changelog editor — open changelog draft from Claude panel for direct editing ──
2346
2700
  on('open-changelog-editor', ({ filePath }) => {
2701
+ if ((_editorOpen || _planEditMode) && !closeFileEditor()) return;
2347
2702
  _changelogEditMode = true;
2348
2703
  _changelogEditFilePath = filePath;
2349
2704
  openFileEditor(filePath);
2350
2705
  });
2351
2706
 
2707
+ on('open-file-editor', ({ filePath, line, column } = {}) => {
2708
+ if (!filePath) return;
2709
+ if ((_editorOpen || _planEditMode) && !closeFileEditor()) return;
2710
+ _planEditContract = null;
2711
+ _planEditMode = false;
2712
+ _planEditFilePath = null;
2713
+ _planEditSource = null;
2714
+ _planEditTabId = null;
2715
+ _changelogEditMode = false;
2716
+ _changelogEditFilePath = null;
2717
+ openFileEditor(filePath, { line, column });
2718
+ });
2719
+
2352
2720
  const panel = $('file-explorer-panel');
2353
2721
  if (!panel) return;
2354
2722
 
@@ -2432,6 +2800,10 @@ export function initFileExplorer() {
2432
2800
  const hl = $('fe-editor-highlight');
2433
2801
  if (hl) { hl.style.whiteSpace = newWrap; hl.style.overflowWrap = newOverflow; }
2434
2802
  wordWrapBtn.classList.toggle('active', !wrapped);
2803
+ // Wrapping changed without a box-size change → re-sync the measuring mirror
2804
+ // and reposition the current-line highlight.
2805
+ invalidateLineMirror();
2806
+ updateLineHighlight();
2435
2807
  });
2436
2808
  }
2437
2809
 
@@ -2503,18 +2875,23 @@ export function initFileExplorer() {
2503
2875
 
2504
2876
  if (editorTextarea) {
2505
2877
  editorTextarea.addEventListener('input', () => {
2878
+ // Immediate: cheap feedback the user perceives directly.
2506
2879
  updateEditorDirtyState();
2507
- updateGutter();
2508
- updateHighlight();
2509
2880
  updateLineHighlight();
2881
+ // Debounced: full-file syntax highlight + gutter reconcile (heavy on big files).
2882
+ debouncedEditorRender();
2510
2883
  });
2511
- // Scroll sync: gutter follows textarea, update scrollmap + line highlight + syntax
2512
- editorTextarea.addEventListener('scroll', () => {
2884
+ // Scroll sync: gutter follows textarea, update scrollmap + line highlight + syntax.
2885
+ // Coalesced to one run per frame (vsync-aligned) so fast scrolling doesn't fire
2886
+ // four DOM-measuring ops on every scroll pixel. Passive: the handler never
2887
+ // calls preventDefault.
2888
+ const onEditorScroll = rafThrottle(() => {
2513
2889
  syncGutterScroll();
2514
2890
  syncHighlightScroll();
2515
2891
  updateScrollmap();
2516
2892
  updateLineHighlight();
2517
2893
  });
2894
+ editorTextarea.addEventListener('scroll', onEditorScroll, { passive: true });
2518
2895
  // Cursor position + line highlight tracking
2519
2896
  editorTextarea.addEventListener('click', () => { updateCursorPos(); updateLineHighlight(); });
2520
2897
  editorTextarea.addEventListener('keyup', () => { updateCursorPos(); updateLineHighlight(); });
@@ -2523,6 +2900,7 @@ export function initFileExplorer() {
2523
2900
  let _undoBurstTimer = null;
2524
2901
 
2525
2902
  editorTextarea.addEventListener('keydown', (e) => {
2903
+ if (_editorSaving) return;
2526
2904
  const ta = e.target;
2527
2905
  const mod = e.ctrlKey || e.metaKey;
2528
2906