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
@@ -13,8 +13,16 @@
13
13
  * MCP tool), blocks Claude to continue the next iteration until
14
14
  * iteration cap or time cap is reached.
15
15
  *
16
- * 2. TASK MEMORY — If 3+ file edits have occurred without a `remember`
16
+ * 2. TASK MEMORY — If file edits have occurred without a `remember`
17
17
  * call, blocks Claude to store the work. Also catches unstored plans.
18
+ * Jev (stop-turn) decides whether the edits are worth a memory, whether a
19
+ * Bash-only turn's shell work is (CHECK 2b), and whether the final message
20
+ * claims a result the turn's output does not show (CHECK 6, at most one
21
+ * block per prompt). Stale-memory verdicts join the unstored-work reason.
22
+ *
23
+ * The turn judgment and a hook loop's goal judgment run in parallel inside
24
+ * the 3 s budget; native and exec loops are never judged (their runtimes own
25
+ * the iteration, and the answer used to be thrown away).
18
26
  *
19
27
  * Safety: Max 3 retries per flag to prevent infinite loops.
20
28
  * Loop: Iteration cap is authoritative. Inactivity (45 min) catches stuck loops.
@@ -28,22 +36,150 @@
28
36
  * {} to allow Claude to stop normally
29
37
  */
30
38
 
31
- import { readFileSync, writeFileSync, existsSync, unlinkSync, appendFileSync, readdirSync, renameSync, statSync } from 'node:fs';
32
- import { dirname, join } from 'node:path';
39
+ import { readFileSync, writeFileSync, existsSync, unlinkSync, appendFileSync, readdirSync, renameSync, statSync, mkdirSync } from 'node:fs';
40
+ import { dirname, join, basename } from 'node:path';
33
41
  import { fileURLToPath } from 'node:url';
