@mindexec/cli 0.2.384 → 0.2.386

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 (267) hide show
  1. package/codex-runtime.js +31 -255
  2. package/package.json +1 -1
  3. package/remote-hub.js +2 -80
  4. package/scripts/remote-fast-live-rate-smoke.mjs +3 -19
  5. package/scripts/remote-fast-mdm-browser-smoke.mjs +2 -28
  6. package/scripts/remote-hub-smoke.mjs +2 -32
  7. package/scripts/setup-tree-sitter-grammars.mjs +5 -26
  8. package/server.js +33 -1811
  9. package/wwwroot/MindExecution.Web.styles.css +3 -0
  10. package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -0
  11. package/wwwroot/_content/MindExecution.Plugins.Directory/MindExecution.Plugins.Directory.u7utcng611.bundle.scp.css +7 -0
  12. package/wwwroot/_content/MindExecution.Plugins.Directory/background.png +0 -0
  13. package/wwwroot/_content/MindExecution.Plugins.Directory/directory-manager.js +202 -0
  14. package/wwwroot/_content/MindExecution.Plugins.Directory/exampleJsInterop.js +6 -0
  15. package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -0
  16. package/wwwroot/_content/MindExecution.Shared/MindExecution.Shared.wsano1j4wp.bundle.scp.css +4 -0
  17. package/wwwroot/_content/MindExecution.Shared/css/admin-dashboard.css +559 -0
  18. package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -0
  19. package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +3705 -0
  20. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Bold.ttf +0 -0
  21. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Regular.ttf +0 -0
  22. package/wwwroot/_content/MindExecution.Shared/js/agent-visualization.js +359 -0
  23. package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1631 -0
  24. package/wwwroot/_content/MindExecution.Shared/js/code-master.js +8316 -0
  25. package/wwwroot/_content/MindExecution.Shared/js/file-system-helper.js +639 -0
  26. package/wwwroot/_content/MindExecution.Shared/js/helpers/InfiniteGridHelper.js +109 -0
  27. package/wwwroot/_content/MindExecution.Shared/js/marked.min.js +69 -0
  28. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +9987 -0
  29. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js.backup +1059 -0
  30. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +24635 -0
  31. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dev-guards.js +325 -0
  32. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +1491 -0
  33. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +434 -0
  34. package/wwwroot/_content/MindExecution.Shared/js/mind-map-glow-shader.js +260 -0
  35. package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +7821 -0
  36. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +160 -0
  37. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +10449 -0
  38. package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +977 -0
  39. package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +1531 -0
  40. package/wwwroot/_content/MindExecution.Shared/js/mind-map-multi-select.js +1716 -0
  41. package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +554 -0
  42. package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +4578 -0
  43. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js +489 -0
  44. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +372 -0
  45. package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +2203 -0
  46. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-lod-system.js +646 -0
  47. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-overlay-v2.js +4735 -0
  48. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +2383 -0
  49. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +1258 -0
  50. package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +890 -0
  51. package/wwwroot/_content/MindExecution.Shared/js/mindmap-toolbar.js +639 -0
  52. package/wwwroot/_content/MindExecution.Shared/js/native-drop-handler.js +170 -0
  53. package/wwwroot/_content/MindExecution.Shared/js/plan-master.js +788 -0
  54. package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +50 -0
  55. package/wwwroot/_content/MindExecution.Shared/js/texture-worker-manager.js +188 -0
  56. package/wwwroot/_content/MindExecution.Shared/js/texture-worker.js +208 -0
  57. package/wwwroot/_content/MindExecution.Shared/js/three.min.js +6 -0
  58. package/wwwroot/_content/MindExecution.Shared/js/titlebar-handler.js +191 -0
  59. package/wwwroot/_content/MindExecution.Shared/js/token-manager.js +37 -0
  60. package/wwwroot/_content/MindExecution.Shared/js/token-worker.js +28 -0
  61. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js +5626 -0
  62. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js.map +7 -0
  63. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/css/all.min.css +9 -0
  64. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.ttf +0 -0
  65. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
  66. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.ttf +0 -0
  67. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
  68. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.ttf +0 -0
  69. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
  70. package/wwwroot/_content/MindExecution.Shared/models/all-MiniLM-L6-v2-quantized.onnx +0 -0
  71. package/wwwroot/_content/MindExecution.Shared/models/vocab.txt +30522 -0
  72. package/wwwroot/_framework/Google.Protobuf.9h59ukbel7.dll +0 -0
  73. package/wwwroot/_framework/Markdig.d1j7v41cl1.dll +0 -0
  74. package/wwwroot/_framework/MessagePack.Annotations.l6qv48kgpt.dll +0 -0
  75. package/wwwroot/_framework/MessagePack.eqoptzx9d5.dll +0 -0
  76. package/wwwroot/_framework/Microsoft.AspNetCore.Authorization.k7dsih5y5g.dll +0 -0
  77. package/wwwroot/_framework/Microsoft.AspNetCore.Components.6nyje9sa0g.dll +0 -0
  78. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Authorization.iycd6unprw.dll +0 -0
  79. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Web.487u3twia4.dll +0 -0
  80. package/wwwroot/_framework/Microsoft.AspNetCore.Components.WebAssembly.d0gcnmlxxz.dll +0 -0
  81. package/wwwroot/_framework/Microsoft.AspNetCore.Metadata.h4yevl9adi.dll +0 -0
  82. package/wwwroot/_framework/Microsoft.CSharp.8bsm8vx6su.dll +0 -0
  83. package/wwwroot/_framework/Microsoft.Data.Sqlite.jdlxgv2jtg.dll +0 -0
  84. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.4gjazp7kjf.dll +0 -0
  85. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Abstractions.gocudnvz7b.dll +0 -0
  86. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Relational.lt4rsvinuo.dll +0 -0
  87. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Sqlite.69luj0fa9r.dll +0 -0
  88. package/wwwroot/_framework/Microsoft.Extensions.Caching.Abstractions.364t4jh3zz.dll +0 -0
  89. package/wwwroot/_framework/Microsoft.Extensions.Caching.Memory.izlxhpzosu.dll +0 -0
  90. package/wwwroot/_framework/Microsoft.Extensions.Configuration.8zq7hh41o7.dll +0 -0
  91. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Abstractions.8if74zs6ea.dll +0 -0
  92. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Json.duvlngw8i0.dll +0 -0
  93. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.Abstractions.t2hh9kvx0o.dll +0 -0
  94. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.n4tg99oy8l.dll +0 -0
  95. package/wwwroot/_framework/Microsoft.Extensions.DependencyModel.h0d06ixk3e.dll +0 -0
  96. package/wwwroot/_framework/Microsoft.Extensions.Logging.Abstractions.rl32bkx2sd.dll +0 -0
  97. package/wwwroot/_framework/Microsoft.Extensions.Logging.dlht1xei0t.dll +0 -0
  98. package/wwwroot/_framework/Microsoft.Extensions.Options.qeunebioml.dll +0 -0
  99. package/wwwroot/_framework/Microsoft.Extensions.Primitives.18cr6vnuuz.dll +0 -0
  100. package/wwwroot/_framework/Microsoft.IO.RecyclableMemoryStream.r915vovvw4.dll +0 -0
  101. package/wwwroot/_framework/Microsoft.IdentityModel.Abstractions.1ejljk3erv.dll +0 -0
  102. package/wwwroot/_framework/Microsoft.IdentityModel.JsonWebTokens.1596zr8gne.dll +0 -0
  103. package/wwwroot/_framework/Microsoft.IdentityModel.Logging.229uyvpgio.dll +0 -0
  104. package/wwwroot/_framework/Microsoft.IdentityModel.Tokens.9sibtajc9f.dll +0 -0
  105. package/wwwroot/_framework/Microsoft.JSInterop.WebAssembly.ryia5gxiad.dll +0 -0
  106. package/wwwroot/_framework/Microsoft.JSInterop.ew9vz9o332.dll +0 -0
  107. package/wwwroot/_framework/Microsoft.ML.OnnxRuntime.w9deo1m5ss.dll +0 -0
  108. package/wwwroot/_framework/Microsoft.ML.Tokenizers.cm2vuv2z61.dll +0 -0
  109. package/wwwroot/_framework/Microsoft.NET.StringTools.3qbrf4v2ki.dll +0 -0
  110. package/wwwroot/_framework/MimeMapping.og9ys58ylm.dll +0 -0
  111. package/wwwroot/_framework/MindExecution.Core.y7ffihhajj.dll +0 -0
  112. package/wwwroot/_framework/MindExecution.Kernel.l5y3qroa7p.dll +0 -0
  113. package/wwwroot/_framework/MindExecution.Plugins.Admin.uuf238xa0h.dll +0 -0
  114. package/wwwroot/_framework/MindExecution.Plugins.Business.nyr3v25v48.dll +0 -0
  115. package/wwwroot/_framework/MindExecution.Plugins.Concept.l9z9tx9svt.dll +0 -0
  116. package/wwwroot/_framework/MindExecution.Plugins.Directory.ju87t8h3zs.dll +0 -0
  117. package/wwwroot/_framework/MindExecution.Plugins.PlanMaster.krn3jgvjpa.dll +0 -0
  118. package/wwwroot/_framework/MindExecution.Plugins.YouTube.5m53srfud6.dll +0 -0
  119. package/wwwroot/_framework/MindExecution.Shared.ojp3psugsm.dll +0 -0
  120. package/wwwroot/_framework/MindExecution.Web.82k6ktlkfg.dll +0 -0
  121. package/wwwroot/_framework/Newtonsoft.Json.a56zs13vug.dll +0 -0
  122. package/wwwroot/_framework/SQLitePCLRaw.batteries_v2.rrd1nzawpp.dll +0 -0
  123. package/wwwroot/_framework/SQLitePCLRaw.core.1dxloztpfz.dll +0 -0
  124. package/wwwroot/_framework/SQLitePCLRaw.provider.e_sqlite3.oekyzl53i1.dll +0 -0
  125. package/wwwroot/_framework/Supabase.Core.s1pkj4aj0l.dll +0 -0
  126. package/wwwroot/_framework/Supabase.Functions.qz4nu782sg.dll +0 -0
  127. package/wwwroot/_framework/Supabase.Gotrue.twah27pkik.dll +0 -0
  128. package/wwwroot/_framework/Supabase.Postgrest.gmuuv369ih.dll +0 -0
  129. package/wwwroot/_framework/Supabase.Realtime.ox3kchdy3w.dll +0 -0
  130. package/wwwroot/_framework/Supabase.Storage.fnjnepaowr.dll +0 -0
  131. package/wwwroot/_framework/Supabase.azmaw5pgcz.dll +0 -0
  132. package/wwwroot/_framework/System.Collections.23yxgetbju.dll +0 -0
  133. package/wwwroot/_framework/System.Collections.Concurrent.vow3rm1dku.dll +0 -0
  134. package/wwwroot/_framework/System.Collections.Immutable.ap9596utv5.dll +0 -0
  135. package/wwwroot/_framework/System.Collections.NonGeneric.npjkaz40oc.dll +0 -0
  136. package/wwwroot/_framework/System.Collections.Specialized.ugkjbs6p02.dll +0 -0
  137. package/wwwroot/_framework/System.ComponentModel.Annotations.clwo0z2oyu.dll +0 -0
  138. package/wwwroot/_framework/System.ComponentModel.Primitives.end4v0xe2c.dll +0 -0
  139. package/wwwroot/_framework/System.ComponentModel.TypeConverter.tgtp5sm4iv.dll +0 -0
  140. package/wwwroot/_framework/System.ComponentModel.wupoltkk1t.dll +0 -0
  141. package/wwwroot/_framework/System.Console.9dik0wogo2.dll +0 -0
  142. package/wwwroot/_framework/System.Data.Common.4v8jejsiu0.dll +0 -0
  143. package/wwwroot/_framework/System.Diagnostics.DiagnosticSource.e2q75ondtq.dll +0 -0
  144. package/wwwroot/_framework/System.Diagnostics.Process.9736yjnxs8.dll +0 -0
  145. package/wwwroot/_framework/System.Diagnostics.TraceSource.h9al53gbbw.dll +0 -0
  146. package/wwwroot/_framework/System.Diagnostics.Tracing.h4bcp2fo98.dll +0 -0
  147. package/wwwroot/_framework/System.Drawing.64oovy8qts.dll +0 -0
  148. package/wwwroot/_framework/System.Drawing.Primitives.o6jiqpgbgl.dll +0 -0
  149. package/wwwroot/_framework/System.Formats.Asn1.rylx5ipd40.dll +0 -0
  150. package/wwwroot/_framework/System.IO.Compression.iceabaupns.dll +0 -0
  151. package/wwwroot/_framework/System.IO.Pipelines.uw8csd3mlz.dll +0 -0
  152. package/wwwroot/_framework/System.IdentityModel.Tokens.Jwt.t67es60z5b.dll +0 -0
  153. package/wwwroot/_framework/System.Linq.Expressions.ty95ava37f.dll +0 -0
  154. package/wwwroot/_framework/System.Linq.Queryable.hs2195jrwy.dll +0 -0
  155. package/wwwroot/_framework/System.Linq.hssodjwmlf.dll +0 -0
  156. package/wwwroot/_framework/System.Memory.1k78n7wdxb.dll +0 -0
  157. package/wwwroot/_framework/System.Net.Http.3br8rfql4c.dll +0 -0
  158. package/wwwroot/_framework/System.Net.Http.Json.860wbh17d8.dll +0 -0
  159. package/wwwroot/_framework/System.Net.NetworkInformation.e3wr00853o.dll +0 -0
  160. package/wwwroot/_framework/System.Net.Ping.r5cw4mf1a4.dll +0 -0
  161. package/wwwroot/_framework/System.Net.Primitives.ksxwiwlvhu.dll +0 -0
  162. package/wwwroot/_framework/System.Net.WebSockets.6rt3n3gl2q.dll +0 -0
  163. package/wwwroot/_framework/System.Net.WebSockets.Client.z3usrzo7rz.dll +0 -0
  164. package/wwwroot/_framework/System.Numerics.Tensors.0c7z4mt3on.dll +0 -0
  165. package/wwwroot/_framework/System.Numerics.Vectors.lbdzx8reja.dll +0 -0
  166. package/wwwroot/_framework/System.ObjectModel.yct1gdirzf.dll +0 -0
  167. package/wwwroot/_framework/System.Private.CoreLib.c1dbswx1b2.dll +0 -0
  168. package/wwwroot/_framework/System.Private.Uri.zp9kmg0z93.dll +0 -0
  169. package/wwwroot/_framework/System.Private.Xml.Linq.lgv2n0akl4.dll +0 -0
  170. package/wwwroot/_framework/System.Private.Xml.dpsk8g304y.dll +0 -0
  171. package/wwwroot/_framework/System.Reactive.t3fuon548l.dll +0 -0
  172. package/wwwroot/_framework/System.Reflection.Emit.ILGeneration.1tcuz2cmbk.dll +0 -0
  173. package/wwwroot/_framework/System.Reflection.Emit.Lightweight.ddt2wylovg.dll +0 -0
  174. package/wwwroot/_framework/System.Reflection.Emit.d8vkadiwhg.dll +0 -0
  175. package/wwwroot/_framework/System.Reflection.Primitives.cpsl71xd1z.dll +0 -0
  176. package/wwwroot/_framework/System.Runtime.InteropServices.31vjgsfk1o.dll +0 -0
  177. package/wwwroot/_framework/System.Runtime.InteropServices.JavaScript.pn2wvizzet.dll +0 -0
  178. package/wwwroot/_framework/System.Runtime.InteropServices.RuntimeInformation.l5rk496q70.dll +0 -0
  179. package/wwwroot/_framework/System.Runtime.Intrinsics.0zee9qcqfy.dll +0 -0
  180. package/wwwroot/_framework/System.Runtime.Loader.xw2jr9wl92.dll +0 -0
  181. package/wwwroot/_framework/System.Runtime.Numerics.ezj1dfyvbj.dll +0 -0
  182. package/wwwroot/_framework/System.Runtime.Serialization.Formatters.0y019e9zkr.dll +0 -0
  183. package/wwwroot/_framework/System.Runtime.Serialization.Primitives.bia5wb62c8.dll +0 -0
  184. package/wwwroot/_framework/System.Runtime.h9cduidfkh.dll +0 -0
  185. package/wwwroot/_framework/System.Security.Claims.2r18wim2rl.dll +0 -0
  186. package/wwwroot/_framework/System.Security.Cryptography.qqgybpoucx.dll +0 -0
  187. package/wwwroot/_framework/System.Text.Encoding.Extensions.9t3hs6kyll.dll +0 -0
  188. package/wwwroot/_framework/System.Text.Encodings.Web.wftjfh2crk.dll +0 -0
  189. package/wwwroot/_framework/System.Text.Json.0v0qgmri0w.dll +0 -0
  190. package/wwwroot/_framework/System.Text.RegularExpressions.cvkox11l6l.dll +0 -0
  191. package/wwwroot/_framework/System.Threading.Channels.419493szqu.dll +0 -0
  192. package/wwwroot/_framework/System.Threading.Thread.xhmys87xh5.dll +0 -0
  193. package/wwwroot/_framework/System.Threading.b66vzsz9g1.dll +0 -0
  194. package/wwwroot/_framework/System.Transactions.Local.7zfffdvnwf.dll +0 -0
  195. package/wwwroot/_framework/System.Web.HttpUtility.9up6xfbtuq.dll +0 -0
  196. package/wwwroot/_framework/System.Xml.Linq.n5rzv9nbf7.dll +0 -0
  197. package/wwwroot/_framework/System.Xml.ReaderWriter.ag8pilllob.dll +0 -0
  198. package/wwwroot/_framework/System.Xml.XDocument.sn51jas17n.dll +0 -0
  199. package/wwwroot/_framework/System.brmz7yk5qh.dll +0 -0
  200. package/wwwroot/_framework/Websocket.Client.vapounvmnl.dll +0 -0
  201. package/wwwroot/_framework/blazor.boot.json +305 -0
  202. package/wwwroot/_framework/blazor.webassembly.js +1 -0
  203. package/wwwroot/_framework/dotnet.js +4 -0
  204. package/wwwroot/_framework/dotnet.native.boem75ye5i.wasm +0 -0
  205. package/wwwroot/_framework/dotnet.native.qc8g39g30v.js +16 -0
  206. package/wwwroot/_framework/dotnet.runtime.opaiwunc3t.js +4 -0
  207. package/wwwroot/_framework/icudt_CJK.tjcz0u77k5.dat +0 -0
  208. package/wwwroot/_framework/icudt_EFIGS.tptq2av103.dat +0 -0
  209. package/wwwroot/_framework/icudt_no_CJK.lfu7j35m59.dat +0 -0
  210. package/wwwroot/_framework/netstandard.yvr3prsx0x.dll +0 -0
  211. package/wwwroot/_headers +17 -50
  212. package/wwwroot/appsettings.json +82 -82
  213. package/wwwroot/icon-192.png +0 -0
  214. package/wwwroot/icon-512.png +0 -0
  215. package/wwwroot/index.html +736 -22
  216. package/wwwroot/js/marketing-tool.js +180 -0
  217. package/wwwroot/manifest.webmanifest +21 -18
  218. package/wwwroot/robots.txt +1 -1
  219. package/wwwroot/service-worker-assets.js +857 -0
  220. package/wwwroot/service-worker.js +31 -5
  221. package/wwwroot/sitemap.xml +8 -20
  222. package/wwwroot/assets/AdminDashboardPage-AhImXOcJ.js +0 -1
  223. package/wwwroot/assets/AdminDashboardPage-B2vz2Px9.css +0 -1
  224. package/wwwroot/assets/AppSidebar-HIF29_Y1.js +0 -2
  225. package/wwwroot/assets/AuthPages-BrH6kRcv.css +0 -1
  226. package/wwwroot/assets/AuthPages-n1KbzJI5.js +0 -1
  227. package/wwwroot/assets/CodePage-Bncc352E.css +0 -1
  228. package/wwwroot/assets/CodePage-OKIzhHoC.js +0 -87
  229. package/wwwroot/assets/CompanyCorePage-Biw4RPhk.js +0 -13
  230. package/wwwroot/assets/CompanyCorePage-ChBnq1ve.css +0 -1
  231. package/wwwroot/assets/ExecutionModePage-BaNPZB_m.js +0 -18
  232. package/wwwroot/assets/ExecutionModePage-TLuld9l3.css +0 -1
  233. package/wwwroot/assets/LaunchLeadCapture-Bx9LM0IX.js +0 -1
  234. package/wwwroot/assets/LaunchLeadCapture-CiRI1shz.css +0 -1
  235. package/wwwroot/assets/MarketingHome-BsyerRpe.js +0 -1
  236. package/wwwroot/assets/MarketingHome-DPzaYzA_.css +0 -1
  237. package/wwwroot/assets/MindCanvas-07gqXHGA.js +0 -49
  238. package/wwwroot/assets/MindCanvas-DtqOZnoW.css +0 -1
  239. package/wwwroot/assets/PlanMasterPage-CJ36rep-.css +0 -1
  240. package/wwwroot/assets/PlanMasterPage-CT87Dr_2.js +0 -4
  241. package/wwwroot/assets/PricingPage-Cg_0i_ZR.css +0 -1
  242. package/wwwroot/assets/PricingPage-dDvHQskC.js +0 -1
  243. package/wwwroot/assets/ToolPages-CKI4mItc.js +0 -28
  244. package/wwwroot/assets/ToolPages-DIB187pZ.css +0 -1
  245. package/wwwroot/assets/YouTubeSearchPage-8iFuPSSo.js +0 -4
  246. package/wwwroot/assets/YouTubeSearchPage-IPPa_BIH.css +0 -1
  247. package/wwwroot/assets/app-runtime-xD2Z3NdN.js +0 -1
  248. package/wwwroot/assets/canvas-runtime-Nq2noXK-.js +0 -44
  249. package/wwwroot/assets/code-agent-runtime-B5PPZd1t.js +0 -74
  250. package/wwwroot/assets/executionModeSettings-NJqurj-o.js +0 -1
  251. package/wwwroot/assets/index-CyNhJb7A.js +0 -2
  252. package/wwwroot/assets/index-yNpEK-gp.css +0 -1
  253. package/wwwroot/assets/marketingTools-DN_rnHeB.js +0 -4
  254. package/wwwroot/assets/mindCanvasSearchWorker-BzPMsHOB.js +0 -1
  255. package/wwwroot/assets/mindexecution-mindcanvas.png +0 -0
  256. package/wwwroot/assets/mindexecution-prod-home-current.png +0 -0
  257. package/wwwroot/assets/mindexecution-prod-pricing-current.png +0 -0
  258. package/wwwroot/assets/pricingCheckoutShell-O-DnwmbU.js +0 -1
  259. package/wwwroot/assets/productionAdapterConfig-C5jfk6oG.js +0 -1
  260. package/wwwroot/assets/runtimeSettingsPersistenceProjection-BoNWmYjU.js +0 -1
  261. package/wwwroot/assets/storage-DPyjZEKZ.js +0 -1
  262. package/wwwroot/assets/supabaseAuthAdapter-m134Qdxn.js +0 -44
  263. package/wwwroot/assets/toolHandoff-D5e5f7t5.js +0 -4
  264. package/wwwroot/assets/vendor-icons-DE3gIReG.js +0 -681
  265. package/wwwroot/assets/vendor-msgpack-BE8aAsr3.js +0 -1
  266. package/wwwroot/assets/vendor-react-BXzpOyCS.js +0 -40
  267. package/wwwroot/favicon.svg +0 -7
