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,391 +1,613 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * SynaBun PostToolUse Hook — Plan Storage
5
- *
6
- * Matches: ^(Enter|Exit)PlanMode$
7
- *
8
- * EnterPlanMode: Injects a reminder to use AskUserQuestion for
9
- * clarifications instead of plain-text questions.
10
- *
11
- * ExitPlanMode: When Claude exits plan mode (plan approved), this hook:
12
- * 1. Finds the most recently modified plan file in ~/.claude/plans/
13
- * 2. Auto-creates a child category under "plans" for the project if needed
14
- * 3. Generates a local embedding and stores the plan in SQLite
15
- * 4. Returns additionalContext confirming storage
16
- *
17
- * Input (stdin JSON):
18
- * { session_id, tool_name, tool_input, tool_response, cwd }
19
- *
20
- * Output (stdout JSON):
21
- * { additionalContext: "..." } on success, or {} on skip/error
22
- */
23
-
24
- import { readFileSync, writeFileSync, appendFileSync, readdirSync, statSync, existsSync, mkdirSync } from 'node:fs';
25
- import { DatabaseSync } from 'node:sqlite';
26
- import { dirname, join } from 'node:path';
27
- import { fileURLToPath, pathToFileURL } from 'node:url';
28
- import { randomUUID } from 'node:crypto';
29
- import { detectProject, getMcpCategoriesPath, MCP_DATA_DIR, DATA_DIR } from './shared.mjs';
30
-
31
- const __dirname = dirname(fileURLToPath(import.meta.url));
32
-
33
- // Debug log (append-only, survives across invocations)
34
- const DEBUG_LOG_PATH = join(DATA_DIR, 'plan-debug.log');
35
- function debugLog(msg) {
36
- try {
37
- const ts = new Date().toISOString();
38
- appendFileSync(DEBUG_LOG_PATH, `[${ts}] ${msg}\n`, 'utf-8');
39
- } catch { /* best-effort */ }
40
- }
41
-
42
- // Plans directory — project-local to avoid ~/.claude/ sensitive-file permission prompts
43
- const PLANS_DIR = join(DATA_DIR, 'plans');
44
- // Fallback: Claude Code's ExitPlanMode may still write to ~/.claude/plans/ internally
45
- const PLANS_DIR_FALLBACK = join(process.env.USERPROFILE || process.env.HOME || '', '.claude', 'plans');
46
-
47
- // Dedup tracker — records which plan files have already been stored
48
- const STORED_PLANS_PATH = join(DATA_DIR, 'stored-plans.json');
49
-
50
- // SQLite database path
51
- const DB_PATH = process.env.SQLITE_DB_PATH || join(MCP_DATA_DIR, 'memory.db');
52
-
53
- // ─── Stdin ───
54
-
55
- function readStdin() {
56
- return new Promise((resolve) => {
57
- if (process.stdin.isTTY) return resolve('{}');
58
- let data = '';
59
- process.stdin.setEncoding('utf8');
60
- process.stdin.on('data', (chunk) => { data += chunk; });
61
- process.stdin.on('end', () => resolve(data));
62
- setTimeout(() => resolve(data || '{}'), 3000);
63
- });
64
- }
65
-
66
- // ─── Local embedding generation ───
67
-
68
- async function generateEmbedding(text) {
69
- const embPath = join(__dirname, '..', '..', 'mcp-server', 'dist', 'services', 'local-embeddings.js');
70
- if (!existsSync(embPath)) {
71
- throw new Error('MCP server not built. Run: cd mcp-server && npm run build');
72
- }
73
- const { generateEmbedding: embed } = await import(pathToFileURL(embPath).href);
74
- return embed(text);
75
- }
76
-
77
- // ─── Vector encoding ───
78
-
79
- function encodeVector(vector) {
80
- const f32 = new Float32Array(vector);
81
- return new Uint8Array(f32.buffer);
82
- }
83
-
84
- // ─── Database storage ───
85
-
86
- function storeInSQLite(id, vector, payload) {
87
- const db = new DatabaseSync(DB_PATH);
88
- db.exec('PRAGMA journal_mode = WAL');
89
- db.exec('PRAGMA busy_timeout = 5000');
90
-
91
- try {
92
- db.prepare(`
93
- INSERT OR REPLACE INTO memories
94
- (id, vector, content, category, subcategory, project, tags, importance, source,
95
- created_at, updated_at, accessed_at, access_count, related_files,
96
- related_memory_ids, file_checksums, trashed_at, source_session_chunks)
97
- VALUES
98
- (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
99
- `).run(
100
- id,
101
- encodeVector(vector),
102
- payload.content,
103
- payload.category,
104
- payload.subcategory || null,
105
- payload.project,
106
- JSON.stringify(payload.tags || []),
107
- payload.importance || 5,
108
- payload.source || 'auto-saved',
109
- payload.created_at,
110
- payload.updated_at,
111
- payload.accessed_at,
112
- payload.access_count || 0,
113
- null, // related_files
114
- null, // related_memory_ids
115
- null, // file_checksums
116
- null, // trashed_at
117
- null, // source_session_chunks
118
- );
119
- } finally {
120
- db.close();
121
- }
122
- }
123
-
124
- // ─── Dedup tracker ───
125
-
126
- function loadStoredPlans() {
127
- try {
128
- if (!existsSync(STORED_PLANS_PATH)) return {};
129
- return JSON.parse(readFileSync(STORED_PLANS_PATH, 'utf-8'));
130
- } catch { return {}; }
131
- }
132
-
133
- function markPlanStored(fileName, memoryId) {
134
- const stored = loadStoredPlans();
135
- stored[fileName] = { memoryId, storedAt: new Date().toISOString() };
136
- try {
137
- if (!existsSync(dirname(STORED_PLANS_PATH))) mkdirSync(dirname(STORED_PLANS_PATH), { recursive: true });
138
- writeFileSync(STORED_PLANS_PATH, JSON.stringify(stored, null, 2), 'utf-8');
139
- } catch { /* best-effort */ }
140
- }
141
-
142
- // ─── Plan file discovery ───
143
-
144
- /**
145
- * List all plan .md files, sorted by mtime descending.
146
- * Each entry: { name, path, mtime }
147
- */
148
- function listPlanFiles() {
149
- const results = [];
150
- for (const dir of [PLANS_DIR, PLANS_DIR_FALLBACK]) {
151
- if (!existsSync(dir)) continue;
152
- for (const f of readdirSync(dir).filter((f) => f.endsWith('.md'))) {
153
- // Skip duplicates (same filename in both dirs — prefer primary)
154
- if (results.some((r) => r.name === f)) continue;
155
- const fullPath = join(dir, f);
156
- const stat = statSync(fullPath);
157
- results.push({ name: f, path: fullPath, mtime: stat.mtimeMs });
158
- }
159
- }
160
- return results.sort((a, b) => b.mtime - a.mtime);
161
- }
162
-
163
- /**
164
- * Match the correct plan file using tool_response content from ExitPlanMode.
165
- * Strategies (in order):
166
- * 1. Filename extraction — tool_response may reference the plan filename
167
- * 2. Content matching — tool_response may contain the plan text; find the file whose content matches
168
- * Returns null if no match or if the matched file is already stored.
169
- */
170
- function findPlanByContent(toolResponse) {
171
- if (!toolResponse || typeof toolResponse !== 'string') return null;
172
-
173
- const stored = loadStoredPlans();
174
- const files = listPlanFiles();
175
- if (files.length === 0) return null;
176
-
177
- // Strategy 1: Extract filename pattern (word-word-word.md) from response
178
- const fnameMatch = toolResponse.match(/([a-z]+-[a-z]+-[a-z]+\.md)/);
179
- if (fnameMatch) {
180
- const matched = files.find((f) => f.name === fnameMatch[1]);
181
- if (matched && !stored[matched.name]) return { ...matched, method: 'filename' };
182
- }
183
-
184
- // Strategy 2: Content matching — compare response text against each unstored plan file
185
- // tool_response from ExitPlanMode likely contains the plan content itself
186
- const responseTrimmed = toolResponse.trim();
187
- if (responseTrimmed.length > 50) {
188
- // Extract first meaningful line (H1 heading or first paragraph) for fast pre-filter
189
- const responseFirstLine = responseTrimmed.split('\n').find((l) => l.trim())?.trim() || '';
190
-
191
- for (const file of files) {
192
- if (stored[file.name]) continue;
193
- try {
194
- const content = readFileSync(file.path, 'utf-8').trim();
195
- // Exact match
196
- if (content === responseTrimmed) return { ...file, method: 'exact-content' };
197
- // Response contains the file content (response may have extra wrapper text)
198
- if (responseTrimmed.includes(content)) return { ...file, method: 'content-in-response' };
199
- // File content contains the response (file is the full plan, response is a subset)
200
- if (content.includes(responseTrimmed)) return { ...file, method: 'response-in-content' };
201
- // First-line match as fallback (H1 heading match)
202
- if (responseFirstLine.length > 10) {
203
- const fileFirstLine = content.split('\n').find((l) => l.trim())?.trim() || '';
204
- if (fileFirstLine === responseFirstLine) return { ...file, method: 'heading-match' };
205
- }
206
- } catch { /* skip unreadable files */ }
207
- }
208
- }
209
-
210
- return null;
211
- }
212
-
213
- /**
214
- * Fallback: return the most recently modified unstored plan file.
215
- * Used only when content matching fails (no tool_response or no match).
216
- */
217
- function findLatestPlan() {
218
- const stored = loadStoredPlans();
219
- const files = listPlanFiles();
220
- if (files.length === 0) return null;
221
- const unstored = files.find((f) => !stored[f.name]);
222
- return unstored ? { ...unstored, method: 'mtime-fallback' } : null;
223
- }
224
-
225
- // ─── Category management ───
226
-
227
- function ensureProjectCategory(project) {
228
- const categoryName = `plans-${project}`;
229
- const catPath = getMcpCategoriesPath();
230
-
231
- try {
232
- const data = JSON.parse(readFileSync(catPath, 'utf-8'));
233
- const categories = data.categories || [];
234
-
235
- // Check if child category already exists
236
- if (categories.some((c) => c.name === categoryName)) {
237
- return categoryName;
238
- }
239
-
240
- // Check if "plans" parent exists
241
- if (!categories.some((c) => c.name === 'plans')) {
242
- // Create parent if missing (shouldn't happen, but safety net)
243
- categories.push({
244
- name: 'plans',
245
- description: 'Implementation plans stored after plan mode approval. Sub-categorized by project name.',
246
- is_parent: true,
247
- color: '#06d6a0',
248
- created_at: new Date().toISOString(),
249
- });
250
- }
251
-
252
- // Create child category for this project
253
- categories.push({
254
- name: categoryName,
255
- description: `Implementation plans for ${project} project`,
256
- parent: 'plans',
257
- created_at: new Date().toISOString(),
258
- });
259
-
260
- data.categories = categories;
261
- writeFileSync(catPath, JSON.stringify(data, null, 2), 'utf-8');
262
-
263
- return categoryName;
264
- } catch {
265
- // If categories file can't be read/written, fall back to parent
266
- return 'plans';
267
- }
268
- }
269
-
270
- // ─── Neural Interface cache invalidation ───
271
-
272
- async function invalidateNeuralInterface() {
273
- try {
274
- // Trigger sync broadcast so the Neural Interface graph refreshes
275
- const niUrl = process.env.SYNABUN_NI_URL || 'http://localhost:3344';
276
- await fetch(`${niUrl}/api/memories?invalidate=true`, {
277
- method: 'GET',
278
- signal: AbortSignal.timeout(2000),
279
- });
280
- } catch { /* fire-and-forget */ }
281
- }
282
-
283
- // ─── Extract plan title from markdown ───
284
-
285
- function extractPlanTitle(content) {
286
- // Look for first H1 heading
287
- const h1Match = content.match(/^#\s+(.+)$/m);
288
- if (h1Match) return h1Match[1].trim();
289
-
290
- // Fall back to first non-empty line
291
- const firstLine = content.split('\n').find((l) => l.trim());
292
- return firstLine?.trim().slice(0, 100) || 'Untitled plan';
293
- }
294
-
295
- // ─── Main ───
296
-
297
- async function main() {
298
- let input = {};
299
- try {
300
- const raw = await readStdin();
301
- input = JSON.parse(raw);
302
- } catch { /* proceed */ }
303
-
304
- const toolName = input.tool_name || '';
305
-
306
- debugLog(`Hook invoked — tool_name: "${toolName}", session: ${input.session_id || 'unknown'}, cwd: ${input.cwd || 'unknown'}`);
307
-
308
- // Handle EnterPlanMode — remind Claude to use AskUserQuestion
309
- if (toolName === 'EnterPlanMode') {
310
- debugLog('EnterPlanMode fired — injecting AskUserQuestion reminder');
311
- process.stdout.write(JSON.stringify({
312
- additionalContext: `SynaBun: You are now in plan mode. When you have questions or need clarification from the user, you MUST use the \`AskUserQuestion\` tool — do NOT write questions as plain text. Load it via \`ToolSearch\` if its schema is not yet available. Use \`ExitPlanMode\` for final plan approval.\n\n**Plan file location**: Write plan files to \`${PLANS_DIR}/\` — NOT \`~/.claude/plans/\`. This avoids sensitive-file permission prompts that stall the session.`,
313
- }));
314
- return;
315
- }
316
-
317
- // Only handle ExitPlanMode beyond this point
318
- if (toolName !== 'ExitPlanMode') {
319
- process.stdout.write(JSON.stringify({}));
320
- return;
321
- }
322
-
323
- // Match plan file: content-match first (session-accurate), mtime fallback
324
- const toolResponse = typeof input.tool_response === 'string'
325
- ? input.tool_response
326
- : (input.tool_response != null ? JSON.stringify(input.tool_response) : '');
327
-
328
- debugLog(`ExitPlanMode fired — tool_response length: ${toolResponse.length}, first 200 chars: ${toolResponse.slice(0, 200).replace(/\n/g, '\\n')}`);
329
-
330
- const planFile = findPlanByContent(toolResponse) || findLatestPlan();
331
- if (!planFile) {
332
- process.stdout.write(JSON.stringify({
333
- additionalContext: 'SynaBun: No unstored plan file found (all plans already in memory).',
334
- }));
335
- return;
336
- }
337
-
338
- const planContent = readFileSync(planFile.path, 'utf-8');
339
- if (!planContent.trim()) {
340
- process.stdout.write(JSON.stringify({}));
341
- return;
342
- }
343
-
344
- const project = detectProject(input.cwd || '');
345
- const planTitle = extractPlanTitle(planContent);
346
-
347
- // Ensure child category exists under "plans"
348
- const categoryName = ensureProjectCategory(project);
349
-
350
- // Generate local embedding (Transformers.js, no API key needed)
351
- const embedding = await generateEmbedding(planContent);
352
-
353
- // Store in SQLite
354
- const id = randomUUID();
355
- const now = new Date().toISOString();
356
-
357
- storeInSQLite(id, embedding, {
358
- content: planContent,
359
- category: categoryName,
360
- project,
361
- importance: 7,
362
- tags: ['plan', 'implementation', project],
363
- source: 'auto-saved',
364
- subcategory: 'plan',
365
- created_at: now,
366
- updated_at: now,
367
- accessed_at: now,
368
- access_count: 0,
369
- });
370
-
371
- // Mark this plan as stored (dedup for future ExitPlanMode calls)
372
- markPlanStored(planFile.name, id);
373
-
374
- // Invalidate Neural Interface cache (fire-and-forget)
375
- invalidateNeuralInterface();
376
-
377
- // Confirm storage — include match method for diagnostics
378
- const shortTitle = planTitle.length > 60 ? planTitle.slice(0, 60) + '...' : planTitle;
379
- const matchInfo = planFile.method || 'unknown';
380
- debugLog(`Stored plan: ${planFile.name} [${matchInfo}] → memory ${id} (project: ${project})`);
381
- process.stdout.write(JSON.stringify({
382
- additionalContext: `SynaBun: Plan stored in memory [${id}] — "${shortTitle}" (category: ${categoryName}, project: ${project}). Source file: ${planFile.name} [matched: ${matchInfo}]`,
383
- }));
384
- }
385
-
386
- main().catch((err) => {
387
- // On error, still output valid JSON so Claude Code doesn't break
388
- process.stdout.write(JSON.stringify({
389
- additionalContext: `SynaBun: Plan storage failed — ${err.message}. The plan file is still saved at ${PLANS_DIR}.`,
390
- }));
391
- });
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * SynaBun PostToolUse Hook — Plan Storage
5
+ *
6
+ * Matches: ^(Enter|Exit)PlanMode$
7
+ *
8
+ * EnterPlanMode: Injects a reminder to use AskUserQuestion for
9
+ * clarifications instead of plain-text questions.
10
+ *
11
+ * ExitPlanMode: When Claude exits plan mode (plan approved), this hook:
12
+ * 1. Migrates any legacy flat plans to date-organized folders (first run only)
13
+ * 2. Finds the most recently modified plan file in data/plans/YYYY-MM-DD/
14
+ * 3. Auto-creates a child category under "plans" for the project if needed
15
+ * 4. Generates a local embedding and stores the plan in SQLite
16
+ * 5. Meanwhile asks the Neural Interface (kind `plan-conflict`) whether the
17
+ * plan contradicts stored project decisions — advisory only, never blocks
18
+ * 6. Returns additionalContext confirming storage + plan file path, plus the
19
+ * advisory line when conflicts came back
20
+ *
21
+ * Input (stdin JSON):
22
+ * { session_id, tool_name, tool_input, tool_response, cwd }
23
+ *
24
+ * Output (stdout JSON):
25
+ * { hookSpecificOutput: { hookEventName, additionalContext } } on success,
26
+ * or {} on skip/error. See emitContext().
27
+ */
28
+
29
+ import { readFileSync, writeFileSync, appendFileSync, readdirSync, statSync, existsSync, mkdirSync, renameSync, unlinkSync } from 'node:fs';
30
+ import { dirname, join, basename } from 'node:path';
31
+ import { fileURLToPath, pathToFileURL } from 'node:url';
32
+ import { createHash } from 'node:crypto';
33
+ import { withStateLock, writeJsonAtomic, planMemoryKey } from './state.mjs';
34
+ import { detectProject, getMcpCategoriesPath, MCP_DATA_DIR, DATA_DIR, readStdin, hookBudget, hookJudge, clipForJudge, isTemporaryChat } from './shared.mjs';
35
+
36
+ // Cross-platform safety: catch uncaught errors and output valid hook JSON
37
+ process.on('uncaughtException', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
38
+ process.on('unhandledRejection', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
39
+
40
+ const __dirname = dirname(fileURLToPath(import.meta.url));
41
+
42
+ /**
43
+ * Emit additionalContext in the shape PostToolUse actually reads. A bare
44
+ * top-level { additionalContext } is accepted as valid JSON and then silently
45
+ * discarded, so every message written that way never reaches the model.
46
+ */
47
+ function emitContext(text) {
48
+ process.stdout.write(JSON.stringify({
49
+ hookSpecificOutput: { hookEventName: 'PostToolUse', additionalContext: text },
50
+ }));
51
+ }
52
+
53
+ // Debug log (append-only, survives across invocations)
54
+ const DEBUG_LOG_PATH = join(DATA_DIR, 'plan-debug.log');
55
+ function debugLog(msg) {
56
+ try {
57
+ const ts = new Date().toISOString();
58
+ appendFileSync(DEBUG_LOG_PATH, `[${ts}] ${msg}\n`, 'utf-8');
59
+ } catch { /* best-effort */ }
60
+ }
61
+
62
+ // Plans directory — project-local to avoid ~/.claude/ sensitive-file permission prompts
63
+ const PLANS_DIR = join(DATA_DIR, 'plans');
64
+ // Fallback: Claude Code's ExitPlanMode may still write to ~/.claude/plans/ internally
65
+ const PLANS_DIR_FALLBACK = join(process.env.USERPROFILE || process.env.HOME || '', '.claude', 'plans');
66
+ // Migration marker — presence means flat-plan migration has already run
67
+ const MIGRATION_MARKER = join(PLANS_DIR, '.migrated');
68
+
69
+ // Dedup tracker — records which plan files have already been stored
70
+ const STORED_PLANS_PATH = join(DATA_DIR, 'stored-plans.json');
71
+
72
+ // ─── Plan check against stored decisions (advisory) ───
73
+
74
+ const budget = hookBudget(15000);
75
+ let conflictCheck = null;
76
+
77
+ // Always resolves; [] when unavailable (SYNABUN_TYPESAFE=off, old server, timeout).
78
+ async function planConflicts(plan, { project, sessionId, cwd, excludeIds }) {
79
+ const text = plan.length > 16000 ? clipForJudge(plan, 16000, 12000) : plan;
80
+ const answer = await hookJudge('plan-conflict', {
81
+ text, project, exclude_ids: excludeIds, session_id: sessionId || undefined, cwd: cwd || undefined,
82
+ }, { timeoutMs: Math.min(5000, budget.callTimeout(1000)) });
83
+ return Array.isArray(answer?.conflicts)
84
+ ? answer.conflicts.filter((c) => c && typeof c.id === 'string' && c.id).slice(0, 3)
85
+ : [];
86
+ }
87
+
88
+ function formatPlanConflicts(conflicts) {
89
+ if (!Array.isArray(conflicts) || !conflicts.length) return '';
90
+ const items = conflicts.map((c) => {
91
+ const p = Number(c.probability);
92
+ const meta = [
93
+ c.probability !== undefined && c.probability !== null && Number.isFinite(p) ? `p=${p.toFixed(2)}` : '',
94
+ typeof c.category === 'string' ? c.category : '',
95
+ typeof c.created_at === 'string' ? c.created_at.slice(0, 10) : '',
96
+ ].filter(Boolean).join(', ');
97
+ const excerpt = String(c.excerpt ?? '').replace(/\s+/g, ' ').trim().slice(0, 160).replace(/"/g, "'");
98
+ return `[${c.id}]${meta ? ` (${meta})` : ''}${excerpt ? ` "${excerpt}"` : ''}`;
99
+ });
100
+ return `SynaBun [Jev] plan check (advisory): this plan may contradict stored decisions — ${items.join('; ')}. Confirm with the user or state why the decision changed before implementing.`;
101
+ }
102
+
103
+ // The same transactional writer as the MCP remember tool owns plan writes.
104
+ async function storePlan(payload, options) {
105
+ const modulePath = join(__dirname, '../../mcp-server/dist/services/memory-writer.js');
106
+ const { writeMemory } = await import(pathToFileURL(modulePath).href);
107
+ const { getDb } = await import(pathToFileURL(join(__dirname, '../../mcp-server/dist/services/sqlite.js')).href);
108
+ const { closeDatabase } = await import(pathToFileURL(join(__dirname, '../../mcp-server/dist/services/sqlite.js')).href);
109
+ const { closeEmbeddings } = await import(pathToFileURL(join(__dirname, '../../mcp-server/dist/services/local-embeddings.js')).href);
110
+ withStateLock(() => getDb()); // Serialize cold schema/WAL initialization too.
111
+ try { return await writeMemory(payload, options); }
112
+ finally { await closeEmbeddings(); closeDatabase(); }
113
+ }
114
+
115
+ // ─── Dedup tracker ───
116
+
117
+ function loadStoredPlans() {
118
+ try {
119
+ if (!existsSync(STORED_PLANS_PATH)) return {};
120
+ return JSON.parse(readFileSync(STORED_PLANS_PATH, 'utf-8'));
121
+ } catch { return {}; }
122
+ }
123
+
124
+ // `key` is the content-addressed plan identity (the one stop.mjs recomputes and
125
+ // looks up); `fileNames` are convenience aliases — our own copy's basename plus
126
+ // Claude Code's, when ExitPlanMode told us about it.
127
+ function markPlanStored(fileNames, memoryId, contentHash, key, project, sourcePath) {
128
+ withStateLock(() => {
129
+ const stored = loadStoredPlans();
130
+ const receipt = { memoryId, contentHash, project, sourcePath, storedAt: new Date().toISOString() };
131
+ for (const name of new Set(fileNames.filter(Boolean))) stored[name] = receipt;
132
+ stored[key] = receipt;
133
+ writeJsonAtomic(STORED_PLANS_PATH, stored);
134
+ });
135
+ }
136
+
137
+ // ─── Date folder helpers ───
138
+
139
+ /**
140
+ * Returns today's date folder path: data/plans/YYYY-MM-DD/
141
+ */
142
+ function getTodayPlanDir() {
143
+ const d = new Date();
144
+ const ymd = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
145
+ return join(PLANS_DIR, ymd);
146
+ }
147
+
148
+ /**
149
+ * Returns YYYY-MM-DD string from a timestamp (ms).
150
+ */
151
+ function dateFromMs(ms) {
152
+ const d = new Date(ms);
153
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
154
+ }
155
+
156
+ /**
157
+ * Convert a plan title to a URL-safe filename slug.
158
+ * Strips leading "Plan:" prefix, lowercases, replaces non-alphanumeric with hyphens.
159
+ */
160
+ function slugify(title) {
161
+ return (title || 'untitled')
162
+ .toLowerCase()
163
+ .replace(/^plan[:\s]+/i, '') // strip leading "Plan: " prefix
164
+ .replace(/[^a-z0-9]+/g, '-') // replace non-alphanumeric runs with hyphen
165
+ .replace(/^-+|-+$/g, '') // trim leading/trailing hyphens
166
+ .slice(0, 60) // max 60 chars
167
+ || 'untitled';
168
+ }
169
+
170
+ /**
171
+ * Resolve a unique filename in targetDir for slug.md.
172
+ * If slug.md already exists, appends -2, -3, etc.
173
+ */
174
+ function uniqueSlugPath(targetDir, slug) {
175
+ let candidate = join(targetDir, `${slug}.md`);
176
+ if (!existsSync(candidate)) return candidate;
177
+ let n = 2;
178
+ while (existsSync(join(targetDir, `${slug}-${n}.md`))) n++;
179
+ return join(targetDir, `${slug}-${n}.md`);
180
+ }
181
+
182
+ // ─── Extract plan title from markdown ───
183
+
184
+ function extractPlanTitle(content) {
185
+ // Look for first H1 heading
186
+ const h1Match = content.match(/^#\s+(.+)$/m);
187
+ if (h1Match) return h1Match[1].trim();
188
+
189
+ // Fall back to first non-empty line
190
+ const firstLine = content.split('\n').find((l) => l.trim());
191
+ return firstLine?.trim().slice(0, 100) || 'Untitled plan';
192
+ }
193
+
194
+ // ─── One-time migration: flat plans → date-organized folders ───
195
+
196
+ /**
197
+ * Migrates legacy flat .md files from data/plans/ into data/plans/YYYY-MM-DD/slug.md.
198
+ * Runs only once (marker file data/plans/.migrated).
199
+ * Updates stored-plans.json keys to reflect new basenames.
200
+ */
201
+ function migrateFlatPlans() {
202
+ if (existsSync(MIGRATION_MARKER)) return; // already done
203
+
204
+ if (!existsSync(PLANS_DIR)) return;
205
+
206
+ const entries = readdirSync(PLANS_DIR);
207
+ const flatFiles = entries.filter((f) => f.endsWith('.md') && !f.startsWith('.'));
208
+ if (flatFiles.length === 0) {
209
+ // Nothing to migrate — just write the marker
210
+ try { writeFileSync(MIGRATION_MARKER, '', 'utf-8'); } catch { /* ok */ }
211
+ return;
212
+ }
213
+
214
+ const stored = loadStoredPlans();
215
+ const updatedStored = { ...stored };
216
+ let moved = 0;
217
+
218
+ for (const fname of flatFiles) {
219
+ const oldPath = join(PLANS_DIR, fname);
220
+ try {
221
+ const stat = statSync(oldPath);
222
+ const dateStr = dateFromMs(stat.mtimeMs);
223
+ const content = readFileSync(oldPath, 'utf-8');
224
+ const title = extractPlanTitle(content);
225
+ const slug = slugify(title);
226
+
227
+ const targetDir = join(PLANS_DIR, dateStr);
228
+ mkdirSync(targetDir, { recursive: true });
229
+
230
+ const targetPath = uniqueSlugPath(targetDir, slug);
231
+ const newBasename = targetPath.split('/').pop();
232
+
233
+ renameSync(oldPath, targetPath);
234
+ moved++;
235
+
236
+ // Update stored-plans.json: old key → new key, preserve value
237
+ if (updatedStored[fname]) {
238
+ updatedStored[newBasename] = updatedStored[fname];
239
+ delete updatedStored[fname];
240
+ }
241
+
242
+ debugLog(`Migrated: ${fname} → ${dateStr}/${newBasename}`);
243
+ } catch (err) {
244
+ debugLog(`Migration skip: ${fname} — ${err.message}`);
245
+ }
246
+ }
247
+
248
+ // Persist updated stored-plans.json
249
+ try {
250
+ writeFileSync(STORED_PLANS_PATH, JSON.stringify(updatedStored, null, 2), 'utf-8');
251
+ } catch { /* best-effort */ }
252
+
253
+ // Write migration marker
254
+ try { writeFileSync(MIGRATION_MARKER, new Date().toISOString(), 'utf-8'); } catch { /* ok */ }
255
+
256
+ debugLog(`Migration complete: ${moved}/${flatFiles.length} files moved`);
257
+ }
258
+
259
+ // ─── Plan file discovery ───
260
+
261
+ /**
262
+ * List all plan .md files from date-organized subdirectories and legacy flat files.
263
+ * Sorted by mtime descending.
264
+ * Each entry: { name, path, mtime }
265
+ */
266
+ function listPlanFiles() {
267
+ const results = [];
268
+
269
+ // Primary: scan PLANS_DIR — date subdirectories (YYYY-MM-DD/) and any remaining flat files
270
+ if (existsSync(PLANS_DIR)) {
271
+ for (const entry of readdirSync(PLANS_DIR)) {
272
+ if (entry.startsWith('.')) continue; // skip .migrated, .gitkeep, etc.
273
+ const entryPath = join(PLANS_DIR, entry);
274
+ const entryStat = statSync(entryPath);
275
+
276
+ if (entryStat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(entry)) {
277
+ // Date folder — scan .md files inside
278
+ for (const f of readdirSync(entryPath).filter((f) => f.endsWith('.md'))) {
279
+ const fullPath = join(entryPath, f);
280
+ const stat = statSync(fullPath);
281
+ results.push({ name: f, path: fullPath, mtime: stat.mtimeMs });
282
+ }
283
+ } else if (entry.endsWith('.md')) {
284
+ // Legacy flat file still in root of PLANS_DIR
285
+ results.push({ name: entry, path: entryPath, mtime: entryStat.mtimeMs });
286
+ }
287
+ }
288
+ }
289
+
290
+ // Fallback: scan ~/.claude/plans/ (flat only)
291
+ if (existsSync(PLANS_DIR_FALLBACK)) {
292
+ for (const f of readdirSync(PLANS_DIR_FALLBACK).filter((f) => f.endsWith('.md'))) {
293
+ if (results.some((r) => r.name === f)) continue; // skip duplicates
294
+ const fullPath = join(PLANS_DIR_FALLBACK, f);
295
+ const stat = statSync(fullPath);
296
+ results.push({ name: f, path: fullPath, mtime: stat.mtimeMs });
297
+ }
298
+ }
299
+
300
+ return results.sort((a, b) => b.mtime - a.mtime);
301
+ }
302
+
303
+ /**
304
+ * Match the correct plan file using tool_response content from ExitPlanMode.
305
+ * Strategies (in order):
306
+ * 1. Filename extraction — tool_response may reference the plan filename
307
+ * 2. Content matching — tool_response may contain the plan text; find the file whose content matches
308
+ * Returns null if no match or if the matched file is already stored.
309
+ */
310
+ function findPlanByContent(toolResponse) {
311
+ if (!toolResponse || typeof toolResponse !== 'string') return null;
312
+
313
+ const stored = loadStoredPlans();
314
+ const files = listPlanFiles();
315
+ if (files.length === 0) return null;
316
+
317
+ // Strategy 1: Extract filename pattern (kebab-slug.md) from response
318
+ const fnameMatch = toolResponse.match(/([a-z][a-z0-9-]+\.md)/);
319
+ if (fnameMatch) {
320
+ const matched = files.find((f) => f.name === fnameMatch[1]);
321
+ if (matched) return { ...matched, method: 'filename' };
322
+ }
323
+
324
+ // Strategy 2: Content matching — compare response text against each unstored plan file
325
+ const responseTrimmed = toolResponse.trim();
326
+ if (responseTrimmed.length > 50) {
327
+ const responseFirstLine = responseTrimmed.split('\n').find((l) => l.trim())?.trim() || '';
328
+
329
+ for (const file of files) {
330
+ try {
331
+ const content = readFileSync(file.path, 'utf-8').trim();
332
+ if (content === responseTrimmed) return { ...file, method: 'exact-content' };
333
+ if (responseTrimmed.includes(content)) return { ...file, method: 'content-in-response' };
334
+ if (content.includes(responseTrimmed)) return { ...file, method: 'response-in-content' };
335
+ if (responseFirstLine.length > 10) {
336
+ const fileFirstLine = content.split('\n').find((l) => l.trim())?.trim() || '';
337
+ if (fileFirstLine === responseFirstLine) return { ...file, method: 'heading-match' };
338
+ }
339
+ } catch { /* skip unreadable files */ }
340
+ }
341
+ }
342
+
343
+ return null;
344
+ }
345
+
346
+ /**
347
+ * Fallback: return the most recently modified unstored plan file.
348
+ */
349
+ function findLatestPlan() {
350
+ const stored = loadStoredPlans();
351
+ const files = listPlanFiles();
352
+ if (files.length === 0) return null;
353
+ const unstored = files.find((f) => !stored[f.name]);
354
+ return unstored ? { ...unstored, method: 'mtime-fallback' } : null;
355
+ }
356
+
357
+ // ─── Category management ───
358
+
359
+ function ensureProjectCategory(project) {
360
+ const categoryName = `plans-${project}`;
361
+ const catPath = getMcpCategoriesPath();
362
+
363
+ try {
364
+ const data = JSON.parse(readFileSync(catPath, 'utf-8'));
365
+ const categories = data.categories || [];
366
+
367
+ if (categories.some((c) => c.name === categoryName)) {
368
+ return categoryName;
369
+ }
370
+
371
+ if (!categories.some((c) => c.name === 'plans')) {
372
+ categories.push({
373
+ name: 'plans',
374
+ description: 'Implementation plans stored after plan mode approval. Sub-categorized by project name.',
375
+ is_parent: true,
376
+ color: '#06d6a0',
377
+ created_at: new Date().toISOString(),
378
+ });
379
+ }
380
+
381
+ categories.push({
382
+ name: categoryName,
383
+ description: `Implementation plans for ${project} project`,
384
+ parent: 'plans',
385
+ created_at: new Date().toISOString(),
386
+ });
387
+
388
+ data.categories = categories;
389
+ writeFileSync(catPath, JSON.stringify(data, null, 2), 'utf-8');
390
+
391
+ return categoryName;
392
+ } catch {
393
+ return 'plans';
394
+ }
395
+ }
396
+
397
+ // ─── Root PLAN.md cleanup ───
398
+
399
+ /**
400
+ * If a PLAN.md exists at the project root and was modified within the last 60s,
401
+ * delete it. Prevents root-level clutter when Claude Code's ExitPlanMode creates it.
402
+ */
403
+ function cleanupRootPlanMd(cwd) {
404
+ if (!cwd) return;
405
+ const rootPlan = join(cwd, 'PLAN.md');
406
+ try {
407
+ if (!existsSync(rootPlan)) return;
408
+ const stat = statSync(rootPlan);
409
+ if (Date.now() - stat.mtimeMs < 60_000) {
410
+ unlinkSync(rootPlan);
411
+ debugLog(`Deleted root PLAN.md at ${rootPlan}`);
412
+ }
413
+ } catch { /* best-effort */ }
414
+ }
415
+
416
+ // ─── Main ───
417
+
418
+ async function main() {
419
+ let input = {};
420
+ try {
421
+ const raw = await readStdin();
422
+ input = JSON.parse(raw);
423
+ } catch { /* proceed */ }
424
+
425
+ // A temporary chat (see isTemporaryChat): its plan is not stored as a file or
426
+ // a memory, and it is not told where SynaBun keeps plans.
427
+ if (isTemporaryChat()) { process.stdout.write(JSON.stringify({})); return; }
428
+
429
+ const toolName = input.tool_name || '';
430
+
431
+ debugLog(`Hook invoked — tool_name: "${toolName}", session: ${input.session_id || 'unknown'}, cwd: ${input.cwd || 'unknown'}`);
432
+
433
+ // Handle EnterPlanMode — remind Claude to use AskUserQuestion + new plan path format
434
+ if (toolName === 'EnterPlanMode') {
435
+ debugLog('EnterPlanMode fired — injecting AskUserQuestion reminder');
436
+ const todayDir = getTodayPlanDir();
437
+ emitContext(`SynaBun: You are now in plan mode.\n\n**CRITICAL CONSTRAINT**: Do NOT make code changes (Edit, Write, NotebookEdit). Plan mode is RESEARCH AND PLANNING ONLY. Investigate, read files, search code — then present your plan. Do NOT implement anything until the user explicitly approves the plan and you exit plan mode.\n\nWhen you have questions or need clarification, you MUST use the \`AskUserQuestion\` tool — do NOT write questions as plain text. Load it via \`ToolSearch\` if its schema is not yet available. Use \`ExitPlanMode\` for final plan approval.\n\n**Plan file location**: Write plan files to \`${todayDir}/your-plan-slug.md\` — use a short descriptive slug derived from the plan title (e.g., \`fix-session-crosstalk.md\`, \`opencode-sidepanel.md\`). Do NOT create \`PLAN.md\` at the project root. Do NOT write to \`~/.claude/plans/\`.`);
438
+ return;
439
+ }
440
+
441
+ // Only handle ExitPlanMode beyond this point
442
+ if (toolName !== 'ExitPlanMode') {
443
+ process.stdout.write(JSON.stringify({}));
444
+ return;
445
+ }
446
+
447
+ // Run one-time migration of legacy flat plans before discovery
448
+ try { withStateLock(() => migrateFlatPlans()); } catch (err) {
449
+ debugLog(`Migration error (non-fatal): ${err.message}`);
450
+ }
451
+
452
+ // Clean up root PLAN.md if it was just created
453
+ cleanupRootPlanMd(input.cwd || '');
454
+
455
+ // Authoritative plan markdown lives in tool_input.plan (and is echoed in tool_response.plan).
456
+ // Pull it directly so we can author the file ourselves if the UI capture failed.
457
+ function readPlanField(obj) {
458
+ if (!obj) return '';
459
+ if (typeof obj === 'string') {
460
+ try {
461
+ const parsed = JSON.parse(obj);
462
+ if (parsed && typeof parsed.plan === 'string') return parsed.plan;
463
+ } catch { /* not JSON — fall through */ }
464
+ return '';
465
+ }
466
+ if (typeof obj === 'object' && typeof obj.plan === 'string') return obj.plan;
467
+ return '';
468
+ }
469
+ // Same tolerance for planFilePath: the old guard required tool_input to be an
470
+ // object, so a JSON-string payload silently dropped the path.
471
+ function readPlanFilePath(obj) {
472
+ if (!obj) return '';
473
+ if (typeof obj === 'string') {
474
+ try {
475
+ const parsed = JSON.parse(obj);
476
+ if (parsed && typeof parsed.planFilePath === 'string') return parsed.planFilePath;
477
+ } catch { /* not JSON — fall through */ }
478
+ return '';
479
+ }
480
+ if (typeof obj === 'object' && typeof obj.planFilePath === 'string') return obj.planFilePath;
481
+ return '';
482
+ }
483
+ const authoritativePlan =
484
+ readPlanField(input.tool_input) ||
485
+ readPlanField(input.tool_response);
486
+
487
+ // Match plan file: content-match first (session-accurate), mtime fallback
488
+ const toolResponse = typeof input.tool_response === 'string'
489
+ ? input.tool_response
490
+ : (input.tool_response != null ? JSON.stringify(input.tool_response) : '');
491
+
492
+ debugLog(`ExitPlanMode fired — tool_response length: ${toolResponse.length}, authoritativePlan length: ${authoritativePlan.length}, first 200 chars: ${toolResponse.slice(0, 200).replace(/\n/g, '\\n')}`);
493
+
494
+ let planFile = null;
495
+
496
+ // Happy path: ExitPlanMode hands us the authoritative plan AND its file path,
497
+ // so we mirror it under that basename instead of mtime-guessing across
498
+ // sessions. Dedup no longer rides on the filename — planMemoryKey hashes the
499
+ // plan text — but recording the path still lets stop.mjs's basename alias and
500
+ // the source_ref point at the file the user actually approved.
501
+ const planFilePathInput =
502
+ readPlanFilePath(input.tool_input) || readPlanFilePath(input.tool_response);
503
+ if (planFilePathInput && authoritativePlan) {
504
+ const base = basename(planFilePathInput);
505
+ try {
506
+ const todayDir = getTodayPlanDir();
507
+ mkdirSync(todayDir, { recursive: true });
508
+ const targetPath = join(todayDir, base);
509
+ writeFileSync(targetPath, authoritativePlan, 'utf-8');
510
+ const stat = statSync(targetPath);
511
+ planFile = { name: base, path: targetPath, mtime: stat.mtimeMs, method: 'planFilePath' };
512
+ debugLog(`Authored plan from planFilePath: ${targetPath}`);
513
+ } catch (err) {
514
+ debugLog(`Failed to author from planFilePath (${base}): ${err.message}`);
515
+ }
516
+ }
517
+
518
+ // Fallback (older Claude Code without planFilePath, or authoring failed):
519
+ // content-match against existing files, then mtime, then author from content.
520
+ if (!planFile) {
521
+ planFile = findPlanByContent(authoritativePlan || toolResponse) || findLatestPlan();
522
+
523
+ // If a match was found but its content doesn't match the authoritative plan,
524
+ // it's stale. Drop it so we author a fresh file from tool_input.plan instead.
525
+ if (planFile && authoritativePlan) {
526
+ try {
527
+ const existing = readFileSync(planFile.path, 'utf-8').trim();
528
+ if (existing !== authoritativePlan.trim()) {
529
+ debugLog(`Match stale (file != tool_input.plan) — discarding ${planFile.path}, will author from tool_input`);
530
+ planFile = null;
531
+ }
532
+ } catch { /* unreadable — fall through to authoring */ planFile = null; }
533
+ }
534
+
535
+ // Author the plan file ourselves if no match and we have authoritative content.
536
+ if (!planFile && authoritativePlan) {
537
+ try {
538
+ const todayDir = getTodayPlanDir();
539
+ mkdirSync(todayDir, { recursive: true });
540
+ const title = extractPlanTitle(authoritativePlan);
541
+ const slug = slugify(title);
542
+ const targetPath = uniqueSlugPath(todayDir, slug);
543
+ writeFileSync(targetPath, authoritativePlan, 'utf-8');
544
+ const stat = statSync(targetPath);
545
+ planFile = {
546
+ name: targetPath.split(/[/\\]/).pop(),
547
+ path: targetPath,
548
+ mtime: stat.mtimeMs,
549
+ method: 'authored-from-tool_input',
550
+ };
551
+ debugLog(`Authored plan file from tool_input.plan: ${targetPath}`);
552
+ } catch (err) {
553
+ debugLog(`Failed to author plan file: ${err.message}`);
554
+ }
555
+ }
556
+ }
557
+
558
+ if (!planFile) {
559
+ emitContext('SynaBun: No plan file found and no plan content in tool_input — UI capture and hook authoring both failed.');
560
+ return;
561
+ }
562
+
563
+ const planContent = authoritativePlan || readFileSync(planFile.path, 'utf-8');
564
+ if (!planContent.trim()) {
565
+ process.stdout.write(JSON.stringify({}));
566
+ return;
567
+ }
568
+
569
+ const project = detectProject(input.cwd || '');
570
+ const planTitle = extractPlanTitle(planContent);
571
+
572
+ // Ensure child category exists under "plans"
573
+ const categoryName = withStateLock(() => ensureProjectCategory(project));
574
+
575
+ const now = new Date().toISOString();
576
+ const originalPath = planFilePathInput || planFile.path;
577
+ // Identity is the plan text, not the path — stop.mjs recomputes this exact key
578
+ // from the transcript's ExitPlanMode payload and finds our receipt.
579
+ const planKey = planMemoryKey(project, planContent);
580
+ const storedPlans = loadStoredPlans();
581
+ const previous = storedPlans[planKey] || storedPlans[planFile.name];
582
+ // In parallel with the write (which loads the embedding model): the plan
583
+ // check needs the network, the write needs the CPU.
584
+ conflictCheck = planConflicts(planContent, {
585
+ project, sessionId: input.session_id, cwd: input.cwd || '',
586
+ excludeIds: previous?.memoryId ? [previous.memoryId] : [],
587
+ });
588
+ const result = await storePlan({
589
+ content: planContent, category: categoryName, project, importance: 7,
590
+ tags: ['plan', 'implementation', project], source: 'auto-saved', subcategory: 'plan',
591
+ created_at: now, updated_at: now, accessed_at: now, access_count: 0,
592
+ }, {
593
+ idempotencyKey: planKey,
594
+ sourceRef: originalPath, kind: 'decision', existingId: previous?.memoryId,
595
+ });
596
+ const id = result.id;
597
+ markPlanStored([planFile.name, planFilePathInput && basename(planFilePathInput)],
598
+ id, createHash('sha256').update(planContent).digest('hex'), planKey, project, originalPath);
599
+
600
+ // Confirm storage — include full plan file path for future NI edit wiring
601
+ const shortTitle = planTitle.length > 60 ? planTitle.slice(0, 60) + '...' : planTitle;
602
+ const matchInfo = planFile.method || 'unknown';
603
+ debugLog(`Stored plan: ${planFile.path} [${matchInfo}] → memory ${id} (project: ${project})`);
604
+ const advisory = formatPlanConflicts(await conflictCheck);
605
+ emitContext(`SynaBun: Plan stored in memory [${id}] — "${shortTitle}" (category: ${categoryName}, project: ${project}). Plan file: ${planFile.path} [matched: ${matchInfo}]${advisory ? `\n\n${advisory}` : ''}`);
606
+ }
607
+
608
+ main().catch(async (err) => {
609
+ // On error, still output valid JSON so Claude Code doesn't break
610
+ let advisory = '';
611
+ try { advisory = conflictCheck ? formatPlanConflicts(await conflictCheck) : ''; } catch { /* advisory only */ }
612
+ emitContext(`SynaBun: Plan storage failed — ${err.message}. The plan file is still saved at ${PLANS_DIR}.${advisory ? `\n\n${advisory}` : ''}`);
613
+ });