synabun 2.0.0 → 2.0.5

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 (334) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/NOTICE +5 -0
  3. package/README.md +1 -1
  4. package/THIRD-PARTY-LICENSES.md +46 -0
  5. package/benchmarks/fixtures/browser/README.md +1 -1
  6. package/benchmarks/fixtures/desktop/README.md +1 -1
  7. package/docs/whatsapp.md +2 -2
  8. package/hooks/claude-code/pre-compact.mjs +11 -0
  9. package/hooks/claude-code/prompt-submit.mjs +60 -184
  10. package/hooks/claude-code/session-start.mjs +73 -16
  11. package/hooks/claude-code/shared.mjs +20 -0
  12. package/hooks/claude-code/stop.mjs +5 -5
  13. package/lib/start-launcher.js +88 -1
  14. package/mcp-server/package-lock.json +2 -2
  15. package/mcp-server/package.json +1 -3
  16. package/neural-interface/i18n/en.json +1500 -153
  17. package/neural-interface/i18n/pt-BR.json +1498 -152
  18. package/neural-interface/lib/assistant-api.js +62 -6
  19. package/neural-interface/lib/assistant-brains/claude.js +4 -0
  20. package/neural-interface/lib/assistant-catalog.js +179 -27
  21. package/neural-interface/lib/assistant-config.js +31 -2
  22. package/neural-interface/lib/assistant-dispatch.js +62 -13
  23. package/neural-interface/lib/assistant-hidden-models.js +393 -66
  24. package/neural-interface/lib/assistant-memory.js +24 -10
  25. package/neural-interface/lib/assistant-persona.js +6 -2
  26. package/neural-interface/lib/assistant-pricing.js +21 -6
  27. package/neural-interface/lib/assistant-runtime.js +181 -12
  28. package/neural-interface/lib/assistant-task-prompt.js +13 -3
  29. package/neural-interface/lib/assistant-test-density.js +142 -0
  30. package/neural-interface/lib/assistant-user-context-budgets.js +123 -0
  31. package/neural-interface/lib/assistant-user-context.js +908 -0
  32. package/neural-interface/lib/assistant-user-knowledge.js +328 -0
  33. package/neural-interface/lib/assistant-user-learn.js +404 -0
  34. package/neural-interface/lib/assistant-user-threads.js +226 -0
  35. package/neural-interface/lib/assistant-user-writer.js +181 -0
  36. package/neural-interface/lib/browser-background-tab.js +134 -0
  37. package/neural-interface/lib/browser-screenshot.js +678 -61
  38. package/neural-interface/lib/claude-agent-bridge.js +33 -6
  39. package/neural-interface/lib/claude-model-catalog.js +30 -2
  40. package/neural-interface/lib/claude-temporary.js +46 -7
  41. package/neural-interface/lib/cloudflared/install.js +533 -0
  42. package/neural-interface/lib/cloudflared/manager.js +545 -0
  43. package/neural-interface/lib/cloudflared/pins.js +115 -0
  44. package/neural-interface/lib/cloudflared/pins.json +63 -0
  45. package/neural-interface/lib/cloudflared/tunnel.js +265 -0
  46. package/neural-interface/lib/editor-completion-endpoint.js +264 -0
  47. package/neural-interface/lib/editor-completion-opencode.js +436 -0
  48. package/neural-interface/lib/editor-completion.js +714 -0
  49. package/neural-interface/lib/editor-config.js +149 -0
  50. package/neural-interface/lib/editor-files-api.js +268 -0
  51. package/neural-interface/lib/editor-git-api.js +134 -0
  52. package/neural-interface/lib/file-explorer-api.js +1039 -0
  53. package/neural-interface/lib/file-explorer-system.js +355 -0
  54. package/neural-interface/lib/file-explorer-trash.ps1 +85 -0
  55. package/neural-interface/lib/file-explorer-watch.js +239 -0
  56. package/neural-interface/lib/git-diff-api.js +103 -0
  57. package/neural-interface/lib/git-read.js +202 -0
  58. package/neural-interface/lib/greeting/api.js +89 -0
  59. package/neural-interface/lib/greeting/budgets.js +90 -0
  60. package/neural-interface/lib/greeting/engine.js +461 -0
  61. package/neural-interface/lib/greeting/facts.js +320 -0
  62. package/neural-interface/lib/greeting/sources.js +252 -0
  63. package/neural-interface/lib/greeting/writer.js +139 -0
  64. package/neural-interface/lib/http-guards.js +189 -13
  65. package/neural-interface/lib/machine-names.js +88 -0
  66. package/neural-interface/lib/memory-api.js +31 -7
  67. package/neural-interface/lib/native-loop-providers.js +10 -5
  68. package/neural-interface/lib/plugin-installer.js +4 -2
  69. package/neural-interface/lib/project-storage.js +5 -7
  70. package/neural-interface/lib/request-gate.js +589 -0
  71. package/neural-interface/lib/ui-blob-api.js +108 -0
  72. package/neural-interface/lib/ui-blob-store.js +68 -0
  73. package/neural-interface/package-lock.json +701 -2
  74. package/neural-interface/package.json +13 -2
  75. package/neural-interface/public/install-app.html +9 -6
  76. package/neural-interface/public/offline.html +3 -2
  77. package/neural-interface/public/onboarding.html +12 -1
  78. package/neural-interface/public/shared/agent-runtime-options.js +22 -6
  79. package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
  80. package/neural-interface/public/shared/assistant/asst-brain-picker.js +312 -62
  81. package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
  82. package/neural-interface/public/shared/assistant/asst-mascot.js +18 -58
  83. package/neural-interface/public/shared/assistant/asst-menu.js +12 -8
  84. package/neural-interface/public/shared/assistant/asst-panel.js +150 -28
  85. package/neural-interface/public/shared/assistant/asst-render.js +162 -19
  86. package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
  87. package/neural-interface/public/shared/assistant/asst-route.js +23 -329
  88. package/neural-interface/public/shared/assistant/asst-routes-editor.js +495 -0
  89. package/neural-interface/public/shared/assistant/asst-sanitize.js +8 -1
  90. package/neural-interface/public/shared/assistant/asst-sidepanel.js +31 -9
  91. package/neural-interface/public/shared/assistant/asst-state.js +185 -1
  92. package/neural-interface/public/shared/assistant/asst-styles.js +158 -4
  93. package/neural-interface/public/shared/blob-store.js +111 -22
  94. package/neural-interface/public/shared/cdx/cdx-panel.js +32 -11
  95. package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
  96. package/neural-interface/public/shared/cdx/cdx-styles.js +36 -0
  97. package/neural-interface/public/shared/cdx/cdx-tabs.js +87 -4
  98. package/neural-interface/public/shared/constants.js +6 -1
  99. package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
  100. package/neural-interface/public/shared/cp/cp-styles.js +15 -0
  101. package/neural-interface/public/shared/editor/editor-ai-logic.js +409 -0
  102. package/neural-interface/public/shared/editor/editor-ai.js +619 -0
  103. package/neural-interface/public/shared/editor/editor-commands.js +212 -0
  104. package/neural-interface/public/shared/editor/editor-compare.js +103 -0
  105. package/neural-interface/public/shared/editor/editor-completion-list.js +172 -0
  106. package/neural-interface/public/shared/editor/editor-doc.js +257 -0
  107. package/neural-interface/public/shared/editor/editor-git-logic.js +131 -0
  108. package/neural-interface/public/shared/editor/editor-git.js +95 -0
  109. package/neural-interface/public/shared/editor/editor-languages.js +156 -0
  110. package/neural-interface/public/shared/editor/editor-lint.js +229 -0
  111. package/neural-interface/public/shared/editor/editor-loader.js +51 -0
  112. package/neural-interface/public/shared/editor/editor-markdown.js +90 -0
  113. package/neural-interface/public/shared/editor/editor-menu.js +233 -0
  114. package/neural-interface/public/shared/editor/editor-minimap.js +371 -0
  115. package/neural-interface/public/shared/editor/editor-palette-logic.js +192 -0
  116. package/neural-interface/public/shared/editor/editor-palette.js +125 -0
  117. package/neural-interface/public/shared/editor/editor-panel-logic.js +288 -0
  118. package/neural-interface/public/shared/editor/editor-panel.js +2099 -0
  119. package/neural-interface/public/shared/editor/editor-prefs.js +224 -0
  120. package/neural-interface/public/shared/editor/editor-safety.js +500 -0
  121. package/neural-interface/public/shared/editor/editor-search.js +352 -0
  122. package/neural-interface/public/shared/editor/editor-statusbar.js +144 -0
  123. package/neural-interface/public/shared/editor/editor-tabs-logic.js +331 -0
  124. package/neural-interface/public/shared/editor/editor-tabs.js +233 -0
  125. package/neural-interface/public/shared/editor/editor-theme.js +244 -0
  126. package/neural-interface/public/shared/editor/editor-view.js +332 -0
  127. package/neural-interface/public/shared/explorer/fx-api.js +216 -0
  128. package/neural-interface/public/shared/explorer/fx-links.js +204 -0
  129. package/neural-interface/public/shared/explorer/fx-logic.js +537 -0
  130. package/neural-interface/public/shared/explorer/fx-main.js +865 -0
  131. package/neural-interface/public/shared/explorer/fx-names.js +87 -0
  132. package/neural-interface/public/shared/explorer/fx-ops.js +370 -0
  133. package/neural-interface/public/shared/explorer/fx-popups.js +490 -0
  134. package/neural-interface/public/shared/explorer/fx-tree.js +790 -0
  135. package/neural-interface/public/shared/file-links.js +339 -0
  136. package/neural-interface/public/shared/greeting/greeting-card.js +178 -0
  137. package/neural-interface/public/shared/greeting/greeting-view.js +148 -0
  138. package/neural-interface/public/shared/html-shell.js +160 -165
  139. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -0
  140. package/neural-interface/public/shared/ocp-v2/ocp-v2-greeting.js +47 -0
  141. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +99 -17
  142. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -1
  143. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +5 -0
  144. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +40 -0
  145. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
  146. package/neural-interface/public/shared/pwa-install-page.js +29 -1
  147. package/neural-interface/public/shared/pwa-install.css +3 -3
  148. package/neural-interface/public/shared/pwa-install.js +100 -1
  149. package/neural-interface/public/shared/settings/settings-code-editor-pane.js +412 -0
  150. package/neural-interface/public/shared/settings/settings-code-editor.js +328 -0
  151. package/neural-interface/public/shared/settings/settings-greeting.js +133 -0
  152. package/neural-interface/public/shared/settings/settings-ia.js +18 -4
  153. package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
  154. package/neural-interface/public/shared/start-bridge.js +238 -19
  155. package/neural-interface/public/shared/styles.css +1414 -721
  156. package/neural-interface/public/shared/synabun-mascot.js +20 -56
  157. package/neural-interface/public/shared/tunnel-view.js +167 -0
  158. package/neural-interface/public/shared/ui-claude-panel.js +157 -16
  159. package/neural-interface/public/shared/ui-detail.js +15 -0
  160. package/neural-interface/public/shared/ui-explorer.js +22 -0
  161. package/neural-interface/public/shared/ui-file-explorer.js +481 -2496
  162. package/neural-interface/public/shared/ui-file-links.js +103 -0
  163. package/neural-interface/public/shared/ui-help.js +26 -0
  164. package/neural-interface/public/shared/ui-invite.js +126 -116
  165. package/neural-interface/public/shared/ui-keybinds.js +4 -0
  166. package/neural-interface/public/shared/ui-loading.js +159 -15
  167. package/neural-interface/public/shared/ui-menubar.js +12 -30
  168. package/neural-interface/public/shared/ui-native-loop-router-state.js +11 -0
  169. package/neural-interface/public/shared/ui-native-loop-router.js +15 -2
  170. package/neural-interface/public/shared/ui-navbar.js +45 -21
  171. package/neural-interface/public/shared/ui-settings.js +455 -488
  172. package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
  173. package/neural-interface/public/shared/ui-sync.js +16 -0
  174. package/neural-interface/public/shared/ui-terminal.js +23 -5
  175. package/neural-interface/public/shared/ui-tunnel.js +130 -0
  176. package/neural-interface/public/shared/ui-tutorial-steps.js +6 -2
  177. package/neural-interface/public/shared/ui-whiteboard.js +12 -0
  178. package/neural-interface/public/shared/ui-worker-end.js +245 -0
  179. package/neural-interface/public/shared/ui-workspaces.js +41 -27
  180. package/neural-interface/public/shared/worker-end.js +251 -0
  181. package/neural-interface/public/sw.js +2 -2
  182. package/neural-interface/public/vendor/codemirror/chunks/apl-CSDKT72Z.js +1 -0
  183. package/neural-interface/public/vendor/codemirror/chunks/asciiarmor-JYYPU5BM.js +1 -0
  184. package/neural-interface/public/vendor/codemirror/chunks/asn1-NRWCZDA6.js +1 -0
  185. package/neural-interface/public/vendor/codemirror/chunks/asterisk-5OU6D4ZQ.js +1 -0
  186. package/neural-interface/public/vendor/codemirror/chunks/brainfuck-ID4N4SYC.js +1 -0
  187. package/neural-interface/public/vendor/codemirror/chunks/chunk-4RZWGCS2.js +1 -0
  188. package/neural-interface/public/vendor/codemirror/chunks/chunk-ACTJM3JR.js +11 -0
  189. package/neural-interface/public/vendor/codemirror/chunks/chunk-S6BMAXLK.js +1 -0
  190. package/neural-interface/public/vendor/codemirror/chunks/chunk-TO2RDOHQ.js +3 -0
  191. package/neural-interface/public/vendor/codemirror/chunks/chunk-US2GMZZQ.js +13 -0
  192. package/neural-interface/public/vendor/codemirror/chunks/chunk-WYYO5ZAJ.js +1 -0
  193. package/neural-interface/public/vendor/codemirror/chunks/chunk-XALZTDJC.js +1 -0
  194. package/neural-interface/public/vendor/codemirror/chunks/chunk-YRNUTRDV.js +1 -0
  195. package/neural-interface/public/vendor/codemirror/chunks/chunk-Z3QOKH62.js +1 -0
  196. package/neural-interface/public/vendor/codemirror/chunks/clike-OWQBSOGL.js +1 -0
  197. package/neural-interface/public/vendor/codemirror/chunks/clojure-KV75UQWC.js +1 -0
  198. package/neural-interface/public/vendor/codemirror/chunks/cmake-GTEP5Y3C.js +1 -0
  199. package/neural-interface/public/vendor/codemirror/chunks/cobol-WCZ7QEGJ.js +1 -0
  200. package/neural-interface/public/vendor/codemirror/chunks/coffeescript-TGLBOT6B.js +1 -0
  201. package/neural-interface/public/vendor/codemirror/chunks/commonlisp-WVVI432V.js +1 -0
  202. package/neural-interface/public/vendor/codemirror/chunks/crystal-S6R6HLKQ.js +1 -0
  203. package/neural-interface/public/vendor/codemirror/chunks/css-PDA2RINP.js +1 -0
  204. package/neural-interface/public/vendor/codemirror/chunks/cypher-HL5QPL4C.js +1 -0
  205. package/neural-interface/public/vendor/codemirror/chunks/d-HHJH2HAJ.js +1 -0
  206. package/neural-interface/public/vendor/codemirror/chunks/diff-MN3A35BY.js +1 -0
  207. package/neural-interface/public/vendor/codemirror/chunks/dist-25SQLBVS.js +3 -0
  208. package/neural-interface/public/vendor/codemirror/chunks/dist-27ZGGJJS.js +1 -0
  209. package/neural-interface/public/vendor/codemirror/chunks/dist-4E52OJIF.js +1 -0
  210. package/neural-interface/public/vendor/codemirror/chunks/dist-6FT73XDC.js +2 -0
  211. package/neural-interface/public/vendor/codemirror/chunks/dist-BE6YGRMW.js +1 -0
  212. package/neural-interface/public/vendor/codemirror/chunks/dist-CJSGKW2O.js +1 -0
  213. package/neural-interface/public/vendor/codemirror/chunks/dist-CRPH2WLI.js +1 -0
  214. package/neural-interface/public/vendor/codemirror/chunks/dist-CTG7JEQN.js +1 -0
  215. package/neural-interface/public/vendor/codemirror/chunks/dist-I3FEVELX.js +1 -0
  216. package/neural-interface/public/vendor/codemirror/chunks/dist-IM5BBSWZ.js +1 -0
  217. package/neural-interface/public/vendor/codemirror/chunks/dist-KERUKTIF.js +1 -0
  218. package/neural-interface/public/vendor/codemirror/chunks/dist-LXTMWZAM.js +1 -0
  219. package/neural-interface/public/vendor/codemirror/chunks/dist-MABASSET.js +1 -0
  220. package/neural-interface/public/vendor/codemirror/chunks/dist-MJVBUZLL.js +3 -0
  221. package/neural-interface/public/vendor/codemirror/chunks/dist-MNB3WZVU.js +1 -0
  222. package/neural-interface/public/vendor/codemirror/chunks/dist-QYWXOE3U.js +7 -0
  223. package/neural-interface/public/vendor/codemirror/chunks/dist-TEBOFWLZ.js +1 -0
  224. package/neural-interface/public/vendor/codemirror/chunks/dist-UNXFROM3.js +1 -0
  225. package/neural-interface/public/vendor/codemirror/chunks/dist-XL2SLQO6.js +1 -0
  226. package/neural-interface/public/vendor/codemirror/chunks/dist-XO42Y3AP.js +6 -0
  227. package/neural-interface/public/vendor/codemirror/chunks/dist-Y2WWDWJK.js +1 -0
  228. package/neural-interface/public/vendor/codemirror/chunks/dist-YFEZKWMU.js +1 -0
  229. package/neural-interface/public/vendor/codemirror/chunks/dist-ZY7SWQO6.js +1 -0
  230. package/neural-interface/public/vendor/codemirror/chunks/dockerfile-3Y4R4NCH.js +1 -0
  231. package/neural-interface/public/vendor/codemirror/chunks/dtd-5343GJ4P.js +1 -0
  232. package/neural-interface/public/vendor/codemirror/chunks/dylan-FI2CXSW2.js +1 -0
  233. package/neural-interface/public/vendor/codemirror/chunks/ebnf-GNQ77YWA.js +1 -0
  234. package/neural-interface/public/vendor/codemirror/chunks/ecl-MRPUAE2L.js +1 -0
  235. package/neural-interface/public/vendor/codemirror/chunks/eiffel-DZROES27.js +1 -0
  236. package/neural-interface/public/vendor/codemirror/chunks/elm-4KICRFKQ.js +1 -0
  237. package/neural-interface/public/vendor/codemirror/chunks/erlang-3IHYC263.js +1 -0
  238. package/neural-interface/public/vendor/codemirror/chunks/factor-C6D3E5UK.js +1 -0
  239. package/neural-interface/public/vendor/codemirror/chunks/fcl-VYTWUJMI.js +1 -0
  240. package/neural-interface/public/vendor/codemirror/chunks/forth-ZBO2EH5M.js +1 -0
  241. package/neural-interface/public/vendor/codemirror/chunks/fortran-5NDCRWIK.js +1 -0
  242. package/neural-interface/public/vendor/codemirror/chunks/gas-SKRMOXFP.js +1 -0
  243. package/neural-interface/public/vendor/codemirror/chunks/gherkin-L45YXZLW.js +1 -0
  244. package/neural-interface/public/vendor/codemirror/chunks/groovy-GLPTLN44.js +1 -0
  245. package/neural-interface/public/vendor/codemirror/chunks/haskell-E7NF7P4Y.js +1 -0
  246. package/neural-interface/public/vendor/codemirror/chunks/haxe-K2NVDOB6.js +1 -0
  247. package/neural-interface/public/vendor/codemirror/chunks/http-Q6DRQIJB.js +1 -0
  248. package/neural-interface/public/vendor/codemirror/chunks/idl-MZYNJVLN.js +1 -0
  249. package/neural-interface/public/vendor/codemirror/chunks/javascript-6YRYK2HR.js +1 -0
  250. package/neural-interface/public/vendor/codemirror/chunks/julia-HXEL2T5G.js +1 -0
  251. package/neural-interface/public/vendor/codemirror/chunks/livescript-MV7CI2JZ.js +1 -0
  252. package/neural-interface/public/vendor/codemirror/chunks/lua-E36NHOOD.js +1 -0
  253. package/neural-interface/public/vendor/codemirror/chunks/mathematica-3XOZZCMC.js +1 -0
  254. package/neural-interface/public/vendor/codemirror/chunks/mbox-ODYGFKS7.js +1 -0
  255. package/neural-interface/public/vendor/codemirror/chunks/mirc-WB43AWF5.js +1 -0
  256. package/neural-interface/public/vendor/codemirror/chunks/mllike-ZT6ET7ZH.js +1 -0
  257. package/neural-interface/public/vendor/codemirror/chunks/modelica-LLMZPFGA.js +1 -0
  258. package/neural-interface/public/vendor/codemirror/chunks/mscgen-2OPNNYFH.js +1 -0
  259. package/neural-interface/public/vendor/codemirror/chunks/mumps-6P3HWJH6.js +1 -0
  260. package/neural-interface/public/vendor/codemirror/chunks/nginx-TCGKQTRW.js +1 -0
  261. package/neural-interface/public/vendor/codemirror/chunks/nsis-ATIGIXTJ.js +1 -0
  262. package/neural-interface/public/vendor/codemirror/chunks/ntriples-5PLBI5OV.js +1 -0
  263. package/neural-interface/public/vendor/codemirror/chunks/octave-QF2S3NL6.js +1 -0
  264. package/neural-interface/public/vendor/codemirror/chunks/oz-JFIVFFH2.js +1 -0
  265. package/neural-interface/public/vendor/codemirror/chunks/pascal-JG6SW76V.js +1 -0
  266. package/neural-interface/public/vendor/codemirror/chunks/perl-4B3IWVVO.js +1 -0
  267. package/neural-interface/public/vendor/codemirror/chunks/pig-ABEBH4MI.js +1 -0
  268. package/neural-interface/public/vendor/codemirror/chunks/powershell-H32XE7TL.js +1 -0
  269. package/neural-interface/public/vendor/codemirror/chunks/properties-NN644MMA.js +1 -0
  270. package/neural-interface/public/vendor/codemirror/chunks/protobuf-YKWQK2J3.js +1 -0
  271. package/neural-interface/public/vendor/codemirror/chunks/pug-RIYXEKFW.js +1 -0
  272. package/neural-interface/public/vendor/codemirror/chunks/puppet-JZQ5WPEV.js +1 -0
  273. package/neural-interface/public/vendor/codemirror/chunks/python-EBCGGHAC.js +1 -0
  274. package/neural-interface/public/vendor/codemirror/chunks/q-5UMH2YQY.js +1 -0
  275. package/neural-interface/public/vendor/codemirror/chunks/r-7XMGG453.js +1 -0
  276. package/neural-interface/public/vendor/codemirror/chunks/rpm-IEV7TSLR.js +1 -0
  277. package/neural-interface/public/vendor/codemirror/chunks/ruby-T4SPFPNM.js +1 -0
  278. package/neural-interface/public/vendor/codemirror/chunks/sas-GEDX67ET.js +1 -0
  279. package/neural-interface/public/vendor/codemirror/chunks/scheme-FTLOWKPC.js +1 -0
  280. package/neural-interface/public/vendor/codemirror/chunks/shell-HUFRKFSJ.js +1 -0
  281. package/neural-interface/public/vendor/codemirror/chunks/sieve-P5QUDVYO.js +1 -0
  282. package/neural-interface/public/vendor/codemirror/chunks/smalltalk-2SORJNQI.js +1 -0
  283. package/neural-interface/public/vendor/codemirror/chunks/solr-M22TGAR5.js +1 -0
  284. package/neural-interface/public/vendor/codemirror/chunks/sparql-4M3KL752.js +1 -0
  285. package/neural-interface/public/vendor/codemirror/chunks/spreadsheet-3K23LA4N.js +1 -0
  286. package/neural-interface/public/vendor/codemirror/chunks/sql-VHRFMUBI.js +1 -0
  287. package/neural-interface/public/vendor/codemirror/chunks/stex-QZDAQUY2.js +1 -0
  288. package/neural-interface/public/vendor/codemirror/chunks/stylus-7ZDKAKBD.js +1 -0
  289. package/neural-interface/public/vendor/codemirror/chunks/swift-WCLCLGMR.js +1 -0
  290. package/neural-interface/public/vendor/codemirror/chunks/tcl-JLMU6WOK.js +1 -0
  291. package/neural-interface/public/vendor/codemirror/chunks/textile-4CHDKZ4T.js +1 -0
  292. package/neural-interface/public/vendor/codemirror/chunks/tiddlywiki-DKMCZZQ4.js +1 -0
  293. package/neural-interface/public/vendor/codemirror/chunks/tiki-F4JIG36Q.js +1 -0
  294. package/neural-interface/public/vendor/codemirror/chunks/toml-BHMHTIM2.js +1 -0
  295. package/neural-interface/public/vendor/codemirror/chunks/troff-YQ2KV5NT.js +1 -0
  296. package/neural-interface/public/vendor/codemirror/chunks/ttcn-ZHRCVFJY.js +1 -0
  297. package/neural-interface/public/vendor/codemirror/chunks/ttcn-cfg-KJOVTY4X.js +1 -0
  298. package/neural-interface/public/vendor/codemirror/chunks/turtle-535P5N6I.js +1 -0
  299. package/neural-interface/public/vendor/codemirror/chunks/vb-76UMQHOT.js +1 -0
  300. package/neural-interface/public/vendor/codemirror/chunks/vbscript-CGNDTK6Z.js +1 -0
  301. package/neural-interface/public/vendor/codemirror/chunks/velocity-VSJDO5T5.js +1 -0
  302. package/neural-interface/public/vendor/codemirror/chunks/verilog-4T6ETXIP.js +1 -0
  303. package/neural-interface/public/vendor/codemirror/chunks/vhdl-T7FNAXUN.js +1 -0
  304. package/neural-interface/public/vendor/codemirror/chunks/webidl-P6MJSJ6J.js +1 -0
  305. package/neural-interface/public/vendor/codemirror/chunks/xquery-UOVILRGN.js +1 -0
  306. package/neural-interface/public/vendor/codemirror/chunks/yacas-CV2APROL.js +1 -0
  307. package/neural-interface/public/vendor/codemirror/chunks/z80-3KFNVM4M.js +1 -0
  308. package/neural-interface/public/vendor/codemirror/codemirror-6.43.14-75f05e67.min.js +2 -0
  309. package/neural-interface/public/vendor/codemirror/manifest.json +60 -0
  310. package/neural-interface/scripts/build-vendor.mjs +78 -2
  311. package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
  312. package/neural-interface/server.js +873 -1028
  313. package/neural-interface/templates/rulesets/README.md +1 -1
  314. package/package.json +2 -8
  315. package/setup.js +44 -7
  316. package/benchmarks/browser-live-results.json +0 -79
  317. package/benchmarks/browser-v2-results.json +0 -258
  318. package/neural-interface/lib/codex-capabilities.d.ts +0 -41
  319. package/neural-interface/public/category-logos/claude.svg +0 -1
  320. package/neural-interface/public/category-logos/gemini-color.svg +0 -1
  321. package/neural-interface/public/category-logos/openai.svg +0 -1
  322. package/neural-interface/public/category-logos/synabun.png +0 -0
  323. package/neural-interface/public/claude.svg +0 -1
  324. package/neural-interface/public/gallery.svg +0 -6
  325. package/neural-interface/public/leonardoai.svg +0 -1
  326. package/neural-interface/public/mcp.svg +0 -4
  327. package/neural-interface/public/opencode-logo-dark-square.svg +0 -1
  328. package/neural-interface/public/pin-svgrepo-com.svg +0 -25
  329. package/neural-interface/public/sessionicon.svg +0 -8
  330. package/neural-interface/public/toolbar-album.svg +0 -8
  331. package/neural-interface/public/toolbar-question.svg +0 -6
  332. package/neural-interface/public/toolbar-sessions.svg +0 -6
  333. package/neural-interface/scripts/codex-protocol-fixture.mjs +0 -83
  334. package/skills/synabun/synabunicon.png +0 -0