34
- import { cleanupStaleLoops, detectProject } from './shared.mjs';
42
+ import { withStateLock, writeJsonAtomic, compactionSourceRef, planMemoryKey, planReceiptMatches, planStoredInDb } from './state.mjs';
43
+ import { cleanupStaleLoops, detectProject, DATA_DIR, appendLoopLog, appendCapped, resolveTranscriptPath, readLastExitPlanMode, judgeText,
44
+ hookBudget, typesafeOff, readTurnActivity, readLastAssistantText, formatStaleNotices, isReadOnlyCommand, clipForJudge, isTemporaryChat } from './shared.mjs';
45
+
46
+ // Cross-platform safety: catch uncaught errors and output valid hook JSON
47
+ process.on('uncaughtException', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
48
+ process.on('unhandledRejection', () => { try { process.stdout.write('{}'); } catch {} process.exit(0); });
35
49
 
36
50
  const __dirname = dirname(fileURLToPath(import.meta.url));
37
- const DATA_DIR = join(__dirname, '..', '..', 'data');
38
51
  const PENDING_COMPACT_DIR = join(DATA_DIR, 'pending-compact');
39
52
  const LOOP_DIR = join(DATA_DIR, 'loop');
53
+ const ACTIVE_POINTER_PATH = join(LOOP_DIR, 'active-pointer.json');
54
+
55
+ function writeActivePointer(sessionId, terminalSessionId, claudeSessionId) {
56
+ try {
57
+ const payload = {
58
+ sessionId,
59
+ terminalSessionId: terminalSessionId || null,
60
+ claudeSessionId: claudeSessionId || null,
61
+ updatedAt: new Date().toISOString(),
62
+ };
63
+ writeJsonAtomic(ACTIVE_POINTER_PATH, payload);
64
+ } catch { /* ok */ }
65
+ }
66
+
67
+ function clearActivePointer() {
68
+ try { if (existsSync(ACTIVE_POINTER_PATH)) unlinkSync(ACTIVE_POINTER_PATH); } catch { /* ok */ }
69
+ }
40
70
  const PENDING_REMEMBER_DIR = join(DATA_DIR, 'pending-remember');
71
+
72
+ // Read-only peeks taken BEFORE the state lock, so the judgments they feed can
73
+ // run outside it (state.mjs refuses async work inside withStateLock). Every
74
+ // consumer re-reads the real state under the lock; these only shape the
75
+ // question, never the decision.
76
+ function peekPendingRemember(sessionId) {
77
+ try {
78
+ const flag = JSON.parse(readFileSync(join(PENDING_REMEMBER_DIR, `${sessionId}.json`), 'utf-8'));
79
+ return {
80
+ files: Array.isArray(flag.files) ? flag.files.slice(0, 20) : [], editCount: flag.editCount || 0,
81
+ claimBlockedPromptId: typeof flag.claimBlockedPromptId === 'string' ? flag.claimBlockedPromptId : null,
82
+ };
83
+ } catch { return { files: [], editCount: 0, claimBlockedPromptId: null }; }
84
+ }
85
+
86
+ const LOOP_INACTIVE_MS = 45 * 60 * 1000;
87
+ const loopKind = (loop) => (loop.driverType === 'native' ? 'native' : loop.driverType === 'exec' ? 'exec' : 'hook');
88
+ const loopIsStale = (loop, now = Date.now()) => now - new Date(loop.lastIterationAt || loop.startedAt || 0).getTime() > LOOP_INACTIVE_MS;
89
+
90
+ /**
91
+ * Which loop owns this Stop, resolved the way handleStop resolves it, but
92
+ * read-only (no /clear rename, no cleanup): the native loop of this terminal,
93
+ * the exact session file, then the terminalSessionId scan that finds a hook
94
+ * loop after /clear gave the session a new id.
95
+ * Returns { kind: 'native'|'exec'|'hook'|null, loop }.
96
+ */
97
+ function peekLoop(sessionId) {
98
+ const terminalSessionEnv = process.env.SYNABUN_TERMINAL_SESSION || '';
99
+ if (terminalSessionEnv) {
100
+ try {
101
+ const nativeLoop = JSON.parse(readFileSync(join(LOOP_DIR, `${terminalSessionEnv}.json`), 'utf-8'));
102
+ if (nativeLoop?.active && nativeLoop.driverType === 'native'
103
+ && nativeLoop.terminalSessionId === terminalSessionEnv) return { kind: 'native', loop: nativeLoop };
104
+ } catch { /* no native loop for this terminal */ }
105
+ }
106
+ const exactPath = join(LOOP_DIR, `${sessionId}.json`);
107
+ if (existsSync(exactPath)) {
108
+ try {
109
+ const loop = JSON.parse(readFileSync(exactPath, 'utf-8'));
110
+ if (!loop?.active || loopIsStale(loop)) return { kind: null, loop: null };
111
+ return { kind: loopKind(loop), loop };
112
+ } catch { /* corrupt: handleStop removes it and scans */ }
113
+ }
114
+ try {
115
+ for (const f of readdirSync(LOOP_DIR)) {
116
+ if (!f.endsWith('.json') || f.startsWith('pending-')) continue;
117
+ let candidate;
118
+ try { candidate = JSON.parse(readFileSync(join(LOOP_DIR, f), 'utf-8')); } catch { continue; }
119
+ if (!candidate?.active || loopIsStale(candidate)) continue;
120
+ if (terminalSessionEnv && candidate.terminalSessionId === terminalSessionEnv) return { kind: loopKind(candidate), loop: candidate };
121
+ if (!terminalSessionEnv && candidate.currentIteration === 0 && !candidate.terminalSessionId) return { kind: loopKind(candidate), loop: candidate };
122
+ }
123
+ } catch { /* no loop dir */ }
124
+ return { kind: null, loop: null };
125
+ }
126
+
127
+ // The state loop-goal judges: only a hook loop mid-run with iterations left.
128
+ function hookLoopGoalState(loop) {
129
+ if (!loop || !(loop.currentIteration > 0) || !loop.task) return null;
130
+ const total = loop.totalIterations || 10;
131
+ if (loop.currentIteration >= total) return null; // the budget ends it anyway
132
+ return {
133
+ task: String(loop.task), context: loop.context ? String(loop.context) : null,
134
+ journal: Array.isArray(loop.journal) ? loop.journal.slice(-5) : [],
135
+ progress_summary: loop.progressSummary ? String(loop.progressSummary) : null,
136
+ iteration: loop.currentIteration || 0, total,
137
+ };
138
+ }
139
+
140
+ /** Shell work this turn that changed something and came after the last memory write. */
141
+ function unsavedShellWork(judged, activity) {
142
+ if (judged.bashOnlyWorth !== true || !activity) return [];
143
+ return (activity.bash_commands || []).filter((c) => c.after_memory_write && !isReadOnlyCommand(c.command));
144
+ }
145
+
146
+ const clipCommand = (command, max = 80) => {
147
+ const s = String(command || '').replace(/\s+/g, ' ').trim();
148
+ return s.length > max ? `${s.slice(0, max - 1)}…` : s;
149
+ };
150
+
151
+ /** Deterministic evidence for a claim block, read from the turn's own output. */
152
+ function claimEvidence(activity) {
153
+ const checks = Array.isArray(activity?.checks) ? activity.checks : [];
154
+ if (!checks.length) return 'no test/build command ran this turn';
155
+ const last = checks[checks.length - 1];
156
+ const cmd = `\`${clipCommand(last.command)}\``;
157
+ if (last.exit === 'error') return `the last ${cmd} exited with an error`;
158
+ if (last.exit === 'interrupted') return `the last ${cmd} was interrupted`;
159
+ if (last.exit === 'background') return `${cmd} was still running in the background`;
160
+ const bash = Array.isArray(activity?.bash_commands) ? activity.bash_commands : [];
161
+ const lastRun = bash[bash.length - 1];
162
+ if (lastRun && lastRun.exit === 'error') return `the last command, \`${clipCommand(lastRun.command)}\`, exited with an error`;
163
+ return `the last check, ${cmd}, exited ok, but the message reports more than this turn's output shows`;
164
+ }
41
165
  const STORED_PLANS_PATH = join(DATA_DIR, 'stored-plans.json');
42
- const PLANS_DIR = join(DATA_DIR, 'plans');
43
- const PLANS_DIR_FALLBACK = join(process.env.USERPROFILE || process.env.HOME || '', '.claude', 'plans');
44
- const PLAN_MAX_AGE_MS = 10 * 60 * 1000; // 10 minutes
166
+ const PLAN_DEBUG_LOG = join(DATA_DIR, 'plan-debug.log');
45
167
  const MAX_RETRIES = 3;
46
168
  const EDIT_THRESHOLD = 1;
169
+ // Session ceiling on task-memory blocks. `retries` resets whenever a new edit
170
+ // segment starts (post-remember.mjs), so it alone can no longer bound the
171
+ // block↔respond cycle. `stop_hook_active` is not honored for task memory (only
172
+ // for plan memory), so this is the only backstop against an agent that
173
+ // edits-then-stops forever.
174
+ const MAX_TASK_BLOCKS = 12;
175
+ // Session ceiling on plan blocks. `planRetries` resets whenever the plan key
176
+ // changes, and Claude Code reuses one plan file path across re-plans within a
177
+ // session, so re-planning alone used to buy a fresh round of MAX_RETRIES blocks.
178
+ const MAX_PLAN_BLOCKS = 3;
179
+
180
+ function planDebug(msg) {
181
+ try { appendCapped(PLAN_DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`); } catch { /* ok */ }
182
+ }
47
183
 
48
184
  /**
49
185
  * Soft-cleanup a pending-remember flag file.
@@ -59,12 +195,17 @@ function softCleanupFlag(flagPath) {
59
195
  const cleaned = {
60
196
  editCount: 0,
61
197
  retries: 0,
198
+ taskBlockTotal: 0,
62
199
  files: [],
63
200
  messageCount: flag.messageCount || 0,
64
201
  totalSessionMessages: flag.totalSessionMessages || 0,
65
202
  totalEdits: flag.totalEdits || 0,
66
203
  greetingDelivered: flag.greetingDelivered || false,
204
+ categoryTreeInjected: flag.categoryTreeInjected || false,
67
205
  rememberCount: flag.rememberCount || 0,
206
+ planRetries: flag.planRetries || 0,
207
+ planBlockTotal: flag.planBlockTotal || 0,
208
+ planKey: flag.planKey || null,
68
209
  autoStoreTriggered: flag.autoStoreTriggered || false,
69
210
  firstMessageAt: flag.firstMessageAt,
70
211
  lastMessageAt: flag.lastMessageAt,
@@ -72,9 +213,16 @@ function softCleanupFlag(flagPath) {
72
213
  userLearningPending: false,
73
214
  userLearningRetries: 0,
74
215
  userLearningObserved: flag.userLearningObserved || false,
216
+ // Every field added to the flag must be listed here or it is dropped.
217
+ userLearningLastNudgeAt: Number.isFinite(flag.userLearningLastNudgeAt) ? flag.userLearningLastNudgeAt : undefined,
218
+ staleShown: Array.isArray(flag.staleShown) ? flag.staleShown.slice(-50) : [],
219
+ claimBlockedPromptId: flag.claimBlockedPromptId || null,
220
+ noticedFiles: flag.noticedFiles && typeof flag.noticedFiles === 'object' && !Array.isArray(flag.noticedFiles) ? flag.noticedFiles : {},
221
+ // A Stop completed after whatever edits the flag held (task-boundary fallback).
222
+ lastStopAt: new Date().toISOString(),
75
223
  };
76
224
 
77
- writeFileSync(flagPath, JSON.stringify(cleaned));
225
+ writeJsonAtomic(flagPath, cleaned);
78
226
  } catch {
79
227
  // If we can't clean up gracefully, leave the file as-is
80
228
  // (better than deleting and resetting greeting tracking)
@@ -82,52 +230,97 @@ function softCleanupFlag(flagPath) {
82
230
  }
83
231
 
84
232
  /**
85
- * Find unstored plan files modified within PLAN_MAX_AGE_MS.
86
- * Returns the most recent unstored plan or null.
233
+ * Session-scoped lookup for an unstored plan.
234
+ *
235
+ * Reads THIS session's transcript, takes the LAST ExitPlanMode tool_use, and
236
+ * returns its authoritative plan ({ basename, content, title }). Returns null
237
+ * when the session never exited plan mode, when the transcript can't be
238
+ * resolved, or when the plan is already in stored-plans.json.
239
+ *
240
+ * This replaces the old mtime scan of the shared global ~/.claude/plans/
241
+ * directory, which was session-blind and would grab a concurrent session's
242
+ * freshly-written plan (the cross-session leak). Sourcing the plan from the
243
+ * session's own ExitPlanMode payload makes selection session-accurate by
244
+ * construction; if the transcript can't be read we skip (never fall back to
245
+ * mtime — that is the bug we're removing).
87
246
  */
88
- function findUnstoredRecentPlan() {
247
+ function getUnstoredSessionPlan({ transcriptPath, sessionId, cwd }) {
89
248
  try {
249
+ const resolved = resolveTranscriptPath(transcriptPath, sessionId, cwd);
250
+ if (!resolved) {
251
+ planDebug(`stop: no transcript for session ${sessionId} — skipping plan check`);
252
+ return null;
253
+ }
254
+
255
+ const exitPlan = readLastExitPlanMode(resolved);
256
+ if (!exitPlan) return null; // session never exited plan mode → nothing to store
257
+
258
+ const content = exitPlan.plan || '';
259
+ if (!content.trim()) return null;
260
+
261
+ // Display name only. It used to be the dedup key, which is precisely why
262
+ // this check was broken: Claude Code names its file <slug>-<random>.md while
263
+ // post-plan.mjs names its copy after the plan's title, so the two basenames
264
+ // could never collide and post-plan's receipt was invisible here.
265
+ let base = '';
266
+ if (exitPlan.planFilePath) base = basename(exitPlan.planFilePath);
267
+ else if (exitPlan.slug) base = `${exitPlan.slug}.md`;
268
+ if (!base) return null;
269
+
90
270
  let stored = {};
91
271
  try {
92
272
  if (existsSync(STORED_PLANS_PATH)) {
93
273
  stored = JSON.parse(readFileSync(STORED_PLANS_PATH, 'utf-8'));
94
274
  }
95
275
  } catch { /* ok */ }
96
-
97
- const now = Date.now();
98
- const allFiles = [];
99
- for (const dir of [PLANS_DIR, PLANS_DIR_FALLBACK]) {
100
- if (!existsSync(dir)) continue;
101
- for (const f of readdirSync(dir).filter(f => f.endsWith('.md'))) {
102
- if (allFiles.some(r => r.name === f)) continue; // skip duplicates
103
- const fullPath = join(dir, f);
104
- const stat = statSync(fullPath);
105
- allFiles.push({ name: f, path: fullPath, mtimeMs: stat.mtimeMs });
106
- }
276
+ const project = detectProject(cwd);
277
+ const sourcePath = planSourcePath(exitPlan, content) || join(cwd || DATA_DIR, base);
278
+ // Content-addressed, so post-plan.mjs computes the identical key from the
279
+ // same plan text without either hook agreeing on a path.
280
+ const key = planMemoryKey(project, content);
281
+ // The database is authoritative; the receipt file is only a fallback for when
282
+ // it can't be opened. The basename alias stays strict — Claude Code reuses one
283
+ // path across re-plans, so a stale basename must not suppress a new plan.
284
+ if (planStoredInDb(project, content)
285
+ || planReceiptMatches(stored[key], project, content, { strict: false })
286
+ || planReceiptMatches(stored[base], project, content)) {
287
+ planDebug(`stop: plan ${base} already stored — skipping (session ${sessionId})`);
288
+ return null;
107
289
  }
108
- allFiles.sort((a, b) => b.mtimeMs - a.mtimeMs);
109
290
 
110
- for (const file of allFiles) {
111
- if (stored[file.name]) continue;
112
- if (now - file.mtimeMs > PLAN_MAX_AGE_MS) break;
113
- return file;
114
- }
115
- } catch { /* ok */ }
116
- return null;
291
+ const title = (content.match(/^#\s+(.+)$/m) || [])[1] || base;
292
+ return { basename: base, content, title, key, sourcePath };
293
+ } catch {
294
+ return null;
295
+ }
117
296
  }
118
297
 
119
298
  /**
120
- * Mark a plan file as stored in the dedup tracker so it's not re-triggered.
299
+ * A readable file holding this plan, for the plan-memory demand to point at:
300
+ * the file ExitPlanMode named, else the one the CLI reported, else SynaBun's
301
+ * copy (the Neural Interface writes one before its approval card; post-plan.mjs
302
+ * after approval), else a copy written now. A named file counts only while it
303
+ * holds this plan: Claude Code reuses one plan file per session, so it may
304
+ * still hold an earlier plan (or another one entirely). Never a path that does
305
+ * not exist: the assistant brain's plan mode refuses writing ~/.claude/plans/,
306
+ * so its plan lives only in ExitPlanMode's input. '' when nothing could be written.
121
307
  */
122
- function markPlanStored(fileName) {
123
- try {
124
- let stored = {};
125
- if (existsSync(STORED_PLANS_PATH)) {
126
- stored = JSON.parse(readFileSync(STORED_PLANS_PATH, 'utf-8'));
127
- }
128
- stored[fileName] = { memoryId: 'pending-remember', storedAt: new Date().toISOString() };
129
- writeFileSync(STORED_PLANS_PATH, JSON.stringify(stored, null, 2), 'utf-8');
130
- } catch { /* best-effort */ }
308
+ function planSourcePath(exitPlan, content) {
309
+ const holds = (path) => { try { return !!path && readFileSync(path, 'utf-8').trim() === content.trim(); } catch { return false; } };
310
+ if (holds(exitPlan.planFilePath)) return exitPlan.planFilePath;
311
+ if (holds(exitPlan.resultFilePath)) return exitPlan.resultFilePath;
312
+ // Named like the Neural Interface's writePlanFile names its copy.
313
+ const title = ((content.match(/^#\s+(.+)$/m) || [])[1] || content.split('\n').find((l) => l.trim()) || '').trim();
314
+ const slug = title.toLowerCase().replace(/^plan[:\s]+/i, '').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 60) || 'untitled';
315
+ const d = new Date();
316
+ const dir = join(DATA_DIR, 'plans', `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`);
317
+ for (let n = 1; n <= 20; n++) {
318
+ const path = join(dir, n === 1 ? `${slug}.md` : `${slug}-${n}.md`);
319
+ if (holds(path)) return path;
320
+ if (existsSync(path)) continue;
321
+ try { mkdirSync(dir, { recursive: true }); writeFileSync(path, content, 'utf-8'); return path; } catch { return ''; }
322
+ }
323
+ return '';
131
324
  }
132
325
 
133
326
  /**
@@ -135,8 +328,9 @@ function markPlanStored(fileName) {
135
328
  * in the browser (login, CAPTCHA, 2FA, etc.). Used to pause the loop instead
136
329
  * of advancing to the next iteration.
137
330
  */
138
- function isHumanBlocker(msg) {
331
+ function isHumanBlocker(msg, judged = {}) {
139
332
  if (!msg) return false;
333
+ if (typeof judged.humanBlocker === 'boolean') return judged.humanBlocker;
140
334
  const blockerPhrases = [
141
335
  'login', 'log in', 'sign in', 'signin',
142
336
  'captcha', 'recaptcha',
@@ -161,8 +355,9 @@ function isHumanBlocker(msg) {
161
355
  * (file upload, selection, login, CAPTCHA, etc.). Used to suppress soft obligations
162
356
  * (user learning, conversation turns) that would interrupt interactive flows.
163
357
  */
164
- function isWaitingForUser(msg) {
358
+ function isWaitingForUser(msg, judged = {}) {
165
359
  if (!msg) return false;
360
+ if (typeof judged.waitingForUser === 'boolean') return judged.waitingForUser;
166
361
  const phrases = [
167
362
  // Interactive flow pauses
168
363
  'attach', 'upload', 'provide', 'select continue',
@@ -190,8 +385,12 @@ function readStdin() {
190
385
  let data = '';
191
386
  process.stdin.setEncoding('utf8');
192
387
  process.stdin.on('data', (chunk) => { data += chunk; });
193
- process.stdin.on('end', () => resolve(data));
194
- setTimeout(() => resolve(data || '{}'), 2000);
388
+ process.stdin.on('end', () => { clearTimeout(guard); resolve(data); });
389
+ // unref + clearTimeout: without both, this timer keeps the event loop alive
390
+ // for its full duration AFTER 'end' already resolved, so every hook
391
+ // invocation stalled ~2s against a 3s configured timeout.
392
+ const guard = setTimeout(() => resolve(data || '{}'), 2000);
393
+ guard.unref?.();
195
394
  });
196
395
  }
197
396
 
@@ -222,7 +421,7 @@ function checkFlag(flagPath, buildReason) {
222
421
  // Increment retry counter
223
422
  flag.retries = retries + 1;
224
423
  try {
225
- writeFileSync(flagPath, JSON.stringify(flag));
424
+ writeJsonAtomic(flagPath, flag);
226
425
  } catch { /* ok */ }
227
426
 
228
427
  return {
@@ -232,22 +431,92 @@ function checkFlag(flagPath, buildReason) {
232
431
  }
233
432
 
234
433
  async function main() {
434
+ // Stop has 3 s. Node startup counts against it.
435
+ const budget = hookBudget(3000);
235
436
  let sessionId = '';
236
- let lastMessage = '';
437
+ let rawMessage = '';
237
438
  let cwd = '';
439
+ let transcriptPath = '';
440
+ let stopHookActive = false;
441
+ let promptId = '';
442
+ let permissionMode = '';
238
443
  try {
239
444
  const raw = await readStdin();
240
445
  const input = JSON.parse(raw);
241
446
  sessionId = input.session_id || '';
242
- lastMessage = (input.last_assistant_message || '').toLowerCase();
447
+ // The phrase lists need lowercase; the judgment wants the message as written.
448
+ rawMessage = String(input.last_assistant_message || '');
243
449
  cwd = input.cwd || '';
450
+ transcriptPath = input.transcript_path || '';
451
+ stopHookActive = input.stop_hook_active === true;
452
+ promptId = typeof input.prompt_id === 'string' ? input.prompt_id : '';
453
+ permissionMode = typeof input.permission_mode === 'string' ? input.permission_mode : '';
244
454
  } catch { /* proceed */ }
245
455
 
246
- if (!sessionId) {
456
+ // A temporary chat (see isTemporaryChat) owes no memory: it stops when it
457
+ // stops, and nothing about the turn is judged, flagged or written.
458
+ if (isTemporaryChat()) { process.stdout.write(JSON.stringify({})); return; }
459
+
460
+ if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) {
247
461
  process.stdout.write(JSON.stringify({}));
248
462
  return;
249
463
  }
250
464
 
465
+ // Judged before the lock is taken: a round trip must not hold state that
466
+ // other hooks are waiting on. {} whenever unavailable, and every reader
467
+ // below falls back to its phrase list or counter.
468
+ // stop-turn: human blocker, waiting on user, whether the turn's edits (or,
469
+ // with no edits, its shell work) are worth a memory, whether the final
470
+ // message claims a result the turn's output does not show, and any
471
+ // edit-time stale verdicts for this session (peek only).
472
+ // loop-goal: whether a hook-driven loop's task is already complete.
473
+ // Native and exec loops are not judged at all: their runtimes own the
474
+ // iteration and the answer was always thrown away.
475
+ const loopPeek = peekLoop(sessionId);
476
+ const runtimeLoop = loopPeek.kind === 'native' || loopPeek.kind === 'exec';
477
+ let judged = {};
478
+ let activity = null;
479
+ let promptKey = promptId;
480
+ if (!runtimeLoop) {
481
+ const resolved = resolveTranscriptPath(transcriptPath, sessionId, cwd);
482
+ if (!rawMessage && resolved) rawMessage = readLastAssistantText(resolved, 4000);
483
+ if (!typesafeOff() && rawMessage.trim()) {
484
+ activity = readTurnActivity(resolved);
485
+ promptKey = promptId || activity.prompt_id || '';
486
+ const pending = peekPendingRemember(sessionId);
487
+ const project = detectProject(cwd);
488
+ // Not in the assistant brain: a relayed worker "tests pass" has its evidence in the worker's turn (worker-claim checks it there).
489
+ const askClaim = !stopHookActive && loopPeek.kind !== 'hook' && !!promptKey
490
+ && pending.claimBlockedPromptId !== promptKey && rawMessage.trim().length >= 40 && !process.env.SYNABUN_ASSISTANT_SESSION;
491
+ const callMs = Math.min(2000, budget.callTimeout(200));
492
+ const goalState = loopPeek.kind === 'hook' ? hookLoopGoalState(loopPeek.loop) : null;
493
+ // The server refuses text over 16000 characters: keep head and tail.
494
+ const message = clipForJudge(rawMessage);
495
+ const [turn, goal] = await Promise.all([
496
+ judgeText('stop-turn', message, { timeoutMs: callMs, extra: {
497
+ files: pending.files, edit_count: pending.editCount,
498
+ bash_commands: activity.bash_commands, tool_results: activity.tool_results,
499
+ ask: { unsupported_claim: askClaim }, want_stale: true,
500
+ session_id: sessionId, cwd: cwd || undefined, project,
501
+ } }),
502
+ goalState
503
+ ? judgeText('loop-goal', message, { timeoutMs: callMs, extra: { ...goalState, session_id: sessionId, cwd: cwd || undefined, project } })
504
+ : Promise.resolve({}),
505
+ ]);
506
+ judged = { ...turn };
507
+ // Only an answer to a question this Stop asked counts.
508
+ if (!askClaim) delete judged.unsupportedClaim;
509
+ if (typeof goal.goalMet === 'boolean') { judged.goalMet = goal.goalMet; judged.goalProbability = goal.goalProbability; }
510
+ }
511
+ }
512
+
513
+ const lockMs = Math.max(100, Math.min(1500, budget.remaining() - 300));
514
+ return withStateLock(() => handleStop({
515
+ sessionId, lastMessage: rawMessage.toLowerCase(), cwd, transcriptPath, judged, activity, stopHookActive, promptKey, permissionMode,
516
+ }), { timeoutMs: lockMs });
517
+ }
518
+
519
+ function handleStop({ sessionId, lastMessage, cwd, transcriptPath, judged = {}, activity = null, stopHookActive = false, promptKey = '', permissionMode = '' }) {
251
520
  // ─── PRE-CHECK: Quick loop scan ───
252
521
  // Determine if a loop is active BEFORE checking compaction. Loops must NEVER
253
522
  // be blocked by compaction — it stalls iteration transitions and kills the loop.
@@ -256,6 +525,7 @@ async function main() {
256
525
  // loops owned by THIS terminal — prevents other automations from suppressing
257
526
  // compaction in unrelated sessions.
258
527
  const terminalSessionEnv = process.env.SYNABUN_TERMINAL_SESSION || '';
528
+ appendLoopLog(terminalSessionEnv || null, 'stop:enter', 'Stop hook fired', { sessionId, hasEnv: !!terminalSessionEnv });
259
529
  let hasActiveLoop = false;
260
530
  try {
261
531
  if (existsSync(LOOP_DIR)) {
@@ -264,8 +534,16 @@ async function main() {
264
534
  try {
265
535
  const candidate = JSON.parse(readFileSync(join(LOOP_DIR, f), 'utf-8'));
266
536
  if (candidate.active && (candidate.currentIteration || 0) > 0) {
267
- // When running inside a loop terminal, only match OUR loop
268
- if (terminalSessionEnv && candidate.terminalSessionId && candidate.terminalSessionId !== terminalSessionEnv) continue;
537
+ // STRICT isolation. Before: `terminalSessionEnv &&` gated the
538
+ // mismatch check, so a session with no env would pick up ANY
539
+ // loop and wrongly suppress its own compaction. Now:
540
+ // - env set → require exact terminalSessionId match
541
+ // - env unset → only count loops WITHOUT terminalSessionId
542
+ if (terminalSessionEnv) {
543
+ if (candidate.terminalSessionId !== terminalSessionEnv) continue;
544
+ } else {
545
+ if (candidate.terminalSessionId) continue;
546
+ }
269
547
  hasActiveLoop = true;
270
548
  break;
271
549
  }
@@ -281,40 +559,23 @@ async function main() {
281
559
  let compactFlagPath = null;
282
560
 
283
561
  if (!hasActiveLoop) {
284
- try {
285
- if (existsSync(PENDING_COMPACT_DIR)) {
286
- const files = readdirSync(PENDING_COMPACT_DIR)
287
- .filter(f => f.endsWith('.json') && !f.startsWith('test-'));
288
- if (files.length > 0) {
289
- let newest = null;
290
- let newestTime = 0;
291
- for (const f of files) {
292
- const fp = join(PENDING_COMPACT_DIR, f);
293
- try {
294
- const flag = JSON.parse(readFileSync(fp, 'utf-8'));
295
- const t = new Date(flag.created_at || 0).getTime();
296
- if (t > newestTime) { newestTime = t; newest = fp; }
297
- } catch { /* skip corrupt */ }
298
- }
299
- compactFlagPath = newest;
300
- }
301
- }
302
- } catch { /* ok */ }
562
+ const ownedFlag = join(PENDING_COMPACT_DIR, `${sessionId}.json`);
563
+ if (existsSync(ownedFlag)) compactFlagPath = ownedFlag;
303
564
 
304
565
  try {
305
- appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] STOP session_id=${sessionId} compactFlagPath=${compactFlagPath}\n`);
566
+ appendCapped(DEBUG_LOG, `[${new Date().toISOString()}] STOP session_id=${sessionId} compactFlagPath=${compactFlagPath}\n`);
306
567
  } catch { /* ok */ }
307
568
 
308
569
  if (compactFlagPath) {
309
570
  const compactResult = checkFlag(
310
571
  compactFlagPath,
311
- (_flag, attempt) =>
312
- `SynaBun: Session compacted but not indexed yet — log it in 'conversations' first. (${attempt}/${MAX_RETRIES})`
572
+ (flag, attempt) =>
573
+ `SynaBun: Session compacted but not indexed yet — call remember in category 'conversations'${flag.generation ? ` with source_ref ${JSON.stringify(compactionSourceRef(sessionId, flag.generation))}` : ''}. (${attempt}/${MAX_RETRIES})`
313
574
  );
314
575
 
315
576
  if (compactResult?.shouldBlock) {
316
577
  try {
317
- appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] STOP BLOCKING session_id=${sessionId} reason=${compactResult.reason}\n`);
578
+ appendCapped(DEBUG_LOG, `[${new Date().toISOString()}] STOP BLOCKING session_id=${sessionId} reason=${compactResult.reason}\n`);
318
579
  } catch { /* ok */ }
319
580
  process.stdout.write(JSON.stringify({
320
581
  decision: 'block',
@@ -325,22 +586,35 @@ async function main() {
325
586
  }
326
587
  } else {
327
588
  try {
328
- appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] STOP session_id=${sessionId} SKIPPING compaction (active loop)\n`);
589
+ appendCapped(DEBUG_LOG, `[${new Date().toISOString()}] STOP session_id=${sessionId} SKIPPING compaction (active loop)\n`);
329
590
  } catch { /* ok */ }
330
- // Also clean up any pending-compact flags — they'll never be handled during a loop
331
- // and would just accumulate. Delete them so they don't stall post-loop stops.
591
+ // Keep the originating session's obligation for after the loop. Never
592
+ // consume another session's pending compaction.
593
+
594
+ }
595
+
596
+ // ─── CHECK 1.5: Active loop ───
597
+ // Native loops keep their state at {runId}.json for the server-owned runtime.
598
+ // Return before the legacy /clear ownership scan can rename that file to the
599
+ // Claude session ID and make the runtime believe its state was deleted.
600
+ if (terminalSessionEnv) {
332
601
  try {
333
- if (existsSync(PENDING_COMPACT_DIR)) {
334
- const compactFiles = readdirSync(PENDING_COMPACT_DIR)
335
- .filter(f => f.endsWith('.json') && !f.startsWith('test-'));
336
- for (const cf of compactFiles) {
337
- try { unlinkSync(join(PENDING_COMPACT_DIR, cf)); } catch { /* ok */ }
602
+ const nativePath = join(LOOP_DIR, `${terminalSessionEnv}.json`);
603
+ if (existsSync(nativePath)) {
604
+ const nativeLoop = JSON.parse(readFileSync(nativePath, 'utf-8'));
605
+ if (nativeLoop?.active && nativeLoop.driverType === 'native'
606
+ && nativeLoop.terminalSessionId === terminalSessionEnv) {
607
+ appendLoopLog(terminalSessionEnv, 'stop:native', 'leaving iteration transition to native runtime', {
608
+ sessionId,
609
+ currentIteration: nativeLoop.currentIteration || 0,
610
+ });
611
+ process.stdout.write(JSON.stringify({}));
612
+ return;
338
613
  }
339
614
  }
340
- } catch { /* ok */ }
615
+ } catch { /* fall through to legacy ownership scan */ }
341
616
  }
342
617
 
343
- // ─── CHECK 1.5: Active loop ───
344
618
  // Deactivate stale loops first (session died, terminal closed, time expired)
345
619
  cleanupStaleLoops(LOOP_DIR);
346
620
  // After /clear, session ID may change. Try exact match first, then scan for any active loop.
@@ -350,6 +624,9 @@ async function main() {
350
624
  if (existsSync(loopFlagPath)) {
351
625
  try {
352
626
  loop = JSON.parse(readFileSync(loopFlagPath, 'utf-8'));
627
+ if (loop?.active) {
628
+ writeActivePointer(sessionId, loop.terminalSessionId || terminalSessionEnv, sessionId);
629
+ }
353
630
  } catch {
354
631
  try { unlinkSync(loopFlagPath); } catch { /* ok */ }
355
632
  }
@@ -384,10 +661,19 @@ async function main() {
384
661
  loop = candidate;
385
662
  const newPath = join(LOOP_DIR, `${sessionId}.json`);
386
663
  if (fp !== newPath) {
387
- try { renameSync(fp, newPath); loopFlagPath = newPath; } catch { loopFlagPath = fp; }
664
+ try {
665
+ renameSync(fp, newPath);
666
+ loopFlagPath = newPath;
667
+ appendLoopLog(terminalSessionEnv, 'stop:claim', 'matched loop via Strategy A (env), renamed', { from: f, to: `${sessionId}.json`, currentIteration: candidate.currentIteration });
668
+ } catch (err) {
669
+ loopFlagPath = fp;
670
+ appendLoopLog(terminalSessionEnv, 'stop:claim', 'matched loop via Strategy A (env), rename FAILED', { from: f, err: err.message });
671
+ }
388
672
  } else {
389
673
  loopFlagPath = fp;
674
+ appendLoopLog(terminalSessionEnv, 'stop:claim', 'matched loop via Strategy A (env), already named correctly', { file: f, currentIteration: candidate.currentIteration });
390
675
  }
676
+ writeActivePointer(sessionId, terminalSessionEnv, sessionId);
391
677
  break;
392
678
  }
393
679
 
@@ -400,6 +686,7 @@ async function main() {
400
686
  } else {
401
687
  loopFlagPath = fp;
402
688
  }
689
+ writeActivePointer(sessionId, candidate.terminalSessionId || null, sessionId);
403
690
  break;
404
691
  }
405
692
  } catch { continue; }
@@ -407,32 +694,47 @@ async function main() {
407
694
  } catch { /* ok */ }
408
695
  }
409
696
 
697
+ // Skip server-driven exec/native loops. Their runtimes own iteration transitions.
698
+ if (loop?.active && (loop.driverType === 'exec' || loop.driverType === 'native')) {
699
+ process.stdout.write(JSON.stringify({}));
700
+ return;
701
+ }
702
+
410
703
  if (loop?.active) {
411
704
  const iterationsDone = loop.currentIteration || 0;
412
705
  const totalIterations = loop.totalIterations || 10;
413
706
 
707
+ if (judged.goalMet === true && iterationsDone > 0) {
708
+ // The task was judged complete from the journal and the last message:
709
+ // end now instead of spending the rest of the iteration budget. The
710
+ // budget stays the fallback whenever the judgment is unavailable.
711
+ appendLoopLog(loop.terminalSessionId || terminalSessionEnv, 'stop:goal-met', 'loop ended early: task judged complete', { iteration: iterationsDone, total: totalIterations, probability: judged.goalProbability });
712
+ try { unlinkSync(loopFlagPath); } catch { /* ok */ }
713
+ clearActivePointer();
714
+ // Fall through to remember/conversation checks
715
+ } else if (iterationsDone >= totalIterations) {
414
716
  // Check cap — iteration limit only (time cap removed; inactivity catches stuck loops)
415
- if (iterationsDone >= totalIterations) {
416
717
  // Loop finished — delete the file (no history keeping)
417
718
  try { unlinkSync(loopFlagPath); } catch { /* ok */ }
719
+ clearActivePointer();
418
720
  // Fall through to remember/conversation checks
419
721
  } else if (loop.memoryPending && (loop.memoryRetries || 0) < MAX_RETRIES) {
420
722
  // Memory enforcement: block until Claude stores progress in memory
421
723
  loop.memoryRetries = (loop.memoryRetries || 0) + 1;
422
- try { writeFileSync(loopFlagPath, JSON.stringify(loop, null, 2)); } catch { /* ok */ }
724
+ try { writeJsonAtomic(loopFlagPath, loop); } catch { /* ok */ }
423
725
 
424
726
  const reason = [
425
727
  `SynaBun Loop: Memory checkpoint required (iteration ${iterationsDone}/${totalIterations}).`,
426
728
  `You've completed ${iterationsDone - (loop.lastMemoryAt || 0)} iterations since your last memory save.`,
427
729
  `Call \`remember\` with progress from iterations ${(loop.lastMemoryAt || 0) + 1}-${iterationsDone}.`,
428
730
  `Include: what was accomplished, accounts/targets engaged, key findings, strategies that worked.`,
429
- `Category: use the task's appropriate category or "social-interactions". Importance: 6-7. Tags: ["loop", "progress"].`,
731
+ `Category: use the task's appropriate category or "social-interactions". Importance: 4-5 for a routine progress log; 6-7 only for a finding, a decision, or a change of strategy. Tags: ["loop", "progress"].`,
430
732
  `Then the loop will continue automatically.`,
431
733
  ].join('\n');
432
734
 
433
735
  process.stdout.write(JSON.stringify({ decision: 'block', reason }));
434
736
  return;
435
- } else if (loop.usesBrowser && isHumanBlocker(lastMessage)) {
737
+ } else if (loop.usesBrowser && isHumanBlocker(lastMessage, judged)) {
436
738
  // Agent is waiting for human action (login, CAPTCHA, etc.) — pause loop
437
739
  process.stdout.write(JSON.stringify({}));
438
740
  return;
@@ -445,7 +747,7 @@ async function main() {
445
747
  const loopUpdateRetries = loop.loopUpdateRetries || 0;
446
748
  if (lastJournalIter < iterationsDone && loopUpdateRetries < MAX_RETRIES) {
447
749
  loop.loopUpdateRetries = loopUpdateRetries + 1;
448
- try { writeFileSync(loopFlagPath, JSON.stringify(loop, null, 2)); } catch { /* ok */ }
750
+ try { writeJsonAtomic(loopFlagPath, loop); } catch { /* ok */ }
449
751
  process.stdout.write(JSON.stringify({
450
752
  decision: 'block',
451
753
  reason: `SynaBun Loop: Before this iteration ends, call \`loop\` action \`update\` with a brief summary of what you accomplished (e.g. which groups were posted, which platforms covered, what's left to do). This preserves context for the next iteration after /clear. Then stop — the loop will advance automatically.`,
@@ -472,7 +774,12 @@ async function main() {
472
774
 
473
775
  // Signal server loop driver to send /clear + next iteration prompt
474
776
  loop.awaitingNext = true;
475
- try { writeFileSync(loopFlagPath, JSON.stringify(loop, null, 2)); } catch { /* ok */ }
777
+ try {
778
+ writeJsonAtomic(loopFlagPath, loop);
779
+ appendLoopLog(loop.terminalSessionId || terminalSessionEnv, 'stop:awaitingNext', 'set awaitingNext=true', { iter: loop.currentIteration, total: loop.totalIterations, file: loopFlagPath });
780
+ } catch (err) {
781
+ appendLoopLog(loop.terminalSessionId || terminalSessionEnv, 'stop:awaitingNext', 'write FAILED', { err: err.message });
782
+ }
476
783
 
477
784
  // Reset edit tracking for fresh iteration context
478
785
  const rememberFlagForReset = join(PENDING_REMEMBER_DIR, `${sessionId}.json`);
@@ -497,7 +804,12 @@ async function main() {
497
804
  }
498
805
 
499
806
  loop.awaitingNext = true;
500
- try { writeFileSync(loopFlagPath, JSON.stringify(loop, null, 2)); } catch { /* ok */ }
807
+ try {
808
+ writeJsonAtomic(loopFlagPath, loop);
809
+ appendLoopLog(loop.terminalSessionId || terminalSessionEnv, 'stop:awaitingNext', 'set awaitingNext=true', { iter: loop.currentIteration, total: loop.totalIterations, file: loopFlagPath });
810
+ } catch (err) {
811
+ appendLoopLog(loop.terminalSessionId || terminalSessionEnv, 'stop:awaitingNext', 'write FAILED', { err: err.message });
812
+ }
501
813
 
502
814
  const rememberFlagForReset = join(PENDING_REMEMBER_DIR, `${sessionId}.json`);
503
815
  if (existsSync(rememberFlagForReset)) {
@@ -517,7 +829,14 @@ async function main() {
517
829
  const obligations = [];
518
830
  const rememberFlagPath = join(PENDING_REMEMBER_DIR, `${sessionId}.json`);
519
831
  let flag = null;
520
- const waitingForUser = isWaitingForUser(lastMessage);
832
+ const waitingForUser = isWaitingForUser(lastMessage, judged);
833
+
834
+ // Resolve THIS session's unstored plan once — shared by CHECK 5 (bundled)
835
+ // and the standalone plan check below, so the transcript is read at most once.
836
+ // Not while the session is planning (plan mode refuses `remember`, so the
837
+ // demand could not be met) nor on a Stop this hook already blocked (the
838
+ // counters bring it back on a later turn): either way it would loop.
839
+ const sessionPlan = stopHookActive || permissionMode === 'plan' ? null : getUnstoredSessionPlan({ transcriptPath, sessionId, cwd });
521
840
 
522
841
  if (existsSync(rememberFlagPath)) {
523
842
  try {
@@ -527,24 +846,74 @@ async function main() {
527
846
  }
528
847
  }
529
848
 
849
+ // Shell work and claim checks can apply to a session whose flag was never
850
+ // created (no prompt hook ran), like an unstored plan.
851
+ const shellWork = unsavedShellWork(judged, activity);
852
+ const claimJudged = judged.unsupportedClaim === true && !stopHookActive && !!promptKey;
853
+ if (!flag && (sessionPlan || shellWork.length || claimJudged)) flag = {editCount:0,files:[],retries:0};
854
+ if (sessionPlan && flag.planKey !== sessionPlan.key) {
855
+ flag.planKey = sessionPlan.key;
856
+ flag.planRetries = 0;
857
+ }
858
+
530
859
  if (flag) {
531
860
  const editCount = flag.editCount || 0;
532
861
  const rememberCount = flag.rememberCount || 0;
862
+ let taskObligation = null;
533
863
 
534
- // CHECK 2: Task remember (edits without memory entry)
535
- if (editCount >= EDIT_THRESHOLD) {
864
+ // CHECK 2: Task remember (edits without memory entry). The raw edit count
865
+ // says something changed; the judgment says whether it was work worth a
866
+ // memory. A confident "trivial" (surface turn-worth) suppresses the nag;
867
+ // no judgment keeps the old behaviour.
868
+ if (editCount >= EDIT_THRESHOLD && judged.worthRemembering !== false) {
536
869
  const retries = flag.retries || 0;
537
- if (retries < MAX_RETRIES) {
870
+ const taskBlockTotal = flag.taskBlockTotal || 0;
871
+ if (retries < MAX_RETRIES && taskBlockTotal < MAX_TASK_BLOCKS) {
538
872
  flag.retries = retries + 1;
873
+ flag.taskBlockTotal = taskBlockTotal + 1;
539
874
  const files = Array.isArray(flag.files) ? flag.files : [];
540
875
  const fileList = files.length > 0
541
876
  ? ` Files: ${files.slice(0, 5).join(', ')}${files.length > 5 ? ` (+${files.length - 5} more)` : ''}`
542
877
  : '';
543
- obligations.push({
878
+ taskObligation = {
544
879
  type: 'task',
545
880
  short: `**Task memory**: unstored edits — call \`remember\` with what/why/how.${fileList}`,
546
881
  verbose: `SynaBun: Unstored file edits — call \`remember\` before finishing.${fileList}`,
547
- });
882
+ };
883
+ obligations.push(taskObligation);
884
+ }
885
+ }
886
+
887
+ // CHECK 2b: A Bash-only turn. No file edits, but shell commands that
888
+ // changed something ran after the last memory write, and Jev judged the
889
+ // work worth a memory (turn-worth.bashOnlyMinProbability). Same retry
890
+ // counters as CHECK 2. A memory written after all of it clears it.
891
+ if (editCount === 0 && shellWork.length) {
892
+ const retries = flag.retries || 0;
893
+ const taskBlockTotal = flag.taskBlockTotal || 0;
894
+ if (retries < MAX_RETRIES && taskBlockTotal < MAX_TASK_BLOCKS) {
895
+ flag.retries = retries + 1;
896
+ flag.taskBlockTotal = taskBlockTotal + 1;
897
+ const names = shellWork.slice(-3).map((c) => `\`${clipCommand(c.command)}\``).join(', ');
898
+ taskObligation = {
899
+ type: 'task',
900
+ short: `**Task memory**: shell work not stored (${names}) — call \`remember\` with what/why/how.`,
901
+ verbose: `SynaBun [Jev]: this turn changed things from the shell and none of it is in memory yet: ${names}. Call \`remember\` with what was done, why, and how before finishing.`,
902
+ };
903
+ obligations.push(taskObligation);
904
+ }
905
+ }
906
+
907
+ // Stale-memory verdicts (edit-time checks) join the unstored-work reason:
908
+ // never a block of their own. The ids shown are recorded so the next
909
+ // prompt acknowledges them instead of showing them again.
910
+ if (taskObligation && Array.isArray(judged.stale)) {
911
+ const shown = new Set(Array.isArray(flag.staleShown) ? flag.staleShown : []);
912
+ const fresh = judged.stale.filter((v) => v && typeof v.memory_id === 'string' && !shown.has(v.memory_id)).slice(0, 3);
913
+ if (fresh.length) {
914
+ taskObligation.verbose += `\n\n${formatStaleNotices(fresh)}`;
915
+ taskObligation.short += ` Also check possibly stale memories ${fresh.map((v) => `[${v.memory_id}]`).join(', ')} (\`reflect\` or \`forget\`).`;
916
+ flag.staleShown = [...shown, ...fresh.map((v) => v.memory_id)].slice(-50);
548
917
  }
549
918
  }
550
919
 
@@ -573,33 +942,58 @@ async function main() {
573
942
  }
574
943
  }
575
944
 
576
- // CHECK 5: Unstored plan file (fallback for when PostToolUse hook doesn't fire)
577
- // ExitPlanMode often returns a tool_use_error because the plan is auto-approved
578
- // before Claude's ExitPlanMode call executes. PostToolUse hooks may not fire on
579
- // errors, so the post-plan.mjs hook never runs. This catches those missed plans.
580
- const unstoredPlan = findUnstoredRecentPlan();
581
- if (unstoredPlan) {
582
- const planRetryKey = 'planRetries';
583
- const planRetries = flag[planRetryKey] || 0;
584
- if (planRetries < MAX_RETRIES) {
585
- flag[planRetryKey] = planRetries + 1;
586
- try {
587
- const planContent = readFileSync(unstoredPlan.path, 'utf-8').trim();
588
- const planTitle = (planContent.match(/^#\s+(.+)$/m) || [])[1] || unstoredPlan.name;
589
- const project = detectProject(cwd);
590
- // Mark as stored to prevent re-triggering
591
- markPlanStored(unstoredPlan.name);
592
- obligations.push({
593
- type: 'plan',
594
- short: `**Plan memory**: "${planTitle}" — call \`remember\` category \`plans-${project}\`, importance 7, tags ["plan", "implementation", "${project}"], source "auto-saved". Include the full plan content.`,
595
- verbose: `SynaBun: Plan "${planTitle}" was approved but not stored in memory (PostToolUse hook missed it). Call \`remember\` with the plan content below. Category: \`plans-${project}\`, importance: 7, tags: ["plan", "implementation", "${project}"], source: "auto-saved".\n\nPlan file: ${unstoredPlan.name}\n\n${planContent.slice(0, 4000)}`,
596
- });
597
- } catch { /* skip unreadable */ }
945
+ // CHECK 5: Unstored plan (fallback for when the post-plan PostToolUse hook
946
+ // didn't fire — ExitPlanMode is often auto-approved and returns a
947
+ // tool_use_error, so PostToolUse never runs). `sessionPlan` is sourced from
948
+ // THIS session's transcript, so it can only ever be this session's plan.
949
+ if (sessionPlan) {
950
+ const planRetries = flag.planRetries || 0;
951
+ const planBlockTotal = flag.planBlockTotal || 0;
952
+ if (planRetries < MAX_RETRIES && planBlockTotal < MAX_PLAN_BLOCKS) {
953
+ flag.planRetries = planRetries + 1;
954
+ flag.planBlockTotal = planBlockTotal + 1;
955
+ const project = detectProject(cwd);
956
+ planDebug(`stop: CHECK5 block plan ${sessionPlan.basename} (session ${sessionId}, project ${project})`);
957
+ // Never ask for a verbatim reproduction of a plan we only show in
958
+ // excerpt — that demand is unsatisfiable, and each attempt used to
959
+ // manufacture one more duplicate memory. Point at the file instead, and
960
+ // accept a paraphrase (see planReceiptMatches `strict: false`).
961
+ obligations.push({
962
+ type: 'plan',
963
+ short: `**Plan memory**: "${sessionPlan.title}" — read ${sessionPlan.sourcePath} and \`remember\` what it says. Category \`plans-${project}\`, importance 7, tags ["plan", "implementation", "${project}"], source "auto-saved", idempotency_key "${sessionPlan.key}", source_ref ${JSON.stringify(sessionPlan.sourcePath)}.`,
964
+ verbose: [
965
+ `SynaBun: Plan "${sessionPlan.title}" was approved but never reached memory (the PostToolUse plan hook missed it).`,
966
+ ``,
967
+ `1. Read ${sessionPlan.sourcePath}`,
968
+ `2. Call \`remember\` with that file's content. Category: \`plans-${project}\`, importance: 7, tags: ["plan", "implementation", "${project}"], source: "auto-saved", idempotency_key: "${sessionPlan.key}", source_ref: ${JSON.stringify(sessionPlan.sourcePath)}.`,
969
+ ``,
970
+ `Read the file — do not retype the plan from the preview below. If it is unreadable, store the preview instead; a close paraphrase is accepted. One successful \`remember\` clears this for good.`,
971
+ ``,
972
+ `--- preview: ${sessionPlan.basename} (first 1200 of ${sessionPlan.content.length} chars) ---`,
973
+ sessionPlan.content.slice(0, 1200),
974
+ ].join('\n'),
975
+ });
598
976
  }
599
977
  }
600
978
 
979
+ // CHECK 6: A claim the turn's output does not support ("tests pass", "the
980
+ // fix works", "verified") — Jev at claim-check.minProbability. One block
981
+ // per prompt, never on a stop-hook continuation, never while waiting for
982
+ // the user. The reason names what the transcript shows.
983
+ if (claimJudged && !waitingForUser && flag.claimBlockedPromptId !== promptKey) {
984
+ flag.claimBlockedPromptId = promptKey;
985
+ const evidence = claimEvidence(activity);
986
+ obligations.push({
987
+ type: 'claim',
988
+ short: `**Unverified result**: ${evidence} — run the check and report its actual output, or say plainly that it is unverified.`,
989
+ verbose: `SynaBun [Jev] claim check: your final message reports a result (tests passing, a fix working, something verified) that this turn's output does not support: ${evidence}. Run the check now and report its actual output, or say plainly that the result is unverified. This check blocks once per prompt.`,
990
+ });
991
+ }
992
+
993
+ flag.lastStopAt = new Date().toISOString();
994
+
601
995
  // Write flag once after all checks (single write instead of per-check writes)
602
- try { writeFileSync(rememberFlagPath, JSON.stringify(flag)); } catch { /* ok */ }
996
+ try { writeJsonAtomic(rememberFlagPath, flag); } catch { /* ok */ }
603
997
 
604
998
  // ─── Emit combined block or soft cleanup ───
605
999
  if (obligations.length > 0) {
@@ -618,25 +1012,6 @@ async function main() {
618
1012
  softCleanupFlag(rememberFlagPath);
619
1013
  }
620
1014
 
621
- // ─── STANDALONE PLAN CHECK (no pending-remember flag needed) ───
622
- // Catches plans even when there's no flag file (e.g., very short sessions)
623
- const standalonePlan = findUnstoredRecentPlan();
624
- if (standalonePlan) {
625
- try {
626
- const planContent = readFileSync(standalonePlan.path, 'utf-8').trim();
627
- const planTitle = (planContent.match(/^#\s+(.+)$/m) || [])[1] || standalonePlan.name;
628
- const project = detectProject(cwd);
629
- // Mark as stored NOW to prevent re-triggering on next stop cycle.
630
- // Claude will remember it via MCP; if that fails, the plan file still exists on disk.
631
- markPlanStored(standalonePlan.name);
632
- process.stdout.write(JSON.stringify({
633
- decision: 'block',
634
- reason: `SynaBun: Plan "${planTitle}" was approved but not stored in memory. Call \`remember\` with the plan content. Category: \`plans-${project}\`, importance: 7, tags: ["plan", "implementation", "${project}"], source: "auto-saved".\n\nPlan file: ${standalonePlan.name}\n\n${planContent.slice(0, 4000)}`,
635
- }));
636
- return;
637
- } catch { /* fall through to allow stop */ }
638
- }
639
-
640
1015
  // No flags, no unstored plans → allow stop
641
1016
  process.stdout.write(JSON.stringify({}));
642
1017
  }