package/server.js CHANGED
@@ -1588,15 +1588,8 @@ const CONTENT_TYPE_BY_EXTENSION = new Map([
1588
1588
  ['.mov', 'video/quicktime'],
1589
1589
  ['.m4v', 'video/mp4'],
1590
1590
  ['.pdf', 'application/pdf'],
1591
- ['.js', 'text/javascript; charset=utf-8'],
1592
- ['.mjs', 'text/javascript; charset=utf-8'],
1593
- ['.css', 'text/css; charset=utf-8'],
1594
- ['.html', 'text/html; charset=utf-8'],
1595
- ['.txt', 'text/plain; charset=utf-8'],
1596
- ['.json', 'application/json; charset=utf-8'],
1597
- ['.map', 'application/json; charset=utf-8'],
1598
- ['.webmanifest', 'application/manifest+json; charset=utf-8'],
1599
- ['.wasm', 'application/wasm']
1591
+ ['.txt', 'text/plain; charset=utf-8'],
1592
+ ['.json', 'application/json; charset=utf-8']
1600
1593
  ]);
1601
1594
 
1602
1595
  function detectContentTypeFromHeader(header) {
@@ -2007,47 +2000,6 @@ app.get('/api/assets/resolve', async (req, res) => {
2007
2000
  });
2008
2001
  });
2009
2002
 
2010
- async function trySendPackagedWebAppAsset(req, res, mountPath) {
2011
- if (!WEB_APP_ROOT || !['GET', 'HEAD'].includes(String(req.method || '').toUpperCase())) {
2012
- return false;
2013
- }
2014
-
2015
- let requestPath = getMountedAssetRequestPath(req, mountPath);
2016
- try {
2017
- requestPath = decodeURIComponent(requestPath);
2018
- } catch {
2019
- return false;
2020
- }
2021
-
2022
- if (!requestPath || requestPath.includes('\0')) {
2023
- return false;
2024
- }
2025
-
2026
- const packagedAssetsRoot = path.resolve(WEB_APP_ROOT, String(mountPath || '').replace(/^\/+/, ''));
2027
- const packagedAssetPath = path.resolve(packagedAssetsRoot, requestPath);
2028
- if (!isPathWithin(packagedAssetsRoot, packagedAssetPath)) {
2029
- return false;
2030
- }
2031
-
2032
- let stats = null;
2033
- try {
2034
- stats = await fs.stat(packagedAssetPath);
2035
- } catch {
2036
- return false;
2037
- }
2038
-
2039
- if (!stats.isFile()) {
2040
- return false;
2041
- }
2042
-
2043
- await sendResolvedAssetFile(req, res, packagedAssetPath, {
2044
- notFoundMessage: 'Web app asset not found',
2045
- errorScope: 'web',
2046
- cacheControl: 'public, max-age=31536000, immutable'
2047
- });
2048
- return true;
2049
- }
2050
-
2051
2003
  // Static file serving for assets (direct image loading - bypasses base64 encoding)
2052
2004
  // This allows browsers to directly fetch images via http://127.0.0.1:5147/assets/filename.png