@@ -7,6 +7,7 @@ import { hostedSidepanelId, sidepanelHost } from './ui-sidepanel-runtime.js';
7
7
  import { storage } from './storage.js';
8
8
  import { fetchBlobNamespace, putBlob, deleteBlob, flushBlobs } from './blob-store.js';
9
9
  import { state, emit, on } from './state.js';
10
+ import { forgetGreeting, mountGreeting } from './greeting/greeting-card.js';
10
11
  import { fetchClaudeSessions, fetchBrowserSessions, searchSessions } from './api.js';
11
12
  import { createFrameRenderer } from './utils.js';
12
13
  import { notify, NOTIF_TYPE } from './ui-notifications.js';
@@ -15,6 +16,9 @@ import { subscribeCliStatus, recheckCliStatus, getCliDocUrl, getCliInstallComman
15
16
  import { nativeLoopWindowId } from './ui-native-window-id.js';
16
17
  import { createStickyScrollController } from './ui-scroll-follow.js';
17
18
  import { requestGeneratedSessionTitle } from './session-title.js';
19
+ import { wireFileLinks } from './ui-file-links.js';
20
+ import { WORKER_END_CLASS, backToAssistant, buildWorkerEndCard, endWorkerRunOnClose, forgetWorkerEnd, trackWorkerEnd, updateWorkerEndBusy } from './ui-worker-end.js';
21
+ import { isDispatchedRun, isEndOfRunAbort } from './worker-end.js';
18
22
  // ── cp/ feature modules (SDK-engine CLI parity: diffs, agents, bash, perms, statusline) ──
19
23
  import { setCpCtx } from './cp/cp-ctx.js';
20
24
  import { buildDiffCard, buildDiffPreviewEl, finalizeDiffCard } from './cp/cp-diff.js';
@@ -24,7 +28,7 @@ import { buildAgentCard, ensureAgentScope, noteAgentActivity, updateAgentTodoBad
24
28
  import { renderPermissionCard, renderPlanApprovalCard, renderElicitationCard, decorateAskCard, askAnnotations, markAskAnswered, PERMISSION_MODES, MODE_LABELS } from './cp/cp-permissions.js';
25
29
  import { normalizeSession, changedStartSettings, sessionFlags, sessionRows, fastModeSupported, fastModeReason, mergeSessionModels, parseMcpServerLines, formatMcpServerLines } from './cp/cp-session-model.js';
26
30
  import { renderSessionSettingsCard } from './cp/cp-session-settings.js';
27
- import { describeOrigin, reconcileTasks, adoptLiveTasks, describeHistorySystemRow, workEndedByRestart } from './cp/cp-tasks-model.js';
31
+ import { describeOrigin, reconcileTasks, adoptLiveTasks, describeHistorySystemRow, workEndedByRestart, isTaskRunning } from './cp/cp-tasks-model.js';
28
32
  import { renderTasksCard } from './cp/cp-tasks.js';
29
33
  import { sessionListLabel, collectTags, tagSession as tagClaudeSession, sessionActionsAvailable, sessionOpsSupported, labelledSessionIds, mergeSessionSearch, writeSessionTitle, forkSession as forkClaudeSession, deleteSession as deleteClaudeSession, fetchSubagentMessages, forkTitle, entryBefore, promptText, removeFrom, sessionRowParts, fillSelectOptions } from './cp/cp-sessions.js';
30
34
  import { contextCard, usageCard, mcpRows, rewindPreviewText, rewindResultText } from './cp/cp-usage-model.js';
@@ -2928,6 +2932,7 @@ function newTabState(sessionId = null, label = 'New chat', id = null) {
2928
2932
  automationRunId: null,
2929
2933
  automationActive: false,
2930
2934
  automationOwnerId: null,
2935
+ releasedRunId: null, // the ended run this tab showed before the user continued it by hand
2931
2936
  };
2932
2937
  }
2933
2938
 
@@ -3130,15 +3135,18 @@ function closeTab(idx, { detachAutomation = false } = {}) {
3130
3135
  if (idx < 0 || idx >= _tabs.length) return;
3131
3136
  const tab = _tabs[idx];
3132
3137
  if (tab.automationRunId && !detachAutomation) {
3138
+ const runId = tab.automationRunId;
3133
3139
  window.dispatchEvent(new CustomEvent('native-loop:dismissed', {
3134
- detail: { runId: tab.automationRunId },
3140
+ detail: { runId },
3135
3141
  }));
3136
- fetch('/api/loop/stop', {
3142
+ // A worker that finished its task is completed; any other run is stopped.
3143
+ endWorkerRunOnClose(runId, () => fetch('/api/loop/stop', {
3137
3144
  method: 'POST',
3138
3145
  headers: { 'Content-Type': 'application/json' },
3139
- body: JSON.stringify({ runId: tab.automationRunId }),
3140
- }).catch(() => {});
3146
+ body: JSON.stringify({ runId }),
3147
+ }).catch(() => {}), { busy: hasLiveBackgroundWork(tab) });
3141
3148
  }
3149
+ if (tab.automationRunId) forgetWorkerEnd(tab.automationRunId);
3142
3150
  flushSessionSnapshotSave(tab);
3143
3151
  recordHookEvent(tab, 'SessionEnd', tab.sessionId || '(new)');
3144
3152
  tab.closed = true;
@@ -3264,7 +3272,7 @@ function saveTabs() {
3264
3272
  try {
3265
3273
  // A temporary tab is never written: not the tab, its label, its queue or its session id.
3266
3274
  const kept = persistableTabs(_tabs, _activeTabIdx);
3267
- const localTabs = kept.tabs.map(t => ({ id: t.id, sessionId: t.sessionId, label: t.label, titleState: t.titleState === 'generating' ? 'default' : (t.titleState || 'default'), sessionCost: t.sessionCost || 0, running: t.running || false, project: t.project || '', model: t.model || '', effort: t.effort || 'off', planMode: t.planMode || false, ...savedMode(t), toolPolicy: t.toolPolicy || 'full', accountId: t.accountId || '', session: normalizeSession(t.session), transcriptAt: t.transcriptAt || null, planFilePath: t.planFilePath || '', conversation: t.conversation || '', queue: t.queue || [], queuePaused: t.queuePaused || false, automationRunId: t.automationRunId || null, automationActive: !!t.automationActive, automationOwnerId: t.automationOwnerId || null }));
3275
+ const localTabs = kept.tabs.map(t => ({ id: t.id, sessionId: t.sessionId, label: t.label, titleState: t.titleState === 'generating' ? 'default' : (t.titleState || 'default'), sessionCost: t.sessionCost || 0, running: t.running || false, project: t.project || '', model: t.model || '', effort: t.effort || 'off', planMode: t.planMode || false, ...savedMode(t), toolPolicy: t.toolPolicy || 'full', accountId: t.accountId || '', session: normalizeSession(t.session), transcriptAt: t.transcriptAt || null, planFilePath: t.planFilePath || '', conversation: t.conversation || '', queue: t.queue || [], queuePaused: t.queuePaused || false, automationRunId: t.automationRunId || null, automationActive: !!t.automationActive, automationOwnerId: t.automationOwnerId || null, releasedRunId: t.releasedRunId || null }));
3268
3276
  const localRunIds = new Set(localTabs.map((tab) => tab.automationRunId).filter(Boolean));
3269
3277
  let foreignAutomationTabs = [];
3270
3278
  try {
@@ -3406,6 +3414,7 @@ function restoreTabs() {
3406
3414
  if (t && saved.automationRunId) t.automationRunId = saved.automationRunId;
3407
3415
  if (t && saved.automationRunId) t.automationActive = !!saved.automationActive;
3408
3416
  if (t && saved.automationRunId) t.automationOwnerId = saved.automationOwnerId || null;
3417
+ if (t && saved.releasedRunId && !saved.automationRunId) t.releasedRunId = saved.releasedRunId;
3409
3418
  }
3410
3419
  if (_tabs.length) {
3411
3420
  switchTab(Math.min(data.activeIdx || 0, _tabs.length - 1));
@@ -7445,7 +7454,57 @@ function handleControlRequest(tab, msg) {
7445
7454
  // What a query tells the bridge about this tab's session: the permission mode
7446
7455
  // (or that the user's own settings should pick it), the tool policy, and what
7447
7456
  // this panel can render. Keys a server that predates them ignores.
7457
+ // ── Greeting (shared/greeting/, lib/greeting/) ──
7458
+ // What SynaBun says when a person comes back and opens a new chat: one or two sentences in the
7459
+ // empty state, written by SynaBun ahead of time (this session's model never greets). Only for a
7460
+ // tab that holds no conversation yet: never a resumed session, a temporary chat or a tab showing
7461
+ // an automation run (hence the short wait: those are marked right after the tab is made). The
7462
+ // server decides whether this opening is a return worth greeting; an older server answers nothing.
7463
+ // Asked from _paintTemporary(), which runs wherever the conversation area is rebuilt. Nothing of it
7464
+ // is kept on the tab object (what a tab carries over, and what is saved of it, is listed elsewhere).
7465
+ const _greetingOf = new WeakMap(); // tab → { seq, host, greeting: { id, session } | null }
7466
+ function _greetingState(tab) {
7467
+ let held = _greetingOf.get(tab);
7468
+ if (!held) { held = { seq: 0, host: null, greeting: null }; _greetingOf.set(tab, held); }
7469
+ return held;
7470
+ }
7471
+ function _offerGreetingSoon(tab) {
7472
+ if (!tab) return;
7473
+ setTimeout(() => { try { _offerGreeting(tab); } catch { /* a tab always opens */ } }, 300);
7474
+ }
7475
+ function _offerGreeting(tab) {
7476
+ if (!_tabs.includes(tab) || tab.sessionId || tab.temporary || tab.automationRunId || tab.automationActive || tab.running) return;
7477
+ const host = tab.messagesEl?.querySelector(':scope > .cp-empty');
7478
+ if (!host || host.dataset.greetingAsked === '1') return;
7479
+ host.dataset.greetingAsked = '1';
7480
+ const held = _greetingState(tab);
7481
+ // The conversation area was rebuilt: a new conversation in the same tab is a new opening.
7482
+ if (held.host && held.host !== host) { held.seq += 1; held.greeting = null; }
7483
+ held.host = host;
7484
+ const session = `${tab.id}.${held.seq}`;
7485
+ const cwd = tab.project || ddGetValue(_panel?.querySelector('#cp-project')) || '';
7486
+ mountGreeting(host, {
7487
+ surface: 'claude-panel', session, cwd,
7488
+ onOpenMemory: (id) => { if (id) emit('memory:open', { id }); },
7489
+ isCurrent: () => !tab.sessionId && !tab.temporary && !tab.automationRunId && held.host === host && tab.messagesEl?.contains(host),
7490
+ }).then((greeting) => {
7491
+ if (held.host === host) held.greeting = greeting ? { id: greeting.id, session } : null;
7492
+ }).catch(() => {});
7493
+ }
7494
+
7495
+ // The greeting a chat opened with goes back once, with its first prompt: the bridge tells the model
7496
+ // what was said (capability 'greeting'). A temporary chat names nothing, so it takes none.
7497
+ function _echoGreeting(tab, msg) {
7498
+ const held = msg.type === 'query' ? _greetingOf.get(tab) : null;
7499
+ if (!held?.greeting?.id) return;
7500
+ if (hasCapability(tab, 'greeting') && !tab.temporary) msg.greetingId = held.greeting.id;
7501
+ forgetGreeting('claude-panel', held.greeting.session);
7502
+ held.greeting = null;
7503
+ }
7504
+
7448
7505
  function _applySessionOptions(tab, msg) {
7506
+ // The greeting this chat opened with goes back once, with its first prompt.
7507
+ _echoGreeting(tab, msg);
7449
7508
  // The tab's own mode (statedMode() in cp/cp-permission-model.js: Bypass only
7450
7509
  // as the user's recorded pick). A tab that never picked one leaves it to the
7451
7510
  // user's Claude Code settings (permissions.defaultMode).
@@ -7471,6 +7530,8 @@ function _applySessionOptions(tab, msg) {
7471
7530
  function _paintTemporary(tab) {
7472
7531
  if (!tab) return;
7473
7532
  paintTemporary(tab, { capable: hasCapability(tab, TEMPORARY_CAPABILITY), onToggle: (on) => _chooseTemporary(tab, on) });
7533
+ // The conversation area was (re)built: a new chat may open with SynaBun's greeting.
7534
+ _offerGreetingSoon(tab);
7474
7535
  }
7475
7536
 
7476
7537
  // The user's choice on a new tab. A process kept ready for the other kind of
@@ -9228,6 +9289,9 @@ function send({ shift = false } = {}) {
9228
9289
  // A temporary chat that is over, or one the running server would save: nothing is sent.
9229
9290
  { const refusal = temporaryRefusal(tab, { capable: hasCapability(tab, TEMPORARY_CAPABILITY) }); if (refusal) { appendStatus(tab, refusal); return; } }
9230
9291
 
9292
+ // A message of the user's own in the tab of a run that ended: the tab is theirs from here on.
9293
+ releaseAutomationForManualUse(tab);
9294
+
9231
9295
  // ── !bash shortcut — prefix a Bash-tool hint so Claude executes the command ──
9232
9296
  if (text.startsWith('!') && text.length > 1) {
9233
9297
  const cmd = text.slice(1).trim();
@@ -10162,15 +10226,7 @@ function _onMessagesClick(e) {
10162
10226
  });
10163
10227
  return;
10164
10228
  }
10165
- const link = e.target.closest('a.file-link');
10166
- if (link) {
10167
- e.preventDefault();
10168
- const path = (link.textContent || '').replace(/:\d+$/, '');
10169
- navigator.clipboard.writeText(path);
10170
- link.style.opacity = '0.5';
10171
- setTimeout(() => { link.style.opacity = ''; }, 300);
10172
- return;
10173
- }
10229
+ // File links (a.file-link, and the links of a message's Markdown) are taken by _fileLinkOptions below.
10174
10230
  const hdr = e.target.closest('.tool-hdr');
10175
10231
  if (hdr && !e.target.closest('button, a, input, select, textarea')) {
10176
10232
  const card = hdr.closest('.tool-card');
@@ -10183,6 +10239,25 @@ function _onMessagesClick(e) {
10183
10239
  }
10184
10240
  }
10185
10241
 
10242
+ // ── File links ──
10243
+ // A link to a file the code editor can open opens it there (ui-file-links.js, shared with the other panels).
10244
+ // The same delegation as above: it covers streaming, finished and snapshot-restored messages of every tab.
10245
+ const _fileLinkOptions = {
10246
+ // A relative path is a path in the folder of the tab the message belongs to.
10247
+ cwd: (link) => {
10248
+ const tab = _tabs.find((t) => t.messagesEl?.contains(link)) || activeTab();
10249
+ return tab?.init?.cwd || tab?.project || '';
10250
+ },
10251
+ textLinks: 'a.file-link',
10252
+ // A path the editor does not open keeps what a click on it did: it is copied.
10253
+ copyPath: (link) => {
10254
+ const path = (link.textContent || '').replace(/:\d+$/, '');
10255
+ link.style.opacity = '0.5';
10256
+ setTimeout(() => { link.style.opacity = ''; }, 300);
10257
+ return navigator.clipboard.writeText(path);
10258
+ },
10259
+ };
10260
+
10186
10261
  // ── Public API ──
10187
10262
  async function _ensureClaudePanelReady() {
10188
10263
  if (!_panel) {
@@ -10197,6 +10272,7 @@ async function _ensureClaudePanelReady() {
10197
10272
  });
10198
10273
  wireEvents();
10199
10274
  _panel.querySelector('#cp-messages-container')?.addEventListener('click', _onMessagesClick);
10275
+ wireFileLinks(_panel.querySelector('#cp-messages-container'), _fileLinkOptions);
10200
10276
  await loadConfig(); // must complete before restoreTabs — checks server boot ID
10201
10277
  loadSkills();
10202
10278
  restoreTabs();
@@ -10248,6 +10324,18 @@ export async function attachClaudeAutomation(run, { focus = !!run?.focus, isCanc
10248
10324
  if (!run?.runId || !run?.providerSessionId) return { ok: false, reason: 'identity_pending' };
10249
10325
  await _ensureClaudePanelReady();
10250
10326
  if (isCancelled()) return { ok: false, reason: 'dismissed' };
10327
+ // The user continued this run's tab by hand after the run ended: it stays theirs. The dock's
10328
+ // Focus raises it; the run is let go again, and nothing in the tab changes.
10329
+ const own = _tabs.find((entry) => !entry.automationRunId && entry.releasedRunId === run.runId && entry.sessionId === run.providerSessionId);
10330
+ if (own && !(run.status === 'starting' || run.status === 'running')) {
10331
+ window.dispatchEvent(new CustomEvent('native-loop:dismissed', { detail: { runId: run.runId } }));
10332
+ if (focus) {
10333
+ if (!_visible) await toggleClaudePanel();
10334
+ const ownIdx = _tabs.indexOf(own);
10335
+ if (ownIdx >= 0) switchTab(ownIdx);
10336
+ }
10337
+ return { ok: true, tabId: own.id, released: true };
10338
+ }
10251
10339
  let tab = _tabs.find((entry) => entry.automationRunId === run.runId)
10252
10340
  || _tabs.find((entry) => entry.sessionId === run.providerSessionId);
10253
10341
  if (!tab) {
@@ -10270,6 +10358,7 @@ export async function attachClaudeAutomation(run, { focus = !!run?.focus, isCanc
10270
10358
  tab.automationRunId = run.runId;
10271
10359
  tab.automationActive = running;
10272
10360
  tab.automationOwnerId = nativeLoopWindowId;
10361
+ tab.releasedRunId = null;
10273
10362
  tab.sdkMode = true;
10274
10363
  tab.sessionId = run.providerSessionId;
10275
10364
  tab.label = run.title || tab.label || 'Automation';
@@ -10288,10 +10377,12 @@ export async function attachClaudeAutomation(run, { focus = !!run?.focus, isCanc
10288
10377
  return { ok: false, reason: 'dismissed' };
10289
10378
  }
10290
10379
  }
10291
- if (run.status === 'failed' && run.error && tab._automationLifecycleError !== run.error) {
10380
+ // (A dispatched worker's failure, with its reason, is on its end card.)
10381
+ if (run.status === 'failed' && run.error && !isDispatchedRun(run) && tab._automationLifecycleError !== run.error) {
10292
10382
  tab._automationLifecycleError = run.error;
10293
10383
  appendError(tab, run.error);
10294
10384
  }
10385
+ trackWorkerEnd(run, { apply: (view) => showWorkerEnd(tab, view), busy: hasLiveBackgroundWork(tab) });
10295
10386
  // The mode control is hidden while the run is active and back when it ended.
10296
10387
  if (tab === activeTab()) populateModeDropdown(_panel?.querySelector('#cp-mode'), tab);
10297
10388
  const idx = _tabs.indexOf(tab);
@@ -10319,10 +10410,60 @@ export function handleClaudeAutomationEvent(runId, payload) {
10319
10410
  return true;
10320
10411
  }
10321
10412
  if (event.type === 'synabun.error') {
10413
+ // Every run's end disposes its SDK query, and the SDK says so in these words: not a failure.
10414
+ if (isEndOfRunAbort(event.message)) return true;
10322
10415
  appendError(tab, event.message || 'Claude Code automation failed');
10323
10416
  return true;
10324
10417
  }
10325
10418
  handleTabMsg(tab, { type: 'event', event, fromRun: true });
10419
+ // Background agents still running keep a warm worker's "Task complete" away.
10420
+ if (event.type === 'system' || event.type === 'result') updateWorkerEndBusy(runId, hasLiveBackgroundWork(tab));
10421
+ return true;
10422
+ }
10423
+
10424
+ function hasLiveBackgroundWork(tab) {
10425
+ for (const task of tab?.tasks?.values?.() || []) {
10426
+ if (task && !task.ambient && isTaskRunning(task)) return true;
10427
+ }
10428
+ return false;
10429
+ }
10430
+
10431
+ // The end of a worker the Assistant dispatched (ui-worker-end.js): one card,
10432
+ // the last row of its transcript. Its button closes this tab the way the X
10433
+ // does (a warm worker that finished its task is completed, one still at work
10434
+ // is stopped; its record stays for the Assistant) and shows the Assistant
10435
+ // session that dispatched it.
10436
+ function showWorkerEnd(tab, view) {
10437
+ tab._workerEnd = view || null;
10438
+ const $msgs = tab.messagesEl;
10439
+ if (!$msgs || tab.closed) return;
10440
+ $msgs.querySelectorAll(`.${WORKER_END_CLASS}`).forEach((el) => el.remove());
10441
+ if (!view) return;
10442
+ $msgs.appendChild(buildWorkerEndCard(view, {
10443
+ classes: { card: 'cp-worker-end', title: 'post-plan-header', actions: 'post-plan-actions', button: 'post-plan-action pp-primary' },
10444
+ onBack: () => {
10445
+ const idx = _tabs.indexOf(tab);
10446
+ if (idx >= 0) closeTab(idx);
10447
+ backToAssistant(view.assistantSessionId);
10448
+ },
10449
+ }));
10450
+ if (tab === activeTab()) scrollEnd(true);
10451
+ }
10452
+
10453
+ // The user sends a message of their own in the tab of a run that ended (Codex's
10454
+ // releaseAutomationForManualUse): the run's end card goes, the tab stops following
10455
+ // the run, and the router leaves the run alone, so nothing of it comes back here.
10456
+ // A run that is still going keeps its tab (the composer refuses a manual turn then).
10457
+ function releaseAutomationForManualUse(tab) {
10458
+ if (!tab?.automationRunId || tab.automationActive) return false;
10459
+ const runId = tab.automationRunId;
10460
+ forgetWorkerEnd(runId);
10461
+ showWorkerEnd(tab, null);
10462
+ tab.automationRunId = null;
10463
+ tab.automationOwnerId = null;
10464
+ tab.releasedRunId = runId;
10465
+ window.dispatchEvent(new CustomEvent('native-loop:dismissed', { detail: { runId } }));
10466
+ saveTabs();
10326
10467
  return true;
10327
10468
  }
10328
10469
 
@@ -1167,6 +1167,21 @@ export function initDetailPanel() {
1167
1167
  closeAllCards();
1168
1168
  });
1169
1169
 
1170
+ // A memory asked for by id: the Assistant's memory chips and automation trace,
1171
+ // Settings → Automation behavior. One that is not on the map yet (just learned,
1172
+ // or filtered out) opens from the store.
1173
+ on('memory:open', ({ id } = {}) => {
1174
+ if (!id) return;
1175
+ const node = state.allNodes.find(n => n.id === id);
1176
+ if (node) {
1177
+ state.selectedNodeId = node.id;
1178
+ openMemoryCard(node);
1179
+ emit('graph:navigate', { node, zoom: 'close' });
1180
+ return;
1181
+ }
1182
+ fetchMemory(id).then((fresh) => { if (fresh?.payload) openMemoryCard({ id, payload: fresh.payload }); }).catch(() => {});
1183
+ });
1184
+
1170
1185
  // Persist open card positions after resize/drag and sync to other clients
1171
1186
  on('detail:layout-changed', (payload) => {
1172
1187
  persistOpenCards();
@@ -1509,6 +1509,28 @@ export function initExplorer() {
1509
1509
  }
1510
1510
  });
1511
1511
 
1512
+ // Open the explorer on one category, expanded and in view (Settings → Automation
1513
+ // behavior → "See all in Memory"). `fallback`: used while `category` does not exist yet.
1514
+ on('explorer:show-category', ({ category, fallback } = {}) => {
1515
+ const name = state.categoryMetadata?.[category] ? category : (fallback || category);
1516
+ if (!name) return;
1517
+ if (!_visible) toggleExplorer();
1518
+ let changed = _collapsed.delete(name);
1519
+ const parent = state.categoryMetadata?.[name]?.parent;
1520
+ if (parent && _collapsed.delete(parent)) changed = true;
1521
+ if (changed) saveCollapsed();
1522
+ buildTreeImpl();
1523
+ const container = $('explorer-tree');
1524
+ if (!container) return;
1525
+ const idx = _flatRows.findIndex(r => r.kind === 'category' && r.item?.name === name);
1526
+ if (_virtActive && idx >= 0) {
1527
+ container.scrollTop = Math.max(0, idx * _rowH - 40);
1528
+ renderVirtualWindow(container);
1529
+ }
1530
+ const row = container.querySelector(`.explorer-node[data-cat="${CSS.escape(name)}"]`);
1531
+ if (row && !_virtActive) row.scrollIntoView({ behavior: 'smooth', block: 'start' });
1532
+ });
1533
+
1512
1534
  // Search integration
1513
1535
  on('search:apply', () => {
1514
1536
  if (_visible) scheduleBuildTree();