2053
2005
  app.use('/assets', async (req, res, next) => {
@@ -2082,15 +2034,11 @@ app.use('/assets', async (req, res, next) => {
2082
2034
  normalizedRequestPath,
2083
2035
  ['.png', '.jpg', '.jpeg', '.webp', '.gif', '.bmp', '.svg', '.mp4', '.webm', '.mov']
2084
2036
  );
2085
- }
2086
-
2087
- if (!resolvedPath) {
2088
- if (await trySendPackagedWebAppAsset(req, res, '/assets')) {
2089
- return;
2090
- }
2091
-
2092
- return res.status(404).json({ error: 'Asset not found' });
2093
- }
2037
+ }
2038
+
2039
+ if (!resolvedPath) {
2040
+ return res.status(404).json({ error: 'Asset not found' });
2041
+ }
2094
2042
 
2095
2043
  return sendResolvedAssetFile(req, res, resolvedPath, {
2096
2044
  notFoundMessage: 'Asset not found',
@@ -2190,19 +2138,11 @@ const PROTECTED_BRIDGE_ROUTES = [
2190
2138
  { method: 'POST', exact: '/api/dir/delete' },
2191
2139
  { method: 'POST', prefix: '/api/assets/' },
2192
2140
  { method: 'POST', exact: '/api/local-files/register' },
2193
- { method: 'POST', exact: '/api/evidence/save' },
2194
- { method: 'POST', exact: '/api/concept/define-composite' },
2195
- { method: 'GET', exact: '/api/concept/status' },
2196
- { method: 'GET', exact: '/api/concept/row' },
2197
- { method: 'GET', exact: '/api/concept/sqlite/row' },
2198
- { method: 'GET', exact: '/api/concept/embed/readiness' },
2199
- { method: 'POST', exact: '/api/concept/embed' },
2200
2141
  { method: 'POST', prefix: '/api/browser/act' },
2201
- { method: 'GET', prefix: '/api/company-core/' },
2142
+ { method: 'GET', prefix: '/api/company-core/' },
2202
2143
  { method: 'POST', prefix: '/api/company-core/' },
2203
2144
  { method: 'PUT', prefix: '/api/company-core/' },
2204
2145
  { method: 'DELETE', prefix: '/api/company-core/' },
2205
- { method: 'GET', prefix: '/api/model-catalog' },
2206
2146
  { method: 'GET', prefix: '/api/codex/' },
2207
2147
  { method: 'POST', prefix: '/api/codex/' },
2208
2148
  { method: 'GET', prefix: '/api/shell/' },
@@ -2721,39 +2661,6 @@ function buildRemoteFrameBinaryPacket(frameEvent) {
2721
2661
  }
2722
2662
 
2723
2663
  const frame = frameEvent.frame || {};
2724
- const droppedByAgent = Number(frame.droppedByAgent ?? frameEvent.droppedByAgent ?? 0);
2725
- const dirtyRectSource = frame.dirtyRectCount
2726
- ?? frame.dirtyRegionCount
2727
- ?? frameEvent.dirtyRectCount
2728
- ?? frameEvent.dirtyRegionCount
2729
- ?? (Array.isArray(frame.dirtyRects) ? frame.dirtyRects.length : undefined)
2730
- ?? (Array.isArray(frameEvent.dirtyRects) ? frameEvent.dirtyRects.length : undefined)
2731
- ?? 0;
2732
- const dirtyRectCount = Number(dirtyRectSource);
2733
- const dirtyRatioSource = frame.dirtyPixelRatio
2734
- ?? frame.dirtyRatio
2735
- ?? frame.dirtyAreaRatio
2736
- ?? frame.changedPixelRatio
2737
- ?? frameEvent.dirtyPixelRatio
2738
- ?? frameEvent.dirtyRatio
2739
- ?? frameEvent.dirtyAreaRatio
2740
- ?? frameEvent.changedPixelRatio
2741
- ?? 0;
2742
- const dirtyRatioNumber = Number(dirtyRatioSource);
2743
- const normalizedDirtyPixelRatio = Number.isFinite(dirtyRatioNumber) && dirtyRatioNumber >= 0
2744
- ? dirtyRatioNumber <= 1
2745
- ? dirtyRatioNumber
2746
- : dirtyRatioNumber <= 100
2747
- ? dirtyRatioNumber / 100
2748
- : 1
2749
- : 0;
2750
- const deltaValue = frame.deltaEncoded ?? frame.isDeltaEncoded ?? frame.deltaFrame
2751
- ?? frameEvent.deltaEncoded ?? frameEvent.isDeltaEncoded ?? frameEvent.deltaFrame;
2752
- const deltaEncoded = typeof deltaValue === 'boolean'
2753
- ? deltaValue
2754
- : typeof deltaValue === 'number'
2755
- ? deltaValue > 0
2756
- : /^(1|true|yes|on|delta)$/i.test(String(deltaValue || '').trim());
2757
2664
  const metadata = {
2758
2665
  type: 'remote.frame.binary',
2759
2666
  kind: frameEvent.kind || 'live',
@@ -2771,16 +2678,7 @@ function buildRemoteFrameBinaryPacket(frameEvent) {
2771
2678
  transport: frame.transport || '',
2772
2679
  contentHash: frame.contentHash || '',
2773
2680
  captureMs: Number(frame.captureMs || 0) || 0,
2774
- sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
2775
- droppedByAgent: Number.isFinite(droppedByAgent) && droppedByAgent >= 0
2776
- ? Math.round(droppedByAgent)
2777
- : 0,
2778
- dirtyRectCount: Number.isFinite(dirtyRectCount) && dirtyRectCount >= 0
2779
- ? Math.round(dirtyRectCount)
2780
- : 0,
2781
- dirtyPixelRatio: normalizedDirtyPixelRatio,
2782
- codec: String(frame.codec || frame.encoder || frame.encoding || frameEvent.codec || frameEvent.encoder || frameEvent.encoding || '').slice(0, 80),
2783
- deltaEncoded
2681
+ sameContentStreak: Number(frame.sameContentStreak || 0) || 0
2784
2682
  };
2785
2683
  const metaBuffer = Buffer.from(JSON.stringify(metadata), 'utf8');
2786
2684
  const header = Buffer.allocUnsafe(4);
@@ -3232,78 +3130,14 @@ function extractCodexOutputPath(command) {
3232
3130
  return match[2] || match[3] || match[4] || null;
3233
3131
  }
3234
3132
 
3235
- const CODEX_CONFIG_PATH = path.join(os.homedir(), '.codex', 'config.toml');
3236
- const CODEX_MODEL_CATALOG_TTL_MS = 15 * 60 * 1000;
3237
- const EXTERNAL_MODEL_CATALOG_TTL_MS = 60 * 1000;
3238
- let cachedCodexConfig = null;
3239
- let cachedCodexConfigMtimeMs = -1;
3133
+ const CODEX_CONFIG_PATH = path.join(os.homedir(), '.codex', 'config.toml');
3134
+ const CODEX_MODEL_CATALOG_TTL_MS = 15 * 60 * 1000;
3135
+ let cachedCodexConfig = null;
3136
+ let cachedCodexConfigMtimeMs = -1;
3240
3137
  let cachedCodexModelCatalog = null;
3241
3138
  let cachedCodexModelCatalogExpiresAt = 0;
3242
- let cachedBridgeModelCatalog = null;
3243
- let cachedBridgeModelCatalogExpiresAt = 0;
3244
3139
  let lastCodexExecRuntime = null;
3245
3140
  let codexRuntime = null;
3246
-
3247
- const FALLBACK_CODEX_TEXT_MODELS = [
3248
- { id: 'gpt-5.5', displayName: 'GPT-5.5' },
3249
- { id: 'gpt-5.4', displayName: 'GPT-5.4' },
3250
- { id: 'gpt-5.4-mini', displayName: 'GPT-5.4 mini' },
3251
- { id: 'gpt-5.3-codex-spark', displayName: 'GPT-5.3 Codex Spark' }
3252
- ];
3253
-
3254
- const FALLBACK_OPENROUTER_TEXT_MODELS = [
3255
- { id: 'openrouter/auto', displayName: 'Auto Router', isFallback: true },
3256
- { id: 'openai/gpt-chat-latest', displayName: 'GPT Chat Latest', isFallback: true },
3257
- { id: 'anthropic/claude-sonnet-4.5', displayName: 'Claude Sonnet 4.5', supportsReasoning: true, isFallback: true },
3258
- { id: 'google/gemini-2.5-pro', displayName: 'Gemini 2.5 Pro', supportsReasoning: true, isFallback: true },
3259
- { id: 'google/gemini-2.5-flash', displayName: 'Gemini 2.5 Flash', isFallback: true }
3260
- ];
3261
-
3262
- const FALLBACK_IMAGE_MODELS = [
3263
- {
3264
- id: 'gpt-image-2',
3265
- label: 'GPT Image 2',
3266
- displayName: 'GPT Image 2',
3267
- provider: 'openai',
3268
- mode: 'image',
3269
- supportedSizes: ['custom'],
3270
- vendorPricing: { averageUsd: 0.02, source: 'fallback' },
3271
- isFallback: true
3272
- },
3273
- {
3274
- id: 'Tongyi-MAI/Z-Image-Turbo:free',
3275
- label: 'Z-Image Turbo',
3276
- displayName: 'Z-Image Turbo',
3277
- provider: 'imagerouter',
3278
- mode: 'image',
3279
- supportedSizes: ['custom'],
3280
- vendorPricing: { averageUsd: 0.02, source: 'fallback' },
3281
- isFallback: true
3282
- }
3283
- ];
3284
-
3285
- const FALLBACK_VIDEO_MODELS = [
3286
- {
3287
- id: 'google/veo-2',
3288
- label: 'Google Veo 2',
3289
- displayName: 'Google Veo 2',
3290
- provider: 'imagerouter',
3291
- mode: 'video',
3292
- supportedSizes: ['1280x720', '720x1280'],
3293
- vendorPricing: { averageUsd: 0.25, maxUsd: 0.25, source: 'fallback' },
3294
- isFallback: true
3295
- },
3296
- {
3297
- id: 'runway/gen-3',
3298
- label: 'Runway Gen-3',
3299
- displayName: 'Runway Gen-3',
3300
- provider: 'imagerouter',
3301
- mode: 'video',
3302
- supportedSizes: ['1280x720', '720x1280'],
3303
- vendorPricing: { averageUsd: 0.20, maxUsd: 0.20, source: 'fallback' },
3304
- isFallback: true
3305
- }
3306
- ];
3307
3141
 
3308
3142
  function readCodexConfig(options = {}) {
3309
3143
  const forceRefresh = Boolean(options.forceRefresh);
@@ -3474,371 +3308,6 @@ async function getCodexModelCatalog(options = {}) {
3474
3308
  }
3475
3309
  }
3476
3310
 
3477
- function getPlainString(value) {
3478
- return String(value ?? '').trim();
3479
- }
3480
-
3481
- function getCatalogString(item, propertyName) {
3482
- if (!item || typeof item !== 'object') {
3483
- return '';
3484
- }
3485
-
3486
- return getPlainString(item[propertyName]);
3487
- }
3488
-
3489
- function getCatalogNumber(item, propertyName) {
3490
- if (!item || typeof item !== 'object') {
3491
- return null;
3492
- }
3493
-
3494
- const value = Number(item[propertyName]);
3495
- return Number.isFinite(value) ? value : null;
3496
- }
3497
-
3498
- function getCatalogStringArray(item, propertyName) {
3499
- if (!item || typeof item !== 'object' || !Array.isArray(item[propertyName])) {
3500
- return [];
3501
- }
3502
-
3503
- return [...new Set(item[propertyName]
3504
- .map(entry => getPlainString(entry))
3505
- .filter(Boolean))];
3506
- }
3507
-
3508
- function getNestedCatalogStringArray(item, objectPropertyName, arrayPropertyName) {
3509
- if (!item || typeof item !== 'object') {
3510
- return [];
3511
- }
3512
-
3513
- return getCatalogStringArray(item[objectPropertyName], arrayPropertyName);
3514
- }
3515
-
3516
- function getNestedCatalogBoolean(item, objectPropertyName, propertyName) {
3517
- if (!item || typeof item !== 'object') {
3518
- return false;
3519
- }
3520
-
3521
- const parent = item[objectPropertyName];
3522
- if (!parent || typeof parent !== 'object') {
3523
- return false;
3524
- }
3525
-
3526
- const value = parent[propertyName];
3527
- return value === true || /^(1|true|yes|on)$/i.test(String(value ?? ''));
3528
- }
3529
-
3530
- function getCatalogDecimal(item, propertyName) {
3531
- const value = getCatalogNumber(item, propertyName);
3532
- return value === null ? undefined : value;
3533
- }
3534
-
3535
- function getOpenRouterPricing(item) {
3536
- const pricing = item?.pricing;
3537
- if (!pricing || typeof pricing !== 'object') {
3538
- return null;
3539
- }
3540
-
3541
- const promptUsdPerToken = getCatalogDecimal(pricing, 'prompt');
3542
- const completionUsdPerToken = getCatalogDecimal(pricing, 'completion');
3543
- const requestUsd = getCatalogDecimal(pricing, 'request');
3544
- if (promptUsdPerToken === undefined && completionUsdPerToken === undefined && requestUsd === undefined) {
3545
- return null;
3546
- }
3547
-
3548
- return {
3549
- promptUsdPerToken,
3550
- completionUsdPerToken,
3551
- requestUsd,
3552
- source: 'openrouter',
3553
- fetchedAt: new Date().toISOString()
3554
- };
3555
- }
3556
-
3557
- function getImageRouterPricing(item) {
3558
- const price = item?.price;
3559
- if (!price || typeof price !== 'object') {
3560
- return null;
3561
- }
3562
-
3563
- const minUsd = getCatalogDecimal(price, 'min');
3564
- const averageUsd = getCatalogDecimal(price, 'average');
3565
- const maxUsd = getCatalogDecimal(price, 'max');
3566
- if (minUsd === undefined && averageUsd === undefined && maxUsd === undefined) {
3567
- return null;
3568
- }
3569
-
3570
- return {
3571
- minUsd,
3572
- averageUsd,
3573
- maxUsd,
3574
- source: 'imagerouter',
3575
- fetchedAt: new Date().toISOString()
3576
- };
3577
- }
3578
-
3579
- function buildCatalogDisplayLabel(name, id) {
3580
- const label = getPlainString(name);
3581
- const modelId = getPlainString(id);
3582
- if (!label || label.toLowerCase() === modelId.toLowerCase()) {
3583
- return modelId;
3584
- }
3585
-
3586
- return `${label} (${modelId})`;
3587
- }
3588
-
3589
- function containsCatalogString(item, propertyName, expected) {
3590
- return getCatalogStringArray(item, propertyName)
3591
- .some(value => value.toLowerCase() === String(expected).toLowerCase());
3592
- }
3593
-
3594
- function containsAnyCatalogString(item, propertyName, expectedValues) {
3595
- const expected = new Set(expectedValues.map(value => String(value).toLowerCase()));
3596
- return getCatalogStringArray(item, propertyName)
3597
- .some(value => expected.has(value.toLowerCase()));
3598
- }
3599
-
3600
- function hasCatalogMediaModalityInElement(item) {
3601
- const modality = getCatalogString(item, 'modality').toLowerCase();
3602
- return containsAnyCatalogString(item, 'input_modalities', ['image', 'video', 'audio'])
3603
- || containsAnyCatalogString(item, 'output_modalities', ['image', 'video', 'audio'])
3604
- || /image|video|audio/i.test(modality);
3605
- }
3606
-
3607
- function supportsOpenRouterTextOnlyOutput(item) {
3608
- const architecture = item?.architecture && typeof item.architecture === 'object'
3609
- ? item.architecture
3610
- : null;
3611
- const supportsText = containsCatalogString(item, 'output_modalities', 'text')
3612
- || (architecture && containsCatalogString(architecture, 'output_modalities', 'text'));
3613
- const hasMedia = hasCatalogMediaModalityInElement(item)
3614
- || (architecture && hasCatalogMediaModalityInElement(architecture));
3615
- return supportsText && !hasMedia;
3616
- }
3617
-
3618
- function normalizeOpenRouterModel(item) {
3619
- const id = getCatalogString(item, 'id');
3620
- if (!id || !supportsOpenRouterTextOnlyOutput(item)) {
3621
- return null;
3622
- }
3623
-
3624
- const name = getCatalogString(item, 'name');
3625
- const supportedParameters = getCatalogStringArray(item, 'supported_parameters');
3626
- return {
3627
- id,
3628
- label: buildCatalogDisplayLabel(name, id),
3629
- displayName: name || id,
3630
- provider: 'openrouter',
3631
- mode: 'text',
3632
- supportsReasoning: supportedParameters.some(value => value.toLowerCase() === 'reasoning'),
3633
- vendorPricing: getOpenRouterPricing(item),
3634
- source: 'openrouter'
3635
- };
3636
- }
3637
-
3638
- async function fetchJsonWithTimeout(url, timeoutMs = 10000) {
3639
- const controller = new AbortController();
3640
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
3641
- try {
3642
- const response = await fetch(url, {
3643
- headers: {
3644
- Accept: 'application/json',
3645
- 'Cache-Control': 'no-store',
3646
- Pragma: 'no-cache'
3647
- },
3648
- signal: controller.signal
3649
- });
3650
- if (!response.ok) {
3651
- throw new Error(`HTTP ${response.status}`);
3652
- }
3653
- return await response.json();
3654
- } finally {
3655
- clearTimeout(timeout);
3656
- }
3657
- }
3658
-
3659
- async function getOpenRouterTextModelCatalog() {
3660
- const payload = await fetchJsonWithTimeout('https://openrouter.ai/api/v1/models', 10000);
3661
- const items = Array.isArray(payload?.data) ? payload.data : [];
3662
- const options = items
3663
- .map(normalizeOpenRouterModel)
3664
- .filter(Boolean)
3665
- .sort((a, b) => String(a.label).localeCompare(String(b.label)));
3666
- return options.length > 0
3667
- ? options
3668
- : FALLBACK_OPENROUTER_TEXT_MODELS.map(option => ({
3669
- id: option.id,
3670
- label: option.displayName,
3671
- displayName: option.displayName,
3672
- provider: 'openrouter',
3673
- mode: 'text',
3674
- supportsReasoning: option.supportsReasoning === true,
3675
- isFallback: true,
3676
- source: 'fallback'
3677
- }));
3678
- }
3679
-
3680
- function normalizeImageRouterModel(item, outputType) {
3681
- const id = getCatalogString(item, 'id');
3682
- if (!id) {
3683
- return null;
3684
- }
3685
-
3686
- const displayName = getCatalogString(item, 'name') || id;
3687
- const supportedSizes = getNestedCatalogStringArray(item, 'inputs', 'size');
3688
- const supportedSeconds = getNestedCatalogStringArray(item, 'inputs', 'seconds');
3689
- return {
3690
- id,
3691
- label: displayName,
3692
- displayName,
3693
- provider: 'imagerouter',
3694
- mode: outputType,
3695
- supportedSizes: supportedSizes.length > 0 ? supportedSizes : (outputType === 'image' ? ['custom'] : []),
3696
- supportedSeconds,
3697
- capabilities: {
3698
- supportsTextToImage: outputType === 'image',
3699
- supportsImageToImage: getNestedCatalogBoolean(item, 'inputs', 'image'),
3700
- supportsInpaint: getNestedCatalogBoolean(item, 'inputs', 'mask'),
3701
- supportsSizeSelection: supportedSizes.length > 0,
3702
- supportedSizes,
3703
- supportedSeconds
3704
- },
3705
- vendorPricing: getImageRouterPricing(item),
3706
- source: 'imagerouter'
3707
- };
3708
- }
3709
-
3710
- async function getImageRouterModelCatalog(outputType) {
3711
- const endpoint = new URL('https://api.imagerouter.io/v2/models');
3712
- endpoint.searchParams.set('outputType', outputType);
3713
- endpoint.searchParams.set('limit', '200');
3714
- endpoint.searchParams.set('fields', 'name,price,inputs');
3715
-
3716
- const payload = await fetchJsonWithTimeout(endpoint.toString(), 10000);
3717
- const items = Array.isArray(payload)
3718
- ? payload
3719
- : Array.isArray(payload?.data)
3720
- ? payload.data
3721
- : [];
3722
- const options = items
3723
- .map(item => normalizeImageRouterModel(item, outputType))
3724
- .filter(Boolean)
3725
- .sort((a, b) => String(a.label).localeCompare(String(b.label)));
3726
-
3727
- if (options.length > 0) {
3728
- return options;
3729
- }
3730
-
3731
- return (outputType === 'image' ? FALLBACK_IMAGE_MODELS : FALLBACK_VIDEO_MODELS)
3732
- .map(option => ({ ...option, source: 'fallback' }));
3733
- }
3734
-
3735
- function normalizeCodexCatalogOption(model) {
3736
- if (!model || typeof model !== 'object') {
3737
- return null;
3738
- }
3739
-
3740
- const id = getCatalogString(model, 'id');
3741
- if (!id) {
3742
- return null;
3743
- }
3744
-
3745
- const displayName = getCatalogString(model, 'displayName') || id;
3746
- return {
3747
- id,
3748
- label: `OpenAI Codex - ${displayName}`,
3749
- displayName,
3750
- description: getCatalogString(model, 'description'),
3751
- provider: 'codex',
3752
- mode: 'text',
3753
- supportsReasoning: true,
3754
- source: 'codex debug models',
3755
- priority: getCatalogNumber(model, 'priority') ?? 999,
3756
- defaultReasoningLevel: getCatalogString(model, 'defaultReasoningLevel'),
3757
- supportedReasoningLevels: getCatalogStringArray(model, 'supportedReasoningLevels'),
3758
- supportedInApi: model.supportedInApi === true
3759
- };
3760
- }
3761
-
3762
- async function getBridgeModelCatalog(options = {}) {
3763
- const now = Date.now();
3764
- if (!options.forceRefresh && cachedBridgeModelCatalog && cachedBridgeModelCatalogExpiresAt > now) {
3765
- return cachedBridgeModelCatalog;
3766
- }
3767
-
3768
- const errors = [];
3769
- const codexCatalog = await getCodexModelCatalog({ forceRefresh: options.forceRefresh });
3770
- if (codexCatalog?.error) {
3771
- errors.push(`codex: ${codexCatalog.error}`);
3772
- }
3773
-
3774
- let codexTextModels = (codexCatalog?.models || [])
3775
- .map(normalizeCodexCatalogOption)
3776
- .filter(Boolean)
3777
- .sort((a, b) => (a.priority ?? 999) - (b.priority ?? 999) || a.id.localeCompare(b.id));
3778
- if (codexTextModels.length === 0) {
3779
- codexTextModels = FALLBACK_CODEX_TEXT_MODELS.map((model, index) => ({
3780
- id: model.id,
3781
- label: `OpenAI Codex - ${model.displayName}`,
3782
- displayName: model.displayName,
3783
- provider: 'codex',
3784
- mode: 'text',
3785
- supportsReasoning: true,
3786
- priority: index,
3787
- isFallback: true,
3788
- source: 'fallback'
3789
- }));
3790
- }
3791
-
3792
- const [openRouterResult, imageResult, videoResult] = await Promise.allSettled([
3793
- getOpenRouterTextModelCatalog(),
3794
- getImageRouterModelCatalog('image'),
3795
- getImageRouterModelCatalog('video')
3796
- ]);
3797
-
3798
- const openRouterTextModels = openRouterResult.status === 'fulfilled'
3799
- ? openRouterResult.value
3800
- : FALLBACK_OPENROUTER_TEXT_MODELS.map(option => ({
3801
- id: option.id,
3802
- label: option.displayName,
3803
- displayName: option.displayName,
3804
- provider: 'openrouter',
3805
- mode: 'text',
3806
- supportsReasoning: option.supportsReasoning === true,
3807
- isFallback: true,
3808
- source: 'fallback'
3809
- }));
3810
- if (openRouterResult.status === 'rejected') {
3811
- errors.push(`openrouter: ${openRouterResult.reason?.message || String(openRouterResult.reason)}`);
3812
- }
3813
-
3814
- const imageModels = imageResult.status === 'fulfilled'
3815
- ? imageResult.value
3816
- : FALLBACK_IMAGE_MODELS.map(option => ({ ...option, source: 'fallback' }));
3817
- if (imageResult.status === 'rejected') {
3818
- errors.push(`imagerouter:image: ${imageResult.reason?.message || String(imageResult.reason)}`);
3819
- }
3820
-
3821
- const videoModels = videoResult.status === 'fulfilled'
3822
- ? videoResult.value
3823
- : FALLBACK_VIDEO_MODELS.map(option => ({ ...option, source: 'fallback' }));
3824
- if (videoResult.status === 'rejected') {
3825
- errors.push(`imagerouter:video: ${videoResult.reason?.message || String(videoResult.reason)}`);
3826
- }
3827
-
3828
- const updatedAt = new Date().toISOString();
3829
- cachedBridgeModelCatalog = {
3830
- success: true,
3831
- textModels: [...codexTextModels, ...openRouterTextModels],
3832
- imageModels,
3833
- videoModels,
3834
- source: 'localbridge-model-catalog',
3835
- updatedAt,
3836
- errors
3837
- };
3838
- cachedBridgeModelCatalogExpiresAt = now + EXTERNAL_MODEL_CATALOG_TTL_MS;
3839
- return cachedBridgeModelCatalog;
3840
- }
3841
-
3842
3311
  function getCodexRuntime() {
3843
3312
  if (!codexRuntime) {
3844
3313
  codexRuntime = createCodexRuntime({
@@ -11489,7 +10958,7 @@ function scoreSearchResult(query, item) {
11489
10958
  return score;
11490
10959
  }
11491
10960
 
11492
- function filterSearchResults(query, items, maxResults) {
10961
+ function filterSearchResults(query, items, maxResults) {
11493
10962
  const clampedMax = Math.max(1, Math.min(Number(maxResults) || 5, 8));
11494
10963
  const list = Array.isArray(items) ? items : [];
11495
10964
  if (!requiresSearchRelevanceFilter(query)) {
@@ -11500,29 +10969,10 @@ function filterSearchResults(query, items, maxResults) {
11500
10969
  .map(item => ({ item, score: scoreSearchResult(query, item) }))
11501
10970
  .filter(entry => entry.score > 0)
11502
10971
  .sort((a, b) => b.score - a.score)
11503
- .map(entry => entry.item)
11504
- .slice(0, clampedMax);
11505
- }
11506
-
11507
- function extractDirectSearchUrl(query) {
11508
- const match = String(query || '').match(/https?:\/\/[^\s"'<>),]+/i);
11509
- if (!match) {
11510
- return '';
11511
- }
11512
-
11513
- try {
11514
- const parsed = new URL(match[0]);
11515
- if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
11516
- return parsed.toString();
11517
- }
11518
- } catch {
11519
- return '';
11520
- }
11521
-
11522
- return '';
11523
- }
11524
-
11525
- async function searchBing(query, maxResults = 5) {
10972
+ .map(entry => entry.item)
10973
+ .slice(0, clampedMax);
10974
+ }
10975
+ async function searchBing(query, maxResults = 5) {
11526
10976
  const clampedMax = Math.max(1, Math.min(Number(maxResults) || 5, 8));
11527
10977
  const searchQuery = expandSearchQuery(query);
11528
10978
  const url = `https://www.bing.com/search?q=${encodeURIComponent(searchQuery)}`;
@@ -11548,22 +10998,8 @@ async function searchBing(query, maxResults = 5) {
11548
10998
  };
11549
10999
  }
11550
11000
 
11551
- async function searchWeb(query, maxResults = 5) {
11001
+ async function searchWeb(query, maxResults = 5) {
11552
11002
  const searchQuery = expandSearchQuery(query);
11553
- const directUrl = extractDirectSearchUrl(searchQuery);
11554
- if (directUrl) {
11555
- return {
11556
- query: searchQuery,
11557
- source: 'direct-url',
11558
- retrievedAt: new Date().toISOString(),
11559
- items: [{
11560
- title: 'Direct URL evidence',
11561
- url: directUrl,
11562
- snippet: `Direct URL extracted from the WebResearch query: ${directUrl}`
11563
- }]
11564
- };
11565
- }
11566
-
11567
11003
  const providers = [
11568
11004
  ['duckduckgo', searchDuckDuckGo],
11569
11005
  ['brave', searchBrave],
@@ -11598,7 +11034,7 @@ async function searchWeb(query, maxResults = 5) {
11598
11034
  throw error;
11599
11035
  }
11600
11036
 
11601
- async function fetchWebPage(url, maxChars = 12000) {
11037
+ async function fetchWebPage(url, maxChars = 12000) {
11602
11038
  let parsedUrl;
11603
11039
  try {
11604
11040
  parsedUrl = new URL(url);
@@ -11647,1104 +11083,10 @@ async function fetchWebPage(url, maxChars = 12000) {
11647
11083
  contentType,
11648
11084
  truncated,
11649
11085
  retrievedAt: new Date().toISOString()
11650
- };
11651
- }
11652
-
11653
- function clampEvidenceText(value, maxLength = 4000) {
11654
- const text = String(value ?? '').replace(/\r\n/g, '\n').replace(/\r/g, '\n').trim();
11655
- if (!text) {
11656
- return '';
11657
- }
11658
- return text.length <= maxLength ? text : `${text.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
11659
- }
11660
-
11661
- function evidenceArray(value, maxItems = 12, maxItemLength = 500) {
11662
- const source = Array.isArray(value) ? value : [];
11663
- const seen = new Set();
11664
- const items = [];
11665
- for (const item of source) {
11666
- const text = clampEvidenceText(item, maxItemLength);
11667
- const key = text.toLowerCase();
11668
- if (!text || seen.has(key)) {
11669
- continue;
11670
- }
11671
- seen.add(key);
11672
- items.push(text);
11673
- if (items.length >= maxItems) {
11674
- break;
11675
- }
11676
- }
11677
- return items;
11678
- }
11679
-
11680
- function slugifyEvidence(value, maxLength = 56) {
11681
- const slug = String(value || 'evidence')
11682
- .normalize('NFKD')
11683
- .replace(/[\u0300-\u036f]/g, '')
11684
- .replace(/[^a-zA-Z0-9]+/g, '-')
11685
- .replace(/^-+|-+$/g, '')
11686
- .toLowerCase();
11687
- return (slug || 'evidence').slice(0, maxLength).replace(/-+$/g, '') || 'evidence';
11688
- }
11689
-
11690
- function safeEvidenceDirectory(baseDir, relativeDirectory) {
11691
- const base = path.resolve(baseDir);
11692
- const raw = String(relativeDirectory || '').trim();
11693
- if (!raw) {
11694
- return base;
11695
- }
11696
-
11697
- const safeSegments = raw
11698
- .replaceAll('\\', '/')
11699
- .split('/')
11700
- .map(segment => slugifyEvidence(segment, 40))
11701
- .filter(Boolean)
11702
- .slice(0, 4);
11703
- const target = path.resolve(base, ...safeSegments);
11704
- if (!isPathWithin(base, target)) {
11705
- const err = new Error('Evidence directory must stay under the evidence cache.');
11706
- err.statusCode = 400;
11707
- throw err;
11708
- }
11709
- return target;
11710
- }
11711
-
11712
- function normalizeEvidenceUrl(value) {
11713
- const text = clampEvidenceText(value, 1200);
11714
- if (!text) {
11715
- return '';
11716
- }
11717
-
11718
- try {
11719
- const parsed = new URL(text);
11720
- if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
11721
- return parsed.toString();
11722
- }
11723
- } catch {
11724
- // SourceUrl is optional. Invalid values are ignored instead of persisted.
11725
- }
11726
-
11727
- return '';
11728
- }
11729
-
11730
- function normalizeStructuredEvidence(value) {
11731
- const source = value && typeof value === 'object' ? value : {};
11732
- const sourceUrl = normalizeEvidenceUrl(source.sourceUrl || source.SourceUrl);
11733
- const sourcePath = clampEvidenceText(source.sourcePath || source.SourcePath, 1200);
11734
- return {
11735
- Schema: clampEvidenceText(source.schema || source.Schema || 'facts', 80) || 'facts',
11736
- SourceType: clampEvidenceText(source.sourceType || source.SourceType || 'web', 80) || 'web',
11737
- SourceUrl: sourceUrl || undefined,
11738
- SourcePath: sourcePath || undefined,
11739
- Title: clampEvidenceText(source.title || source.Title, 240),
11740
- Summary: clampEvidenceText(source.summary || source.Summary, 2000),
11741
- Facts: evidenceArray(source.facts || source.Facts, 16, 600),
11742
- Dates: evidenceArray(source.dates || source.Dates, 12, 120),
11743
- Links: evidenceArray(source.links || source.Links, 16, 1200),
11744
- Prices: evidenceArray(source.prices || source.Prices, 12, 120),
11745
- CharCount: Math.max(0, Math.min(Number(source.charCount || source.CharCount || 0) || 0, 1000000)),
11746
- ExtractedAtUtc: clampEvidenceText(source.structuredAt || source.extractedAt || source.ExtractedAtUtc, 80) || new Date().toISOString()
11747
- };
11748
- }
11749
-
11750
- function normalizeEvidenceMetadata(value, kind, sourceUrl) {
11751
- const source = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
11752
- const metadata = {};
11753
- for (const [key, item] of Object.entries(source)) {
11754
- const safeKey = String(key || '').replace(/[^a-zA-Z0-9_.:-]/g, '').slice(0, 80);
11755
- const safeValue = clampEvidenceText(item, 500);
11756
- if (safeKey && safeValue) {
11757
- metadata[safeKey] = safeValue;
11758
- }
11759
- }
11760
-
11761
- if (!metadata.kind) {
11762
- metadata.kind = kind;
11763
- }
11764
-
11765
- if (sourceUrl) {
11766
- try {
11767
- metadata.sourceHost = new URL(sourceUrl).host;
11768
- } catch {
11769
- metadata.sourceHost = sourceUrl;
11770
- }
11771
- }
11772
-
11773
- return metadata;
11774
- }
11775
-
11776
- function buildEvidenceResponse(record) {
11777
- return {
11778
- success: true,
11779
- id: record.Id,
11780
- kind: record.Kind,
11781
- title: record.Title,
11782
- query: record.Query,
11783
- sourceUrl: record.SourceUrl,
11784
- sourcePath: record.SourcePath,
11785
- excerpt: record.Excerpt,
11786
- notes: record.Notes,
11787
- path: record.Path,
11788
- sha256: record.Sha256,
11789
- capturedAt: record.CapturedAtUtc,
11790
- metadata: record.Metadata,
11791
- structured: record.Structured
11792
- };
11793
- }
11794
-
11795
- async function saveEvidenceRecord(request = {}) {
11796
- const capturedAt = new Date();
11797
- const structured = normalizeStructuredEvidence(request.structured || request.Structured);
11798
- const kind = clampEvidenceText(request.kind || request.Kind || 'evidence', 120) || 'evidence';
11799
- const sourceUrl = normalizeEvidenceUrl(request.sourceUrl || request.SourceUrl) || structured.SourceUrl || '';
11800
- const title = clampEvidenceText(request.title || request.Title || structured.Title || request.query || request.Query || sourceUrl || kind, 240);
11801
- const query = clampEvidenceText(request.query || request.Query, 500);
11802
- const sourcePath = clampEvidenceText(request.sourcePath || request.SourcePath || structured.SourcePath, 1200);
11803
- const excerpt = clampEvidenceText(request.excerpt || request.Excerpt || structured.Summary, 2400);
11804
- const notes = clampEvidenceText(request.notes || request.Notes, 2000);
11805
- const metadata = normalizeEvidenceMetadata(request.metadata || request.Metadata, kind, sourceUrl);
11806
- const baseEvidenceDir = path.join(getAiPath(), 'external', 'evidence');
11807
- const targetDir = safeEvidenceDirectory(baseEvidenceDir, request.relativeDirectory || request.RelativeDirectory);
11808
- const slugSource = title || query || sourceUrl || sourcePath || kind || 'evidence';
11809
- const fileName = `${capturedAt.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}Z$/, 'Z')}-${slugifyEvidence(slugSource)}.json`;
11810
- const fullPath = path.resolve(targetDir, fileName);
11811
- if (!isPathWithin(baseEvidenceDir, fullPath)) {
11812
- const err = new Error('Evidence path must stay under the evidence cache.');
11813
- err.statusCode = 400;
11814
- throw err;
11815
- }
11816
-
11817
- const relativePath = normalizePathForClient(path.relative(workspacePath, fullPath));
11818
- const id = `evidence-${capturedAt.toISOString().replace(/[-:T.]/g, '').slice(0, 14)}-${crypto.randomUUID().replace(/-/g, '').slice(0, 8)}`;
11819
- const record = {
11820
- Id: id,
11821
- Kind: kind,
11822
- Title: title,
11823
- Query: query || undefined,
11824
- SourceUrl: sourceUrl || undefined,
11825
- SourcePath: sourcePath || undefined,
11826
- Excerpt: excerpt,
11827
- Notes: notes || undefined,
11828
- CapturedAtUtc: capturedAt.toISOString(),
11829
- Structured: structured,
11830
- Metadata: metadata,
11831
- Path: relativePath
11832
- };
11833
-
11834
- const unsignedJson = JSON.stringify(record, null, 2);
11835
- record.Sha256 = crypto.createHash('sha256').update(unsignedJson, 'utf8').digest('hex');
11836
- const finalJson = `${JSON.stringify(record, null, 2)}\n`;
11837
- await writeFileAtomically(fullPath, finalJson, 'utf8');
11838
- return record;
11839
- }
11840
-
11841
- const CONCEPT_HASH_ALGORITHM = 'xxHash64(seed=0, utf8-trim)';
11842
- const CONCEPT_EMBEDDING_MODEL = 'local-xxhash64-preview-16';
11843
- const CONCEPT_EMBED_LIVE_CONFIRM_VALUE = 'I_UNDERSTAND_THIS_CALLS_EMBEDDING_PROVIDER';
11844
- const CONCEPT_U64_MASK = (1n << 64n) - 1n;
11845
- const CONCEPT_I64_MAX = (1n << 63n) - 1n;
11846
- const CONCEPT_U64_SIZE = 1n << 64n;
11847
- const CONCEPT_PRIME64_1 = 11400714785074694791n;
11848
- const CONCEPT_PRIME64_2 = 14029467366897019727n;
11849
- const CONCEPT_PRIME64_3 = 1609587929392839161n;
11850
- const CONCEPT_PRIME64_4 = 9650029242287828579n;
11851
- const CONCEPT_PRIME64_5 = 2870177450012600261n;
11852
- let nodeSqliteModulePromise = null;
11853
-
11854
- function conceptU64(value) {
11855
- return BigInt.asUintN(64, value);
11856
- }
11857
-
11858
- function conceptRotateLeft(value, count) {
11859
- const shift = BigInt(count);
11860
- return conceptU64((conceptU64(value) << shift) | (conceptU64(value) >> (64n - shift)));
11861
- }
11862
-
11863
- function conceptReadUInt32LE(data, offset) {
11864
- return Number(data[offset])
11865
- | (Number(data[offset + 1]) << 8)
11866
- | (Number(data[offset + 2]) << 16)
11867
- | (Number(data[offset + 3]) << 24);
11868
- }
11869
-
11870
- function conceptReadUInt64LE(data, offset) {
11871
- let value = 0n;
11872
- for (let index = 0; index < 8; index += 1) {
11873
- value |= BigInt(data[offset + index]) << BigInt(index * 8);
11874
- }
11875
- return conceptU64(value);
11876
- }
11877
-
11878
- function conceptXxHash64Round(acc, input) {
11879
- let value = conceptU64(acc + conceptU64(input * CONCEPT_PRIME64_2));
11880
- value = conceptRotateLeft(value, 31);
11881
- return conceptU64(value * CONCEPT_PRIME64_1);
11882
- }
11883
-
11884
- function conceptXxHash64MergeRound(acc, value) {
11885
- let next = conceptU64(acc ^ conceptXxHash64Round(0n, value));
11886
- next = conceptU64(next * CONCEPT_PRIME64_1 + CONCEPT_PRIME64_4);
11887
- return next;
11888
- }
11889
-
11890
- function conceptXxHash64(bytes, seed = 0n) {
11891
- const data = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes || []);
11892
- const len = data.length;
11893
- let index = 0;
11894
- let h64;
11895
-
11896
- if (len >= 32) {
11897
- let v1 = conceptU64(seed + CONCEPT_PRIME64_1 + CONCEPT_PRIME64_2);
11898
- let v2 = conceptU64(seed + CONCEPT_PRIME64_2);
11899
- let v3 = conceptU64(seed);
11900
- let v4 = conceptU64(seed - CONCEPT_PRIME64_1);
11901
- const limit = len - 32;
11902
- while (index <= limit) {
11903
- v1 = conceptXxHash64Round(v1, conceptReadUInt64LE(data, index)); index += 8;
11904
- v2 = conceptXxHash64Round(v2, conceptReadUInt64LE(data, index)); index += 8;
11905
- v3 = conceptXxHash64Round(v3, conceptReadUInt64LE(data, index)); index += 8;
11906
- v4 = conceptXxHash64Round(v4, conceptReadUInt64LE(data, index)); index += 8;
11907
- }
11908
- h64 = conceptU64(
11909
- conceptRotateLeft(v1, 1)
11910
- + conceptRotateLeft(v2, 7)
11911
- + conceptRotateLeft(v3, 12)
11912
- + conceptRotateLeft(v4, 18)
11913
- );
11914
- h64 = conceptXxHash64MergeRound(h64, v1);
11915
- h64 = conceptXxHash64MergeRound(h64, v2);
11916
- h64 = conceptXxHash64MergeRound(h64, v3);
11917
- h64 = conceptXxHash64MergeRound(h64, v4);
11918
- } else {
11919
- h64 = conceptU64(seed + CONCEPT_PRIME64_5);
11920
- }
11921
-
11922
- h64 = conceptU64(h64 + BigInt(len));
11923
- while (index <= len - 8) {
11924
- const k1 = conceptXxHash64Round(0n, conceptReadUInt64LE(data, index));
11925
- h64 = conceptU64(h64 ^ k1);
11926
- h64 = conceptU64(conceptRotateLeft(h64, 27) * CONCEPT_PRIME64_1 + CONCEPT_PRIME64_4);
11927
- index += 8;
11928
- }
11929
- if (index <= len - 4) {
11930
- h64 = conceptU64(h64 ^ (BigInt(conceptReadUInt32LE(data, index) >>> 0) * CONCEPT_PRIME64_1));
11931
- h64 = conceptU64(conceptRotateLeft(h64, 23) * CONCEPT_PRIME64_2 + CONCEPT_PRIME64_3);
11932
- index += 4;
11933
- }
11934
- while (index < len) {
11935
- h64 = conceptU64(h64 ^ (BigInt(data[index]) * CONCEPT_PRIME64_5));
11936
- h64 = conceptU64(conceptRotateLeft(h64, 11) * CONCEPT_PRIME64_1);
11937
- index += 1;
11938
- }
11939
-
11940
- h64 = conceptU64(h64 ^ (h64 >> 33n));
11941
- h64 = conceptU64(h64 * CONCEPT_PRIME64_2);
11942
- h64 = conceptU64(h64 ^ (h64 >> 29n));
11943
- h64 = conceptU64(h64 * CONCEPT_PRIME64_3);
11944
- h64 = conceptU64(h64 ^ (h64 >> 32n));
11945
- return h64 & CONCEPT_U64_MASK;
11946
- }
11947
-
11948
- function conceptHash64Hex(signature) {
11949
- const clean = String(signature || '').trim();
11950
- if (!clean) {
11951
- const err = new Error('signature is required');
11952
- err.statusCode = 400;
11953
- throw err;
11954
- }
11955
- return `0x${conceptXxHash64(Buffer.from(clean, 'utf8')).toString(16).padStart(16, '0')}`;
11956
- }
11957
-
11958
- function normalizeConceptHex64(value, field = 'id') {
11959
- const text = String(value || '').trim().toLowerCase();
11960
- if (!/^0x[0-9a-f]{16}$/.test(text)) {
11961
- const err = new Error(`${field} must be 0x[0-9a-f]{16}`);
11962
- err.statusCode = 400;
11963
- throw err;
11964
- }
11965
- return text;
11966
- }
11967
-
11968
- function conceptSqlKeyString(hex64) {
11969
- const unsigned = BigInt(hex64);
11970
- return unsigned > CONCEPT_I64_MAX
11971
- ? (unsigned - CONCEPT_U64_SIZE).toString()
11972
- : unsigned.toString();
11973
- }
11974
-
11975
- async function loadNodeSqliteModule() {
11976
- if (!nodeSqliteModulePromise) {
11977
- nodeSqliteModulePromise = import('node:sqlite').catch(err => {
11978
- nodeSqliteModulePromise = null;
11979
- throw err;
11980
- });
11981
- }
11982
- return nodeSqliteModulePromise;
11983
- }
11984
-
11985
- function normalizeConceptSequence(ir) {
11986
- const text = String(ir || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n').trim();
11987
- if (!text) {
11988
- const err = new Error('ir is required');
11989
- err.statusCode = 400;
11990
- throw err;
11991
- }
11992
- if (text.length > 240000) {
11993
- const err = new Error('ir is too large');
11994
- err.statusCode = 413;
11995
- throw err;
11996
- }
11997
-
11998
- let parsed;
11999
- try {
12000
- parsed = JSON.parse(text);
12001
- } catch (parseErr) {
12002
- const err = new Error(`ir must be valid ConceptSequence JSON: ${parseErr?.message || parseErr}`);
12003
- err.statusCode = 400;
12004
- throw err;
12005
- }
12006
- const literals = Array.isArray(parsed?.literals) ? parsed.literals : [];
12007
- const instructions = Array.isArray(parsed?.instructions) ? parsed.instructions : [];
12008
- if (instructions.length === 0) {
12009
- const err = new Error('ir must include a non-empty instructions array');
12010
- err.statusCode = 400;
12011
- throw err;
12012
- }
12013
- return { body: text, literals, instructions };
12014
- }
12015
-
12016
- function deterministicConceptVector(signature, description, dimensions = 16) {
12017
- const size = Math.max(4, Math.min(64, Math.trunc(Number(dimensions) || 16)));
12018
- const input = `${signature}\n\nDescription: ${description || ''}`;
12019
- return Array.from({ length: size }, (_, index) => {
12020
- const hash = BigInt(conceptHash64Hex(`${input}#${index}`));
12021
- const normalized = Number(hash & 0xffffn) / 32767.5 - 1;
12022
- return Number(normalized.toFixed(6));
12023
- });
12024
- }
12025
-
12026
- function serializeConceptFloatVectorBase64(vector) {
12027
- const values = Array.isArray(vector) ? vector : [];
12028
- const buffer = Buffer.alloc(values.length * 4);
12029
- values.forEach((value, index) => {
12030
- buffer.writeFloatLE(Number(value) || 0, index * 4);
12031
- });
12032
- return buffer.toString('base64');
12033
- }
12034
-
12035
- async function readJsonIfExists(filePath, fallback) {
12036
- try {
12037
- const content = await fs.readFile(filePath, 'utf8');
12038
- return JSON.parse(content);
12039
- } catch (err) {
12040
- if (err?.code === 'ENOENT') {
12041
- return fallback;
12042
- }
12043
- throw err;
12044
- }
12045
- }
12046
-
12047
- function normalizeNullableConceptText(value) {
12048
- const text = String(value ?? '').trim();
12049
- return text ? text : null;
12050
- }
12051
-
12052
- function conceptEmbeddingBlobFromBase64(base64) {
12053
- const text = String(base64 || '').trim();
12054
- if (!text) return null;
12055
- return Buffer.from(text, 'base64');
12056
- }
12057
-
12058
- function conceptSqliteRowFromRecord(record) {
12059
- const concept = record?.Concept || {};
12060
- const sqlKey = String(concept.SqlKey || conceptSqlKeyString(normalizeConceptHex64(concept.Id, 'id'))).trim();
12061
- return {
12062
- id: BigInt(sqlKey),
12063
- idText: sqlKey,
12064
- signature: String(concept.Signature || ''),
12065
- body: normalizeNullableConceptText(concept.Body),
12066
- category: normalizeNullableConceptText(concept.Category),
12067
- conceptType: normalizeNullableConceptText(concept.ConceptType),
12068
- createdUtc: normalizeNullableConceptText(concept.CreatedUtc),
12069
- updatedUtc: normalizeNullableConceptText(concept.UpdatedUtc),
12070
- description: normalizeNullableConceptText(concept.Description),
12071
- embedding: conceptEmbeddingBlobFromBase64(concept.EmbeddingBase64),
12072
- embeddingModel: normalizeNullableConceptText(concept.EmbeddingModel),
12073
- embeddingUpdatedUtc: normalizeNullableConceptText(concept.EmbeddingUpdatedUtc)
12074
- };
12075
- }
12076
-
12077
- function initializeConceptSqliteDatabase(db) {
12078
- db.exec(`
12079
- PRAGMA journal_mode=WAL;
12080
- PRAGMA synchronous=NORMAL;
12081
- PRAGMA temp_store=MEMORY;
12082
- CREATE TABLE IF NOT EXISTS tbl_concepts (
12083
- id INTEGER PRIMARY KEY,
12084
- signature TEXT NOT NULL,
12085
- body TEXT NULL,
12086
- category TEXT NULL,
12087
- concept_type TEXT NULL,
12088
- created_utc TEXT NULL,
12089
- updated_utc TEXT NULL,
12090
- description TEXT NULL,
12091
- embedding BLOB NULL,
12092
- embedding_model TEXT NULL,
12093
- embedding_updated_utc TEXT NULL
12094
- );
12095
- CREATE INDEX IF NOT EXISTS idx_tbl_concepts_category ON tbl_concepts(category);
12096
- `);
12097
- }
12098
-
12099
- function bindConceptSqliteReadBigInts(statement) {
12100
- if (typeof statement?.setReadBigInts === 'function') {
12101
- statement.setReadBigInts(true);
12102
- }
12103
- return statement;
12104
- }
12105
-
12106
- function normalizeConceptSqliteRow(row, sqlitePath) {
12107
- if (!row) return null;
12108
- const embedding = row.embedding ? Buffer.from(row.embedding) : null;
12109
- const idValue = typeof row.id === 'bigint' ? row.id : BigInt(row.id);
12110
- const hex = `0x${BigInt.asUintN(64, idValue).toString(16).padStart(16, '0')}`;
12111
- return {
12112
- success: true,
12113
- provider: 'LocalBridgeNativeSQLiteConceptStore',
12114
- adapterState: 'native-sqlite',
12115
- originalTable: 'tbl_concepts',
12116
- sqlitePath,
12117
- id: hex,
12118
- sqlKey: idValue.toString(),
12119
- signature: row.signature || '',
12120
- body: row.body || null,
12121
- category: row.category || '',
12122
- conceptType: row.concept_type || null,
12123
- createdAt: row.created_utc || null,
12124
- updatedAt: row.updated_utc || null,
12125
- description: row.description || null,
12126
- embeddingBase64: embedding ? embedding.toString('base64') : null,
12127
- embeddingBytes: embedding ? embedding.length : 0,
12128
- embeddingModel: row.embedding_model || null,
12129
- embeddingUpdatedAt: row.embedding_updated_utc || null
12130
- };
12131
- }
12132
-
12133
- function buildConceptCompositeResponse(record) {
12134
- return {
12135
- success: true,
12136
- id: record.Concept.Id,
12137
- sqlKey: record.Concept.SqlKey,
12138
- signature: record.Concept.Signature,
12139
- category: record.Concept.Category,
12140
- conceptType: record.Concept.ConceptType,
12141
- path: record.Path,
12142
- indexPath: record.IndexPath,
12143
- sha256: record.Sha256,
12144
- hashAlgorithm: record.HashAlgorithm,
12145
- embeddingModel: record.Concept.EmbeddingModel,
12146
- embeddingVector: record.Concept.EmbeddingVector,
12147
- embeddingBase64: record.Concept.EmbeddingBase64,
12148
- nativeSqlite: record.NativeSqlite || null,
12149
- updatedAt: record.Concept.UpdatedUtc
12150
- };
12151
- }
12152
-
12153
- async function saveConceptCompositeRecord(request = {}) {
12154
- const nowUtc = new Date().toISOString();
12155
- const signature = clampEvidenceText(request.signature || request.Signature, 500);
12156
- const id = normalizeConceptHex64(request.id || request.Id || conceptHash64Hex(signature), 'id');
12157
- const derivedId = conceptHash64Hex(signature);
12158
- if (id !== derivedId) {
12159
- const err = new Error(`signature does not match id. signature->id=${derivedId}, id=${id}`);
12160
- err.statusCode = 400;
12161
- throw err;
12162
- }
12163
-
12164
- const sequence = normalizeConceptSequence(request.ir || request.IR || request.body || request.Body);
12165
- const description = clampEvidenceText(request.description || request.Description, 2400);
12166
- const category = clampEvidenceText(request.category || request.Category || 'Composite.Dynamic', 160) || 'Composite.Dynamic';
12167
- const conceptType = clampEvidenceText(request.conceptType || request.ConceptType || 'Axiom', 80) || 'Axiom';
12168
- const vector = deterministicConceptVector(signature, description, request.embeddingDimensions || request.EmbeddingDimensions || 16);
12169
- const baseConceptDir = path.resolve(getAiPath(), 'concepts');
12170
- const rowDir = path.resolve(baseConceptDir, 'rows');
12171
- const fileName = `${id.slice(2)}-${slugifyEvidence(signature, 64)}.json`;
12172
- const fullPath = path.resolve(rowDir, fileName);
12173
- const indexPath = path.resolve(baseConceptDir, 'tbl_concepts.rows.json');
12174
-
12175
- if (!isPathWithin(baseConceptDir, fullPath) || !isPathWithin(baseConceptDir, indexPath)) {
12176
- const err = new Error('Concept path must stay under the concept cache.');
12177
- err.statusCode = 400;
12178
- throw err;
12179
- }
12180
-
12181
- const relativePath = normalizePathForClient(path.relative(workspacePath, fullPath));
12182
- const relativeIndexPath = normalizePathForClient(path.relative(workspacePath, indexPath));
12183
- const conceptRow = {
12184
- Id: id,
12185
- SqlKey: conceptSqlKeyString(id),
12186
- Signature: signature,
12187
- Body: sequence.body,
12188
- Category: category,
12189
- ConceptType: conceptType,
12190
- CreatedUtc: nowUtc,
12191
- UpdatedUtc: nowUtc,
12192
- Description: description || undefined,
12193
- EmbeddingVector: vector,
12194
- EmbeddingBase64: serializeConceptFloatVectorBase64(vector),
12195
- EmbeddingModel: CONCEPT_EMBEDDING_MODEL,
12196
- EmbeddingUpdatedUtc: nowUtc,
12197
- AtomCount: sequence.instructions.length,
12198
- LiteralCount: sequence.literals.length
12199
- };
12200
- const record = {
12201
- Schema: 'MindExecution.Kernel.Store.ConceptConcept/v1',
12202
- Store: {
12203
- Provider: 'LocalBridgeJsonConceptStore',
12204
- OriginalTable: 'tbl_concepts',
12205
- Notes: 'JSON row projection for local React parity; LocalBridge also mirrors the row into native SQLite tbl_concepts.'
12206
- },
12207
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12208
- Concept: conceptRow,
12209
- Path: relativePath,
12210
- IndexPath: relativeIndexPath
12211
- };
12212
-
12213
- const unsignedJson = JSON.stringify(record, null, 2);
12214
- record.Sha256 = crypto.createHash('sha256').update(unsignedJson, 'utf8').digest('hex');
12215
- await writeFileAtomically(fullPath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
12216
-
12217
- const currentIndex = await readJsonIfExists(indexPath, {
12218
- Schema: 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12219
- Store: 'LocalBridgeJsonConceptStore',
12220
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12221
- Rows: []
12222
- });
12223
- const rows = Array.isArray(currentIndex.Rows) ? currentIndex.Rows : [];
12224
- const nextRows = [
12225
- {
12226
- Id: conceptRow.Id,
12227
- SqlKey: conceptRow.SqlKey,
12228
- Signature: conceptRow.Signature,
12229
- Category: conceptRow.Category,
12230
- ConceptType: conceptRow.ConceptType,
12231
- UpdatedUtc: conceptRow.UpdatedUtc,
12232
- AtomCount: conceptRow.AtomCount,
12233
- LiteralCount: conceptRow.LiteralCount,
12234
- Path: relativePath,
12235
- Sha256: record.Sha256
12236
- },
12237
- ...rows.filter(row => String(row?.Id || '').toLowerCase() !== conceptRow.Id)
12238
- ].slice(0, 512);
12239
-
12240
- const nextIndex = {
12241
- Schema: 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12242
- Store: 'LocalBridgeJsonConceptStore',
12243
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12244
- UpdatedUtc: nowUtc,
12245
- RowCount: nextRows.length,
12246
- Rows: nextRows
12247
- };
12248
- await writeFileAtomically(indexPath, `${JSON.stringify(nextIndex, null, 2)}\n`, 'utf8');
12249
- record.NativeSqlite = await upsertConceptNativeSqlite(record);
12250
- return record;
12251
- }
12252
-
12253
- function getConceptStorePaths() {
12254
- const baseConceptDir = path.resolve(getAiPath(), 'concepts');
12255
- const rowDir = path.resolve(baseConceptDir, 'rows');
12256
- const indexPath = path.resolve(baseConceptDir, 'tbl_concepts.rows.json');
12257
- const sqlitePath = path.resolve(baseConceptDir, 'mind_concepts.db');
12258
- return { baseConceptDir, rowDir, indexPath, sqlitePath };
12259
- }
12260
-
12261
- async function upsertConceptNativeSqlite(record) {
12262
- const { DatabaseSync } = await loadNodeSqliteModule();
12263
- const { baseConceptDir, sqlitePath } = getConceptStorePaths();
12264
- if (!isPathWithin(baseConceptDir, sqlitePath)) {
12265
- const err = new Error('Concept SQLite path must stay under the concept cache.');
12266
- err.statusCode = 400;
12267
- throw err;
12268
- }
12269
-
12270
- await fs.mkdir(baseConceptDir, { recursive: true });
12271
- const sqliteRow = conceptSqliteRowFromRecord(record);
12272
- const db = new DatabaseSync(sqlitePath, { readOnly: false });
12273
- try {
12274
- initializeConceptSqliteDatabase(db);
12275
- db.exec('BEGIN IMMEDIATE;');
12276
- try {
12277
- db.prepare(`
12278
- INSERT INTO tbl_concepts (id, signature, body, category, concept_type, created_utc, updated_utc, description, embedding, embedding_model, embedding_updated_utc)
12279
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
12280
- ON CONFLICT(id) DO UPDATE SET
12281
- signature=excluded.signature,
12282
- body=excluded.body,
12283
- category=excluded.category,
12284
- concept_type=excluded.concept_type,
12285
- created_utc=excluded.created_utc,
12286
- updated_utc=excluded.updated_utc,
12287
- description=excluded.description,
12288
- embedding=excluded.embedding,
12289
- embedding_model=excluded.embedding_model,
12290
- embedding_updated_utc=excluded.embedding_updated_utc;
12291
- `).run(
12292
- sqliteRow.id,
12293
- sqliteRow.signature,
12294
- sqliteRow.body,
12295
- sqliteRow.category,
12296
- sqliteRow.conceptType,
12297
- sqliteRow.createdUtc,
12298
- sqliteRow.updatedUtc,
12299
- sqliteRow.description,
12300
- sqliteRow.embedding,
12301
- sqliteRow.embeddingModel,
12302
- sqliteRow.embeddingUpdatedUtc
12303
- );
12304
- db.exec('COMMIT;');
12305
- } catch (err) {
12306
- try { db.exec('ROLLBACK;'); } catch {}
12307
- throw err;
12308
- }
12309
-
12310
- const countRow = db.prepare('SELECT COUNT(*) AS row_count FROM tbl_concepts;').get();
12311
- const relativeSqlitePath = normalizePathForClient(path.relative(workspacePath, sqlitePath));
12312
- return {
12313
- success: true,
12314
- provider: 'LocalBridgeNativeSQLiteConceptStore',
12315
- adapterState: 'native-sqlite',
12316
- originalTable: 'tbl_concepts',
12317
- sqlitePath: relativeSqlitePath,
12318
- rowCount: Number(countRow?.row_count || 0),
12319
- lastSqlKey: sqliteRow.idText,
12320
- lastId: record?.Concept?.Id || null
12321
- };
12322
- } finally {
12323
- db.close();
12324
- }
12325
- }
12326
-
12327
- async function readConceptNativeSqliteRowById(id) {
12328
- const normalizedId = normalizeConceptHex64(id, 'id');
12329
- const { DatabaseSync } = await loadNodeSqliteModule();
12330
- const { baseConceptDir, sqlitePath } = getConceptStorePaths();
12331
- if (!isPathWithin(baseConceptDir, sqlitePath)) {
12332
- const err = new Error('Concept SQLite path must stay under the concept cache.');
12333
- err.statusCode = 400;
12334
- throw err;
12335
- }
12336
-
12337
- try {
12338
- await fs.access(sqlitePath);
12339
- } catch {
12340
- const err = new Error('Concept native SQLite database has not been created yet.');
12341
- err.statusCode = 404;
12342
- throw err;
12343
- }
12344
-
12345
- const db = new DatabaseSync(sqlitePath, { readOnly: true });
12346
- try {
12347
- const sqlKey = BigInt(conceptSqlKeyString(normalizedId));
12348
- const statement = bindConceptSqliteReadBigInts(db.prepare(`
12349
- SELECT id, signature, body, category, concept_type, created_utc, updated_utc, description, embedding, embedding_model, embedding_updated_utc
12350
- FROM tbl_concepts
12351
- WHERE id = ?
12352
- LIMIT 1;
12353
- `));
12354
- const row = statement.get(sqlKey);
12355
- if (!row) {
12356
- const err = new Error(`Concept SQLite row not found: ${normalizedId}`);
12357
- err.statusCode = 404;
12358
- throw err;
12359
- }
12360
- const relativeSqlitePath = normalizePathForClient(path.relative(workspacePath, sqlitePath));
12361
- return normalizeConceptSqliteRow(row, relativeSqlitePath);
12362
- } finally {
12363
- db.close();
12364
- }
12365
- }
12366
-
12367
- async function readConceptStoreIndex() {
12368
- const { baseConceptDir, indexPath } = getConceptStorePaths();
12369
- if (!isPathWithin(baseConceptDir, indexPath)) {
12370
- const err = new Error('Concept index path must stay under the concept cache.');
12371
- err.statusCode = 400;
12372
- throw err;
12373
- }
12374
-
12375
- const fallback = {
12376
- Schema: 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12377
- Store: 'LocalBridgeJsonConceptStore',
12378
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12379
- UpdatedUtc: null,
12380
- RowCount: 0,
12381
- Rows: []
12382
- };
12383
- const index = await readJsonIfExists(indexPath, fallback);
12384
- const rows = Array.isArray(index.Rows) ? index.Rows : [];
12385
- return {
12386
- ...fallback,
12387
- ...index,
12388
- Rows: rows,
12389
- RowCount: Number.isFinite(Number(index.RowCount)) ? Number(index.RowCount) : rows.length,
12390
- Path: normalizePathForClient(path.relative(workspacePath, indexPath))
12391
- };
12392
- }
12393
-
12394
- async function readConceptNativeSqliteStatus() {
12395
- const { baseConceptDir, sqlitePath } = getConceptStorePaths();
12396
- const relativeSqlitePath = normalizePathForClient(path.relative(workspacePath, sqlitePath));
12397
- try {
12398
- const { DatabaseSync } = await loadNodeSqliteModule();
12399
- await fs.access(sqlitePath);
12400
- const db = new DatabaseSync(sqlitePath, { readOnly: true });
12401
- try {
12402
- const tableRows = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='tbl_concepts' LIMIT 1;").all();
12403
- const hasTable = tableRows.length > 0;
12404
- const rowCount = hasTable ? Number(db.prepare('SELECT COUNT(*) AS row_count FROM tbl_concepts;').get()?.row_count || 0) : 0;
12405
- const columnRows = hasTable ? db.prepare('PRAGMA table_info(tbl_concepts);').all() : [];
12406
- return {
12407
- success: true,
12408
- provider: 'LocalBridgeNativeSQLiteConceptStore',
12409
- adapterState: hasTable ? 'native-sqlite' : 'native-sqlite-pending',
12410
- originalTable: 'tbl_concepts',
12411
- sqlitePath: relativeSqlitePath,
12412
- rowCount,
12413
- hasTable,
12414
- columns: columnRows.map(row => String(row.name || '')).filter(Boolean)
12415
- };
12416
- } finally {
12417
- db.close();
12418
- }
12419
- } catch (err) {
12420
- if (err?.code === 'ENOENT') {
12421
- return {
12422
- success: true,
12423
- provider: 'LocalBridgeNativeSQLiteConceptStore',
12424
- adapterState: 'native-sqlite-pending',
12425
- originalTable: 'tbl_concepts',
12426
- sqlitePath: relativeSqlitePath,
12427
- rowCount: 0,
12428
- hasTable: false,
12429
- columns: []
12430
- };
12431
- }
12432
- return {
12433
- success: false,
12434
- provider: 'LocalBridgeNativeSQLiteConceptStore',
12435
- adapterState: 'native-sqlite-error',
12436
- originalTable: 'tbl_concepts',
12437
- sqlitePath: relativeSqlitePath,
12438
- rowCount: 0,
12439
- hasTable: false,
12440
- columns: [],
12441
- error: err?.message || String(err)
12442
- };
12443
- }
12444
- }
12445
-
12446
- function buildConceptStoreStatusResponse(index, nativeSqlite = null) {
12447
- const rows = Array.isArray(index.Rows) ? index.Rows : [];
12448
- return {
12449
- success: true,
12450
- provider: 'LocalBridgeJsonConceptStore',
12451
- adapterState: 'json-row-projection',
12452
- originalTable: 'tbl_concepts',
12453
- schema: index.Schema || 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12454
- hashAlgorithm: index.HashAlgorithm || CONCEPT_HASH_ALGORITHM,
12455
- embeddingModel: CONCEPT_EMBEDDING_MODEL,
12456
- rowCount: rows.length,
12457
- indexPath: index.Path,
12458
- updatedAt: index.UpdatedUtc || null,
12459
- latestRows: rows.slice(0, 12).map(row => ({
12460
- id: row.Id,
12461
- sqlKey: row.SqlKey,
12462
- signature: row.Signature,
12463
- category: row.Category,
12464
- conceptType: row.ConceptType,
12465
- atomCount: row.AtomCount,
12466
- literalCount: row.LiteralCount,
12467
- path: row.Path,
12468
- sha256: row.Sha256,
12469
- updatedAt: row.UpdatedUtc
12470
- })),
12471
- sqliteReadyColumns: [
12472
- 'Id',
12473
- 'SqlKey',
12474
- 'Signature',
12475
- 'Body',
12476
- 'Category',
12477
- 'ConceptType',
12478
- 'Description',
12479
- 'EmbeddingVector',
12480
- 'EmbeddingBase64',
12481
- 'EmbeddingModel',
12482
- 'AtomCount',
12483
- 'LiteralCount',
12484
- 'CreatedUtc',
12485
- 'UpdatedUtc'
12486
- ],
12487
- paidEmbeddingAdapterState: 'adapter-gated',
12488
- nativeSqliteAdapterState: nativeSqlite?.adapterState || 'native-sqlite-pending',
12489
- nativeSqlite
12490
- };
12491
- }
12492
-
12493
- async function readConceptCompositeRecordById(id) {
12494
- const normalizedId = normalizeConceptHex64(id, 'id');
12495
- const index = await readConceptStoreIndex();
12496
- const row = (Array.isArray(index.Rows) ? index.Rows : []).find(item => String(item?.Id || '').toLowerCase() === normalizedId);
12497
- if (!row?.Path) {
12498
- const err = new Error(`Concept row not found: ${normalizedId}`);
12499
- err.statusCode = 404;
12500
- throw err;
12501
- }
12502
-
12503
- const fullPath = path.resolve(workspacePath, String(row.Path));
12504
- const { baseConceptDir } = getConceptStorePaths();
12505
- if (!isPathWithin(baseConceptDir, fullPath)) {
12506
- const err = new Error('Concept row path must stay under the concept cache.');
12507
- err.statusCode = 400;
12508
- throw err;
12509
- }
12510
-
12511
- const record = JSON.parse(await fs.readFile(fullPath, 'utf8'));
12512
- if (String(record?.Concept?.Id || '').toLowerCase() !== normalizedId) {
12513
- const err = new Error(`Concept row id mismatch: expected ${normalizedId}`);
12514
- err.statusCode = 409;
12515
- throw err;
12516
- }
12517
- return record;
12518
- }
12519
-
12520
- function getConceptEmbeddingProviderConfig() {
12521
- const baseUrl = String(
12522
- process.env.MINDEXEC_CONCEPT_EMBED_BASE_URL
12523
- || process.env.OPENAI_BASE_URL
12524
- || process.env.OPENROUTER_BASE_URL
12525
- || 'https://api.openai.com/v1'
12526
- ).trim().replace(/\/+$/, '');
12527
- const model = String(
12528
- process.env.MINDEXEC_CONCEPT_EMBED_MODEL
12529
- || process.env.OPENAI_EMBEDDING_MODEL
12530
- || 'text-embedding-3-small'
12531
- ).trim();
12532
- const apiKey = String(
12533
- process.env.MINDEXEC_CONCEPT_EMBED_API_KEY
12534
- || process.env.OPENAI_API_KEY
12535
- || process.env.OPENROUTER_API_KEY
12536
- || ''
12537
- ).trim();
12538
- const confirm = String(process.env.MINDEXEC_CONCEPT_EMBED_LIVE_CONFIRM || '').trim();
12539
- return {
12540
- baseUrl,
12541
- model,
12542
- apiKey,
12543
- hasApiKey: Boolean(apiKey) && !apiKey.includes('__PUT_YOUR_KEY_HERE__'),
12544
- confirm,
12545
- confirmed: confirm === CONCEPT_EMBED_LIVE_CONFIRM_VALUE
12546
- };
12547
- }
12548
-
12549
- function buildConceptEmbeddingReadinessResponse() {
12550
- const config = getConceptEmbeddingProviderConfig();
12551
- const url = new URL(`${config.baseUrl}/embeddings`);
12552
- return {
12553
- success: true,
12554
- provider: 'OpenAI-compatible embeddings',
12555
- adapterState: config.confirmed && config.hasApiKey ? 'available-opt-in' : 'adapter-gated',
12556
- confirmationEnv: 'MINDEXEC_CONCEPT_EMBED_LIVE_CONFIRM',
12557
- requiredConfirmation: CONCEPT_EMBED_LIVE_CONFIRM_VALUE,
12558
- confirmationState: config.confirmed ? 'confirmed' : 'missing',
12559
- apiKeyState: config.hasApiKey ? 'present' : 'missing',
12560
- baseUrlHost: url.host,
12561
- endpointPath: url.pathname,
12562
- model: config.model,
12563
- inputPolicy: 'signature + "\\n\\nDescription: " + description',
12564
- storesEmbeddingBase64: true,
12565
- defaultRunMode: 'blocked-until-confirmed'
12566
- };
12567
- }
12568
-
12569
- function normalizeConceptEmbeddingRequest(request = {}) {
12570
- const signature = clampEvidenceText(request.signature || request.Signature, 500);
12571
- const description = clampEvidenceText(request.description || request.Description, 2400);
12572
- if (!signature.trim()) {
12573
- const err = new Error('signature is required');
12574
- err.statusCode = 400;
12575
- throw err;
12576
- }
12577
- if (!description.trim()) {
12578
- const err = new Error('description is required');
12579
- err.statusCode = 400;
12580
- throw err;
12581
- }
12582
- return {
12583
- signature: signature.trim(),
12584
- description: description.trim(),
12585
- category: clampEvidenceText(request.category || request.Category || '', 160),
12586
- conceptType: clampEvidenceText(request.conceptType || request.ConceptType || 'Axiom', 80) || 'Axiom'
12587
- };
12588
- }
12589
-
12590
- async function callConceptEmbeddingProvider(input, config) {
12591
- const controller = new AbortController();
12592
- const timeout = setTimeout(() => controller.abort(), 45000);
12593
- try {
12594
- const response = await fetch(`${config.baseUrl}/embeddings`, {
12595
- method: 'POST',
12596
- headers: {
12597
- 'Authorization': `Bearer ${config.apiKey}`,
12598
- 'Content-Type': 'application/json'
12599
- },
12600
- body: JSON.stringify({ model: config.model, input }),
12601
- signal: controller.signal
12602
- });
12603
- const text = await response.text();
12604
- if (!response.ok) {
12605
- const err = new Error(`OpenAI-compatible embeddings error ${response.status}: ${text.slice(0, 500)}`);
12606
- err.statusCode = 502;
12607
- throw err;
12608
- }
12609
- let payload;
12610
- try {
12611
- payload = text ? JSON.parse(text) : {};
12612
- } catch (parseErr) {
12613
- const err = new Error(`Embedding provider returned invalid JSON: ${parseErr?.message || parseErr}`);
12614
- err.statusCode = 502;
12615
- throw err;
12616
- }
12617
- const embedding = payload?.data?.[0]?.embedding;
12618
- if (!Array.isArray(embedding) || embedding.length === 0) {
12619
- const err = new Error('Embedding provider returned an empty embedding.');
12620
- err.statusCode = 502;
12621
- throw err;
12622
- }
12623
- if (embedding.length > 16384) {
12624
- const err = new Error(`Embedding vector too large: ${embedding.length}`);
12625
- err.statusCode = 413;
12626
- throw err;
12627
- }
12628
- return embedding.map(value => Number(value) || 0);
12629
- } finally {
12630
- clearTimeout(timeout);
12631
- }
12632
- }
12633
-
12634
- async function upsertConceptEmbeddingRecord(request = {}) {
12635
- const normalized = normalizeConceptEmbeddingRequest(request);
12636
- const config = getConceptEmbeddingProviderConfig();
12637
- if (!config.confirmed) {
12638
- const err = new Error(`Embedding provider calls require MINDEXEC_CONCEPT_EMBED_LIVE_CONFIRM=${CONCEPT_EMBED_LIVE_CONFIRM_VALUE}`);
12639
- err.statusCode = 403;
12640
- throw err;
12641
- }
12642
- if (!config.hasApiKey) {
12643
- const err = new Error('Embedding provider API key is missing from server environment.');
12644
- err.statusCode = 403;
12645
- throw err;
12646
- }
12647
-
12648
- const id = conceptHash64Hex(normalized.signature);
12649
- let existing = null;
12650
- try {
12651
- existing = await readConceptCompositeRecordById(id);
12652
- } catch (err) {
12653
- if (Number(err?.statusCode) !== 404) throw err;
12654
- }
12655
-
12656
- const input = `${normalized.signature}\n\nDescription: ${normalized.description}`;
12657
- const vector = await callConceptEmbeddingProvider(input, config);
12658
- const nowUtc = new Date().toISOString();
12659
- const { baseConceptDir, rowDir, indexPath } = getConceptStorePaths();
12660
- const fileName = existing?.Path
12661
- ? path.basename(existing.Path)
12662
- : `${id.slice(2)}-${slugifyEvidence(normalized.signature, 64)}.json`;
12663
- const fullPath = existing?.Path
12664
- ? path.resolve(workspacePath, existing.Path)
12665
- : path.resolve(rowDir, fileName);
12666
-
12667
- if (!isPathWithin(baseConceptDir, fullPath) || !isPathWithin(baseConceptDir, indexPath)) {
12668
- const err = new Error('Concept embedding path must stay under the concept cache.');
12669
- err.statusCode = 400;
12670
- throw err;
12671
- }
12672
-
12673
- const relativePath = normalizePathForClient(path.relative(workspacePath, fullPath));
12674
- const relativeIndexPath = normalizePathForClient(path.relative(workspacePath, indexPath));
12675
- const previousConcept = existing?.Concept || {};
12676
- const conceptRow = {
12677
- Id: id,
12678
- SqlKey: conceptSqlKeyString(id),
12679
- Signature: normalized.signature,
12680
- Body: previousConcept.Body,
12681
- Category: normalized.category || previousConcept.Category || '',
12682
- ConceptType: normalized.conceptType || previousConcept.ConceptType || 'Axiom',
12683
- CreatedUtc: previousConcept.CreatedUtc || nowUtc,
12684
- UpdatedUtc: nowUtc,
12685
- Description: normalized.description,
12686
- EmbeddingVector: vector,
12687
- EmbeddingBase64: serializeConceptFloatVectorBase64(vector),
12688
- EmbeddingModel: config.model,
12689
- EmbeddingUpdatedUtc: nowUtc,
12690
- AtomCount: Number(previousConcept.AtomCount || 0),
12691
- LiteralCount: Number(previousConcept.LiteralCount || 0)
12692
- };
12693
- const record = {
12694
- Schema: 'MindExecution.Kernel.Store.ConceptConcept/v1',
12695
- Store: {
12696
- Provider: 'LocalBridgeJsonConceptStore',
12697
- OriginalTable: 'tbl_concepts',
12698
- Notes: 'OpenAI-compatible embedding provider result stored as JSON row projection and mirrored into native SQLite tbl_concepts.'
12699
- },
12700
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12701
- Concept: conceptRow,
12702
- Path: relativePath,
12703
- IndexPath: relativeIndexPath
12704
- };
12705
-
12706
- const unsignedJson = JSON.stringify(record, null, 2);
12707
- record.Sha256 = crypto.createHash('sha256').update(unsignedJson, 'utf8').digest('hex');
12708
- await writeFileAtomically(fullPath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
12709
-
12710
- const currentIndex = await readJsonIfExists(indexPath, {
12711
- Schema: 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12712
- Store: 'LocalBridgeJsonConceptStore',
12713
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12714
- Rows: []
12715
- });
12716
- const rows = Array.isArray(currentIndex.Rows) ? currentIndex.Rows : [];
12717
- const nextRows = [
12718
- {
12719
- Id: conceptRow.Id,
12720
- SqlKey: conceptRow.SqlKey,
12721
- Signature: conceptRow.Signature,
12722
- Category: conceptRow.Category,
12723
- ConceptType: conceptRow.ConceptType,
12724
- UpdatedUtc: conceptRow.UpdatedUtc,
12725
- AtomCount: conceptRow.AtomCount,
12726
- LiteralCount: conceptRow.LiteralCount,
12727
- Path: relativePath,
12728
- Sha256: record.Sha256,
12729
- EmbeddingModel: conceptRow.EmbeddingModel,
12730
- EmbeddingUpdatedUtc: conceptRow.EmbeddingUpdatedUtc
12731
- },
12732
- ...rows.filter(row => String(row?.Id || '').toLowerCase() !== conceptRow.Id)
12733
- ].slice(0, 512);
12734
- const nextIndex = {
12735
- Schema: 'MindExecution.Kernel.Store.ConceptConceptIndex/v1',
12736
- Store: 'LocalBridgeJsonConceptStore',
12737
- HashAlgorithm: CONCEPT_HASH_ALGORITHM,
12738
- UpdatedUtc: nowUtc,
12739
- RowCount: nextRows.length,
12740
- Rows: nextRows
12741
- };
12742
- await writeFileAtomically(indexPath, `${JSON.stringify(nextIndex, null, 2)}\n`, 'utf8');
12743
- record.NativeSqlite = await upsertConceptNativeSqlite(record);
12744
- return record;
12745
- }
12746
-
12747
- function parseHtmlAttributes(attrs) {
11086
+ };
11087
+ }
11088
+
11089
+ function parseHtmlAttributes(attrs) {
12748
11090
  const result = {};
12749
11091
  const regex = /([A-Za-z_:][-A-Za-z0-9_:.]*)\s*=\s*["']([^"']*)["']/g;
12750
11092
  let match;
@@ -14031,19 +12373,6 @@ app.get('/api/codex/capabilities', async (req, res) => {
14031
12373
  }
14032
12374
  });
14033
12375
 
14034
- app.get('/api/model-catalog', async (req, res) => {
14035
- try {
14036
- const forceRefresh = /^(1|true|yes|on)$/i.test(String(req.query?.refresh || ''));
14037
- res.json(await getBridgeModelCatalog({ forceRefresh }));
14038
- } catch (err) {
14039
- console.error('[ModelCatalog] Error:', err);
14040
- res.status(500).json({
14041
- success: false,
14042
- error: err?.message || String(err)
14043
- });
14044
- }
14045
- });
14046
-
14047
12376
  app.post('/api/codex/thread/start', async (req, res) => {
14048
12377
  try {
14049
12378
  res.json(await getCodexRuntime().startThread(req.body || {}));
@@ -14315,9 +12644,9 @@ app.post('/api/web/search', async (req, res) => {
14315
12644
  }
14316
12645
  });
14317
12646
 
14318
- app.post('/api/web/fetch', async (req, res) => {
14319
- try {
14320
- const { url, maxChars = 12000 } = req.body || {};
12647
+ app.post('/api/web/fetch', async (req, res) => {
12648
+ try {
12649
+ const { url, maxChars = 12000 } = req.body || {};
14321
12650
  if (!url || !String(url).trim()) {
14322
12651
  return res.status(400).json({ error: 'URL is required' });
14323
12652
  }
@@ -14333,119 +12662,12 @@ app.post('/api/web/fetch', async (req, res) => {
14333
12662
  console.error('[Web/Fetch] Error:', err);
14334
12663
  const statusCode = Number(err?.statusCode) || 500;
14335
12664
  res.status(statusCode).json({ error: err?.message || 'Web fetch failed' });
14336
- }
14337
- });
14338
-
14339
- app.post('/api/evidence/save', async (req, res) => {
14340
- try {
14341
- const record = await saveEvidenceRecord(req.body || {});
14342
- logToolAction(
14343
- 'Evidence.Save',
14344
- `${formatKeyValue('path', tone(record.Path, 'path'))} ${formatKeyValue('kind', record.Kind)} ${formatKeyValue('source', shortenText(record.SourceUrl || record.SourcePath || '-', 100))}`,
14345
- 'success');
14346
- res.json(buildEvidenceResponse(record));
14347
- } catch (err) {
14348
- console.error('[Evidence/Save] Error:', err);
14349
- const statusCode = Number(err?.statusCode) || 500;
14350
- res.status(statusCode).json({ success: false, error: err?.message || 'Evidence save failed' });
14351
- }
14352
- });
14353
-
14354
- app.post('/api/concept/define-composite', async (req, res) => {
14355
- try {
14356
- const record = await saveConceptCompositeRecord(req.body || {});
14357
- logToolAction(
14358
- 'Concept.DefineComposite',
14359
- `${formatKeyValue('id', record.Concept.Id)} ${formatKeyValue('path', tone(record.Path, 'path'))} ${formatKeyValue('atoms', record.Concept.AtomCount)}`,
14360
- 'success');
14361
- res.json(buildConceptCompositeResponse(record));
14362
- } catch (err) {
14363
- console.error('[Concept/DefineComposite] Error:', err);
14364
- const statusCode = Number(err?.statusCode) || 500;
14365
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept composite save failed' });
14366
- }
14367
- });
14368
-
14369
- app.get('/api/concept/status', async (req, res) => {
14370
- try {
14371
- const index = await readConceptStoreIndex();
14372
- const nativeSqlite = await readConceptNativeSqliteStatus();
14373
- const response = buildConceptStoreStatusResponse(index, nativeSqlite);
14374
- logToolAction(
14375
- 'Concept.Status',
14376
- `${formatKeyValue('rows', response.rowCount)} ${formatKeyValue('store', response.adapterState)} ${formatKeyValue('sqlite', response.nativeSqliteAdapterState)} ${formatKeyValue('index', tone(response.indexPath || '-', 'path'))}`,
14377
- response.adapterState === 'json-row-projection' ? 'bridge' : 'warn');
14378
- res.json(response);
14379
- } catch (err) {
14380
- console.error('[Concept/Status] Error:', err);
14381
- const statusCode = Number(err?.statusCode) || 500;
14382
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept status failed' });
14383
- }
14384
- });
14385
-
14386
- app.get('/api/concept/row', async (req, res) => {
14387
- try {
14388
- const record = await readConceptCompositeRecordById(req.query?.id || req.query?.Id);
14389
- logToolAction(
14390
- 'Concept.Row',
14391
- `${formatKeyValue('id', record.Concept.Id)} ${formatKeyValue('path', tone(record.Path, 'path'))} ${formatKeyValue('atoms', record.Concept.AtomCount)}`,
14392
- 'bridge');
14393
- res.json(buildConceptCompositeResponse(record));
14394
- } catch (err) {
14395
- console.error('[Concept/Row] Error:', err);
14396
- const statusCode = Number(err?.statusCode) || 500;
14397
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept row read failed' });
14398
- }
14399
- });
14400
-
14401
- app.get('/api/concept/sqlite/row', async (req, res) => {
14402
- try {
14403
- const response = await readConceptNativeSqliteRowById(req.query?.id || req.query?.Id);
14404
- logToolAction(
14405
- 'Concept.SQLite.Row',
14406
- `${formatKeyValue('id', response.id)} ${formatKeyValue('path', tone(response.sqlitePath, 'path'))} ${formatKeyValue('bytes', response.embeddingBytes)}`,
14407
- 'bridge');
14408
- res.json(response);
14409
- } catch (err) {
14410
- console.error('[Concept/SQLite/Row] Error:', err);
14411
- const statusCode = Number(err?.statusCode) || 500;
14412
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept SQLite row read failed' });
14413
- }
14414
- });
14415
-
14416
- app.get('/api/concept/embed/readiness', async (req, res) => {
14417
- try {
14418
- const response = buildConceptEmbeddingReadinessResponse();
14419
- logToolAction(
14420
- 'Concept.Embed.Readiness',
14421
- `${formatKeyValue('state', response.adapterState)} ${formatKeyValue('model', response.model)} ${formatKeyValue('endpoint', `${response.baseUrlHost}${response.endpointPath}`)}`,
14422
- response.adapterState === 'available-opt-in' ? 'bridge' : 'warn');
14423
- res.json(response);
14424
- } catch (err) {
14425
- console.error('[Concept/Embed/Readiness] Error:', err);
14426
- const statusCode = Number(err?.statusCode) || 500;
14427
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept embed readiness failed' });
14428
- }
14429
- });
14430
-
14431
- app.post('/api/concept/embed', async (req, res) => {
14432
- try {
14433
- const record = await upsertConceptEmbeddingRecord(req.body || {});
14434
- logToolAction(
14435
- 'Concept.Embed',
14436
- `${formatKeyValue('id', record.Concept.Id)} ${formatKeyValue('dim', Array.isArray(record.Concept.EmbeddingVector) ? record.Concept.EmbeddingVector.length : 0)} ${formatKeyValue('model', record.Concept.EmbeddingModel)}`,
14437
- 'success');
14438
- res.json(buildConceptCompositeResponse(record));
14439
- } catch (err) {
14440
- console.error('[Concept/Embed] Error:', err);
14441
- const statusCode = Number(err?.statusCode) || 500;
14442
- res.status(statusCode).json({ success: false, error: err?.message || 'Concept embed failed' });
14443
- }
14444
- });
14445
-
14446
- app.post('/api/browser/open', async (req, res) => {
14447
- try {
14448
- const { url } = req.body || {};
12665
+ }
12666
+ });
12667
+
12668
+ app.post('/api/browser/open', async (req, res) => {
12669
+ try {
12670
+ const { url } = req.body || {};
14449
12671
  if (!url || !String(url).trim()) {
14450
12672
  return res.status(400).json({ error: 'URL is required' });
14451
12673
  }