hermes-web-ui 0.4.3 → 0.4.4

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 (202) hide show
  1. package/README.md +2 -1
  2. package/dist/client/assets/Add-C5vmHXvi.js +1 -0
  3. package/dist/client/assets/{Button-vKfgky-Y.js → Button-BkFCVws1.js} +3 -3
  4. package/dist/client/assets/{ChannelsView-CHWtzAkF.js → ChannelsView-kmohhCQz.js} +1 -1
  5. package/dist/client/assets/ChatView-BqERLIKm.js +3 -0
  6. package/dist/client/assets/{ChatView-b0_L3ucp.css → ChatView-CjCcr65D.css} +1 -1
  7. package/dist/client/assets/{Close-Brba3ay5.js → Close-BQv4cWxW.js} +2 -2
  8. package/dist/client/assets/Dropdown-CalW5lgg.js +125 -0
  9. package/dist/client/assets/Empty-Crwpm9aR.js +24 -0
  10. package/dist/client/assets/FilesView-BIhdGj93.css +1 -0
  11. package/dist/client/assets/FilesView-DDqOER0C.js +279 -0
  12. package/dist/client/assets/{FormItem-kXuCeSKq.js → FormItem-rZXpOEwq.js} +3 -3
  13. package/dist/client/assets/GatewaysView-CBisX7sg.js +1 -0
  14. package/dist/client/assets/Input-CACQWEc-.js +234 -0
  15. package/dist/client/assets/{InputNumber-BXy4reTI.js → InputNumber-BtDJhuZ_.js} +2 -2
  16. package/dist/client/assets/JobsView-D2rkutWf.js +2 -0
  17. package/dist/client/assets/LoginView-fbo3JyWY.js +1 -0
  18. package/dist/client/assets/LogsView-D6S5uWNR.js +1 -0
  19. package/dist/client/assets/{MarkdownRenderer-B7t0ZEw0.js → MarkdownRenderer-4flsL0HK.js} +17 -17
  20. package/dist/client/assets/MemoryView-Ct-Xub44.js +7 -0
  21. package/dist/client/assets/{Modal-6Bv1v4kO.js → Modal-pv2obz6L.js} +4 -4
  22. package/dist/client/assets/{ModelsView-BStkMmEH.css → ModelsView-DoxebjaU.css} +1 -1
  23. package/dist/client/assets/ModelsView-NQaSxgAw.js +1 -0
  24. package/dist/client/assets/Popconfirm-BtGpKlX7.js +16 -0
  25. package/dist/client/assets/Popover-CrGHm4Ci.js +117 -0
  26. package/dist/client/assets/ProfilesView-BkxAC36G.js +1 -0
  27. package/dist/client/assets/Select-D9RT-keZ.js +317 -0
  28. package/dist/client/assets/SettingRow-Uz-cvlWh.js +1 -0
  29. package/dist/client/assets/SettingsView-ZqYSPWDq.js +352 -0
  30. package/dist/client/assets/SkillsView-CynAdT4a.js +1 -0
  31. package/dist/client/assets/{Spin-DKwUVt1F.js → Spin-Cl861IYY.js} +3 -3
  32. package/dist/client/assets/Suffix-lZvgRyRJ.js +90 -0
  33. package/dist/client/assets/{Switch-DG-3EwdR.js → Switch-Cgr6t0l5.js} +2 -2
  34. package/dist/client/assets/{Tag-BWD1u63m.js → Tag-DTjJYhIj.js} +2 -2
  35. package/dist/client/assets/{TerminalView-DTR8bNOy.js → TerminalView-B-24Rkd7.js} +6 -6
  36. package/dist/client/assets/Tooltip-BSRTJcks.js +1 -0
  37. package/dist/client/assets/Upload-GVPlkKwO.js +440 -0
  38. package/dist/client/assets/UsageView-MG6jNAat.js +1 -0
  39. package/dist/client/assets/{Warning-CCZES7el.js → Warning-C_N-vtES.js} +1 -1
  40. package/dist/client/assets/{_plugin-vue_export-helper-Bl_Pm_OI.js → _plugin-vue_export-helper-BQLp1Z61.js} +2 -2
  41. package/dist/client/assets/abap-Cj2ZJqTY.js +1 -0
  42. package/dist/client/assets/apex-DMOzUZZB.js +1 -0
  43. package/dist/client/assets/app-CawwM3Gr.js +1 -0
  44. package/dist/client/assets/app-DMdMpEzR.js +1 -0
  45. package/dist/client/assets/{auth-BPBv1nNQ.js → auth-Bkk8rJhI.js} +1 -1
  46. package/dist/client/assets/azcli-BJqyCQCD.js +1 -0
  47. package/dist/client/assets/bat-D9jfAgXL.js +1 -0
  48. package/dist/client/assets/bicep-IyCF8AHg.js +2 -0
  49. package/dist/client/assets/browser-C0KKMpa8.js +47 -0
  50. package/dist/client/assets/cameligo-DqphQ1Vf.js +1 -0
  51. package/dist/client/assets/chat-BdoAzXti.js +6 -0
  52. package/dist/client/assets/chunk-DECur_0Z.js +1 -0
  53. package/dist/client/assets/clipboard-D5ziXDzU.js +1 -0
  54. package/dist/client/assets/clojure-CqmBZ3SB.js +1 -0
  55. package/dist/client/assets/codicon-ngg6Pgfi.ttf +0 -0
  56. package/dist/client/assets/coffee-CD7nYioG.js +1 -0
  57. package/dist/client/assets/composables-gdfCfHJJ.js +1 -0
  58. package/dist/client/assets/cpp-CJjcH3OV.js +1 -0
  59. package/dist/client/assets/{create-5zWq3BEB.js → create-DgSD0xTd.js} +1 -1
  60. package/dist/client/assets/csharp-Bh3KEkzK.js +1 -0
  61. package/dist/client/assets/csp-Bwqlbr_S.js +1 -0
  62. package/dist/client/assets/css-CoIOcuFa.js +3 -0
  63. package/dist/client/assets/css.worker-DyDu5ynT.js +89 -0
  64. package/dist/client/assets/cssMode-DEq9g7fF.js +1 -0
  65. package/dist/client/assets/cypher-BI5xYxDU.js +1 -0
  66. package/dist/client/assets/dart-C48Nsypx.js +1 -0
  67. package/dist/client/assets/dockerfile-ueCsFBIO.js +1 -0
  68. package/dist/client/assets/ecl-bYObu0Am.js +1 -0
  69. package/dist/client/assets/editor-Br_kD0ds.css +1 -0
  70. package/dist/client/assets/editor.api2-Be2SWebq.js +872 -0
  71. package/dist/client/assets/editor.worker-Dpt_xPrs.js +26 -0
  72. package/dist/client/assets/elixir-C3hRLmcx.js +1 -0
  73. package/dist/client/assets/fade-in.cssr-D3Wt-ego.js +12 -0
  74. package/dist/client/assets/flow9-DFj18iNE.js +1 -0
  75. package/dist/client/assets/freemarker2-DL4Fzu5B.js +3 -0
  76. package/dist/client/assets/fsharp-AnzNBUww.js +1 -0
  77. package/dist/client/assets/go-tJ6Rmw6i.js +1 -0
  78. package/dist/client/assets/graphql-C0hIG8nm.js +1 -0
  79. package/dist/client/assets/handlebars-BHnMuvUj.js +1 -0
  80. package/dist/client/assets/hcl-BuyUNygY.js +1 -0
  81. package/dist/client/assets/html-GXFtBUzj.js +1 -0
  82. package/dist/client/assets/html.worker-IWNXhnIC.js +502 -0
  83. package/dist/client/assets/htmlMode-BcCXcf_0.js +1 -0
  84. package/dist/client/assets/index-8ao2g7sV.js +284 -0
  85. package/dist/client/assets/{index-BRXOdlZt.css → index-C9EadcMt.css} +1 -1
  86. package/dist/client/assets/ini-BeJtyijW.js +1 -0
  87. package/dist/client/assets/java-C2VAgfs1.js +1 -0
  88. package/dist/client/assets/javascript-U_9WP-aM.js +1 -0
  89. package/dist/client/assets/jobs-B5TmkmHx.js +1 -0
  90. package/dist/client/assets/jobs-ByeskmbT.js +1 -0
  91. package/dist/client/assets/json.worker-c4h5s80L.js +58 -0
  92. package/dist/client/assets/jsonMode-tONQS06s.js +7 -0
  93. package/dist/client/assets/julia-L5N2QjZH.js +1 -0
  94. package/dist/client/assets/kotlin-CoM2kw6K.js +1 -0
  95. package/dist/client/assets/less-zbg2EZtP.js +2 -0
  96. package/dist/client/assets/lexon-DYXVK96z.js +1 -0
  97. package/dist/client/assets/{light-DLz3o2il.js → light-0XEUqxc9.js} +1 -1
  98. package/dist/client/assets/{light-BNuYwJcs.js → light-5OhOi42N.js} +1 -1
  99. package/dist/client/assets/light-B2F950-4.js +1 -0
  100. package/dist/client/assets/{light-DcGe0-g1.js → light-CqEvxEaQ.js} +1 -1
  101. package/dist/client/assets/{light-DbUQYfY2.js → light-KCWDej_e.js} +1 -1
  102. package/dist/client/assets/{light-cIgLWDVk.js → light-Q_cJ87-J.js} +1 -1
  103. package/dist/client/assets/light-m-6OEHOE.js +1 -0
  104. package/dist/client/assets/liquid-B0bBAmrr.js +1 -0
  105. package/dist/client/assets/lspLanguageFeatures-CTVvD5p-.js +4 -0
  106. package/dist/client/assets/lua-BLOIBWLB.js +1 -0
  107. package/dist/client/assets/m3-cDvqo2bv.js +1 -0
  108. package/dist/client/assets/markdown-Dl_DNBM2.js +1 -0
  109. package/dist/client/assets/mdx-RopAvSlP.js +1 -0
  110. package/dist/client/assets/mips-BzzKjtTI.js +1 -0
  111. package/dist/client/assets/{models-EKNn3-zC.js → models-B81NGa-M.js} +1 -1
  112. package/dist/client/assets/monaco.contribution-BEuTYscZ.js +2 -0
  113. package/dist/client/assets/msdax-sEefJb9Q.js +1 -0
  114. package/dist/client/assets/mysql-DRV1IKn4.js +1 -0
  115. package/dist/client/assets/objective-c-DYtfYpNc.js +1 -0
  116. package/dist/client/assets/pascal-CpR5h_uZ.js +1 -0
  117. package/dist/client/assets/pascaligo-BI_Gz9Bp.js +1 -0
  118. package/dist/client/assets/perl-K9wCPr4J.js +1 -0
  119. package/dist/client/assets/pgsql-NrZG2xAf.js +1 -0
  120. package/dist/client/assets/php-DT0D5Htf.js +1 -0
  121. package/dist/client/assets/{pinia-C8BDM-Fc.js → pinia-Bf3FnMGw.js} +1 -1
  122. package/dist/client/assets/pla-COSVs9tJ.js +1 -0
  123. package/dist/client/assets/postiats-CpQICSCZ.js +1 -0
  124. package/dist/client/assets/powerquery-hpQUPY_r.js +1 -0
  125. package/dist/client/assets/powershell-CXKJShJs.js +1 -0
  126. package/dist/client/assets/preload-helper-rov5CBGT.js +1 -0
  127. package/dist/client/assets/profiles-CySy48VW.js +1 -0
  128. package/dist/client/assets/protobuf-VEer4AfK.js +2 -0
  129. package/dist/client/assets/pug-CCviz4wy.js +1 -0
  130. package/dist/client/assets/python-DPgAafol.js +1 -0
  131. package/dist/client/assets/qsharp-DTveMB6M.js +1 -0
  132. package/dist/client/assets/r-CnY31RFU.js +1 -0
  133. package/dist/client/assets/razor-BRbs1kR5.js +1 -0
  134. package/dist/client/assets/redis-1g6etttg.js +1 -0
  135. package/dist/client/assets/redshift-BQFehQo7.js +1 -0
  136. package/dist/client/assets/restructuredtext-CR8m-OPX.js +1 -0
  137. package/dist/client/assets/router-DSISOBmz.js +4 -0
  138. package/dist/client/assets/ruby-BljIZnPI.js +1 -0
  139. package/dist/client/assets/rust-C7icjueR.js +1 -0
  140. package/dist/client/assets/sb-Cl_sCxp1.js +1 -0
  141. package/dist/client/assets/scala-CT-TSn-3.js +1 -0
  142. package/dist/client/assets/scheme-BkJvX1f4.js +1 -0
  143. package/dist/client/assets/scss-B5N7uefM.js +3 -0
  144. package/dist/client/assets/{session-browser-prefs-BI-rZu2N.js → session-browser-prefs-LLoiG_YM.js} +1 -1
  145. package/dist/client/assets/{sessions-CJI89wYu.js → sessions-LymnKAC6.js} +1 -1
  146. package/dist/client/assets/shell-DGQq63Qg.js +1 -0
  147. package/dist/client/assets/{skills-DjdZmDZP.js → skills-5sEozVye.js} +1 -1
  148. package/dist/client/assets/solidity-BGsdM1K-.js +1 -0
  149. package/dist/client/assets/sophia-2vdPWHk_.js +1 -0
  150. package/dist/client/assets/sparql-BVtOOc6V.js +1 -0
  151. package/dist/client/assets/sql-ceGY-xNe.js +1 -0
  152. package/dist/client/assets/st-DupPN7oj.js +1 -0
  153. package/dist/client/assets/swift-BVzV3sGw.js +1 -0
  154. package/dist/client/assets/systemverilog-hp5X8uST.js +1 -0
  155. package/dist/client/assets/tcl-D56hFaYe.js +1 -0
  156. package/dist/client/assets/ts.worker-BwM5Ha3L.js +67719 -0
  157. package/dist/client/assets/tsMode-DGr7-1MY.js +11 -0
  158. package/dist/client/assets/twig-C2ivmPwo.js +1 -0
  159. package/dist/client/assets/typescript-yGuzzsRv.js +1 -0
  160. package/dist/client/assets/typespec-DxADZqov.js +1 -0
  161. package/dist/client/assets/{use-message-sSsrvqld.js → use-message-DOCgeMXd.js} +1 -1
  162. package/dist/client/assets/{useTheme-DgQIobZP.js → useTheme-Dm7n8Zfn.js} +1 -1
  163. package/dist/client/assets/vb-EBCrbQ4-.js +1 -0
  164. package/dist/client/assets/wgsl-9pwzQzLa.js +298 -0
  165. package/dist/client/assets/workers-LkP66fNk.js +1 -0
  166. package/dist/client/assets/xml-Dnyprwt6.js +1 -0
  167. package/dist/client/assets/yaml-BU-x4ie7.js +1 -0
  168. package/dist/client/index.html +36 -31
  169. package/dist/server/index.js +2201 -398
  170. package/dist/server/index.js.map +4 -4
  171. package/package.json +18 -4
  172. package/dist/client/assets/Add-DiTv65Se.js +0 -1
  173. package/dist/client/assets/ChatView--lvFbW3I.js +0 -127
  174. package/dist/client/assets/GatewaysView-DUPP1UyD.js +0 -1
  175. package/dist/client/assets/Input-BS71ZaoJ.js +0 -234
  176. package/dist/client/assets/JobsView-CXa1h0NF.js +0 -2
  177. package/dist/client/assets/LoginView-Cpod3SAL.js +0 -1
  178. package/dist/client/assets/LogsView-CgxeVMn-.js +0 -1
  179. package/dist/client/assets/MemoryView-BQjYVDJc.js +0 -7
  180. package/dist/client/assets/ModelsView-CVghPzgk.js +0 -1
  181. package/dist/client/assets/Popconfirm-Bpz_dC1j.js +0 -16
  182. package/dist/client/assets/Popover-CXrjClQw.js +0 -117
  183. package/dist/client/assets/ProfilesView-Brpyzl-Q.js +0 -440
  184. package/dist/client/assets/Select-Z20Mp4nQ.js +0 -340
  185. package/dist/client/assets/SettingRow-Cz749k-e.js +0 -1
  186. package/dist/client/assets/SettingsView-C3HbKb4w.js +0 -352
  187. package/dist/client/assets/SkillsView-qVZkbI37.js +0 -1
  188. package/dist/client/assets/Suffix-C1Mw6UwH.js +0 -90
  189. package/dist/client/assets/Tooltip-Dka1-DNs.js +0 -1
  190. package/dist/client/assets/UsageView-elTUQCED.js +0 -1
  191. package/dist/client/assets/app-BMD_VOYs.js +0 -1
  192. package/dist/client/assets/app-y8cD3FPg.js +0 -1
  193. package/dist/client/assets/browser-DlPqZ-4M.js +0 -47
  194. package/dist/client/assets/chat-3-o9JAHE.js +0 -6
  195. package/dist/client/assets/composables-CoSqDggz.js +0 -1
  196. package/dist/client/assets/fade-in.cssr-D0suZaLL.js +0 -12
  197. package/dist/client/assets/index-CeFFa_Wg.js +0 -284
  198. package/dist/client/assets/jobs-DMiCP2Li.js +0 -1
  199. package/dist/client/assets/profiles-1vZTTlBc.js +0 -1
  200. package/dist/client/assets/router-kR4kqS2l.js +0 -4
  201. /package/dist/client/assets/{_common-D_mHAddk.js → _common-DdtSL-nr.js} +0 -0
  202. /package/dist/client/assets/{logo-Cd-t_oGE.js → logo-D12u0f1i.js} +0 -0
@@ -2172,7 +2172,7 @@ var require_content_disposition = __commonJS({
2172
2172
  "use strict";
2173
2173
  module2.exports = contentDisposition;
2174
2174
  module2.exports.parse = parse2;
2175
- var basename2 = require("path").basename;
2175
+ var basename4 = require("path").basename;
2176
2176
  var Buffer2 = require_safe_buffer().Buffer;
2177
2177
  var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
2178
2178
  var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
@@ -2208,9 +2208,9 @@ var require_content_disposition = __commonJS({
2208
2208
  if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
2209
2209
  throw new TypeError("fallback must be ISO-8859-1 string");
2210
2210
  }
2211
- var name = basename2(filename);
2211
+ var name = basename4(filename);
2212
2212
  var isQuotedString = TEXT_REGEXP.test(name);
2213
- var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename2(fallback);
2213
+ var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename4(fallback);
2214
2214
  var hasFallback = typeof fallbackName === "string" && fallbackName !== name;
2215
2215
  if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
2216
2216
  params["filename*"] = name;
@@ -10866,7 +10866,7 @@ var require_mime_types = __commonJS({
10866
10866
  "node_modules/mime-types/index.js"(exports2) {
10867
10867
  "use strict";
10868
10868
  var db = require_mime_db();
10869
- var extname = require("path").extname;
10869
+ var extname2 = require("path").extname;
10870
10870
  var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
10871
10871
  var TEXT_TYPE_REGEXP = /^text\//i;
10872
10872
  exports2.charset = charset;
@@ -10920,7 +10920,7 @@ var require_mime_types = __commonJS({
10920
10920
  if (!path || typeof path !== "string") {
10921
10921
  return false;
10922
10922
  }
10923
- var extension3 = extname("x." + path).toLowerCase().substr(1);
10923
+ var extension3 = extname2("x." + path).toLowerCase().substr(1);
10924
10924
  if (!extension3) {
10925
10925
  return false;
10926
10926
  }
@@ -11247,7 +11247,7 @@ var require_type_is = __commonJS({
11247
11247
  module2.exports = typeofrequest;
11248
11248
  module2.exports.is = typeis2;
11249
11249
  module2.exports.hasBody = hasbody;
11250
- module2.exports.normalize = normalize;
11250
+ module2.exports.normalize = normalize2;
11251
11251
  module2.exports.match = mimeMatch;
11252
11252
  function typeis2(value, types_) {
11253
11253
  var i;
@@ -11267,7 +11267,7 @@ var require_type_is = __commonJS({
11267
11267
  }
11268
11268
  var type2;
11269
11269
  for (i = 0; i < types2.length; i++) {
11270
- if (mimeMatch(normalize(type2 = types2[i]), val)) {
11270
+ if (mimeMatch(normalize2(type2 = types2[i]), val)) {
11271
11271
  return type2[0] === "+" || type2.indexOf("*") !== -1 ? val : type2;
11272
11272
  }
11273
11273
  }
@@ -11290,7 +11290,7 @@ var require_type_is = __commonJS({
11290
11290
  var value = req.headers["content-type"];
11291
11291
  return typeis2(value, types2);
11292
11292
  }
11293
- function normalize(type2) {
11293
+ function normalize2(type2) {
11294
11294
  if (typeof type2 !== "string") {
11295
11295
  return false;
11296
11296
  }
@@ -11420,10 +11420,10 @@ var require_statuses = __commonJS({
11420
11420
  "node_modules/koa/node_modules/statuses/index.js"(exports2, module2) {
11421
11421
  "use strict";
11422
11422
  var codes = require_codes();
11423
- module2.exports = status2;
11424
- status2.STATUS_CODES = codes;
11425
- status2.codes = populateStatusesMap(status2, codes);
11426
- status2.redirect = {
11423
+ module2.exports = status3;
11424
+ status3.STATUS_CODES = codes;
11425
+ status3.codes = populateStatusesMap(status3, codes);
11426
+ status3.redirect = {
11427
11427
  300: true,
11428
11428
  301: true,
11429
11429
  302: true,
@@ -11432,12 +11432,12 @@ var require_statuses = __commonJS({
11432
11432
  307: true,
11433
11433
  308: true
11434
11434
  };
11435
- status2.empty = {
11435
+ status3.empty = {
11436
11436
  204: true,
11437
11437
  205: true,
11438
11438
  304: true
11439
11439
  };
11440
- status2.retry = {
11440
+ status3.retry = {
11441
11441
  502: true,
11442
11442
  503: true,
11443
11443
  504: true
@@ -11446,17 +11446,17 @@ var require_statuses = __commonJS({
11446
11446
  var arr = [];
11447
11447
  Object.keys(codes2).forEach(function forEachCode(code) {
11448
11448
  var message2 = codes2[code];
11449
- var status3 = Number(code);
11450
- statuses[status3] = message2;
11451
- statuses[message2] = status3;
11452
- statuses[message2.toLowerCase()] = status3;
11453
- arr.push(status3);
11449
+ var status4 = Number(code);
11450
+ statuses[status4] = message2;
11451
+ statuses[message2] = status4;
11452
+ statuses[message2.toLowerCase()] = status4;
11453
+ arr.push(status4);
11454
11454
  });
11455
11455
  return arr;
11456
11456
  }
11457
- function status2(code) {
11457
+ function status3(code) {
11458
11458
  if (typeof code === "number") {
11459
- if (!status2[code]) throw new Error("invalid status code: " + code);
11459
+ if (!status3[code]) throw new Error("invalid status code: " + code);
11460
11460
  return code;
11461
11461
  }
11462
11462
  if (typeof code !== "string") {
@@ -11464,10 +11464,10 @@ var require_statuses = __commonJS({
11464
11464
  }
11465
11465
  var n = parseInt(code, 10);
11466
11466
  if (!isNaN(n)) {
11467
- if (!status2[n]) throw new Error("invalid status code: " + n);
11467
+ if (!status3[n]) throw new Error("invalid status code: " + n);
11468
11468
  return n;
11469
11469
  }
11470
- n = status2[code.toLowerCase()];
11470
+ n = status3[code.toLowerCase()];
11471
11471
  if (!n) throw new Error('invalid status message: "' + code + '"');
11472
11472
  return n;
11473
11473
  }
@@ -11601,24 +11601,24 @@ var require_vary = __commonJS({
11601
11601
  function parse2(header) {
11602
11602
  var end = 0;
11603
11603
  var list6 = [];
11604
- var start3 = 0;
11604
+ var start4 = 0;
11605
11605
  for (var i = 0, len = header.length; i < len; i++) {
11606
11606
  switch (header.charCodeAt(i)) {
11607
11607
  case 32:
11608
- if (start3 === end) {
11609
- start3 = end = i + 1;
11608
+ if (start4 === end) {
11609
+ start4 = end = i + 1;
11610
11610
  }
11611
11611
  break;
11612
11612
  case 44:
11613
- list6.push(header.substring(start3, end));
11614
- start3 = end = i + 1;
11613
+ list6.push(header.substring(start4, end));
11614
+ start4 = end = i + 1;
11615
11615
  break;
11616
11616
  default:
11617
11617
  end = i + 1;
11618
11618
  break;
11619
11619
  }
11620
11620
  }
11621
- list6.push(header.substring(start3, end));
11621
+ list6.push(header.substring(start4, end));
11622
11622
  return list6;
11623
11623
  }
11624
11624
  function vary(res, field) {
@@ -11675,7 +11675,7 @@ var require_response = __commonJS({
11675
11675
  var statuses = require_statuses();
11676
11676
  var destroy = require_destroy();
11677
11677
  var assert = require("assert");
11678
- var extname = require("path").extname;
11678
+ var extname2 = require("path").extname;
11679
11679
  var vary = require_vary();
11680
11680
  var only = require_only();
11681
11681
  var util3 = require("util");
@@ -11901,7 +11901,7 @@ var require_response = __commonJS({
11901
11901
  * @api public
11902
11902
  */
11903
11903
  attachment(filename, options) {
11904
- if (filename) this.type = extname(filename);
11904
+ if (filename) this.type = extname2(filename);
11905
11905
  this.set("Content-Disposition", contentDisposition(filename, options));
11906
11906
  },
11907
11907
  /**
@@ -12693,19 +12693,19 @@ var require_http_errors = __commonJS({
12693
12693
  module2.exports.HttpError = createHttpErrorConstructor();
12694
12694
  module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
12695
12695
  populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
12696
- function codeClass(status2) {
12697
- return Number(String(status2).charAt(0) + "00");
12696
+ function codeClass(status3) {
12697
+ return Number(String(status3).charAt(0) + "00");
12698
12698
  }
12699
12699
  function createError() {
12700
12700
  var err;
12701
12701
  var msg;
12702
- var status2 = 500;
12702
+ var status3 = 500;
12703
12703
  var props = {};
12704
12704
  for (var i = 0; i < arguments.length; i++) {
12705
12705
  var arg = arguments[i];
12706
12706
  if (arg instanceof Error) {
12707
12707
  err = arg;
12708
- status2 = err.status || err.statusCode || status2;
12708
+ status3 = err.status || err.statusCode || status3;
12709
12709
  continue;
12710
12710
  }
12711
12711
  switch (typeof arg) {
@@ -12713,7 +12713,7 @@ var require_http_errors = __commonJS({
12713
12713
  msg = arg;
12714
12714
  break;
12715
12715
  case "number":
12716
- status2 = arg;
12716
+ status3 = arg;
12717
12717
  if (i !== 0) {
12718
12718
  deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
12719
12719
  }
@@ -12723,20 +12723,20 @@ var require_http_errors = __commonJS({
12723
12723
  break;
12724
12724
  }
12725
12725
  }
12726
- if (typeof status2 === "number" && (status2 < 400 || status2 >= 600)) {
12726
+ if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
12727
12727
  deprecate2("non-error status code; use only 4xx or 5xx status codes");
12728
12728
  }
12729
- if (typeof status2 !== "number" || !statuses[status2] && (status2 < 400 || status2 >= 600)) {
12730
- status2 = 500;
12729
+ if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
12730
+ status3 = 500;
12731
12731
  }
12732
- var HttpError3 = createError[status2] || createError[codeClass(status2)];
12732
+ var HttpError3 = createError[status3] || createError[codeClass(status3)];
12733
12733
  if (!err) {
12734
- err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status2]);
12734
+ err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
12735
12735
  Error.captureStackTrace(err, createError);
12736
12736
  }
12737
- if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status2) {
12738
- err.expose = status2 < 500;
12739
- err.status = err.statusCode = status2;
12737
+ if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
12738
+ err.expose = status3 < 500;
12739
+ err.status = err.statusCode = status3;
12740
12740
  }
12741
12741
  for (var key in props) {
12742
12742
  if (key !== "status" && key !== "statusCode") {
@@ -13357,10 +13357,10 @@ var require_statuses2 = __commonJS({
13357
13357
  "node_modules/http-assert/node_modules/statuses/index.js"(exports2, module2) {
13358
13358
  "use strict";
13359
13359
  var codes = require_codes2();
13360
- module2.exports = status2;
13361
- status2.STATUS_CODES = codes;
13362
- status2.codes = populateStatusesMap(status2, codes);
13363
- status2.redirect = {
13360
+ module2.exports = status3;
13361
+ status3.STATUS_CODES = codes;
13362
+ status3.codes = populateStatusesMap(status3, codes);
13363
+ status3.redirect = {
13364
13364
  300: true,
13365
13365
  301: true,
13366
13366
  302: true,
@@ -13369,12 +13369,12 @@ var require_statuses2 = __commonJS({
13369
13369
  307: true,
13370
13370
  308: true
13371
13371
  };
13372
- status2.empty = {
13372
+ status3.empty = {
13373
13373
  204: true,
13374
13374
  205: true,
13375
13375
  304: true
13376
13376
  };
13377
- status2.retry = {
13377
+ status3.retry = {
13378
13378
  502: true,
13379
13379
  503: true,
13380
13380
  504: true
@@ -13383,17 +13383,17 @@ var require_statuses2 = __commonJS({
13383
13383
  var arr = [];
13384
13384
  Object.keys(codes2).forEach(function forEachCode(code) {
13385
13385
  var message2 = codes2[code];
13386
- var status3 = Number(code);
13387
- statuses[status3] = message2;
13388
- statuses[message2] = status3;
13389
- statuses[message2.toLowerCase()] = status3;
13390
- arr.push(status3);
13386
+ var status4 = Number(code);
13387
+ statuses[status4] = message2;
13388
+ statuses[message2] = status4;
13389
+ statuses[message2.toLowerCase()] = status4;
13390
+ arr.push(status4);
13391
13391
  });
13392
13392
  return arr;
13393
13393
  }
13394
- function status2(code) {
13394
+ function status3(code) {
13395
13395
  if (typeof code === "number") {
13396
- if (!status2[code]) throw new Error("invalid status code: " + code);
13396
+ if (!status3[code]) throw new Error("invalid status code: " + code);
13397
13397
  return code;
13398
13398
  }
13399
13399
  if (typeof code !== "string") {
@@ -13401,10 +13401,10 @@ var require_statuses2 = __commonJS({
13401
13401
  }
13402
13402
  var n = parseInt(code, 10);
13403
13403
  if (!isNaN(n)) {
13404
- if (!status2[n]) throw new Error("invalid status code: " + n);
13404
+ if (!status3[n]) throw new Error("invalid status code: " + n);
13405
13405
  return n;
13406
13406
  }
13407
- n = status2[code.toLowerCase()];
13407
+ n = status3[code.toLowerCase()];
13408
13408
  if (!n) throw new Error('invalid status message: "' + code + '"');
13409
13409
  return n;
13410
13410
  }
@@ -13424,19 +13424,19 @@ var require_http_errors2 = __commonJS({
13424
13424
  module2.exports.HttpError = createHttpErrorConstructor();
13425
13425
  module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
13426
13426
  populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
13427
- function codeClass(status2) {
13428
- return Number(String(status2).charAt(0) + "00");
13427
+ function codeClass(status3) {
13428
+ return Number(String(status3).charAt(0) + "00");
13429
13429
  }
13430
13430
  function createError() {
13431
13431
  var err;
13432
13432
  var msg;
13433
- var status2 = 500;
13433
+ var status3 = 500;
13434
13434
  var props = {};
13435
13435
  for (var i = 0; i < arguments.length; i++) {
13436
13436
  var arg = arguments[i];
13437
13437
  if (arg instanceof Error) {
13438
13438
  err = arg;
13439
- status2 = err.status || err.statusCode || status2;
13439
+ status3 = err.status || err.statusCode || status3;
13440
13440
  continue;
13441
13441
  }
13442
13442
  switch (typeof arg) {
@@ -13444,7 +13444,7 @@ var require_http_errors2 = __commonJS({
13444
13444
  msg = arg;
13445
13445
  break;
13446
13446
  case "number":
13447
- status2 = arg;
13447
+ status3 = arg;
13448
13448
  if (i !== 0) {
13449
13449
  deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
13450
13450
  }
@@ -13454,20 +13454,20 @@ var require_http_errors2 = __commonJS({
13454
13454
  break;
13455
13455
  }
13456
13456
  }
13457
- if (typeof status2 === "number" && (status2 < 400 || status2 >= 600)) {
13457
+ if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
13458
13458
  deprecate2("non-error status code; use only 4xx or 5xx status codes");
13459
13459
  }
13460
- if (typeof status2 !== "number" || !statuses[status2] && (status2 < 400 || status2 >= 600)) {
13461
- status2 = 500;
13460
+ if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
13461
+ status3 = 500;
13462
13462
  }
13463
- var HttpError3 = createError[status2] || createError[codeClass(status2)];
13463
+ var HttpError3 = createError[status3] || createError[codeClass(status3)];
13464
13464
  if (!err) {
13465
- err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status2]);
13465
+ err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
13466
13466
  Error.captureStackTrace(err, createError);
13467
13467
  }
13468
- if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status2) {
13469
- err.expose = status2 < 500;
13470
- err.status = err.statusCode = status2;
13468
+ if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
13469
+ err.expose = status3 < 500;
13470
+ err.status = err.statusCode = status3;
13471
13471
  }
13472
13472
  for (var key in props) {
13473
13473
  if (key !== "status" && key !== "statusCode") {
@@ -13698,33 +13698,33 @@ var require_http_assert = __commonJS({
13698
13698
  var createError = require_http_errors2();
13699
13699
  var eql = require_deep_equal();
13700
13700
  module2.exports = assert;
13701
- function assert(value, status2, msg, opts) {
13701
+ function assert(value, status3, msg, opts) {
13702
13702
  if (value) return;
13703
- throw createError(status2, msg, opts);
13703
+ throw createError(status3, msg, opts);
13704
13704
  }
13705
- assert.fail = function(status2, msg, opts) {
13706
- assert(false, status2, msg, opts);
13705
+ assert.fail = function(status3, msg, opts) {
13706
+ assert(false, status3, msg, opts);
13707
13707
  };
13708
- assert.equal = function(a, b, status2, msg, opts) {
13709
- assert(a == b, status2, msg, opts);
13708
+ assert.equal = function(a, b, status3, msg, opts) {
13709
+ assert(a == b, status3, msg, opts);
13710
13710
  };
13711
- assert.notEqual = function(a, b, status2, msg, opts) {
13712
- assert(a != b, status2, msg, opts);
13711
+ assert.notEqual = function(a, b, status3, msg, opts) {
13712
+ assert(a != b, status3, msg, opts);
13713
13713
  };
13714
- assert.ok = function(value, status2, msg, opts) {
13715
- assert(value, status2, msg, opts);
13714
+ assert.ok = function(value, status3, msg, opts) {
13715
+ assert(value, status3, msg, opts);
13716
13716
  };
13717
- assert.strictEqual = function(a, b, status2, msg, opts) {
13718
- assert(a === b, status2, msg, opts);
13717
+ assert.strictEqual = function(a, b, status3, msg, opts) {
13718
+ assert(a === b, status3, msg, opts);
13719
13719
  };
13720
- assert.notStrictEqual = function(a, b, status2, msg, opts) {
13721
- assert(a !== b, status2, msg, opts);
13720
+ assert.notStrictEqual = function(a, b, status3, msg, opts) {
13721
+ assert(a !== b, status3, msg, opts);
13722
13722
  };
13723
- assert.deepEqual = function(a, b, status2, msg, opts) {
13724
- assert(eql(a, b), status2, msg, opts);
13723
+ assert.deepEqual = function(a, b, status3, msg, opts) {
13724
+ assert(eql(a, b), status3, msg, opts);
13725
13725
  };
13726
- assert.notDeepEqual = function(a, b, status2, msg, opts) {
13727
- assert(!eql(a, b), status2, msg, opts);
13726
+ assert.notDeepEqual = function(a, b, status3, msg, opts) {
13727
+ assert(!eql(a, b), status3, msg, opts);
13728
13728
  };
13729
13729
  }
13730
13730
  });
@@ -15301,24 +15301,24 @@ var require_fresh = __commonJS({
15301
15301
  function parseTokenList(str2) {
15302
15302
  var end = 0;
15303
15303
  var list6 = [];
15304
- var start3 = 0;
15304
+ var start4 = 0;
15305
15305
  for (var i = 0, len = str2.length; i < len; i++) {
15306
15306
  switch (str2.charCodeAt(i)) {
15307
15307
  case 32:
15308
- if (start3 === end) {
15309
- start3 = end = i + 1;
15308
+ if (start4 === end) {
15309
+ start4 = end = i + 1;
15310
15310
  }
15311
15311
  break;
15312
15312
  case 44:
15313
- list6.push(str2.substring(start3, end));
15314
- start3 = end = i + 1;
15313
+ list6.push(str2.substring(start4, end));
15314
+ start4 = end = i + 1;
15315
15315
  break;
15316
15316
  default:
15317
15317
  end = i + 1;
15318
15318
  break;
15319
15319
  }
15320
15320
  }
15321
- list6.push(str2.substring(start3, end));
15321
+ list6.push(str2.substring(start4, end));
15322
15322
  return list6;
15323
15323
  }
15324
15324
  }
@@ -15958,9 +15958,9 @@ var require_co = __commonJS({
15958
15958
  function co(gen) {
15959
15959
  var ctx = this;
15960
15960
  var args2 = slice.call(arguments, 1);
15961
- return new Promise(function(resolve10, reject) {
15961
+ return new Promise(function(resolve11, reject) {
15962
15962
  if (typeof gen === "function") gen = gen.apply(ctx, args2);
15963
- if (!gen || typeof gen.next !== "function") return resolve10(gen);
15963
+ if (!gen || typeof gen.next !== "function") return resolve11(gen);
15964
15964
  onFulfilled();
15965
15965
  function onFulfilled(res) {
15966
15966
  var ret;
@@ -15981,7 +15981,7 @@ var require_co = __commonJS({
15981
15981
  next(ret);
15982
15982
  }
15983
15983
  function next(ret) {
15984
- if (ret.done) return resolve10(ret.value);
15984
+ if (ret.done) return resolve11(ret.value);
15985
15985
  var value = toPromise.call(ctx, ret.value);
15986
15986
  if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
15987
15987
  return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, but the following object was passed: "' + String(ret.value) + '"'));
@@ -15999,11 +15999,11 @@ var require_co = __commonJS({
15999
15999
  }
16000
16000
  function thunkToPromise(fn2) {
16001
16001
  var ctx = this;
16002
- return new Promise(function(resolve10, reject) {
16002
+ return new Promise(function(resolve11, reject) {
16003
16003
  fn2.call(ctx, function(err, res) {
16004
16004
  if (err) return reject(err);
16005
16005
  if (arguments.length > 2) res = slice.call(arguments, 1);
16006
- resolve10(res);
16006
+ resolve11(res);
16007
16007
  });
16008
16008
  });
16009
16009
  }
@@ -16640,11 +16640,11 @@ var require_statuses3 = __commonJS({
16640
16640
  "node_modules/statuses/index.js"(exports2, module2) {
16641
16641
  "use strict";
16642
16642
  var codes = require_codes3();
16643
- module2.exports = status2;
16644
- status2.message = codes;
16645
- status2.code = createMessageToStatusCodeMap(codes);
16646
- status2.codes = createStatusCodeList(codes);
16647
- status2.redirect = {
16643
+ module2.exports = status3;
16644
+ status3.message = codes;
16645
+ status3.code = createMessageToStatusCodeMap(codes);
16646
+ status3.codes = createStatusCodeList(codes);
16647
+ status3.redirect = {
16648
16648
  300: true,
16649
16649
  301: true,
16650
16650
  302: true,
@@ -16653,12 +16653,12 @@ var require_statuses3 = __commonJS({
16653
16653
  307: true,
16654
16654
  308: true
16655
16655
  };
16656
- status2.empty = {
16656
+ status3.empty = {
16657
16657
  204: true,
16658
16658
  205: true,
16659
16659
  304: true
16660
16660
  };
16661
- status2.retry = {
16661
+ status3.retry = {
16662
16662
  502: true,
16663
16663
  503: true,
16664
16664
  504: true
@@ -16667,8 +16667,8 @@ var require_statuses3 = __commonJS({
16667
16667
  var map2 = {};
16668
16668
  Object.keys(codes2).forEach(function forEachCode(code) {
16669
16669
  var message2 = codes2[code];
16670
- var status3 = Number(code);
16671
- map2[message2.toLowerCase()] = status3;
16670
+ var status4 = Number(code);
16671
+ map2[message2.toLowerCase()] = status4;
16672
16672
  });
16673
16673
  return map2;
16674
16674
  }
@@ -16679,18 +16679,18 @@ var require_statuses3 = __commonJS({
16679
16679
  }
16680
16680
  function getStatusCode(message2) {
16681
16681
  var msg = message2.toLowerCase();
16682
- if (!Object.prototype.hasOwnProperty.call(status2.code, msg)) {
16682
+ if (!Object.prototype.hasOwnProperty.call(status3.code, msg)) {
16683
16683
  throw new Error('invalid status message: "' + message2 + '"');
16684
16684
  }
16685
- return status2.code[msg];
16685
+ return status3.code[msg];
16686
16686
  }
16687
16687
  function getStatusMessage(code) {
16688
- if (!Object.prototype.hasOwnProperty.call(status2.message, code)) {
16688
+ if (!Object.prototype.hasOwnProperty.call(status3.message, code)) {
16689
16689
  throw new Error("invalid status code: " + code);
16690
16690
  }
16691
- return status2.message[code];
16691
+ return status3.message[code];
16692
16692
  }
16693
- function status2(code) {
16693
+ function status3(code) {
16694
16694
  if (typeof code === "number") {
16695
16695
  return getStatusMessage(code);
16696
16696
  }
@@ -16719,22 +16719,22 @@ var require_http_errors3 = __commonJS({
16719
16719
  module2.exports.HttpError = createHttpErrorConstructor();
16720
16720
  module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
16721
16721
  populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
16722
- function codeClass(status2) {
16723
- return Number(String(status2).charAt(0) + "00");
16722
+ function codeClass(status3) {
16723
+ return Number(String(status3).charAt(0) + "00");
16724
16724
  }
16725
16725
  function createError() {
16726
16726
  var err;
16727
16727
  var msg;
16728
- var status2 = 500;
16728
+ var status3 = 500;
16729
16729
  var props = {};
16730
16730
  for (var i = 0; i < arguments.length; i++) {
16731
16731
  var arg = arguments[i];
16732
16732
  var type2 = typeof arg;
16733
16733
  if (type2 === "object" && arg instanceof Error) {
16734
16734
  err = arg;
16735
- status2 = err.status || err.statusCode || status2;
16735
+ status3 = err.status || err.statusCode || status3;
16736
16736
  } else if (type2 === "number" && i === 0) {
16737
- status2 = arg;
16737
+ status3 = arg;
16738
16738
  } else if (type2 === "string") {
16739
16739
  msg = arg;
16740
16740
  } else if (type2 === "object") {
@@ -16743,20 +16743,20 @@ var require_http_errors3 = __commonJS({
16743
16743
  throw new TypeError("argument #" + (i + 1) + " unsupported type " + type2);
16744
16744
  }
16745
16745
  }
16746
- if (typeof status2 === "number" && (status2 < 400 || status2 >= 600)) {
16746
+ if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
16747
16747
  deprecate2("non-error status code; use only 4xx or 5xx status codes");
16748
16748
  }
16749
- if (typeof status2 !== "number" || !statuses.message[status2] && (status2 < 400 || status2 >= 600)) {
16750
- status2 = 500;
16749
+ if (typeof status3 !== "number" || !statuses.message[status3] && (status3 < 400 || status3 >= 600)) {
16750
+ status3 = 500;
16751
16751
  }
16752
- var HttpError3 = createError[status2] || createError[codeClass(status2)];
16752
+ var HttpError3 = createError[status3] || createError[codeClass(status3)];
16753
16753
  if (!err) {
16754
- err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses.message[status2]);
16754
+ err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses.message[status3]);
16755
16755
  Error.captureStackTrace(err, createError);
16756
16756
  }
16757
- if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status2) {
16758
- err.expose = status2 < 500;
16759
- err.status = err.statusCode = status2;
16757
+ if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
16758
+ err.expose = status3 < 500;
16759
+ err.status = err.statusCode = status3;
16760
16760
  }
16761
16761
  for (var key in props) {
16762
16762
  if (key !== "status" && key !== "statusCode") {
@@ -20060,13 +20060,13 @@ var require_extend_node = __commonJS({
20060
20060
  };
20061
20061
  var SlowBuffer = require("buffer").SlowBuffer;
20062
20062
  original.SlowBufferToString = SlowBuffer.prototype.toString;
20063
- SlowBuffer.prototype.toString = function(encoding, start3, end) {
20063
+ SlowBuffer.prototype.toString = function(encoding, start4, end) {
20064
20064
  encoding = String(encoding || "utf8").toLowerCase();
20065
20065
  if (Buffer2.isNativeEncoding(encoding))
20066
- return original.SlowBufferToString.call(this, encoding, start3, end);
20067
- if (typeof start3 == "undefined") start3 = 0;
20066
+ return original.SlowBufferToString.call(this, encoding, start4, end);
20067
+ if (typeof start4 == "undefined") start4 = 0;
20068
20068
  if (typeof end == "undefined") end = this.length;
20069
- return iconv.decode(this.slice(start3, end), encoding);
20069
+ return iconv.decode(this.slice(start4, end), encoding);
20070
20070
  };
20071
20071
  original.SlowBufferWrite = SlowBuffer.prototype.write;
20072
20072
  SlowBuffer.prototype.write = function(string, offset, length, encoding) {
@@ -20113,13 +20113,13 @@ var require_extend_node = __commonJS({
20113
20113
  return iconv.encode(str2, encoding).length;
20114
20114
  };
20115
20115
  original.BufferToString = Buffer2.prototype.toString;
20116
- Buffer2.prototype.toString = function(encoding, start3, end) {
20116
+ Buffer2.prototype.toString = function(encoding, start4, end) {
20117
20117
  encoding = String(encoding || "utf8").toLowerCase();
20118
20118
  if (Buffer2.isNativeEncoding(encoding))
20119
- return original.BufferToString.call(this, encoding, start3, end);
20120
- if (typeof start3 == "undefined") start3 = 0;
20119
+ return original.BufferToString.call(this, encoding, start4, end);
20120
+ if (typeof start4 == "undefined") start4 = 0;
20121
20121
  if (typeof end == "undefined") end = this.length;
20122
- return iconv.decode(this.slice(start3, end), encoding);
20122
+ return iconv.decode(this.slice(start4, end), encoding);
20123
20123
  };
20124
20124
  original.BufferWrite = Buffer2.prototype.write;
20125
20125
  Buffer2.prototype.write = function(string, offset, length, encoding) {
@@ -20381,10 +20381,10 @@ var require_raw_body = __commonJS({
20381
20381
  if (done) {
20382
20382
  return readStream2(stream4, encoding, length, limit, wrap(done));
20383
20383
  }
20384
- return new Promise(function executor(resolve10, reject) {
20384
+ return new Promise(function executor(resolve11, reject) {
20385
20385
  readStream2(stream4, encoding, length, limit, function onRead(err, buf) {
20386
20386
  if (err) return reject(err);
20387
- resolve10(buf);
20387
+ resolve11(buf);
20388
20388
  });
20389
20389
  });
20390
20390
  }
@@ -22852,8 +22852,8 @@ var require_lodash = __commonJS({
22852
22852
  }
22853
22853
  assignMergeValue(object, key, newValue);
22854
22854
  }
22855
- function baseRest(func, start3) {
22856
- return setToString(overRest(func, start3, identity), func + "");
22855
+ function baseRest(func, start4) {
22856
+ return setToString(overRest(func, start4, identity), func + "");
22857
22857
  }
22858
22858
  var baseSetToString = !defineProperty ? identity : function(func, string) {
22859
22859
  return defineProperty(func, "toString", {
@@ -23002,19 +23002,19 @@ var require_lodash = __commonJS({
23002
23002
  function objectToString(value) {
23003
23003
  return nativeObjectToString.call(value);
23004
23004
  }
23005
- function overRest(func, start3, transform) {
23006
- start3 = nativeMax(start3 === void 0 ? func.length - 1 : start3, 0);
23005
+ function overRest(func, start4, transform) {
23006
+ start4 = nativeMax(start4 === void 0 ? func.length - 1 : start4, 0);
23007
23007
  return function() {
23008
- var args2 = arguments, index = -1, length = nativeMax(args2.length - start3, 0), array = Array(length);
23008
+ var args2 = arguments, index = -1, length = nativeMax(args2.length - start4, 0), array = Array(length);
23009
23009
  while (++index < length) {
23010
- array[index] = args2[start3 + index];
23010
+ array[index] = args2[start4 + index];
23011
23011
  }
23012
23012
  index = -1;
23013
- var otherArgs = Array(start3 + 1);
23014
- while (++index < start3) {
23013
+ var otherArgs = Array(start4 + 1);
23014
+ while (++index < start4) {
23015
23015
  otherArgs[index] = args2[index];
23016
23016
  }
23017
- otherArgs[start3] = transform(array);
23017
+ otherArgs[start4] = transform(array);
23018
23018
  return apply(func, this, otherArgs);
23019
23019
  };
23020
23020
  }
@@ -24001,10 +24001,10 @@ var require_statuses4 = __commonJS({
24001
24001
  "node_modules/resolve-path/node_modules/statuses/index.js"(exports2, module2) {
24002
24002
  "use strict";
24003
24003
  var codes = require_codes4();
24004
- module2.exports = status2;
24005
- status2.STATUS_CODES = codes;
24006
- status2.codes = populateStatusesMap(status2, codes);
24007
- status2.redirect = {
24004
+ module2.exports = status3;
24005
+ status3.STATUS_CODES = codes;
24006
+ status3.codes = populateStatusesMap(status3, codes);
24007
+ status3.redirect = {
24008
24008
  300: true,
24009
24009
  301: true,
24010
24010
  302: true,
@@ -24013,12 +24013,12 @@ var require_statuses4 = __commonJS({
24013
24013
  307: true,
24014
24014
  308: true
24015
24015
  };
24016
- status2.empty = {
24016
+ status3.empty = {
24017
24017
  204: true,
24018
24018
  205: true,
24019
24019
  304: true
24020
24020
  };
24021
- status2.retry = {
24021
+ status3.retry = {
24022
24022
  502: true,
24023
24023
  503: true,
24024
24024
  504: true
@@ -24027,17 +24027,17 @@ var require_statuses4 = __commonJS({
24027
24027
  var arr = [];
24028
24028
  Object.keys(codes2).forEach(function forEachCode(code) {
24029
24029
  var message2 = codes2[code];
24030
- var status3 = Number(code);
24031
- statuses[status3] = message2;
24032
- statuses[message2] = status3;
24033
- statuses[message2.toLowerCase()] = status3;
24034
- arr.push(status3);
24030
+ var status4 = Number(code);
24031
+ statuses[status4] = message2;
24032
+ statuses[message2] = status4;
24033
+ statuses[message2.toLowerCase()] = status4;
24034
+ arr.push(status4);
24035
24035
  });
24036
24036
  return arr;
24037
24037
  }
24038
- function status2(code) {
24038
+ function status3(code) {
24039
24039
  if (typeof code === "number") {
24040
- if (!status2[code]) throw new Error("invalid status code: " + code);
24040
+ if (!status3[code]) throw new Error("invalid status code: " + code);
24041
24041
  return code;
24042
24042
  }
24043
24043
  if (typeof code !== "string") {
@@ -24045,10 +24045,10 @@ var require_statuses4 = __commonJS({
24045
24045
  }
24046
24046
  var n = parseInt(code, 10);
24047
24047
  if (!isNaN(n)) {
24048
- if (!status2[n]) throw new Error("invalid status code: " + n);
24048
+ if (!status3[n]) throw new Error("invalid status code: " + n);
24049
24049
  return n;
24050
24050
  }
24051
- n = status2[code.toLowerCase()];
24051
+ n = status3[code.toLowerCase()];
24052
24052
  if (!n) throw new Error('invalid status message: "' + code + '"');
24053
24053
  return n;
24054
24054
  }
@@ -24108,19 +24108,19 @@ var require_http_errors4 = __commonJS({
24108
24108
  module2.exports = createError;
24109
24109
  module2.exports.HttpError = createHttpErrorConstructor();
24110
24110
  populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
24111
- function codeClass(status2) {
24112
- return Number(String(status2).charAt(0) + "00");
24111
+ function codeClass(status3) {
24112
+ return Number(String(status3).charAt(0) + "00");
24113
24113
  }
24114
24114
  function createError() {
24115
24115
  var err;
24116
24116
  var msg;
24117
- var status2 = 500;
24117
+ var status3 = 500;
24118
24118
  var props = {};
24119
24119
  for (var i = 0; i < arguments.length; i++) {
24120
24120
  var arg = arguments[i];
24121
24121
  if (arg instanceof Error) {
24122
24122
  err = arg;
24123
- status2 = err.status || err.statusCode || status2;
24123
+ status3 = err.status || err.statusCode || status3;
24124
24124
  continue;
24125
24125
  }
24126
24126
  switch (typeof arg) {
@@ -24128,7 +24128,7 @@ var require_http_errors4 = __commonJS({
24128
24128
  msg = arg;
24129
24129
  break;
24130
24130
  case "number":
24131
- status2 = arg;
24131
+ status3 = arg;
24132
24132
  if (i !== 0) {
24133
24133
  deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
24134
24134
  }
@@ -24138,20 +24138,20 @@ var require_http_errors4 = __commonJS({
24138
24138
  break;
24139
24139
  }
24140
24140
  }
24141
- if (typeof status2 === "number" && (status2 < 400 || status2 >= 600)) {
24141
+ if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
24142
24142
  deprecate2("non-error status code; use only 4xx or 5xx status codes");
24143
24143
  }
24144
- if (typeof status2 !== "number" || !statuses[status2] && (status2 < 400 || status2 >= 600)) {
24145
- status2 = 500;
24144
+ if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
24145
+ status3 = 500;
24146
24146
  }
24147
- var HttpError3 = createError[status2] || createError[codeClass(status2)];
24147
+ var HttpError3 = createError[status3] || createError[codeClass(status3)];
24148
24148
  if (!err) {
24149
- err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status2]);
24149
+ err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
24150
24150
  Error.captureStackTrace(err, createError);
24151
24151
  }
24152
- if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status2) {
24153
- err.expose = status2 < 500;
24154
- err.status = err.statusCode = status2;
24152
+ if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
24153
+ err.expose = status3 < 500;
24154
+ err.status = err.statusCode = status3;
24155
24155
  }
24156
24156
  for (var key in props) {
24157
24157
  if (key !== "status" && key !== "statusCode") {
@@ -24277,9 +24277,9 @@ var require_resolve_path = __commonJS({
24277
24277
  "use strict";
24278
24278
  var createError = require_http_errors4();
24279
24279
  var join14 = require("path").join;
24280
- var normalize = require("path").normalize;
24280
+ var normalize2 = require("path").normalize;
24281
24281
  var pathIsAbsolute = require_path_is_absolute();
24282
- var resolve10 = require("path").resolve;
24282
+ var resolve11 = require("path").resolve;
24283
24283
  var sep = require("path").sep;
24284
24284
  module2.exports = resolvePath;
24285
24285
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
@@ -24308,10 +24308,10 @@ var require_resolve_path = __commonJS({
24308
24308
  if (pathIsAbsolute.posix(path) || pathIsAbsolute.win32(path)) {
24309
24309
  throw createError(400, "Malicious Path");
24310
24310
  }
24311
- if (UP_PATH_REGEXP.test(normalize("." + sep + path))) {
24311
+ if (UP_PATH_REGEXP.test(normalize2("." + sep + path))) {
24312
24312
  throw createError(403);
24313
24313
  }
24314
- return normalize(join14(resolve10(root), path));
24314
+ return normalize2(join14(resolve11(root), path));
24315
24315
  }
24316
24316
  }
24317
24317
  });
@@ -24819,10 +24819,10 @@ var require_statuses5 = __commonJS({
24819
24819
  "node_modules/koa-send/node_modules/statuses/index.js"(exports2, module2) {
24820
24820
  "use strict";
24821
24821
  var codes = require_codes5();
24822
- module2.exports = status2;
24823
- status2.STATUS_CODES = codes;
24824
- status2.codes = populateStatusesMap(status2, codes);
24825
- status2.redirect = {
24822
+ module2.exports = status3;
24823
+ status3.STATUS_CODES = codes;
24824
+ status3.codes = populateStatusesMap(status3, codes);
24825
+ status3.redirect = {
24826
24826
  300: true,
24827
24827
  301: true,
24828
24828
  302: true,
@@ -24831,12 +24831,12 @@ var require_statuses5 = __commonJS({
24831
24831
  307: true,
24832
24832
  308: true
24833
24833
  };
24834
- status2.empty = {
24834
+ status3.empty = {
24835
24835
  204: true,
24836
24836
  205: true,
24837
24837
  304: true
24838
24838
  };
24839
- status2.retry = {
24839
+ status3.retry = {
24840
24840
  502: true,
24841
24841
  503: true,
24842
24842
  504: true
@@ -24845,17 +24845,17 @@ var require_statuses5 = __commonJS({
24845
24845
  var arr = [];
24846
24846
  Object.keys(codes2).forEach(function forEachCode(code) {
24847
24847
  var message2 = codes2[code];
24848
- var status3 = Number(code);
24849
- statuses[status3] = message2;
24850
- statuses[message2] = status3;
24851
- statuses[message2.toLowerCase()] = status3;
24852
- arr.push(status3);
24848
+ var status4 = Number(code);
24849
+ statuses[status4] = message2;
24850
+ statuses[message2] = status4;
24851
+ statuses[message2.toLowerCase()] = status4;
24852
+ arr.push(status4);
24853
24853
  });
24854
24854
  return arr;
24855
24855
  }
24856
- function status2(code) {
24856
+ function status3(code) {
24857
24857
  if (typeof code === "number") {
24858
- if (!status2[code]) throw new Error("invalid status code: " + code);
24858
+ if (!status3[code]) throw new Error("invalid status code: " + code);
24859
24859
  return code;
24860
24860
  }
24861
24861
  if (typeof code !== "string") {
@@ -24863,10 +24863,10 @@ var require_statuses5 = __commonJS({
24863
24863
  }
24864
24864
  var n = parseInt(code, 10);
24865
24865
  if (!isNaN(n)) {
24866
- if (!status2[n]) throw new Error("invalid status code: " + n);
24866
+ if (!status3[n]) throw new Error("invalid status code: " + n);
24867
24867
  return n;
24868
24868
  }
24869
- n = status2[code.toLowerCase()];
24869
+ n = status3[code.toLowerCase()];
24870
24870
  if (!n) throw new Error('invalid status message: "' + code + '"');
24871
24871
  return n;
24872
24872
  }
@@ -24886,19 +24886,19 @@ var require_http_errors5 = __commonJS({
24886
24886
  module2.exports.HttpError = createHttpErrorConstructor();
24887
24887
  module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
24888
24888
  populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
24889
- function codeClass(status2) {
24890
- return Number(String(status2).charAt(0) + "00");
24889
+ function codeClass(status3) {
24890
+ return Number(String(status3).charAt(0) + "00");
24891
24891
  }
24892
24892
  function createError() {
24893
24893
  var err;
24894
24894
  var msg;
24895
- var status2 = 500;
24895
+ var status3 = 500;
24896
24896
  var props = {};
24897
24897
  for (var i = 0; i < arguments.length; i++) {
24898
24898
  var arg = arguments[i];
24899
24899
  if (arg instanceof Error) {
24900
24900
  err = arg;
24901
- status2 = err.status || err.statusCode || status2;
24901
+ status3 = err.status || err.statusCode || status3;
24902
24902
  continue;
24903
24903
  }
24904
24904
  switch (typeof arg) {
@@ -24906,7 +24906,7 @@ var require_http_errors5 = __commonJS({
24906
24906
  msg = arg;
24907
24907
  break;
24908
24908
  case "number":
24909
- status2 = arg;
24909
+ status3 = arg;
24910
24910
  if (i !== 0) {
24911
24911
  deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
24912
24912
  }
@@ -24916,20 +24916,20 @@ var require_http_errors5 = __commonJS({
24916
24916
  break;
24917
24917
  }
24918
24918
  }
24919
- if (typeof status2 === "number" && (status2 < 400 || status2 >= 600)) {
24919
+ if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
24920
24920
  deprecate2("non-error status code; use only 4xx or 5xx status codes");
24921
24921
  }
24922
- if (typeof status2 !== "number" || !statuses[status2] && (status2 < 400 || status2 >= 600)) {
24923
- status2 = 500;
24922
+ if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
24923
+ status3 = 500;
24924
24924
  }
24925
- var HttpError3 = createError[status2] || createError[codeClass(status2)];
24925
+ var HttpError3 = createError[status3] || createError[codeClass(status3)];
24926
24926
  if (!err) {
24927
- err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status2]);
24927
+ err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
24928
24928
  Error.captureStackTrace(err, createError);
24929
24929
  }
24930
- if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status2) {
24931
- err.expose = status2 < 500;
24932
- err.status = err.statusCode = status2;
24930
+ if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
24931
+ err.expose = status3 < 500;
24932
+ err.status = err.statusCode = status3;
24933
24933
  }
24934
24934
  for (var key in props) {
24935
24935
  if (key !== "status" && key !== "statusCode") {
@@ -25067,10 +25067,10 @@ var require_koa_send = __commonJS({
25067
25067
  }
25068
25068
  }
25069
25069
  var {
25070
- normalize,
25071
- basename: basename2,
25072
- extname,
25073
- resolve: resolve10,
25070
+ normalize: normalize2,
25071
+ basename: basename4,
25072
+ extname: extname2,
25073
+ resolve: resolve11,
25074
25074
  parse: parse2,
25075
25075
  sep
25076
25076
  } = require("path");
@@ -25079,7 +25079,7 @@ var require_koa_send = __commonJS({
25079
25079
  assert(ctx, "koa context required");
25080
25080
  assert(path, "pathname required");
25081
25081
  debug2('send "%s" %j', path, opts);
25082
- const root = opts.root ? normalize(resolve10(opts.root)) : "";
25082
+ const root = opts.root ? normalize2(resolve11(opts.root)) : "";
25083
25083
  const trailingSlash = path[path.length - 1] === "/";
25084
25084
  path = path.substr(parse2(path).root.length);
25085
25085
  const index = opts.index;
@@ -25111,7 +25111,7 @@ var require_koa_send = __commonJS({
25111
25111
  ctx.res.removeHeader("Content-Length");
25112
25112
  encodingExt = ".gz";
25113
25113
  }
25114
- if (extensions && !/\./.exec(basename2(path))) {
25114
+ if (extensions && !/\./.exec(basename4(path))) {
25115
25115
  const list6 = [].concat(extensions);
25116
25116
  for (let i = 0; i < list6.length; i++) {
25117
25117
  let ext = list6[i];
@@ -25166,7 +25166,7 @@ var require_koa_send = __commonJS({
25166
25166
  return false;
25167
25167
  }
25168
25168
  function type2(file, ext) {
25169
- return ext !== "" ? extname(basename2(file, ext)) : extname(file);
25169
+ return ext !== "" ? extname2(basename4(file, ext)) : extname2(file);
25170
25170
  }
25171
25171
  function decode(path) {
25172
25172
  try {
@@ -25183,7 +25183,7 @@ var require_koa_static = __commonJS({
25183
25183
  "node_modules/koa-static/index.js"(exports2, module2) {
25184
25184
  "use strict";
25185
25185
  var debug2 = require_src2()("koa-static");
25186
- var { resolve: resolve10 } = require("path");
25186
+ var { resolve: resolve11 } = require("path");
25187
25187
  var assert = require("assert");
25188
25188
  var send2 = require_koa_send();
25189
25189
  module2.exports = serve2;
@@ -25191,7 +25191,7 @@ var require_koa_static = __commonJS({
25191
25191
  opts = Object.assign({}, opts);
25192
25192
  assert(root, "root directory is required to serve files");
25193
25193
  debug2('static "%s" %j', root, opts);
25194
- opts.root = resolve10(root);
25194
+ opts.root = resolve11(root);
25195
25195
  if (opts.index !== false) opts.index = opts.index || "index.html";
25196
25196
  if (!opts.defer) {
25197
25197
  return async function serve3(ctx, next) {
@@ -25877,10 +25877,10 @@ function throwWarning(state, message2) {
25877
25877
  state.onWarning.call(null, generateError(state, message2));
25878
25878
  }
25879
25879
  }
25880
- function captureSegment(state, start3, end, checkJson) {
25880
+ function captureSegment(state, start4, end, checkJson) {
25881
25881
  var _position, _length, _character, _result;
25882
- if (start3 < end) {
25883
- _result = state.input.slice(start3, end);
25882
+ if (start4 < end) {
25883
+ _result = state.input.slice(start4, end);
25884
25884
  if (checkJson) {
25885
25885
  for (_position = 0, _length = _result.length; _position < _length; _position += 1) {
25886
25886
  _character = _result.charCodeAt(_position);
@@ -27105,22 +27105,22 @@ function foldLine(line, width) {
27105
27105
  if (line === "" || line[0] === " ") return line;
27106
27106
  var breakRe = / [^ ]/g;
27107
27107
  var match;
27108
- var start3 = 0, end, curr = 0, next = 0;
27108
+ var start4 = 0, end, curr = 0, next = 0;
27109
27109
  var result = "";
27110
27110
  while (match = breakRe.exec(line)) {
27111
27111
  next = match.index;
27112
- if (next - start3 > width) {
27113
- end = curr > start3 ? curr : next;
27114
- result += "\n" + line.slice(start3, end);
27115
- start3 = end + 1;
27112
+ if (next - start4 > width) {
27113
+ end = curr > start4 ? curr : next;
27114
+ result += "\n" + line.slice(start4, end);
27115
+ start4 = end + 1;
27116
27116
  }
27117
27117
  curr = next;
27118
27118
  }
27119
27119
  result += "\n";
27120
- if (line.length - start3 > width && curr > start3) {
27121
- result += line.slice(start3, curr) + "\n" + line.slice(curr + 1);
27120
+ if (line.length - start4 > width && curr > start4) {
27121
+ result += line.slice(start4, curr) + "\n" + line.slice(curr + 1);
27122
27122
  } else {
27123
- result += line.slice(start3);
27123
+ result += line.slice(start4);
27124
27124
  }
27125
27125
  return result.slice(1);
27126
27126
  }
@@ -28593,7 +28593,7 @@ var require_redact = __commonJS({
28593
28593
  }
28594
28594
  return cloneSelectively(obj, pathStructure);
28595
28595
  }
28596
- function validatePath(path) {
28596
+ function validatePath2(path) {
28597
28597
  if (typeof path !== "string") {
28598
28598
  throw new Error("Paths must be (non-empty) strings");
28599
28599
  }
@@ -28637,7 +28637,7 @@ var require_redact = __commonJS({
28637
28637
  throw new TypeError("paths must be an array");
28638
28638
  }
28639
28639
  for (const path of paths) {
28640
- validatePath(path);
28640
+ validatePath2(path);
28641
28641
  }
28642
28642
  }
28643
28643
  function slowRedact(options = {}) {
@@ -29101,7 +29101,7 @@ var require_sonic_boom = __commonJS({
29101
29101
  if (!(this instanceof SonicBoom)) {
29102
29102
  return new SonicBoom(opts);
29103
29103
  }
29104
- let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append: append2 = true, mkdir: mkdir5, retryEAGAIN, fsync, contentMode, mode } = opts || {};
29104
+ let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append: append2 = true, mkdir: mkdir6, retryEAGAIN, fsync, contentMode, mode } = opts || {};
29105
29105
  fd = fd || dest;
29106
29106
  this._len = 0;
29107
29107
  this.fd = -1;
@@ -29126,7 +29126,7 @@ var require_sonic_boom = __commonJS({
29126
29126
  this.append = append2 || false;
29127
29127
  this.mode = mode;
29128
29128
  this.retryEAGAIN = retryEAGAIN || (() => true);
29129
- this.mkdir = mkdir5 || false;
29129
+ this.mkdir = mkdir6 || false;
29130
29130
  let fsWriteSync;
29131
29131
  let fsWrite;
29132
29132
  if (contentMode === kContentModeBuffer) {
@@ -30257,9 +30257,9 @@ var require_transport = __commonJS({
30257
30257
  "node_modules/pino/lib/transport.js"(exports2, module2) {
30258
30258
  "use strict";
30259
30259
  var { createRequire } = require("module");
30260
- var { existsSync: existsSync14 } = require("node:fs");
30260
+ var { existsSync: existsSync16 } = require("node:fs");
30261
30261
  var getCallers = require_caller();
30262
- var { join: join14, isAbsolute, sep } = require("node:path");
30262
+ var { join: join14, isAbsolute: isAbsolute2, sep } = require("node:path");
30263
30263
  var { fileURLToPath } = require("node:url");
30264
30264
  var sleep = require_atomic_sleep();
30265
30265
  var onExit = require_on_exit_leak_free();
@@ -30331,7 +30331,7 @@ var require_transport = __commonJS({
30331
30331
  return false;
30332
30332
  }
30333
30333
  }
30334
- return isAbsolute(path) && !existsSync14(path);
30334
+ return isAbsolute2(path) && !existsSync16(path);
30335
30335
  }
30336
30336
  function stripQuotes(value) {
30337
30337
  const first = value[0];
@@ -30449,7 +30449,7 @@ var require_transport = __commonJS({
30449
30449
  return buildStream(fixTarget(target), options, worker, sync, name);
30450
30450
  function fixTarget(origin2) {
30451
30451
  origin2 = bundlerOverrides[origin2] || origin2;
30452
- if (isAbsolute(origin2) || origin2.indexOf("file://") === 0) {
30452
+ if (isAbsolute2(origin2) || origin2.indexOf("file://") === 0) {
30453
30453
  return origin2;
30454
30454
  }
30455
30455
  if (origin2 === "pino/file") {
@@ -32106,11 +32106,11 @@ var require_pino = __commonJS({
32106
32106
  depthLimit: 5,
32107
32107
  edgeLimit: 100
32108
32108
  };
32109
- var normalize = createArgsNormalizer(defaultOptions);
32109
+ var normalize2 = createArgsNormalizer(defaultOptions);
32110
32110
  var serializers = Object.assign(/* @__PURE__ */ Object.create(null), stdSerializers);
32111
32111
  function pino2(...args2) {
32112
32112
  const instance = {};
32113
- const { opts, stream: stream4 } = normalize(instance, caller(), ...args2);
32113
+ const { opts, stream: stream4 } = normalize2(instance, caller(), ...args2);
32114
32114
  if (opts.level && typeof opts.level === "string" && DEFAULT_LEVELS[opts.level.toLowerCase()] !== void 0) opts.level = opts.level.toLowerCase();
32115
32115
  const {
32116
32116
  redact,
@@ -32365,22 +32365,22 @@ var init_gateway_manager = __esm({
32365
32365
  /** 尝试绑定端口,检测端口是否被系统级进程占用 */
32366
32366
  checkPortAvailable(port, host) {
32367
32367
  if (port < 0 || port > 65535) return Promise.resolve(false);
32368
- return new Promise((resolve10) => {
32368
+ return new Promise((resolve11) => {
32369
32369
  const server2 = (0, import_net.createServer)();
32370
32370
  server2.once("error", () => {
32371
32371
  server2.close();
32372
- resolve10(false);
32372
+ resolve11(false);
32373
32373
  });
32374
32374
  server2.once("listening", () => {
32375
32375
  server2.close();
32376
- resolve10(true);
32376
+ resolve11(true);
32377
32377
  });
32378
32378
  server2.listen(port, host);
32379
32379
  });
32380
32380
  }
32381
32381
  /** 从 base 端口开始递增查找空闲端口(上限 65535) */
32382
32382
  findFreePort(base, host = "127.0.0.1") {
32383
- return new Promise((resolve10, reject) => {
32383
+ return new Promise((resolve11, reject) => {
32384
32384
  const tryPort = (port) => {
32385
32385
  if (port > 65535) {
32386
32386
  reject(new Error(`No free port found in range ${base}-65535`));
@@ -32393,7 +32393,7 @@ var init_gateway_manager = __esm({
32393
32393
  });
32394
32394
  server2.once("listening", () => {
32395
32395
  server2.close();
32396
- resolve10(port);
32396
+ resolve11(port);
32397
32397
  });
32398
32398
  server2.listen(port, host);
32399
32399
  };
@@ -32574,7 +32574,7 @@ var init_gateway_manager = __esm({
32574
32574
  const hermesHome = this.profileDir(name);
32575
32575
  const url2 = `http://${host}:${port}`;
32576
32576
  if (needsRunMode) {
32577
- return new Promise((resolve10, reject) => {
32577
+ return new Promise((resolve11, reject) => {
32578
32578
  const env2 = { ...process.env, HERMES_HOME: hermesHome };
32579
32579
  const child = (0, import_child_process.spawn)(HERMES_BIN, ["gateway", "run", "--replace"], {
32580
32580
  detached: true,
@@ -32585,7 +32585,7 @@ var init_gateway_manager = __esm({
32585
32585
  child.unref();
32586
32586
  const pid = child.pid ?? 0;
32587
32587
  logger.info('Starting gateway for profile "%s" (run mode, PID: %d, port: %d)', name, pid, port);
32588
- this.waitForReady(name, pid, port, host, url2).then(resolve10).catch(reject);
32588
+ this.waitForReady(name, pid, port, host, url2).then(resolve11).catch(reject);
32589
32589
  });
32590
32590
  }
32591
32591
  logger.info('Starting gateway for profile "%s" (start mode, port: %d)', name, port);
@@ -32690,9 +32690,9 @@ var init_gateway_manager = __esm({
32690
32690
  logger.info("Scanning profiles for running gateways...");
32691
32691
  const profiles = await this.listProfiles();
32692
32692
  for (const name of profiles) {
32693
- const status2 = await this.detectStatus(name);
32694
- if (status2.running) {
32695
- logger.info("%s: running (PID: %s, port: %d)", name, status2.pid, status2.port);
32693
+ const status3 = await this.detectStatus(name);
32694
+ if (status3.running) {
32695
+ logger.info("%s: running (PID: %s, port: %d)", name, status3.pid, status3.port);
32696
32696
  } else {
32697
32697
  logger.debug("%s: stopped", name);
32698
32698
  }
@@ -34852,7 +34852,7 @@ var require_extension = __commonJS({
34852
34852
  let inQuotes = false;
34853
34853
  let extensionName;
34854
34854
  let paramName;
34855
- let start3 = -1;
34855
+ let start4 = -1;
34856
34856
  let code = -1;
34857
34857
  let end = -1;
34858
34858
  let i = 0;
@@ -34860,45 +34860,45 @@ var require_extension = __commonJS({
34860
34860
  code = header.charCodeAt(i);
34861
34861
  if (extensionName === void 0) {
34862
34862
  if (end === -1 && tokenChars[code] === 1) {
34863
- if (start3 === -1) start3 = i;
34863
+ if (start4 === -1) start4 = i;
34864
34864
  } else if (i !== 0 && (code === 32 || code === 9)) {
34865
- if (end === -1 && start3 !== -1) end = i;
34865
+ if (end === -1 && start4 !== -1) end = i;
34866
34866
  } else if (code === 59 || code === 44) {
34867
- if (start3 === -1) {
34867
+ if (start4 === -1) {
34868
34868
  throw new SyntaxError(`Unexpected character at index ${i}`);
34869
34869
  }
34870
34870
  if (end === -1) end = i;
34871
- const name = header.slice(start3, end);
34871
+ const name = header.slice(start4, end);
34872
34872
  if (code === 44) {
34873
34873
  push(offers, name, params);
34874
34874
  params = /* @__PURE__ */ Object.create(null);
34875
34875
  } else {
34876
34876
  extensionName = name;
34877
34877
  }
34878
- start3 = end = -1;
34878
+ start4 = end = -1;
34879
34879
  } else {
34880
34880
  throw new SyntaxError(`Unexpected character at index ${i}`);
34881
34881
  }
34882
34882
  } else if (paramName === void 0) {
34883
34883
  if (end === -1 && tokenChars[code] === 1) {
34884
- if (start3 === -1) start3 = i;
34884
+ if (start4 === -1) start4 = i;
34885
34885
  } else if (code === 32 || code === 9) {
34886
- if (end === -1 && start3 !== -1) end = i;
34886
+ if (end === -1 && start4 !== -1) end = i;
34887
34887
  } else if (code === 59 || code === 44) {
34888
- if (start3 === -1) {
34888
+ if (start4 === -1) {
34889
34889
  throw new SyntaxError(`Unexpected character at index ${i}`);
34890
34890
  }
34891
34891
  if (end === -1) end = i;
34892
- push(params, header.slice(start3, end), true);
34892
+ push(params, header.slice(start4, end), true);
34893
34893
  if (code === 44) {
34894
34894
  push(offers, extensionName, params);
34895
34895
  params = /* @__PURE__ */ Object.create(null);
34896
34896
  extensionName = void 0;
34897
34897
  }
34898
- start3 = end = -1;
34899
- } else if (code === 61 && start3 !== -1 && end === -1) {
34900
- paramName = header.slice(start3, i);
34901
- start3 = end = -1;
34898
+ start4 = end = -1;
34899
+ } else if (code === 61 && start4 !== -1 && end === -1) {
34900
+ paramName = header.slice(start4, i);
34901
+ start4 = end = -1;
34902
34902
  } else {
34903
34903
  throw new SyntaxError(`Unexpected character at index ${i}`);
34904
34904
  }
@@ -34907,13 +34907,13 @@ var require_extension = __commonJS({
34907
34907
  if (tokenChars[code] !== 1) {
34908
34908
  throw new SyntaxError(`Unexpected character at index ${i}`);
34909
34909
  }
34910
- if (start3 === -1) start3 = i;
34910
+ if (start4 === -1) start4 = i;
34911
34911
  else if (!mustUnescape) mustUnescape = true;
34912
34912
  isEscaping = false;
34913
34913
  } else if (inQuotes) {
34914
34914
  if (tokenChars[code] === 1) {
34915
- if (start3 === -1) start3 = i;
34916
- } else if (code === 34 && start3 !== -1) {
34915
+ if (start4 === -1) start4 = i;
34916
+ } else if (code === 34 && start4 !== -1) {
34917
34917
  inQuotes = false;
34918
34918
  end = i;
34919
34919
  } else if (code === 92) {
@@ -34924,15 +34924,15 @@ var require_extension = __commonJS({
34924
34924
  } else if (code === 34 && header.charCodeAt(i - 1) === 61) {
34925
34925
  inQuotes = true;
34926
34926
  } else if (end === -1 && tokenChars[code] === 1) {
34927
- if (start3 === -1) start3 = i;
34928
- } else if (start3 !== -1 && (code === 32 || code === 9)) {
34927
+ if (start4 === -1) start4 = i;
34928
+ } else if (start4 !== -1 && (code === 32 || code === 9)) {
34929
34929
  if (end === -1) end = i;
34930
34930
  } else if (code === 59 || code === 44) {
34931
- if (start3 === -1) {
34931
+ if (start4 === -1) {
34932
34932
  throw new SyntaxError(`Unexpected character at index ${i}`);
34933
34933
  }
34934
34934
  if (end === -1) end = i;
34935
- let value = header.slice(start3, end);
34935
+ let value = header.slice(start4, end);
34936
34936
  if (mustUnescape) {
34937
34937
  value = value.replace(/\\/g, "");
34938
34938
  mustUnescape = false;
@@ -34944,17 +34944,17 @@ var require_extension = __commonJS({
34944
34944
  extensionName = void 0;
34945
34945
  }
34946
34946
  paramName = void 0;
34947
- start3 = end = -1;
34947
+ start4 = end = -1;
34948
34948
  } else {
34949
34949
  throw new SyntaxError(`Unexpected character at index ${i}`);
34950
34950
  }
34951
34951
  }
34952
34952
  }
34953
- if (start3 === -1 || inQuotes || code === 32 || code === 9) {
34953
+ if (start4 === -1 || inQuotes || code === 32 || code === 9) {
34954
34954
  throw new SyntaxError("Unexpected end of input");
34955
34955
  }
34956
34956
  if (end === -1) end = i;
34957
- const token = header.slice(start3, end);
34957
+ const token = header.slice(start4, end);
34958
34958
  if (extensionName === void 0) {
34959
34959
  push(offers, token, params);
34960
34960
  } else {
@@ -35979,34 +35979,34 @@ var require_subprotocol = __commonJS({
35979
35979
  var { tokenChars } = require_validation();
35980
35980
  function parse2(header) {
35981
35981
  const protocols = /* @__PURE__ */ new Set();
35982
- let start3 = -1;
35982
+ let start4 = -1;
35983
35983
  let end = -1;
35984
35984
  let i = 0;
35985
35985
  for (i; i < header.length; i++) {
35986
35986
  const code = header.charCodeAt(i);
35987
35987
  if (end === -1 && tokenChars[code] === 1) {
35988
- if (start3 === -1) start3 = i;
35988
+ if (start4 === -1) start4 = i;
35989
35989
  } else if (i !== 0 && (code === 32 || code === 9)) {
35990
- if (end === -1 && start3 !== -1) end = i;
35990
+ if (end === -1 && start4 !== -1) end = i;
35991
35991
  } else if (code === 44) {
35992
- if (start3 === -1) {
35992
+ if (start4 === -1) {
35993
35993
  throw new SyntaxError(`Unexpected character at index ${i}`);
35994
35994
  }
35995
35995
  if (end === -1) end = i;
35996
- const protocol2 = header.slice(start3, end);
35996
+ const protocol2 = header.slice(start4, end);
35997
35997
  if (protocols.has(protocol2)) {
35998
35998
  throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
35999
35999
  }
36000
36000
  protocols.add(protocol2);
36001
- start3 = end = -1;
36001
+ start4 = end = -1;
36002
36002
  } else {
36003
36003
  throw new SyntaxError(`Unexpected character at index ${i}`);
36004
36004
  }
36005
36005
  }
36006
- if (start3 === -1 || end !== -1) {
36006
+ if (start4 === -1 || end !== -1) {
36007
36007
  throw new SyntaxError("Unexpected end of input");
36008
36008
  }
36009
- const protocol = header.slice(start3, i);
36009
+ const protocol = header.slice(start4, i);
36010
36010
  if (protocols.has(protocol)) {
36011
36011
  throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
36012
36012
  }
@@ -38365,10 +38365,10 @@ function bindShutdown(server2) {
38365
38365
  logger.info("Shutting down (%s)...", signal);
38366
38366
  try {
38367
38367
  if (server2) {
38368
- await new Promise((resolve10) => {
38368
+ await new Promise((resolve11) => {
38369
38369
  server2.close(() => {
38370
38370
  logger.info("HTTP server closed");
38371
- resolve10();
38371
+ resolve11();
38372
38372
  });
38373
38373
  });
38374
38374
  }
@@ -40217,15 +40217,15 @@ function resolveHermesBin() {
40217
40217
  var HERMES_BIN2 = resolveHermesBin();
40218
40218
  function parseSessionExport(stdout) {
40219
40219
  const lines = stdout.trim().split("\n").filter(Boolean);
40220
- const sessions2 = [];
40220
+ const sessions3 = [];
40221
40221
  for (const line of lines) {
40222
40222
  try {
40223
40223
  const raw = JSON.parse(line);
40224
- sessions2.push(raw);
40224
+ sessions3.push(raw);
40225
40225
  } catch {
40226
40226
  }
40227
40227
  }
40228
- return sessions2;
40228
+ return sessions3;
40229
40229
  }
40230
40230
  async function exportSessionsRaw(source) {
40231
40231
  const args2 = ["sessions", "export", "-"];
@@ -40245,7 +40245,7 @@ async function exportSessionsRaw(source) {
40245
40245
  }
40246
40246
  async function listSessions(source, limit) {
40247
40247
  const raws = await exportSessionsRaw(source);
40248
- const sessions2 = [];
40248
+ const sessions3 = [];
40249
40249
  for (const raw of raws) {
40250
40250
  let title = raw.title;
40251
40251
  if (!title && raw.messages) {
@@ -40255,7 +40255,7 @@ async function listSessions(source, limit) {
40255
40255
  title = t + (String(firstUser.content).length > 40 ? "..." : "");
40256
40256
  }
40257
40257
  }
40258
- sessions2.push({
40258
+ sessions3.push({
40259
40259
  id: raw.id,
40260
40260
  source: raw.source,
40261
40261
  user_id: raw.user_id,
@@ -40277,11 +40277,11 @@ async function listSessions(source, limit) {
40277
40277
  cost_status: raw.cost_status || ""
40278
40278
  });
40279
40279
  }
40280
- sessions2.sort((a, b) => b.started_at - a.started_at);
40280
+ sessions3.sort((a, b) => b.started_at - a.started_at);
40281
40281
  if (limit && limit > 0) {
40282
- return sessions2.slice(0, limit);
40282
+ return sessions3.slice(0, limit);
40283
40283
  }
40284
- return sessions2;
40284
+ return sessions3;
40285
40285
  }
40286
40286
  async function getSession(id) {
40287
40287
  const args2 = ["sessions", "export", "-", "--session-id", id];
@@ -40590,11 +40590,11 @@ async function importProfile(archivePath, name) {
40590
40590
  }
40591
40591
 
40592
40592
  // packages/server/src/controllers/health.ts
40593
- var LOCAL_VERSION = true ? "0.4.3" : (() => {
40593
+ var LOCAL_VERSION = true ? "0.4.4" : (() => {
40594
40594
  try {
40595
- const { readFileSync: readFileSync10 } = null;
40596
- const { resolve: resolve10 } = null;
40597
- return JSON.parse(readFileSync10(resolve10(__dirname, "../../package.json"), "utf-8")).version;
40595
+ const { readFileSync: readFileSync12 } = null;
40596
+ const { resolve: resolve11 } = null;
40597
+ return JSON.parse(readFileSync12(resolve11(__dirname, "../../package.json"), "utf-8")).version;
40598
40598
  } catch {
40599
40599
  return "0.0.0";
40600
40600
  }
@@ -40602,8 +40602,8 @@ var LOCAL_VERSION = true ? "0.4.3" : (() => {
40602
40602
  var cachedLatestVersion = "";
40603
40603
  async function checkLatestVersion() {
40604
40604
  try {
40605
- const { readFileSync: readFileSync10 } = require("fs");
40606
- const pkg = JSON.parse(readFileSync10(resolve6(require("path").join(__dirname, "../../package.json")), "utf-8"));
40605
+ const { readFileSync: readFileSync12 } = require("fs");
40606
+ const pkg = JSON.parse(readFileSync12(resolve6(require("path").join(__dirname, "../../package.json")), "utf-8"));
40607
40607
  const name = pkg.name;
40608
40608
  const res = await fetch(`https://registry.npmjs.org/${name}/latest`, { signal: AbortSignal.timeout(1e4) });
40609
40609
  if (res.ok) {
@@ -40638,7 +40638,8 @@ async function healthCheck(ctx) {
40638
40638
  gateway: gatewayOk ? "running" : "stopped",
40639
40639
  webui_version: LOCAL_VERSION,
40640
40640
  webui_latest: cachedLatestVersion,
40641
- webui_update_available: cachedLatestVersion && cachedLatestVersion !== LOCAL_VERSION
40641
+ webui_update_available: cachedLatestVersion && cachedLatestVersion !== LOCAL_VERSION,
40642
+ node_version: process.versions.node
40642
40643
  };
40643
40644
  }
40644
40645
  function resolve6(p) {
@@ -40813,14 +40814,14 @@ async function handleUpload(ctx) {
40813
40814
  }
40814
40815
  function splitMultipart(raw, boundary) {
40815
40816
  const parts = [];
40816
- let start3 = 0;
40817
+ let start4 = 0;
40817
40818
  while (true) {
40818
- const idx = raw.indexOf(boundary, start3);
40819
+ const idx = raw.indexOf(boundary, start4);
40819
40820
  if (idx === -1) break;
40820
- if (start3 > 0) {
40821
- parts.push(raw.subarray(start3 + 2, idx));
40821
+ if (start4 > 0) {
40822
+ parts.push(raw.subarray(start4 + 2, idx));
40822
40823
  }
40823
- start3 = idx + boundary.length;
40824
+ start4 = idx + boundary.length;
40824
40825
  }
40825
40826
  return parts;
40826
40827
  }
@@ -41223,14 +41224,14 @@ function normalizeVisibleMessage(message2, session, index) {
41223
41224
  timestamp: timestamp2
41224
41225
  };
41225
41226
  }
41226
- function visibleMessagesForSessions(sessions2) {
41227
- return sessions2.flatMap((session) => sessionMessages(session).map((message2, index) => normalizeVisibleMessage({ ...message2, session_id: safeText(message2.session_id || session.id) }, session, index))).filter((message2) => !!message2).sort((a, b) => {
41227
+ function visibleMessagesForSessions(sessions3) {
41228
+ return sessions3.flatMap((session) => sessionMessages(session).map((message2, index) => normalizeVisibleMessage({ ...message2, session_id: safeText(message2.session_id || session.id) }, session, index))).filter((message2) => !!message2).sort((a, b) => {
41228
41229
  if (a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
41229
41230
  return String(a.id).localeCompare(String(b.id));
41230
41231
  });
41231
41232
  }
41232
- function hasVisibleHumanMessages(sessions2) {
41233
- return visibleMessagesForSessions(sessions2).length > 0;
41233
+ function hasVisibleHumanMessages(sessions3) {
41234
+ return visibleMessagesForSessions(sessions3).length > 0;
41234
41235
  }
41235
41236
  function toSummary(session) {
41236
41237
  return {
@@ -41308,10 +41309,10 @@ async function loadSessions(source) {
41308
41309
  async function listConversationSummaries(options = {}) {
41309
41310
  const humanOnly = options.humanOnly !== false;
41310
41311
  const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CONVERSATION_LIMIT;
41311
- const sessions2 = await loadSessions(options.source);
41312
- const byId = new Map(sessions2.map((session) => [session.id, session]));
41312
+ const sessions3 = await loadSessions(options.source);
41313
+ const byId = new Map(sessions3.map((session) => [session.id, session]));
41313
41314
  const childrenByParent = /* @__PURE__ */ new Map();
41314
- for (const session of sessions2) {
41315
+ for (const session of sessions3) {
41315
41316
  const key = session.parent_session_id ?? null;
41316
41317
  const siblings = childrenByParent.get(key) || [];
41317
41318
  siblings.push(session.id);
@@ -41319,18 +41320,18 @@ async function listConversationSummaries(options = {}) {
41319
41320
  }
41320
41321
  if (!humanOnly) {
41321
41322
  return sortByRecency(
41322
- sessions2.filter((session) => session.source !== "tool").map(toSummary)
41323
+ sessions3.filter((session) => session.source !== "tool").map(toSummary)
41323
41324
  ).slice(0, limit);
41324
41325
  }
41325
- const summaries = sessions2.filter((session) => isVisibleRoot(session, byId)).map((session) => aggregateSummary(session.id, byId, childrenByParent)).filter((summary) => !!summary);
41326
+ const summaries = sessions3.filter((session) => isVisibleRoot(session, byId)).map((session) => aggregateSummary(session.id, byId, childrenByParent)).filter((summary) => !!summary);
41326
41327
  return sortByRecency(summaries).slice(0, limit);
41327
41328
  }
41328
41329
  async function getConversationDetail(sessionId, options = {}) {
41329
41330
  const humanOnly = options.humanOnly !== false;
41330
- const sessions2 = await loadSessions(options.source);
41331
- const byId = new Map(sessions2.map((session) => [session.id, session]));
41331
+ const sessions3 = await loadSessions(options.source);
41332
+ const byId = new Map(sessions3.map((session) => [session.id, session]));
41332
41333
  const childrenByParent = /* @__PURE__ */ new Map();
41333
- for (const session of sessions2) {
41334
+ for (const session of sessions3) {
41334
41335
  const key = session.parent_session_id ?? null;
41335
41336
  const siblings = childrenByParent.get(key) || [];
41336
41337
  siblings.push(session.id);
@@ -41360,13 +41361,34 @@ async function getConversationDetail(sessionId, options = {}) {
41360
41361
  };
41361
41362
  }
41362
41363
 
41363
- // packages/server/src/db/hermes/sessions-db.ts
41364
+ // packages/server/src/db/hermes/conversations-db.ts
41364
41365
  init_hermes_profile();
41365
41366
  var SQLITE_AVAILABLE2 = (() => {
41366
41367
  const [major, minor] = process.versions.node.split(".").map(Number);
41367
41368
  return major > 22 || major === 22 && minor >= 5;
41368
41369
  })();
41369
- function sessionDbPath() {
41370
+ var LINEAGE_TOLERANCE_SECONDS2 = 3;
41371
+ var LIVE_WINDOW_SECONDS2 = 300;
41372
+ var DEFAULT_CONVERSATION_LIMIT2 = 200;
41373
+ var SYNTHETIC_USER_PREFIXES2 = [
41374
+ "[system:",
41375
+ "you've reached the maximum number of tool-calling iterations allowed.",
41376
+ "you have reached the maximum number of tool-calling iterations allowed."
41377
+ ];
41378
+ var VISIBLE_HUMAN_MESSAGE_SQL = `
41379
+ m.content IS NOT NULL
41380
+ AND m.content != ''
41381
+ AND (
41382
+ m.role = 'assistant'
41383
+ OR (
41384
+ m.role = 'user'
41385
+ AND LOWER(m.content) NOT LIKE '[system:%'
41386
+ AND LOWER(m.content) NOT LIKE 'you''ve reached the maximum number of tool-calling iterations allowed.%'
41387
+ AND LOWER(m.content) NOT LIKE 'you have reached the maximum number of tool-calling iterations allowed.%'
41388
+ )
41389
+ )
41390
+ `;
41391
+ function conversationDbPath() {
41370
41392
  return `${getActiveProfileDir()}/state.db`;
41371
41393
  }
41372
41394
  function normalizeNumber(value, fallback = 0) {
@@ -41383,19 +41405,80 @@ function normalizeNullableString(value) {
41383
41405
  if (value == null || value === "") return null;
41384
41406
  return String(value);
41385
41407
  }
41386
- function mapRow(row) {
41408
+ function safeText2(value) {
41409
+ if (typeof value === "string") return value;
41410
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
41411
+ return "";
41412
+ }
41413
+ function textFromContent2(value) {
41414
+ if (typeof value === "string") {
41415
+ const trimmed = value.trim();
41416
+ if (trimmed && (trimmed.startsWith("{") || trimmed.startsWith("["))) {
41417
+ try {
41418
+ const parsed = JSON.parse(trimmed);
41419
+ const nested = textFromContent2(parsed);
41420
+ if (nested) return nested;
41421
+ } catch {
41422
+ }
41423
+ }
41424
+ return value;
41425
+ }
41426
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
41427
+ if (Array.isArray(value)) {
41428
+ return value.map((item) => textFromContent2(item).trim()).filter(Boolean).join("\n");
41429
+ }
41430
+ if (!value || typeof value !== "object") return "";
41431
+ const record = value;
41432
+ for (const key of ["text", "content", "value"]) {
41433
+ const direct = record[key];
41434
+ if (typeof direct === "string") return direct;
41435
+ if (Array.isArray(direct)) {
41436
+ const nested = textFromContent2(direct);
41437
+ if (nested) return nested;
41438
+ }
41439
+ }
41440
+ for (const key of ["parts", "children", "items"]) {
41441
+ if (Array.isArray(record[key])) {
41442
+ const nested = textFromContent2(record[key]);
41443
+ if (nested) return nested;
41444
+ }
41445
+ }
41446
+ const flattened = Object.values(record).map((entry) => textFromContent2(entry).trim()).filter(Boolean).join("\n");
41447
+ if (flattened) return flattened;
41448
+ try {
41449
+ return JSON.stringify(record);
41450
+ } catch {
41451
+ return "";
41452
+ }
41453
+ }
41454
+ function normalizeText2(value) {
41455
+ return textFromContent2(value).replace(/\s+/g, " ").trim().toLowerCase();
41456
+ }
41457
+ function excerpt2(value, width = 80) {
41458
+ const text = textFromContent2(value).replace(/\s+/g, " ").trim();
41459
+ if (!text) return "";
41460
+ return text.length > width ? `${text.slice(0, width)}\u2026` : text;
41461
+ }
41462
+ function isSyntheticUserText2(content) {
41463
+ const text = normalizeText2(content);
41464
+ return SYNTHETIC_USER_PREFIXES2.some((prefix) => text.startsWith(prefix));
41465
+ }
41466
+ function mapSessionRow(row, nowSeconds) {
41387
41467
  const startedAt = normalizeNumber(row.started_at);
41468
+ const endedAt = normalizeNullableNumber(row.ended_at);
41469
+ const preview = excerpt2(row.preview || "");
41388
41470
  const rawTitle = normalizeNullableString(row.title);
41389
- const preview = String(row.preview || "");
41390
- const title = rawTitle || (preview ? preview.length > 40 ? preview.slice(0, 40) + "..." : preview : null);
41471
+ const title = rawTitle || (preview ? preview.length > 40 ? `${preview.slice(0, 40)}...` : preview : null);
41472
+ const lastActive = normalizeNumber(row.last_active, startedAt);
41391
41473
  return {
41392
41474
  id: String(row.id || ""),
41393
41475
  source: String(row.source || ""),
41394
41476
  user_id: normalizeNullableString(row.user_id),
41395
41477
  model: String(row.model || ""),
41396
41478
  title,
41479
+ parent_session_id: normalizeNullableString(row.parent_session_id),
41397
41480
  started_at: startedAt,
41398
- ended_at: normalizeNullableNumber(row.ended_at),
41481
+ ended_at: endedAt,
41399
41482
  end_reason: normalizeNullableString(row.end_reason),
41400
41483
  message_count: normalizeNumber(row.message_count),
41401
41484
  tool_call_count: normalizeNumber(row.tool_call_count),
@@ -41408,8 +41491,338 @@ function mapRow(row) {
41408
41491
  estimated_cost_usd: normalizeNumber(row.estimated_cost_usd),
41409
41492
  actual_cost_usd: normalizeNullableNumber(row.actual_cost_usd),
41410
41493
  cost_status: String(row.cost_status || ""),
41494
+ preview,
41495
+ last_active: lastActive,
41496
+ has_visible_messages: !!normalizeNumber(row.has_visible_messages),
41497
+ is_active: endedAt == null && nowSeconds - lastActive <= LIVE_WINDOW_SECONDS2
41498
+ };
41499
+ }
41500
+ function sortByRecency2(items) {
41501
+ return [...items].sort((a, b) => {
41502
+ if (b.last_active !== a.last_active) return b.last_active - a.last_active;
41503
+ if (b.started_at !== a.started_at) return b.started_at - a.started_at;
41504
+ return a.id.localeCompare(b.id);
41505
+ });
41506
+ }
41507
+ function timingMatchesParent2(parent, child) {
41508
+ if (!parent || !child || parent.ended_at == null) return false;
41509
+ return Math.abs(Number(child.started_at || 0) - Number(parent.ended_at || 0)) <= LINEAGE_TOLERANCE_SECONDS2;
41510
+ }
41511
+ function isBranchRoot2(session, byId) {
41512
+ if (!session?.parent_session_id) return false;
41513
+ const parent = byId.get(session.parent_session_id);
41514
+ return !!parent && parent.end_reason === "branched" && timingMatchesParent2(parent, session);
41515
+ }
41516
+ function isVisibleRoot2(session, byId) {
41517
+ if (!session || session.source === "tool") return false;
41518
+ return session.parent_session_id == null || isBranchRoot2(session, byId);
41519
+ }
41520
+ function continuationCandidates2(parent, byId, childrenByParent) {
41521
+ const childIds = childrenByParent.get(parent.id) || [];
41522
+ return childIds.map((childId) => byId.get(childId)).filter((child) => !!child).filter((child) => child.source !== "tool").filter((child) => child.source === parent.source).filter((child) => timingMatchesParent2(parent, child)).sort((a, b) => {
41523
+ const aDelta = Math.abs(Number(a.started_at || 0) - Number(parent.ended_at || 0));
41524
+ const bDelta = Math.abs(Number(b.started_at || 0) - Number(parent.ended_at || 0));
41525
+ if (aDelta !== bDelta) return aDelta - bDelta;
41526
+ return a.id.localeCompare(b.id);
41527
+ });
41528
+ }
41529
+ function nextContinuationChild2(parent, byId, childrenByParent) {
41530
+ if (parent.end_reason !== "compression") return null;
41531
+ const candidates = continuationCandidates2(parent, byId, childrenByParent);
41532
+ if (candidates.length === 1) return candidates[0];
41533
+ const exactPreviewMatches = candidates.filter((child) => {
41534
+ const childPreview = normalizeText2(child.preview);
41535
+ const parentPreview = normalizeText2(parent.preview);
41536
+ return !!childPreview && childPreview === parentPreview;
41537
+ });
41538
+ if (exactPreviewMatches.length === 1) return exactPreviewMatches[0];
41539
+ return null;
41540
+ }
41541
+ function collectConversationChain2(rootId, byId, childrenByParent) {
41542
+ const chain = [];
41543
+ const seen = /* @__PURE__ */ new Set();
41544
+ let current = byId.get(rootId) || null;
41545
+ while (current && !seen.has(current.id)) {
41546
+ chain.push(current);
41547
+ seen.add(current.id);
41548
+ current = nextContinuationChild2(current, byId, childrenByParent);
41549
+ }
41550
+ return chain;
41551
+ }
41552
+ function toSummary2(session) {
41553
+ return {
41554
+ id: session.id,
41555
+ source: safeText2(session.source),
41556
+ model: safeText2(session.model),
41557
+ title: session.title ?? null,
41558
+ started_at: Number(session.started_at || 0),
41559
+ ended_at: session.ended_at ?? null,
41560
+ last_active: session.last_active,
41561
+ message_count: Number(session.message_count || 0),
41562
+ tool_call_count: Number(session.tool_call_count || 0),
41563
+ input_tokens: Number(session.input_tokens || 0),
41564
+ output_tokens: Number(session.output_tokens || 0),
41565
+ cache_read_tokens: Number(session.cache_read_tokens || 0),
41566
+ cache_write_tokens: Number(session.cache_write_tokens || 0),
41567
+ reasoning_tokens: Number(session.reasoning_tokens || 0),
41568
+ billing_provider: session.billing_provider ?? null,
41569
+ estimated_cost_usd: Number(session.estimated_cost_usd || 0),
41570
+ actual_cost_usd: session.actual_cost_usd ?? null,
41571
+ cost_status: safeText2(session.cost_status),
41572
+ preview: session.preview,
41573
+ is_active: session.is_active,
41574
+ thread_session_count: 1
41575
+ };
41576
+ }
41577
+ function aggregateSummary2(rootId, byId, childrenByParent) {
41578
+ const chain = collectConversationChain2(rootId, byId, childrenByParent);
41579
+ if (!chain.length || !chain.some((session) => session.has_visible_messages)) return null;
41580
+ const root = chain[0];
41581
+ const last = chain[chain.length - 1];
41582
+ const firstPreview = chain.map((session) => session.preview).find(Boolean) || "";
41583
+ const costStatuses = Array.from(new Set(chain.map((session) => safeText2(session.cost_status)).filter(Boolean)));
41584
+ return {
41585
+ ...toSummary2(root),
41586
+ title: root.title || firstPreview || null,
41587
+ preview: root.preview || firstPreview,
41588
+ model: safeText2(last?.model || root.model),
41589
+ ended_at: last?.ended_at ?? null,
41590
+ last_active: Math.max(...chain.map((session) => session.last_active)),
41591
+ is_active: chain.some((session) => session.is_active),
41592
+ billing_provider: last?.billing_provider ?? root.billing_provider ?? null,
41593
+ cost_status: costStatuses.length === 1 ? costStatuses[0] : "mixed",
41594
+ thread_session_count: chain.length,
41595
+ message_count: chain.reduce((sum, session) => sum + Number(session.message_count || 0), 0),
41596
+ tool_call_count: chain.reduce((sum, session) => sum + Number(session.tool_call_count || 0), 0),
41597
+ input_tokens: chain.reduce((sum, session) => sum + Number(session.input_tokens || 0), 0),
41598
+ output_tokens: chain.reduce((sum, session) => sum + Number(session.output_tokens || 0), 0),
41599
+ cache_read_tokens: chain.reduce((sum, session) => sum + Number(session.cache_read_tokens || 0), 0),
41600
+ cache_write_tokens: chain.reduce((sum, session) => sum + Number(session.cache_write_tokens || 0), 0),
41601
+ reasoning_tokens: chain.reduce((sum, session) => sum + Number(session.reasoning_tokens || 0), 0),
41602
+ estimated_cost_usd: chain.reduce((sum, session) => sum + Number(session.estimated_cost_usd || 0), 0),
41603
+ actual_cost_usd: chain.reduce((sum, session) => {
41604
+ const actual = session.actual_cost_usd;
41605
+ if (actual == null) return sum;
41606
+ return (sum || 0) + Number(actual);
41607
+ }, null)
41608
+ };
41609
+ }
41610
+ function normalizeVisibleMessage2(message2, fallbackTimestamp) {
41611
+ const role = safeText2(message2.role);
41612
+ const content = textFromContent2(message2.content).trim();
41613
+ if (!content) return null;
41614
+ if (role !== "user" && role !== "assistant") return null;
41615
+ if (role === "user" && isSyntheticUserText2(content)) return null;
41616
+ return {
41617
+ id: message2.id,
41618
+ session_id: message2.session_id,
41619
+ role,
41620
+ content,
41621
+ timestamp: Number.isFinite(Number(message2.timestamp)) && Number(message2.timestamp) > 0 ? Number(message2.timestamp) : fallbackTimestamp
41622
+ };
41623
+ }
41624
+ async function openConversationDb() {
41625
+ if (!SQLITE_AVAILABLE2) {
41626
+ throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
41627
+ }
41628
+ const { DatabaseSync: DatabaseSync2 } = await import("node:sqlite");
41629
+ return new DatabaseSync2(conversationDbPath(), { open: true, readOnly: true });
41630
+ }
41631
+ function buildConversationSessionSql(source) {
41632
+ const sql = `
41633
+ SELECT
41634
+ s.id,
41635
+ s.source,
41636
+ COALESCE(s.user_id, '') AS user_id,
41637
+ COALESCE(s.model, '') AS model,
41638
+ COALESCE(s.title, '') AS title,
41639
+ s.parent_session_id AS parent_session_id,
41640
+ COALESCE(s.started_at, 0) AS started_at,
41641
+ s.ended_at AS ended_at,
41642
+ COALESCE(s.end_reason, '') AS end_reason,
41643
+ COALESCE(s.message_count, 0) AS message_count,
41644
+ COALESCE(s.tool_call_count, 0) AS tool_call_count,
41645
+ COALESCE(s.input_tokens, 0) AS input_tokens,
41646
+ COALESCE(s.output_tokens, 0) AS output_tokens,
41647
+ COALESCE(s.cache_read_tokens, 0) AS cache_read_tokens,
41648
+ COALESCE(s.cache_write_tokens, 0) AS cache_write_tokens,
41649
+ COALESCE(s.reasoning_tokens, 0) AS reasoning_tokens,
41650
+ COALESCE(s.billing_provider, '') AS billing_provider,
41651
+ COALESCE(s.estimated_cost_usd, 0) AS estimated_cost_usd,
41652
+ s.actual_cost_usd AS actual_cost_usd,
41653
+ COALESCE(s.cost_status, '') AS cost_status,
41654
+ COALESCE(
41655
+ (
41656
+ SELECT SUBSTR(REPLACE(REPLACE(m.content, CHAR(10), ' '), CHAR(13), ' '), 1, 80)
41657
+ FROM messages m
41658
+ WHERE m.session_id = s.id
41659
+ AND ${VISIBLE_HUMAN_MESSAGE_SQL}
41660
+ ORDER BY m.timestamp, m.id
41661
+ LIMIT 1
41662
+ ),
41663
+ ''
41664
+ ) AS preview,
41665
+ COALESCE((SELECT MAX(m2.timestamp) FROM messages m2 WHERE m2.session_id = s.id), s.started_at) AS last_active,
41666
+ CASE WHEN EXISTS (
41667
+ SELECT 1
41668
+ FROM messages m
41669
+ WHERE m.session_id = s.id
41670
+ AND ${VISIBLE_HUMAN_MESSAGE_SQL}
41671
+ ) THEN 1 ELSE 0 END AS has_visible_messages
41672
+ FROM sessions s
41673
+ WHERE s.source != 'tool'
41674
+ ${source ? "AND s.source = ?" : ""}
41675
+ ORDER BY s.started_at DESC
41676
+ `;
41677
+ return { sql, params: source ? [source] : [] };
41678
+ }
41679
+ async function loadConversationSessions(source) {
41680
+ const db = await openConversationDb();
41681
+ try {
41682
+ const { sql, params } = buildConversationSessionSql(source);
41683
+ const rows = db.prepare(sql).all(...params);
41684
+ const nowSeconds = Date.now() / 1e3;
41685
+ return rows.map((row) => mapSessionRow(row, nowSeconds));
41686
+ } finally {
41687
+ db.close();
41688
+ }
41689
+ }
41690
+ async function listConversationSummariesFromDb(options = {}) {
41691
+ const humanOnly = options.humanOnly !== false;
41692
+ const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CONVERSATION_LIMIT2;
41693
+ const sessions3 = await loadConversationSessions(options.source);
41694
+ const byId = new Map(sessions3.map((session) => [session.id, session]));
41695
+ const childrenByParent = /* @__PURE__ */ new Map();
41696
+ for (const session of sessions3) {
41697
+ const key = session.parent_session_id ?? null;
41698
+ const siblings = childrenByParent.get(key) || [];
41699
+ siblings.push(session.id);
41700
+ childrenByParent.set(key, siblings);
41701
+ }
41702
+ if (!humanOnly) {
41703
+ return sortByRecency2(sessions3.map(toSummary2)).slice(0, limit);
41704
+ }
41705
+ const summaries = sessions3.filter((session) => isVisibleRoot2(session, byId)).map((session) => aggregateSummary2(session.id, byId, childrenByParent)).filter((summary) => !!summary);
41706
+ return sortByRecency2(summaries).slice(0, limit);
41707
+ }
41708
+ async function getConversationDetailFromDb(sessionId, options = {}) {
41709
+ const humanOnly = options.humanOnly !== false;
41710
+ const sessions3 = await loadConversationSessions(options.source);
41711
+ const byId = new Map(sessions3.map((session) => [session.id, session]));
41712
+ const childrenByParent = /* @__PURE__ */ new Map();
41713
+ for (const session of sessions3) {
41714
+ const key = session.parent_session_id ?? null;
41715
+ const siblings = childrenByParent.get(key) || [];
41716
+ siblings.push(session.id);
41717
+ childrenByParent.set(key, siblings);
41718
+ }
41719
+ let chain = [];
41720
+ if (!humanOnly) {
41721
+ const session = byId.get(sessionId);
41722
+ if (!session || session.source === "tool") return null;
41723
+ chain = [session];
41724
+ } else {
41725
+ const root = byId.get(sessionId);
41726
+ if (!isVisibleRoot2(root, byId)) return null;
41727
+ chain = collectConversationChain2(sessionId, byId, childrenByParent);
41728
+ }
41729
+ if (!chain.length) return null;
41730
+ const db = await openConversationDb();
41731
+ try {
41732
+ const ids = chain.map((session) => session.id);
41733
+ const placeholders = ids.map(() => "?").join(", ");
41734
+ const rows = db.prepare(`
41735
+ SELECT id, session_id, role, content, timestamp
41736
+ FROM messages
41737
+ WHERE session_id IN (${placeholders})
41738
+ AND role IN ('user', 'assistant')
41739
+ AND content IS NOT NULL
41740
+ AND content != ''
41741
+ ORDER BY timestamp, id
41742
+ `).all(...ids);
41743
+ const sessionById = new Map(chain.map((session) => [session.id, session]));
41744
+ const messages = rows.map((row) => {
41745
+ const session = sessionById.get(String(row.session_id || ""));
41746
+ return normalizeVisibleMessage2({
41747
+ id: row.id,
41748
+ session_id: String(row.session_id || ""),
41749
+ role: String(row.role || ""),
41750
+ content: row.content,
41751
+ timestamp: normalizeNumber(row.timestamp)
41752
+ }, session?.last_active || session?.started_at || 0);
41753
+ }).filter((message2) => !!message2).sort((a, b) => {
41754
+ if (a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
41755
+ return String(a.id).localeCompare(String(b.id));
41756
+ });
41757
+ if (!messages.length) {
41758
+ return humanOnly ? null : {
41759
+ session_id: sessionId,
41760
+ messages: [],
41761
+ visible_count: 0,
41762
+ thread_session_count: chain.length
41763
+ };
41764
+ }
41765
+ return {
41766
+ session_id: sessionId,
41767
+ messages,
41768
+ visible_count: messages.length,
41769
+ thread_session_count: chain.length
41770
+ };
41771
+ } finally {
41772
+ db.close();
41773
+ }
41774
+ }
41775
+
41776
+ // packages/server/src/db/hermes/sessions-db.ts
41777
+ init_hermes_profile();
41778
+ var SQLITE_AVAILABLE3 = (() => {
41779
+ const [major, minor] = process.versions.node.split(".").map(Number);
41780
+ return major > 22 || major === 22 && minor >= 5;
41781
+ })();
41782
+ function sessionDbPath() {
41783
+ return `${getActiveProfileDir()}/state.db`;
41784
+ }
41785
+ function normalizeNumber2(value, fallback = 0) {
41786
+ if (value == null || value === "") return fallback;
41787
+ const num = Number(value);
41788
+ return Number.isFinite(num) ? num : fallback;
41789
+ }
41790
+ function normalizeNullableNumber2(value) {
41791
+ if (value == null || value === "") return null;
41792
+ const num = Number(value);
41793
+ return Number.isFinite(num) ? num : null;
41794
+ }
41795
+ function normalizeNullableString2(value) {
41796
+ if (value == null || value === "") return null;
41797
+ return String(value);
41798
+ }
41799
+ function mapRow(row) {
41800
+ const startedAt = normalizeNumber2(row.started_at);
41801
+ const rawTitle = normalizeNullableString2(row.title);
41802
+ const preview = String(row.preview || "");
41803
+ const title = rawTitle || (preview ? preview.length > 40 ? preview.slice(0, 40) + "..." : preview : null);
41804
+ return {
41805
+ id: String(row.id || ""),
41806
+ source: String(row.source || ""),
41807
+ user_id: normalizeNullableString2(row.user_id),
41808
+ model: String(row.model || ""),
41809
+ title,
41810
+ started_at: startedAt,
41811
+ ended_at: normalizeNullableNumber2(row.ended_at),
41812
+ end_reason: normalizeNullableString2(row.end_reason),
41813
+ message_count: normalizeNumber2(row.message_count),
41814
+ tool_call_count: normalizeNumber2(row.tool_call_count),
41815
+ input_tokens: normalizeNumber2(row.input_tokens),
41816
+ output_tokens: normalizeNumber2(row.output_tokens),
41817
+ cache_read_tokens: normalizeNumber2(row.cache_read_tokens),
41818
+ cache_write_tokens: normalizeNumber2(row.cache_write_tokens),
41819
+ reasoning_tokens: normalizeNumber2(row.reasoning_tokens),
41820
+ billing_provider: normalizeNullableString2(row.billing_provider),
41821
+ estimated_cost_usd: normalizeNumber2(row.estimated_cost_usd),
41822
+ actual_cost_usd: normalizeNullableNumber2(row.actual_cost_usd),
41823
+ cost_status: String(row.cost_status || ""),
41411
41824
  preview: String(row.preview || ""),
41412
- last_active: normalizeNumber(row.last_active, startedAt)
41825
+ last_active: normalizeNumber2(row.last_active, startedAt)
41413
41826
  };
41414
41827
  }
41415
41828
  var SESSION_SELECT = `
@@ -41472,6 +41885,35 @@ function containsCjk(text) {
41472
41885
  }
41473
41886
  return false;
41474
41887
  }
41888
+ function isNumericQuery(text) {
41889
+ return /^\d+(?:\s+\d+)*$/.test(text.trim());
41890
+ }
41891
+ function hasUnsafeChars(text) {
41892
+ return /[^\w\s\u4e00-\u9fff\u3400-\u4dbf\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(text);
41893
+ }
41894
+ function runLikeContentSearch(db, source, query) {
41895
+ const likeBase = buildBaseSessionSql(source);
41896
+ const likeSql = `
41897
+ WITH base AS (
41898
+ ${likeBase.sql}
41899
+ )
41900
+ SELECT
41901
+ base.*,
41902
+ m.id AS matched_message_id,
41903
+ substr(
41904
+ m.content,
41905
+ max(1, instr(m.content, ?) - 40),
41906
+ 120
41907
+ ) AS snippet,
41908
+ 0 AS rank
41909
+ FROM base
41910
+ JOIN messages m ON m.session_id = base.id
41911
+ WHERE m.content LIKE ?
41912
+ ORDER BY base.last_active DESC, m.timestamp DESC
41913
+ `;
41914
+ const likeStatement = db.prepare(likeSql);
41915
+ return likeStatement.all(...likeBase.params, query, `%${query}%`);
41916
+ }
41475
41917
  function sanitizeFtsQuery(query) {
41476
41918
  const quotedParts = [];
41477
41919
  const preserved = query.replace(/"[^"]*"/g, (match) => {
@@ -41502,13 +41944,13 @@ function toPrefixQuery(query) {
41502
41944
  function mapSearchRow(row) {
41503
41945
  return {
41504
41946
  ...mapRow(row),
41505
- matched_message_id: normalizeNullableNumber(row.matched_message_id),
41947
+ matched_message_id: normalizeNullableNumber2(row.matched_message_id),
41506
41948
  snippet: String(row.snippet || row.preview || ""),
41507
41949
  rank: Number.isFinite(Number(row.rank)) ? Number(row.rank) : 0
41508
41950
  };
41509
41951
  }
41510
41952
  async function listSessionSummaries(source, limit = 2e3) {
41511
- if (!SQLITE_AVAILABLE2) {
41953
+ if (!SQLITE_AVAILABLE3) {
41512
41954
  throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
41513
41955
  }
41514
41956
  const { DatabaseSync: DatabaseSync2 } = await import("node:sqlite");
@@ -41523,7 +41965,7 @@ async function listSessionSummaries(source, limit = 2e3) {
41523
41965
  }
41524
41966
  }
41525
41967
  async function searchSessionSummaries(query, source, limit = 20) {
41526
- if (!SQLITE_AVAILABLE2) {
41968
+ if (!SQLITE_AVAILABLE3) {
41527
41969
  throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
41528
41970
  }
41529
41971
  const trimmed = query.trim();
@@ -41540,6 +41982,7 @@ async function searchSessionSummaries(query, source, limit = 20) {
41540
41982
  const db = new DatabaseSync2(sessionDbPath(), { open: true, readOnly: true });
41541
41983
  const normalized = sanitizeFtsQuery(trimmed);
41542
41984
  const prefixQuery = toPrefixQuery(normalized);
41985
+ let titleRows = [];
41543
41986
  try {
41544
41987
  const titleBase = buildBaseSessionSql(source);
41545
41988
  const contentBase = buildBaseSessionSql(source);
@@ -41561,7 +42004,7 @@ async function searchSessionSummaries(query, source, limit = 20) {
41561
42004
  LIMIT ?
41562
42005
  `;
41563
42006
  const titleStatement = db.prepare(titleSql);
41564
- const titleRows = titleStatement.all(...titleBase.params, `%${trimmed.toLowerCase()}%`, limit);
42007
+ titleRows = titleStatement.all(...titleBase.params, `%${trimmed.toLowerCase()}%`, limit);
41565
42008
  const contentSql = `
41566
42009
  WITH base AS (
41567
42010
  ${contentBase.sql}
@@ -41597,28 +42040,9 @@ async function searchSessionSummaries(query, source, limit = 20) {
41597
42040
  });
41598
42041
  return items.slice(0, limit);
41599
42042
  } catch (err) {
42043
+ const message2 = err instanceof Error ? err.message : String(err);
41600
42044
  if (containsCjk(normalized)) {
41601
- const likeBase = buildBaseSessionSql(source);
41602
- const likeSql = `
41603
- WITH base AS (
41604
- ${likeBase.sql}
41605
- )
41606
- SELECT
41607
- base.*,
41608
- m.id AS matched_message_id,
41609
- substr(
41610
- m.content,
41611
- max(1, instr(m.content, ?) - 40),
41612
- 120
41613
- ) AS snippet,
41614
- 0 AS rank
41615
- FROM base
41616
- JOIN messages m ON m.session_id = base.id
41617
- WHERE m.content LIKE ?
41618
- ORDER BY base.last_active DESC, m.timestamp DESC
41619
- `;
41620
- const likeStatement = db.prepare(likeSql);
41621
- const likeRows = likeStatement.all(...likeBase.params, trimmed, `%${trimmed}%`);
42045
+ const likeRows = runLikeContentSearch(db, source, trimmed);
41622
42046
  const merged = /* @__PURE__ */ new Map();
41623
42047
  for (const row of likeRows) {
41624
42048
  const mapped = mapSearchRow(row);
@@ -41628,7 +42052,21 @@ async function searchSessionSummaries(query, source, limit = 20) {
41628
42052
  }
41629
42053
  return [...merged.values()].slice(0, limit);
41630
42054
  }
41631
- const message2 = err instanceof Error ? err.message : String(err);
42055
+ if (isNumericQuery(trimmed) || hasUnsafeChars(trimmed)) {
42056
+ const likeRows = runLikeContentSearch(db, source, trimmed);
42057
+ const merged = /* @__PURE__ */ new Map();
42058
+ for (const row of titleRows) {
42059
+ const mapped = mapSearchRow(row);
42060
+ merged.set(mapped.id, mapped);
42061
+ }
42062
+ for (const row of likeRows) {
42063
+ const mapped = mapSearchRow(row);
42064
+ if (!merged.has(mapped.id)) {
42065
+ merged.set(mapped.id, mapped);
42066
+ }
42067
+ }
42068
+ return [...merged.values()].slice(0, limit);
42069
+ }
41632
42070
  throw new Error(`Failed to search sessions: ${message2}`);
41633
42071
  } finally {
41634
42072
  db.close();
@@ -41721,12 +42159,31 @@ async function listConversations(ctx) {
41721
42159
  const source = ctx.query.source || void 0;
41722
42160
  const humanOnly = parseHumanOnly(ctx.query.humanOnly);
41723
42161
  const limit = parseLimit(ctx.query.limit);
41724
- const sessions2 = await listConversationSummaries({ source, humanOnly, limit });
41725
- ctx.body = { sessions: sessions2 };
42162
+ try {
42163
+ const sessions4 = await listConversationSummariesFromDb({ source, humanOnly, limit });
42164
+ ctx.body = { sessions: sessions4 };
42165
+ return;
42166
+ } catch (err) {
42167
+ logger.warn(err, "Hermes Conversation DB: summary query failed, falling back to CLI export");
42168
+ }
42169
+ const sessions3 = await listConversationSummaries({ source, humanOnly, limit });
42170
+ ctx.body = { sessions: sessions3 };
41726
42171
  }
41727
42172
  async function getConversationMessages(ctx) {
41728
42173
  const source = ctx.query.source || void 0;
41729
42174
  const humanOnly = parseHumanOnly(ctx.query.humanOnly);
42175
+ try {
42176
+ const detail2 = await getConversationDetailFromDb(ctx.params.id, { source, humanOnly });
42177
+ if (!detail2) {
42178
+ ctx.status = 404;
42179
+ ctx.body = { error: "Conversation not found" };
42180
+ return;
42181
+ }
42182
+ ctx.body = detail2;
42183
+ return;
42184
+ } catch (err) {
42185
+ logger.warn(err, "Hermes Conversation DB: detail query failed, falling back to CLI export");
42186
+ }
41730
42187
  const detail = await getConversationDetail(ctx.params.id, { source, humanOnly });
41731
42188
  if (!detail) {
41732
42189
  ctx.status = 404;
@@ -41739,14 +42196,14 @@ async function list(ctx) {
41739
42196
  const source = ctx.query.source || void 0;
41740
42197
  const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : void 0;
41741
42198
  try {
41742
- const sessions3 = await listSessionSummaries(source, limit && limit > 0 ? limit : 2e3);
41743
- ctx.body = { sessions: sessions3 };
42199
+ const sessions4 = await listSessionSummaries(source, limit && limit > 0 ? limit : 2e3);
42200
+ ctx.body = { sessions: sessions4 };
41744
42201
  return;
41745
42202
  } catch (err) {
41746
42203
  logger.warn(err, "Hermes Session DB: summary query failed, falling back to CLI");
41747
42204
  }
41748
- const sessions2 = await listSessions(source, limit);
41749
- ctx.body = { sessions: sessions2 };
42205
+ const sessions3 = await listSessions(source, limit);
42206
+ ctx.body = { sessions: sessions3 };
41750
42207
  }
41751
42208
  async function search(ctx) {
41752
42209
  const q = typeof ctx.query.q === "string" ? ctx.query.q : "";
@@ -42081,6 +42538,8 @@ var PROVIDER_ENV_MAP = {
42081
42538
  "opencode-go": { api_key_env: "OPENCODE_API_KEY", base_url_env: "" },
42082
42539
  huggingface: { api_key_env: "HF_TOKEN", base_url_env: "" },
42083
42540
  arcee: { api_key_env: "ARCEE_API_KEY", base_url_env: "" },
42541
+ stepfun: { api_key_env: "STEPFUN_API_KEY", base_url_env: "" },
42542
+ nous: { api_key_env: "", base_url_env: "" },
42084
42543
  "openai-codex": { api_key_env: "", base_url_env: "" }
42085
42544
  };
42086
42545
  var configPath = () => getActiveConfigPath();
@@ -42193,7 +42652,7 @@ async function listFilesRecursive(dir, prefix) {
42193
42652
  }
42194
42653
  async function fetchProviderModels(baseUrl, apiKey) {
42195
42654
  const base = baseUrl.replace(/\/+$/, "");
42196
- const modelsUrl = base.endsWith("/v1") ? `${base}/models` : `${base}/v1/models`;
42655
+ const modelsUrl = /\/v\d+\/?$/.test(base) ? `${base}/models` : `${base}/v1/models`;
42197
42656
  try {
42198
42657
  const res = await fetch(modelsUrl, {
42199
42658
  headers: { Authorization: `Bearer ${apiKey}` },
@@ -42463,6 +42922,7 @@ var PROVIDER_PRESETS = [
42463
42922
  base_url: "https://api.kimi.com/coding/v1",
42464
42923
  models: [
42465
42924
  "kimi-for-coding",
42925
+ "kimi-k2.6",
42466
42926
  "kimi-k2.5",
42467
42927
  "kimi-k2-thinking",
42468
42928
  "kimi-k2-turbo-preview",
@@ -42475,6 +42935,7 @@ var PROVIDER_PRESETS = [
42475
42935
  builtin: true,
42476
42936
  base_url: "https://api.moonshot.cn/v1",
42477
42937
  models: [
42938
+ "kimi-k2.6",
42478
42939
  "kimi-k2.5",
42479
42940
  "kimi-k2-thinking",
42480
42941
  "kimi-k2-turbo-preview",
@@ -42638,6 +43099,50 @@ var PROVIDER_PRESETS = [
42638
43099
  base_url: "https://api.arcee.ai/v1",
42639
43100
  models: ["trinity-large-thinking", "trinity-large-preview", "trinity-mini"]
42640
43101
  },
43102
+ {
43103
+ label: "Nous Portal",
43104
+ value: "nous",
43105
+ builtin: true,
43106
+ base_url: "https://inference-api.nousresearch.com/v1",
43107
+ models: [
43108
+ "moonshotai/kimi-k2.6",
43109
+ "xiaomi/mimo-v2.5-pro",
43110
+ "xiaomi/mimo-v2.5",
43111
+ "anthropic/claude-opus-4.7",
43112
+ "anthropic/claude-opus-4.6",
43113
+ "anthropic/claude-sonnet-4.6",
43114
+ "anthropic/claude-sonnet-4.5",
43115
+ "anthropic/claude-haiku-4.5",
43116
+ "openai/gpt-5.4",
43117
+ "openai/gpt-5.4-mini",
43118
+ "openai/gpt-5.3-codex",
43119
+ "google/gemini-3-pro-preview",
43120
+ "google/gemini-3-flash-preview",
43121
+ "google/gemini-3.1-pro-preview",
43122
+ "google/gemini-3.1-flash-lite-preview",
43123
+ "qwen/qwen3.5-plus-02-15",
43124
+ "qwen/qwen3.5-35b-a3b",
43125
+ "stepfun/step-3.5-flash",
43126
+ "minimax/minimax-m2.7",
43127
+ "minimax/minimax-m2.5",
43128
+ "minimax/minimax-m2.5:free",
43129
+ "z-ai/glm-5.1",
43130
+ "z-ai/glm-5v-turbo",
43131
+ "z-ai/glm-5-turbo",
43132
+ "x-ai/grok-4.20-beta",
43133
+ "nvidia/nemotron-3-super-120b-a12b",
43134
+ "arcee-ai/trinity-large-thinking",
43135
+ "openai/gpt-5.4-pro",
43136
+ "openai/gpt-5.4-nano"
43137
+ ]
43138
+ },
43139
+ {
43140
+ label: "StepFun",
43141
+ value: "stepfun",
43142
+ builtin: true,
43143
+ base_url: "https://api.stepfun.ai/step_plan/v1",
43144
+ models: ["step-3.5-flash", "step-3.5-flash-2603"]
43145
+ },
42641
43146
  {
42642
43147
  label: "OpenRouter",
42643
43148
  value: "openrouter",
@@ -42700,7 +43205,9 @@ async function getAvailable(ctx) {
42700
43205
  const authPath = getActiveAuthPath();
42701
43206
  if (!(0, import_fs11.existsSync)(authPath)) return false;
42702
43207
  const auth = JSON.parse((0, import_fs11.readFileSync)(authPath, "utf-8"));
42703
- return !!auth.providers?.[providerKey]?.tokens?.access_token;
43208
+ const provider = auth.providers?.[providerKey];
43209
+ if (!provider) return false;
43210
+ return !!(provider.tokens?.access_token || provider.access_token);
42704
43211
  } catch {
42705
43212
  return false;
42706
43213
  }
@@ -43372,7 +43879,7 @@ async function codexLoginWorker(session, authPath) {
43372
43879
  const startTime = Date.now();
43373
43880
  const interval = POLL_DEFAULT_INTERVAL;
43374
43881
  while (Date.now() - startTime < POLL_MAX_DURATION) {
43375
- await new Promise((resolve10) => setTimeout(resolve10, interval));
43882
+ await new Promise((resolve11) => setTimeout(resolve11, interval));
43376
43883
  if (session.status !== "pending") return;
43377
43884
  try {
43378
43885
  const pollRes = await fetch(CODEX_DEVICE_TOKEN_URL, {
@@ -43533,6 +44040,232 @@ codexAuthRoutes.post("/api/hermes/auth/codex/start", start);
43533
44040
  codexAuthRoutes.get("/api/hermes/auth/codex/poll/:sessionId", poll);
43534
44041
  codexAuthRoutes.get("/api/hermes/auth/codex/status", status);
43535
44042
 
44043
+ // packages/server/src/controllers/hermes/nous-auth.ts
44044
+ var import_crypto4 = require("crypto");
44045
+ var import_fs15 = require("fs");
44046
+ init_hermes_profile();
44047
+ init_logger();
44048
+ var NOUS_PORTAL_URL = "https://portal.nousresearch.com";
44049
+ var NOUS_CLIENT_ID = "hermes-cli";
44050
+ var NOUS_SCOPE = "inference:mint_agent_key";
44051
+ var POLL_MAX_DURATION2 = 15 * 60 * 1e3;
44052
+ var POLL_DEFAULT_INTERVAL2 = 5e3;
44053
+ var sessions2 = /* @__PURE__ */ new Map();
44054
+ function cleanupExpiredSessions2() {
44055
+ const now = Date.now();
44056
+ sessions2.forEach((s, id) => {
44057
+ if (now - s.createdAt > POLL_MAX_DURATION2 + 6e4) sessions2.delete(id);
44058
+ });
44059
+ }
44060
+ function loadAuthJson2(authPath) {
44061
+ try {
44062
+ return JSON.parse((0, import_fs15.readFileSync)(authPath, "utf-8"));
44063
+ } catch {
44064
+ return { version: 1 };
44065
+ }
44066
+ }
44067
+ function saveAuthJson2(authPath, data) {
44068
+ data.updated_at = (/* @__PURE__ */ new Date()).toISOString();
44069
+ const dir = authPath.substring(0, authPath.lastIndexOf("/"));
44070
+ if (!(0, import_fs15.existsSync)(dir)) (0, import_fs15.mkdirSync)(dir, { recursive: true });
44071
+ (0, import_fs15.writeFileSync)(authPath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
44072
+ }
44073
+ async function nousLoginWorker(session, authPath) {
44074
+ const startTime = Date.now();
44075
+ let interval = session.interval || POLL_DEFAULT_INTERVAL2;
44076
+ while (Date.now() - startTime < POLL_MAX_DURATION2) {
44077
+ await new Promise((resolve11) => setTimeout(resolve11, interval));
44078
+ if (session.status !== "pending") return;
44079
+ try {
44080
+ const res = await fetch(`${NOUS_PORTAL_URL}/api/oauth/token`, {
44081
+ method: "POST",
44082
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
44083
+ body: new URLSearchParams({
44084
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
44085
+ client_id: NOUS_CLIENT_ID,
44086
+ device_code: session.deviceCode
44087
+ }).toString(),
44088
+ signal: AbortSignal.timeout(15e3)
44089
+ });
44090
+ if (res.ok) {
44091
+ const tokenData = await res.json();
44092
+ const inferenceBaseUrl = tokenData.inference_base_url || "https://inference-api.nousresearch.com/v1";
44093
+ let agentKey = "";
44094
+ let agentKeyExpiresAt = "";
44095
+ try {
44096
+ const mintRes = await fetch(`${NOUS_PORTAL_URL}/api/oauth/agent-key`, {
44097
+ method: "POST",
44098
+ headers: {
44099
+ "Authorization": `Bearer ${tokenData.access_token}`,
44100
+ "Content-Type": "application/json"
44101
+ },
44102
+ body: JSON.stringify({ min_ttl_seconds: 1800 }),
44103
+ signal: AbortSignal.timeout(15e3)
44104
+ });
44105
+ if (mintRes.ok) {
44106
+ const mintData = await mintRes.json();
44107
+ agentKey = mintData.api_key;
44108
+ agentKeyExpiresAt = mintData.expires_at;
44109
+ if (mintData.inference_base_url) {
44110
+ void mintData.inference_base_url;
44111
+ }
44112
+ }
44113
+ } catch (err) {
44114
+ logger.warn(err, "Nous agent key minting failed, proceeding without");
44115
+ }
44116
+ const auth = loadAuthJson2(authPath);
44117
+ if (!auth.providers) auth.providers = {};
44118
+ const now = /* @__PURE__ */ new Date();
44119
+ auth.providers["nous"] = {
44120
+ portal_base_url: NOUS_PORTAL_URL,
44121
+ inference_base_url: inferenceBaseUrl,
44122
+ client_id: NOUS_CLIENT_ID,
44123
+ scope: NOUS_SCOPE,
44124
+ token_type: "Bearer",
44125
+ access_token: tokenData.access_token,
44126
+ refresh_token: tokenData.refresh_token || null,
44127
+ obtained_at: now.toISOString(),
44128
+ expires_at: tokenData.expires_in ? new Date(now.getTime() + tokenData.expires_in * 1e3).toISOString() : null,
44129
+ agent_key: agentKey || null,
44130
+ agent_key_expires_at: agentKeyExpiresAt || null,
44131
+ agent_key_obtained_at: agentKey ? now.toISOString() : null
44132
+ };
44133
+ if (!auth.credential_pool) auth.credential_pool = {};
44134
+ auth.credential_pool["nous"] = [{
44135
+ id: `nous-${Date.now()}`,
44136
+ label: "Nous Portal",
44137
+ auth_type: "oauth",
44138
+ source: "device_code",
44139
+ priority: 0,
44140
+ access_token: tokenData.access_token,
44141
+ refresh_token: tokenData.refresh_token || null,
44142
+ portal_base_url: NOUS_PORTAL_URL,
44143
+ inference_base_url: inferenceBaseUrl,
44144
+ agent_key: agentKey || null,
44145
+ agent_key_expires_at: agentKeyExpiresAt || null,
44146
+ base_url: inferenceBaseUrl
44147
+ }];
44148
+ saveAuthJson2(authPath, auth);
44149
+ session.status = "approved";
44150
+ logger.info("Nous login successful");
44151
+ return;
44152
+ }
44153
+ const errData = await res.json().catch(() => ({}));
44154
+ const errorCode = errData.error;
44155
+ if (errorCode === "authorization_pending") {
44156
+ continue;
44157
+ }
44158
+ if (errorCode === "slow_down") {
44159
+ interval = Math.min(interval + 1e3, 3e4);
44160
+ continue;
44161
+ }
44162
+ if (errorCode === "access_denied" || errorCode === "expired_token") {
44163
+ session.status = errorCode === "access_denied" ? "denied" : "expired";
44164
+ return;
44165
+ }
44166
+ logger.error("Nous poll error: %s %s", res.status, errorCode);
44167
+ session.status = "error";
44168
+ session.error = `OAuth error: ${errorCode}`;
44169
+ return;
44170
+ } catch (err) {
44171
+ if (err.name === "TimeoutError" || err.name === "AbortError") continue;
44172
+ logger.error(err, "Nous poll error");
44173
+ session.status = "error";
44174
+ session.error = err.message;
44175
+ return;
44176
+ }
44177
+ }
44178
+ session.status = "expired";
44179
+ }
44180
+ async function start2(ctx) {
44181
+ try {
44182
+ cleanupExpiredSessions2();
44183
+ const res = await fetch(`${NOUS_PORTAL_URL}/api/oauth/device/code`, {
44184
+ method: "POST",
44185
+ headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json" },
44186
+ body: new URLSearchParams({
44187
+ client_id: NOUS_CLIENT_ID,
44188
+ scope: NOUS_SCOPE
44189
+ }).toString(),
44190
+ signal: AbortSignal.timeout(15e3)
44191
+ });
44192
+ if (!res.ok) {
44193
+ let errorBody = null;
44194
+ try {
44195
+ errorBody = await res.json();
44196
+ } catch {
44197
+ }
44198
+ logger.error("Nous device code request failed: %d %s", res.status, errorBody);
44199
+ ctx.status = 502;
44200
+ ctx.body = { error: `Nous Portal error: ${res.status}` };
44201
+ return;
44202
+ }
44203
+ const data = await res.json();
44204
+ const sessionId = (0, import_crypto4.randomUUID)();
44205
+ const session = {
44206
+ id: sessionId,
44207
+ deviceCode: data.device_code,
44208
+ userCode: data.user_code,
44209
+ verificationUrl: data.verification_uri,
44210
+ verificationUrlComplete: data.verification_uri_complete,
44211
+ expiresIn: data.expires_in,
44212
+ interval: data.interval,
44213
+ status: "pending",
44214
+ createdAt: Date.now()
44215
+ };
44216
+ sessions2.set(sessionId, session);
44217
+ const authPath = getActiveAuthPath();
44218
+ nousLoginWorker(session, authPath).catch((err) => {
44219
+ logger.error(err, "Nous login worker error");
44220
+ session.status = "error";
44221
+ session.error = err.message;
44222
+ });
44223
+ ctx.body = {
44224
+ session_id: sessionId,
44225
+ user_code: data.user_code,
44226
+ verification_url: data.verification_uri_complete,
44227
+ expires_in: data.expires_in
44228
+ };
44229
+ } catch (err) {
44230
+ if (err.name === "TimeoutError" || err.name === "AbortError") {
44231
+ ctx.status = 504;
44232
+ ctx.body = { error: "Nous Portal timeout" };
44233
+ return;
44234
+ }
44235
+ ctx.status = 500;
44236
+ ctx.body = { error: err.message };
44237
+ }
44238
+ }
44239
+ async function poll2(ctx) {
44240
+ const session = sessions2.get(ctx.params.sessionId);
44241
+ if (!session) {
44242
+ ctx.status = 404;
44243
+ ctx.body = { error: "Session not found" };
44244
+ return;
44245
+ }
44246
+ ctx.body = { status: session.status, error: session.error || null };
44247
+ }
44248
+ async function status2(ctx) {
44249
+ try {
44250
+ const authPath = getActiveAuthPath();
44251
+ const auth = loadAuthJson2(authPath);
44252
+ const nousProvider = auth.providers?.["nous"];
44253
+ if (!nousProvider?.access_token) {
44254
+ ctx.body = { authenticated: false };
44255
+ return;
44256
+ }
44257
+ ctx.body = { authenticated: true };
44258
+ } catch {
44259
+ ctx.body = { authenticated: false };
44260
+ }
44261
+ }
44262
+
44263
+ // packages/server/src/routes/hermes/nous-auth.ts
44264
+ var nousAuthRoutes = new router_default();
44265
+ nousAuthRoutes.post("/api/hermes/auth/nous/start", start2);
44266
+ nousAuthRoutes.get("/api/hermes/auth/nous/poll/:sessionId", poll2);
44267
+ nousAuthRoutes.get("/api/hermes/auth/nous/status", status2);
44268
+
43536
44269
  // packages/server/src/controllers/hermes/gateways.ts
43537
44270
  async function list5(ctx) {
43538
44271
  const mgr = getGatewayManagerInstance();
@@ -43544,7 +44277,7 @@ async function list5(ctx) {
43544
44277
  const gateways = await mgr.listAll();
43545
44278
  ctx.body = { gateways };
43546
44279
  }
43547
- async function start2(ctx) {
44280
+ async function start3(ctx) {
43548
44281
  const mgr = getGatewayManagerInstance();
43549
44282
  if (!mgr) {
43550
44283
  ctx.status = 503;
@@ -43552,8 +44285,8 @@ async function start2(ctx) {
43552
44285
  return;
43553
44286
  }
43554
44287
  try {
43555
- const status2 = await mgr.start(ctx.params.name);
43556
- ctx.body = { success: true, gateway: status2 };
44288
+ const status3 = await mgr.start(ctx.params.name);
44289
+ ctx.body = { success: true, gateway: status3 };
43557
44290
  } catch (err) {
43558
44291
  ctx.status = 500;
43559
44292
  ctx.body = { error: err.message };
@@ -43581,14 +44314,14 @@ async function health(ctx) {
43581
44314
  ctx.body = { error: "GatewayManager not initialized" };
43582
44315
  return;
43583
44316
  }
43584
- const status2 = await mgr.detectStatus(ctx.params.name);
43585
- ctx.body = { gateway: status2 };
44317
+ const status3 = await mgr.detectStatus(ctx.params.name);
44318
+ ctx.body = { gateway: status3 };
43586
44319
  }
43587
44320
 
43588
44321
  // packages/server/src/routes/hermes/gateways.ts
43589
44322
  var gatewayRoutes = new router_default();
43590
44323
  gatewayRoutes.get("/api/hermes/gateways", list5);
43591
- gatewayRoutes.post("/api/hermes/gateways/:name/start", start2);
44324
+ gatewayRoutes.post("/api/hermes/gateways/:name/start", start3);
43592
44325
  gatewayRoutes.post("/api/hermes/gateways/:name/stop", stop);
43593
44326
  gatewayRoutes.get("/api/hermes/gateways/:name/health", health);
43594
44327
 
@@ -44363,7 +45096,7 @@ var import_url2 = __toESM(require("url"), 1);
44363
45096
  var URLSearchParams_default = import_url2.default.URLSearchParams;
44364
45097
 
44365
45098
  // node_modules/axios/lib/platform/node/index.js
44366
- var import_crypto4 = __toESM(require("crypto"), 1);
45099
+ var import_crypto5 = __toESM(require("crypto"), 1);
44367
45100
  var ALPHA = "abcdefghijklmnopqrstuvwxyz";
44368
45101
  var DIGIT = "0123456789";
44369
45102
  var ALPHABET = {
@@ -44375,7 +45108,7 @@ var generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
44375
45108
  let str2 = "";
44376
45109
  const { length } = alphabet;
44377
45110
  const randomValues = new Uint32Array(size);
44378
- import_crypto4.default.randomFillSync(randomValues);
45111
+ import_crypto5.default.randomFillSync(randomValues);
44379
45112
  for (let i = 0; i < size; i++) {
44380
45113
  str2 += alphabet[randomValues[i] % length];
44381
45114
  }
@@ -44582,8 +45315,8 @@ var defaults = {
44582
45315
  FormData: platform_default.classes.FormData,
44583
45316
  Blob: platform_default.classes.Blob
44584
45317
  },
44585
- validateStatus: function validateStatus(status2) {
44586
- return status2 >= 200 && status2 < 300;
45318
+ validateStatus: function validateStatus(status3) {
45319
+ return status3 >= 200 && status3 < 300;
44587
45320
  },
44588
45321
  headers: {
44589
45322
  common: {
@@ -44941,10 +45674,10 @@ var CanceledError = class extends AxiosError_default {
44941
45674
  var CanceledError_default = CanceledError;
44942
45675
 
44943
45676
  // node_modules/axios/lib/core/settle.js
44944
- function settle(resolve10, reject, response) {
45677
+ function settle(resolve11, reject, response) {
44945
45678
  const validateStatus2 = response.config.validateStatus;
44946
45679
  if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
44947
- resolve10(response);
45680
+ resolve11(response);
44948
45681
  } else {
44949
45682
  reject(
44950
45683
  new AxiosError_default(
@@ -45731,7 +46464,7 @@ function setProxy(options, configProxy, location) {
45731
46464
  }
45732
46465
  var isHttpAdapterSupported = typeof process !== "undefined" && utils_default.kindOf(process) === "process";
45733
46466
  var wrapAsync = (asyncExecutor) => {
45734
- return new Promise((resolve10, reject) => {
46467
+ return new Promise((resolve11, reject) => {
45735
46468
  let onDone;
45736
46469
  let isDone;
45737
46470
  const done = (value, isRejected) => {
@@ -45741,7 +46474,7 @@ var wrapAsync = (asyncExecutor) => {
45741
46474
  };
45742
46475
  const _resolve = (value) => {
45743
46476
  done(value);
45744
- resolve10(value);
46477
+ resolve11(value);
45745
46478
  };
45746
46479
  const _reject = (reason) => {
45747
46480
  done(reason, true);
@@ -45778,17 +46511,17 @@ var http2Transport = {
45778
46511
  req.once("response", (responseHeaders) => {
45779
46512
  const response = req;
45780
46513
  responseHeaders = Object.assign({}, responseHeaders);
45781
- const status2 = responseHeaders[HTTP2_HEADER_STATUS];
46514
+ const status3 = responseHeaders[HTTP2_HEADER_STATUS];
45782
46515
  delete responseHeaders[HTTP2_HEADER_STATUS];
45783
46516
  response.headers = responseHeaders;
45784
- response.statusCode = +status2;
46517
+ response.statusCode = +status3;
45785
46518
  cb(response);
45786
46519
  });
45787
46520
  return req;
45788
46521
  }
45789
46522
  };
45790
46523
  var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
45791
- return wrapAsync(async function dispatchHttpRequest(resolve10, reject, onDone) {
46524
+ return wrapAsync(async function dispatchHttpRequest(resolve11, reject, onDone) {
45792
46525
  let { data, lookup, family, httpVersion = 1, http2Options } = config2;
45793
46526
  const { responseType, responseEncoding } = config2;
45794
46527
  const method = config2.method.toUpperCase();
@@ -45878,7 +46611,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
45878
46611
  }
45879
46612
  let convertedData;
45880
46613
  if (method !== "GET") {
45881
- return settle(resolve10, reject, {
46614
+ return settle(resolve11, reject, {
45882
46615
  status: 405,
45883
46616
  statusText: "method not allowed",
45884
46617
  headers: {},
@@ -45900,7 +46633,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
45900
46633
  } else if (responseType === "stream") {
45901
46634
  convertedData = import_stream5.default.Readable.from(convertedData);
45902
46635
  }
45903
- return settle(resolve10, reject, {
46636
+ return settle(resolve11, reject, {
45904
46637
  data: convertedData,
45905
46638
  status: 200,
45906
46639
  statusText: "OK",
@@ -46141,7 +46874,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
46141
46874
  };
46142
46875
  if (responseType === "stream") {
46143
46876
  response.data = responseStream;
46144
- settle(resolve10, reject, response);
46877
+ settle(resolve11, reject, response);
46145
46878
  } else {
46146
46879
  const responseBuffer = [];
46147
46880
  let totalResponseBytes = 0;
@@ -46191,7 +46924,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
46191
46924
  } catch (err) {
46192
46925
  return reject(AxiosError_default.from(err, null, config2, response.request, response));
46193
46926
  }
46194
- settle(resolve10, reject, response);
46927
+ settle(resolve11, reject, response);
46195
46928
  });
46196
46929
  }
46197
46930
  abortEmitter.once("abort", (err) => {
@@ -46452,7 +47185,7 @@ var resolveConfig_default = (config2) => {
46452
47185
  // node_modules/axios/lib/adapters/xhr.js
46453
47186
  var isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
46454
47187
  var xhr_default = isXHRAdapterSupported && function(config2) {
46455
- return new Promise(function dispatchXhrRequest(resolve10, reject) {
47188
+ return new Promise(function dispatchXhrRequest(resolve11, reject) {
46456
47189
  const _config = resolveConfig_default(config2);
46457
47190
  let requestData = _config.data;
46458
47191
  const requestHeaders = AxiosHeaders_default.from(_config.headers).normalize();
@@ -46487,7 +47220,7 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
46487
47220
  };
46488
47221
  settle(
46489
47222
  function _resolve(value) {
46490
- resolve10(value);
47223
+ resolve11(value);
46491
47224
  done();
46492
47225
  },
46493
47226
  function _reject(err) {
@@ -46518,7 +47251,7 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
46518
47251
  reject(new AxiosError_default("Request aborted", AxiosError_default.ECONNABORTED, config2, request));
46519
47252
  request = null;
46520
47253
  };
46521
- request.onerror = function handleError(event) {
47254
+ request.onerror = function handleError2(event) {
46522
47255
  const msg = event && event.message ? event.message : "Network Error";
46523
47256
  const err = new AxiosError_default(msg, AxiosError_default.ERR_NETWORK, config2, request);
46524
47257
  err.event = event || null;
@@ -46887,8 +47620,8 @@ var factory = (env) => {
46887
47620
  config2
46888
47621
  );
46889
47622
  !isStreamResponse && unsubscribe && unsubscribe();
46890
- return await new Promise((resolve10, reject) => {
46891
- settle(resolve10, reject, {
47623
+ return await new Promise((resolve11, reject) => {
47624
+ settle(resolve11, reject, {
46892
47625
  data: responseData,
46893
47626
  headers: AxiosHeaders_default.from(response.headers),
46894
47627
  status: response.status,
@@ -47314,8 +48047,8 @@ var CancelToken = class _CancelToken {
47314
48047
  throw new TypeError("executor must be a function.");
47315
48048
  }
47316
48049
  let resolvePromise;
47317
- this.promise = new Promise(function promiseExecutor(resolve10) {
47318
- resolvePromise = resolve10;
48050
+ this.promise = new Promise(function promiseExecutor(resolve11) {
48051
+ resolvePromise = resolve11;
47319
48052
  });
47320
48053
  const token = this;
47321
48054
  this.promise.then((cancel) => {
@@ -47328,9 +48061,9 @@ var CancelToken = class _CancelToken {
47328
48061
  });
47329
48062
  this.promise.then = (onfulfilled) => {
47330
48063
  let _resolve;
47331
- const promise = new Promise((resolve10) => {
47332
- token.subscribe(resolve10);
47333
- _resolve = resolve10;
48064
+ const promise = new Promise((resolve11) => {
48065
+ token.subscribe(resolve11);
48066
+ _resolve = resolve11;
47334
48067
  }).then(onfulfilled);
47335
48068
  promise.cancel = function reject() {
47336
48069
  token.unsubscribe(_resolve);
@@ -47577,11 +48310,11 @@ async function pollStatus(ctx) {
47577
48310
  try {
47578
48311
  const res = await axios_default.get(`${ILINK_BASE}/ilink/bot/get_qrcode_status`, { params: { qrcode }, timeout: 35e3 });
47579
48312
  const data = res.data;
47580
- const status2 = data?.status || "wait";
47581
- if (status2 === "confirmed") {
48313
+ const status3 = data?.status || "wait";
48314
+ if (status3 === "confirmed") {
47582
48315
  ctx.body = { status: "confirmed", account_id: data.ilink_bot_id, token: data.bot_token, base_url: data.baseurl };
47583
48316
  } else {
47584
- ctx.body = { status: status2 };
48317
+ ctx.body = { status: status3 };
47585
48318
  }
47586
48319
  } catch (err) {
47587
48320
  ctx.status = 500;
@@ -47650,6 +48383,1073 @@ weixinRoutes.get("/api/hermes/weixin/qrcode", getQrcode);
47650
48383
  weixinRoutes.get("/api/hermes/weixin/qrcode/status", pollStatus);
47651
48384
  weixinRoutes.post("/api/hermes/weixin/save", save2);
47652
48385
 
48386
+ // packages/server/src/services/hermes/file-provider.ts
48387
+ var import_promises14 = require("fs/promises");
48388
+ var import_path17 = require("path");
48389
+ var import_child_process5 = require("child_process");
48390
+ var import_util5 = require("util");
48391
+ var import_fs16 = require("fs");
48392
+ init_js_yaml();
48393
+ init_hermes_profile();
48394
+ var execFileAsync3 = (0, import_util5.promisify)(import_child_process5.execFile);
48395
+ var MAX_DOWNLOAD_SIZE = parseInt(process.env.MAX_DOWNLOAD_SIZE || "", 10) || 100 * 1024 * 1024;
48396
+ var BACKEND_TIMEOUT = 3e4;
48397
+ var MAX_EDIT_SIZE = parseInt(process.env.MAX_EDIT_SIZE || "", 10) || 10 * 1024 * 1024;
48398
+ var SENSITIVE_FILES = /* @__PURE__ */ new Set([".env", "auth.json"]);
48399
+ function validatePath(filePath) {
48400
+ if (!filePath) throw Object.assign(new Error("Missing file path"), { code: "missing_path" });
48401
+ const resolved = (0, import_path17.resolve)(filePath);
48402
+ const normalized = (0, import_path17.normalize)(resolved);
48403
+ if (normalized.includes("..")) {
48404
+ throw Object.assign(new Error("Invalid file path"), { code: "invalid_path" });
48405
+ }
48406
+ if (!(0, import_path17.isAbsolute)(normalized)) {
48407
+ throw Object.assign(new Error("Path must be absolute"), { code: "invalid_path" });
48408
+ }
48409
+ return normalized;
48410
+ }
48411
+ function isInUploadDir(filePath) {
48412
+ const normalized = (0, import_path17.normalize)((0, import_path17.resolve)(filePath));
48413
+ const uploadNormalized = (0, import_path17.normalize)((0, import_path17.resolve)(config.uploadDir));
48414
+ return normalized.startsWith(uploadNormalized + "/") || normalized.startsWith(uploadNormalized + "\\") || normalized === uploadNormalized;
48415
+ }
48416
+ function isSensitivePath(relativePath) {
48417
+ const parts = relativePath.replace(/\\/g, "/").split("/");
48418
+ const fileName = parts[parts.length - 1];
48419
+ return SENSITIVE_FILES.has(fileName);
48420
+ }
48421
+ function resolveHermesPath(relativePath) {
48422
+ const homeDir = getActiveProfileDir();
48423
+ if (!relativePath || relativePath === "." || relativePath === "/") {
48424
+ return homeDir;
48425
+ }
48426
+ const normalized = (0, import_path17.normalize)(relativePath).replace(/\\/g, "/");
48427
+ if (normalized.startsWith("..") || normalized.includes("/../") || normalized.startsWith("/")) {
48428
+ throw Object.assign(new Error("Invalid file path"), { code: "invalid_path" });
48429
+ }
48430
+ const resolved = (0, import_path17.resolve)(homeDir, normalized);
48431
+ if (!resolved.startsWith(homeDir)) {
48432
+ throw Object.assign(new Error("Path traversal detected"), { code: "invalid_path" });
48433
+ }
48434
+ return resolved;
48435
+ }
48436
+ var LocalFileProvider = class {
48437
+ type = "local";
48438
+ async readFile(filePath) {
48439
+ const p = validatePath(filePath);
48440
+ const s = await (0, import_promises14.stat)(p);
48441
+ if (!s.isFile()) throw Object.assign(new Error("Not a file"), { code: "not_found" });
48442
+ if (s.size > MAX_DOWNLOAD_SIZE) {
48443
+ throw Object.assign(new Error(`File too large: ${s.size} bytes`), { code: "file_too_large" });
48444
+ }
48445
+ return (0, import_promises14.readFile)(p);
48446
+ }
48447
+ async exists(filePath) {
48448
+ try {
48449
+ const p = validatePath(filePath);
48450
+ const s = await (0, import_promises14.stat)(p);
48451
+ return s.isFile();
48452
+ } catch {
48453
+ return false;
48454
+ }
48455
+ }
48456
+ async listDir(dirPath) {
48457
+ const p = validatePath(dirPath);
48458
+ const homeDir = getActiveProfileDir();
48459
+ const entries = await (0, import_promises14.readdir)(p, { withFileTypes: true });
48460
+ const results = [];
48461
+ for (const entry of entries) {
48462
+ try {
48463
+ const fullPath = (0, import_path17.resolve)(p, entry.name);
48464
+ const s = await (0, import_promises14.stat)(fullPath);
48465
+ const relPath = fullPath.startsWith(homeDir) ? fullPath.slice(homeDir.length + 1) : entry.name;
48466
+ results.push({
48467
+ name: entry.name,
48468
+ path: relPath,
48469
+ isDir: s.isDirectory(),
48470
+ size: s.size,
48471
+ modTime: s.mtime.toISOString()
48472
+ });
48473
+ } catch {
48474
+ }
48475
+ }
48476
+ return results;
48477
+ }
48478
+ async stat(filePath) {
48479
+ const p = validatePath(filePath);
48480
+ const homeDir = getActiveProfileDir();
48481
+ const s = await (0, import_promises14.stat)(p);
48482
+ const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1) : (0, import_path17.basename)(p);
48483
+ return {
48484
+ name: (0, import_path17.basename)(p),
48485
+ path: relPath || (0, import_path17.basename)(p),
48486
+ isDir: s.isDirectory(),
48487
+ size: s.size,
48488
+ modTime: s.mtime.toISOString()
48489
+ };
48490
+ }
48491
+ async writeFile(filePath, content) {
48492
+ const p = validatePath(filePath);
48493
+ await (0, import_promises14.writeFile)(p, content);
48494
+ }
48495
+ async deleteFile(filePath) {
48496
+ const p = validatePath(filePath);
48497
+ const s = await (0, import_promises14.stat)(p);
48498
+ if (!s.isFile()) throw Object.assign(new Error("Not a file"), { code: "not_found" });
48499
+ await (0, import_promises14.rm)(p);
48500
+ }
48501
+ async deleteDir(dirPath) {
48502
+ const p = validatePath(dirPath);
48503
+ const s = await (0, import_promises14.stat)(p);
48504
+ if (!s.isDirectory()) throw Object.assign(new Error("Not a directory"), { code: "not_found" });
48505
+ await (0, import_promises14.rm)(p, { recursive: true });
48506
+ }
48507
+ async renameFile(oldPath, newPath) {
48508
+ const op = validatePath(oldPath);
48509
+ const np = validatePath(newPath);
48510
+ await (0, import_promises14.rename)(op, np);
48511
+ }
48512
+ async mkDir(dirPath) {
48513
+ const p = validatePath(dirPath);
48514
+ await (0, import_promises14.mkdir)(p, { recursive: true });
48515
+ }
48516
+ async copyFile(srcPath, destPath) {
48517
+ const sp = validatePath(srcPath);
48518
+ const dp = validatePath(destPath);
48519
+ await (0, import_promises14.copyFile)(sp, dp);
48520
+ }
48521
+ };
48522
+ function parseLsOutput(output, parentRelPath) {
48523
+ const entries = [];
48524
+ for (const line of output.split("\n")) {
48525
+ const trimmed = line.trim();
48526
+ if (!trimmed || trimmed.startsWith("total ")) continue;
48527
+ const parts = trimmed.split(/\s+/);
48528
+ if (parts.length < 7) continue;
48529
+ const permissions = parts[0];
48530
+ const size = parseInt(parts[4], 10) || 0;
48531
+ const modTime = parts[5];
48532
+ const name = parts.slice(6).join(" ");
48533
+ if (name === "." || name === "..") continue;
48534
+ const isDir = permissions.startsWith("d");
48535
+ const relPath = parentRelPath ? `${parentRelPath}/${name}` : name;
48536
+ entries.push({ name, path: relPath, isDir, size, modTime: modTime.includes("T") ? modTime : new Date(modTime).toISOString() });
48537
+ }
48538
+ return entries;
48539
+ }
48540
+ function parseStatOutput(output, relativePath) {
48541
+ const parts = output.trim().split("|");
48542
+ if (parts.length < 4) throw Object.assign(new Error("Failed to parse stat output"), { code: "backend_error" });
48543
+ const name = (0, import_path17.basename)(parts[0]);
48544
+ const fileType = parts[1].toLowerCase();
48545
+ const size = parseInt(parts[2], 10) || 0;
48546
+ const modEpoch = parseInt(parts[3], 10) || 0;
48547
+ const isDir = fileType.includes("directory");
48548
+ return {
48549
+ name,
48550
+ path: relativePath,
48551
+ isDir,
48552
+ size,
48553
+ modTime: new Date(modEpoch * 1e3).toISOString()
48554
+ };
48555
+ }
48556
+ var DockerFileProvider = class {
48557
+ type = "docker";
48558
+ containerName;
48559
+ constructor(containerName) {
48560
+ this.containerName = containerName;
48561
+ }
48562
+ async readFile(filePath) {
48563
+ const p = validatePath(filePath);
48564
+ try {
48565
+ const { stdout } = await execFileAsync3("docker", [
48566
+ "exec",
48567
+ this.containerName,
48568
+ "cat",
48569
+ p
48570
+ ], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
48571
+ return stdout;
48572
+ } catch (err) {
48573
+ if (err.code === "ETIMEDOUT" || err.killed) {
48574
+ throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48575
+ }
48576
+ if (err.stderr && /no such file/i.test(String(err.stderr))) {
48577
+ throw Object.assign(new Error("File not found in container"), { code: "not_found" });
48578
+ }
48579
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48580
+ }
48581
+ }
48582
+ async exists(filePath) {
48583
+ const p = validatePath(filePath);
48584
+ try {
48585
+ await execFileAsync3("docker", [
48586
+ "exec",
48587
+ this.containerName,
48588
+ "test",
48589
+ "-f",
48590
+ p
48591
+ ], { timeout: 5e3 });
48592
+ return true;
48593
+ } catch {
48594
+ return false;
48595
+ }
48596
+ }
48597
+ async listDir(dirPath) {
48598
+ const p = validatePath(dirPath);
48599
+ try {
48600
+ const { stdout } = await execFileAsync3("docker", [
48601
+ "exec",
48602
+ this.containerName,
48603
+ "ls",
48604
+ "-la",
48605
+ "--time-style=+%Y-%m-%dT%H:%M:%S",
48606
+ p
48607
+ ], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
48608
+ const homeDir = getActiveProfileDir();
48609
+ const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
48610
+ return parseLsOutput(stdout, relParent);
48611
+ } catch (err) {
48612
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48613
+ if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
48614
+ throw Object.assign(new Error("Directory not found"), { code: "not_found" });
48615
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48616
+ }
48617
+ }
48618
+ async stat(filePath) {
48619
+ const p = validatePath(filePath);
48620
+ try {
48621
+ const { stdout } = await execFileAsync3("docker", [
48622
+ "exec",
48623
+ this.containerName,
48624
+ "stat",
48625
+ "-c",
48626
+ "%n|%F|%s|%Y",
48627
+ p
48628
+ ], { timeout: BACKEND_TIMEOUT });
48629
+ const homeDir = getActiveProfileDir();
48630
+ const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
48631
+ return parseStatOutput(stdout, relPath);
48632
+ } catch (err) {
48633
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48634
+ if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
48635
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48636
+ }
48637
+ }
48638
+ async writeFile(filePath, content) {
48639
+ const p = validatePath(filePath);
48640
+ try {
48641
+ await execFileAsync3("docker", [
48642
+ "exec",
48643
+ "-i",
48644
+ this.containerName,
48645
+ "sh",
48646
+ "-c",
48647
+ `cat > '${p.replace(/'/g, "'\\''")}'`
48648
+ ], { timeout: BACKEND_TIMEOUT, input: content });
48649
+ } catch (err) {
48650
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48651
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48652
+ }
48653
+ }
48654
+ async deleteFile(filePath) {
48655
+ const p = validatePath(filePath);
48656
+ try {
48657
+ await execFileAsync3("docker", ["exec", this.containerName, "rm", p], { timeout: BACKEND_TIMEOUT });
48658
+ } catch (err) {
48659
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48660
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48661
+ }
48662
+ }
48663
+ async deleteDir(dirPath) {
48664
+ const p = validatePath(dirPath);
48665
+ try {
48666
+ await execFileAsync3("docker", ["exec", this.containerName, "rm", "-rf", p], { timeout: BACKEND_TIMEOUT });
48667
+ } catch (err) {
48668
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48669
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48670
+ }
48671
+ }
48672
+ async renameFile(oldPath, newPath) {
48673
+ const op = validatePath(oldPath);
48674
+ const np = validatePath(newPath);
48675
+ try {
48676
+ await execFileAsync3("docker", ["exec", this.containerName, "mv", op, np], { timeout: BACKEND_TIMEOUT });
48677
+ } catch (err) {
48678
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48679
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48680
+ }
48681
+ }
48682
+ async mkDir(dirPath) {
48683
+ const p = validatePath(dirPath);
48684
+ try {
48685
+ await execFileAsync3("docker", ["exec", this.containerName, "mkdir", "-p", p], { timeout: BACKEND_TIMEOUT });
48686
+ } catch (err) {
48687
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48688
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48689
+ }
48690
+ }
48691
+ async copyFile(srcPath, destPath) {
48692
+ const sp = validatePath(srcPath);
48693
+ const dp = validatePath(destPath);
48694
+ try {
48695
+ await execFileAsync3("docker", ["exec", this.containerName, "cp", sp, dp], { timeout: BACKEND_TIMEOUT });
48696
+ } catch (err) {
48697
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48698
+ throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
48699
+ }
48700
+ }
48701
+ };
48702
+ var SSHFileProvider = class {
48703
+ type = "ssh";
48704
+ host;
48705
+ user;
48706
+ keyPath;
48707
+ constructor(host, user, keyPath) {
48708
+ this.host = host;
48709
+ this.user = user;
48710
+ this.keyPath = keyPath;
48711
+ }
48712
+ sshArgs() {
48713
+ const args2 = ["-o", "StrictHostKeyChecking=no", "-o", "BatchMode=yes"];
48714
+ if (this.keyPath) args2.push("-i", this.keyPath);
48715
+ args2.push(`${this.user}@${this.host}`);
48716
+ return args2;
48717
+ }
48718
+ /**
48719
+ * Shell-escape a string for safe use in a remote SSH command.
48720
+ * Wraps in single quotes and escapes embedded single quotes.
48721
+ */
48722
+ shellEscape(s) {
48723
+ return "'" + s.replace(/'/g, "'\\''") + "'";
48724
+ }
48725
+ async readFile(filePath) {
48726
+ const p = validatePath(filePath);
48727
+ try {
48728
+ const { stdout } = await execFileAsync3("ssh", [
48729
+ ...this.sshArgs(),
48730
+ `cat ${this.shellEscape(p)}`
48731
+ ], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
48732
+ return stdout;
48733
+ } catch (err) {
48734
+ if (err.code === "ETIMEDOUT" || err.killed) {
48735
+ throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48736
+ }
48737
+ if (err.stderr && /no such file/i.test(String(err.stderr))) {
48738
+ throw Object.assign(new Error("File not found on remote"), { code: "not_found" });
48739
+ }
48740
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48741
+ }
48742
+ }
48743
+ async exists(filePath) {
48744
+ const p = validatePath(filePath);
48745
+ try {
48746
+ await execFileAsync3("ssh", [
48747
+ ...this.sshArgs(),
48748
+ `test -f ${this.shellEscape(p)}`
48749
+ ], { timeout: 5e3 });
48750
+ return true;
48751
+ } catch {
48752
+ return false;
48753
+ }
48754
+ }
48755
+ async listDir(dirPath) {
48756
+ const p = validatePath(dirPath);
48757
+ try {
48758
+ const { stdout } = await execFileAsync3("ssh", [
48759
+ ...this.sshArgs(),
48760
+ `ls -la --time-style=+%Y-%m-%dT%H:%M:%S ${this.shellEscape(p)}`
48761
+ ], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
48762
+ const homeDir = getActiveProfileDir();
48763
+ const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
48764
+ return parseLsOutput(stdout, relParent);
48765
+ } catch (err) {
48766
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48767
+ if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
48768
+ throw Object.assign(new Error("Directory not found"), { code: "not_found" });
48769
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48770
+ }
48771
+ }
48772
+ async stat(filePath) {
48773
+ const p = validatePath(filePath);
48774
+ try {
48775
+ const { stdout } = await execFileAsync3("ssh", [
48776
+ ...this.sshArgs(),
48777
+ `stat -c '%n|%F|%s|%Y' ${this.shellEscape(p)}`
48778
+ ], { timeout: BACKEND_TIMEOUT });
48779
+ const homeDir = getActiveProfileDir();
48780
+ const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
48781
+ return parseStatOutput(stdout, relPath);
48782
+ } catch (err) {
48783
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48784
+ if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
48785
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48786
+ }
48787
+ }
48788
+ async writeFile(filePath, content) {
48789
+ const p = validatePath(filePath);
48790
+ try {
48791
+ await execFileAsync3("ssh", [
48792
+ ...this.sshArgs(),
48793
+ `cat > ${this.shellEscape(p)}`
48794
+ ], { timeout: BACKEND_TIMEOUT, input: content });
48795
+ } catch (err) {
48796
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48797
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48798
+ }
48799
+ }
48800
+ async deleteFile(filePath) {
48801
+ const p = validatePath(filePath);
48802
+ try {
48803
+ await execFileAsync3("ssh", [...this.sshArgs(), `rm ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
48804
+ } catch (err) {
48805
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48806
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48807
+ }
48808
+ }
48809
+ async deleteDir(dirPath) {
48810
+ const p = validatePath(dirPath);
48811
+ try {
48812
+ await execFileAsync3("ssh", [...this.sshArgs(), `rm -rf ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
48813
+ } catch (err) {
48814
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48815
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48816
+ }
48817
+ }
48818
+ async renameFile(oldPath, newPath) {
48819
+ const op = validatePath(oldPath);
48820
+ const np = validatePath(newPath);
48821
+ try {
48822
+ await execFileAsync3("ssh", [...this.sshArgs(), `mv ${this.shellEscape(op)} ${this.shellEscape(np)}`], { timeout: BACKEND_TIMEOUT });
48823
+ } catch (err) {
48824
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48825
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48826
+ }
48827
+ }
48828
+ async mkDir(dirPath) {
48829
+ const p = validatePath(dirPath);
48830
+ try {
48831
+ await execFileAsync3("ssh", [...this.sshArgs(), `mkdir -p ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
48832
+ } catch (err) {
48833
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48834
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48835
+ }
48836
+ }
48837
+ async copyFile(srcPath, destPath) {
48838
+ const sp = validatePath(srcPath);
48839
+ const dp = validatePath(destPath);
48840
+ try {
48841
+ await execFileAsync3("ssh", [...this.sshArgs(), `cp ${this.shellEscape(sp)} ${this.shellEscape(dp)}`], { timeout: BACKEND_TIMEOUT });
48842
+ } catch (err) {
48843
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48844
+ throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
48845
+ }
48846
+ }
48847
+ };
48848
+ var SingularityFileProvider = class {
48849
+ type = "singularity";
48850
+ imagePath;
48851
+ constructor(imagePath) {
48852
+ this.imagePath = imagePath;
48853
+ }
48854
+ async readFile(filePath) {
48855
+ const p = validatePath(filePath);
48856
+ try {
48857
+ const { stdout } = await execFileAsync3("singularity", [
48858
+ "exec",
48859
+ this.imagePath,
48860
+ "cat",
48861
+ p
48862
+ ], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
48863
+ return stdout;
48864
+ } catch (err) {
48865
+ if (err.code === "ETIMEDOUT" || err.killed) {
48866
+ throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48867
+ }
48868
+ if (err.stderr && /no such file/i.test(String(err.stderr))) {
48869
+ throw Object.assign(new Error("File not found in container"), { code: "not_found" });
48870
+ }
48871
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48872
+ }
48873
+ }
48874
+ async exists(filePath) {
48875
+ const p = validatePath(filePath);
48876
+ try {
48877
+ await execFileAsync3("singularity", [
48878
+ "exec",
48879
+ this.imagePath,
48880
+ "test",
48881
+ "-f",
48882
+ p
48883
+ ], { timeout: 5e3 });
48884
+ return true;
48885
+ } catch {
48886
+ return false;
48887
+ }
48888
+ }
48889
+ async listDir(dirPath) {
48890
+ const p = validatePath(dirPath);
48891
+ try {
48892
+ const { stdout } = await execFileAsync3("singularity", [
48893
+ "exec",
48894
+ this.imagePath,
48895
+ "ls",
48896
+ "-la",
48897
+ "--time-style=+%Y-%m-%dT%H:%M:%S",
48898
+ p
48899
+ ], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
48900
+ const homeDir = getActiveProfileDir();
48901
+ const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
48902
+ return parseLsOutput(stdout, relParent);
48903
+ } catch (err) {
48904
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48905
+ if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
48906
+ throw Object.assign(new Error("Directory not found"), { code: "not_found" });
48907
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48908
+ }
48909
+ }
48910
+ async stat(filePath) {
48911
+ const p = validatePath(filePath);
48912
+ try {
48913
+ const { stdout } = await execFileAsync3("singularity", [
48914
+ "exec",
48915
+ this.imagePath,
48916
+ "stat",
48917
+ "-c",
48918
+ "%n|%F|%s|%Y",
48919
+ p
48920
+ ], { timeout: BACKEND_TIMEOUT });
48921
+ const homeDir = getActiveProfileDir();
48922
+ const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
48923
+ return parseStatOutput(stdout, relPath);
48924
+ } catch (err) {
48925
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48926
+ if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
48927
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48928
+ }
48929
+ }
48930
+ async writeFile(filePath, content) {
48931
+ const p = validatePath(filePath);
48932
+ try {
48933
+ await execFileAsync3("singularity", [
48934
+ "exec",
48935
+ this.imagePath,
48936
+ "sh",
48937
+ "-c",
48938
+ `cat > '${p.replace(/'/g, "'\\''")}'`
48939
+ ], { timeout: BACKEND_TIMEOUT, input: content });
48940
+ } catch (err) {
48941
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48942
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48943
+ }
48944
+ }
48945
+ async deleteFile(filePath) {
48946
+ const p = validatePath(filePath);
48947
+ try {
48948
+ await execFileAsync3("singularity", ["exec", this.imagePath, "rm", p], { timeout: BACKEND_TIMEOUT });
48949
+ } catch (err) {
48950
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48951
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48952
+ }
48953
+ }
48954
+ async deleteDir(dirPath) {
48955
+ const p = validatePath(dirPath);
48956
+ try {
48957
+ await execFileAsync3("singularity", ["exec", this.imagePath, "rm", "-rf", p], { timeout: BACKEND_TIMEOUT });
48958
+ } catch (err) {
48959
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48960
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48961
+ }
48962
+ }
48963
+ async renameFile(oldPath, newPath) {
48964
+ const op = validatePath(oldPath);
48965
+ const np = validatePath(newPath);
48966
+ try {
48967
+ await execFileAsync3("singularity", ["exec", this.imagePath, "mv", op, np], { timeout: BACKEND_TIMEOUT });
48968
+ } catch (err) {
48969
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48970
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48971
+ }
48972
+ }
48973
+ async mkDir(dirPath) {
48974
+ const p = validatePath(dirPath);
48975
+ try {
48976
+ await execFileAsync3("singularity", ["exec", this.imagePath, "mkdir", "-p", p], { timeout: BACKEND_TIMEOUT });
48977
+ } catch (err) {
48978
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48979
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48980
+ }
48981
+ }
48982
+ async copyFile(srcPath, destPath) {
48983
+ const sp = validatePath(srcPath);
48984
+ const dp = validatePath(destPath);
48985
+ try {
48986
+ await execFileAsync3("singularity", ["exec", this.imagePath, "cp", sp, dp], { timeout: BACKEND_TIMEOUT });
48987
+ } catch (err) {
48988
+ if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
48989
+ throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
48990
+ }
48991
+ }
48992
+ };
48993
+ function getTerminalConfig() {
48994
+ try {
48995
+ const configPath3 = `${getActiveProfileDir()}/config.yaml`;
48996
+ if (!(0, import_fs16.existsSync)(configPath3)) return { backend: "local" };
48997
+ const raw = (0, import_fs16.readFileSync)(configPath3, "utf-8");
48998
+ const doc = jsYaml.load(raw);
48999
+ const t = doc?.terminal || {};
49000
+ return {
49001
+ backend: t.backend || "local",
49002
+ docker_image: t.docker_image,
49003
+ docker_container_name: t.docker_container_name,
49004
+ cwd: t.cwd,
49005
+ singularity_image: t.singularity_image
49006
+ };
49007
+ } catch {
49008
+ return { backend: "local" };
49009
+ }
49010
+ }
49011
+ function getSSHEnvVars() {
49012
+ try {
49013
+ const envPath3 = getActiveEnvPath();
49014
+ if (!(0, import_fs16.existsSync)(envPath3)) return {};
49015
+ const raw = (0, import_fs16.readFileSync)(envPath3, "utf-8");
49016
+ const vars = {};
49017
+ for (const line of raw.split("\n")) {
49018
+ const trimmed = line.trim();
49019
+ if (!trimmed || trimmed.startsWith("#")) continue;
49020
+ const eqIdx = trimmed.indexOf("=");
49021
+ if (eqIdx === -1) continue;
49022
+ let value = trimmed.slice(eqIdx + 1).trim();
49023
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
49024
+ value = value.slice(1, -1);
49025
+ }
49026
+ vars[trimmed.slice(0, eqIdx).trim()] = value;
49027
+ }
49028
+ return {
49029
+ host: vars.TERMINAL_SSH_HOST,
49030
+ user: vars.TERMINAL_SSH_USER,
49031
+ key: vars.TERMINAL_SSH_KEY
49032
+ };
49033
+ } catch {
49034
+ return {};
49035
+ }
49036
+ }
49037
+ async function resolveDockerContainer(cfg) {
49038
+ if (cfg.docker_container_name) return cfg.docker_container_name;
49039
+ if (cfg.docker_image) {
49040
+ try {
49041
+ const { stdout } = await execFileAsync3("docker", [
49042
+ "ps",
49043
+ "-q",
49044
+ "--filter",
49045
+ `ancestor=${cfg.docker_image}`,
49046
+ "--latest"
49047
+ ], { timeout: 5e3 });
49048
+ const id = stdout.trim();
49049
+ if (id) return id;
49050
+ } catch {
49051
+ }
49052
+ }
49053
+ throw Object.assign(
49054
+ new Error("Cannot determine Docker container. Set terminal.docker_container_name in hermes config."),
49055
+ { code: "backend_error" }
49056
+ );
49057
+ }
49058
+ var cachedProvider = null;
49059
+ var cachedAt = 0;
49060
+ var CACHE_TTL = 1e4;
49061
+ function _resetFileProviderCache() {
49062
+ cachedProvider = null;
49063
+ cachedAt = 0;
49064
+ }
49065
+ async function createFileProvider() {
49066
+ const now = Date.now();
49067
+ if (cachedProvider && now - cachedAt < CACHE_TTL) return cachedProvider;
49068
+ const cfg = getTerminalConfig();
49069
+ let provider;
49070
+ switch (cfg.backend) {
49071
+ case "docker": {
49072
+ const container = await resolveDockerContainer(cfg);
49073
+ provider = new DockerFileProvider(container);
49074
+ break;
49075
+ }
49076
+ case "ssh": {
49077
+ const ssh = getSSHEnvVars();
49078
+ if (!ssh.host || !ssh.user) {
49079
+ throw Object.assign(
49080
+ new Error("SSH backend requires TERMINAL_SSH_HOST and TERMINAL_SSH_USER in .env"),
49081
+ { code: "backend_error" }
49082
+ );
49083
+ }
49084
+ provider = new SSHFileProvider(ssh.host, ssh.user, ssh.key);
49085
+ break;
49086
+ }
49087
+ case "singularity": {
49088
+ if (!cfg.singularity_image) {
49089
+ throw Object.assign(
49090
+ new Error("Singularity backend requires terminal.singularity_image in config"),
49091
+ { code: "backend_error" }
49092
+ );
49093
+ }
49094
+ provider = new SingularityFileProvider(cfg.singularity_image);
49095
+ break;
49096
+ }
49097
+ case "modal":
49098
+ case "daytona":
49099
+ throw Object.assign(
49100
+ new Error(`File download not yet supported for '${cfg.backend}' backend`),
49101
+ { code: "unsupported_backend" }
49102
+ );
49103
+ default:
49104
+ provider = new LocalFileProvider();
49105
+ }
49106
+ cachedProvider = provider;
49107
+ cachedAt = now;
49108
+ return provider;
49109
+ }
49110
+ var localProvider = new LocalFileProvider();
49111
+
49112
+ // packages/server/src/routes/hermes/files.ts
49113
+ var fileRoutes = new router_default();
49114
+ function handleError(ctx, err) {
49115
+ const code = err.code || "unknown";
49116
+ const statusMap = {
49117
+ missing_path: 400,
49118
+ invalid_path: 400,
49119
+ not_found: 404,
49120
+ ENOENT: 404,
49121
+ already_exists: 409,
49122
+ permission_denied: 403,
49123
+ file_too_large: 413,
49124
+ not_a_directory: 400,
49125
+ not_a_file: 400,
49126
+ unsupported_backend: 501,
49127
+ backend_error: 502,
49128
+ backend_timeout: 504
49129
+ };
49130
+ ctx.status = statusMap[code] || 500;
49131
+ ctx.body = { error: err.message, code };
49132
+ }
49133
+ fileRoutes.get("/api/hermes/files/list", async (ctx) => {
49134
+ const relativePath = ctx.query.path || "";
49135
+ try {
49136
+ const absPath = resolveHermesPath(relativePath);
49137
+ const provider = await createFileProvider();
49138
+ const entries = await provider.listDir(absPath);
49139
+ entries.sort((a, b) => {
49140
+ if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
49141
+ return a.name.localeCompare(b.name);
49142
+ });
49143
+ ctx.body = { entries, path: relativePath };
49144
+ } catch (err) {
49145
+ handleError(ctx, err);
49146
+ }
49147
+ });
49148
+ fileRoutes.get("/api/hermes/files/stat", async (ctx) => {
49149
+ const relativePath = ctx.query.path;
49150
+ if (!relativePath) {
49151
+ ctx.status = 400;
49152
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49153
+ return;
49154
+ }
49155
+ try {
49156
+ const absPath = resolveHermesPath(relativePath);
49157
+ const provider = await createFileProvider();
49158
+ const info = await provider.stat(absPath);
49159
+ ctx.body = info;
49160
+ } catch (err) {
49161
+ handleError(ctx, err);
49162
+ }
49163
+ });
49164
+ fileRoutes.get("/api/hermes/files/read", async (ctx) => {
49165
+ const relativePath = ctx.query.path;
49166
+ if (!relativePath) {
49167
+ ctx.status = 400;
49168
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49169
+ return;
49170
+ }
49171
+ try {
49172
+ const absPath = resolveHermesPath(relativePath);
49173
+ const provider = await createFileProvider();
49174
+ const data = await provider.readFile(absPath);
49175
+ if (data.length > MAX_EDIT_SIZE) {
49176
+ ctx.status = 413;
49177
+ ctx.body = { error: "File too large to edit", code: "file_too_large" };
49178
+ return;
49179
+ }
49180
+ ctx.body = { content: data.toString("utf-8"), path: relativePath, size: data.length };
49181
+ } catch (err) {
49182
+ handleError(ctx, err);
49183
+ }
49184
+ });
49185
+ fileRoutes.put("/api/hermes/files/write", async (ctx) => {
49186
+ const { path: relativePath, content } = ctx.request.body;
49187
+ if (!relativePath) {
49188
+ ctx.status = 400;
49189
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49190
+ return;
49191
+ }
49192
+ if (isSensitivePath(relativePath)) {
49193
+ ctx.status = 403;
49194
+ ctx.body = { error: "Cannot modify sensitive file", code: "permission_denied" };
49195
+ return;
49196
+ }
49197
+ try {
49198
+ const buf = Buffer.from(content || "", "utf-8");
49199
+ if (buf.length > MAX_EDIT_SIZE) {
49200
+ ctx.status = 413;
49201
+ ctx.body = { error: "Content too large", code: "file_too_large" };
49202
+ return;
49203
+ }
49204
+ const absPath = resolveHermesPath(relativePath);
49205
+ const provider = await createFileProvider();
49206
+ await provider.writeFile(absPath, buf);
49207
+ ctx.body = { ok: true, path: relativePath };
49208
+ } catch (err) {
49209
+ handleError(ctx, err);
49210
+ }
49211
+ });
49212
+ fileRoutes.delete("/api/hermes/files/delete", async (ctx) => {
49213
+ const { path: relativePath, recursive } = ctx.request.body;
49214
+ if (!relativePath) {
49215
+ ctx.status = 400;
49216
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49217
+ return;
49218
+ }
49219
+ if (isSensitivePath(relativePath)) {
49220
+ ctx.status = 403;
49221
+ ctx.body = { error: "Cannot delete sensitive file", code: "permission_denied" };
49222
+ return;
49223
+ }
49224
+ try {
49225
+ const absPath = resolveHermesPath(relativePath);
49226
+ const provider = await createFileProvider();
49227
+ if (recursive) {
49228
+ await provider.deleteDir(absPath);
49229
+ } else {
49230
+ await provider.deleteFile(absPath);
49231
+ }
49232
+ ctx.body = { ok: true };
49233
+ } catch (err) {
49234
+ handleError(ctx, err);
49235
+ }
49236
+ });
49237
+ fileRoutes.post("/api/hermes/files/rename", async (ctx) => {
49238
+ const { oldPath, newPath } = ctx.request.body;
49239
+ if (!oldPath || !newPath) {
49240
+ ctx.status = 400;
49241
+ ctx.body = { error: "Missing oldPath or newPath", code: "missing_path" };
49242
+ return;
49243
+ }
49244
+ if (isSensitivePath(oldPath)) {
49245
+ ctx.status = 403;
49246
+ ctx.body = { error: "Cannot rename sensitive file", code: "permission_denied" };
49247
+ return;
49248
+ }
49249
+ try {
49250
+ const absOld = resolveHermesPath(oldPath);
49251
+ const absNew = resolveHermesPath(newPath);
49252
+ const provider = await createFileProvider();
49253
+ await provider.renameFile(absOld, absNew);
49254
+ ctx.body = { ok: true };
49255
+ } catch (err) {
49256
+ handleError(ctx, err);
49257
+ }
49258
+ });
49259
+ fileRoutes.post("/api/hermes/files/mkdir", async (ctx) => {
49260
+ const { path: relativePath } = ctx.request.body;
49261
+ if (!relativePath) {
49262
+ ctx.status = 400;
49263
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49264
+ return;
49265
+ }
49266
+ try {
49267
+ const absPath = resolveHermesPath(relativePath);
49268
+ const provider = await createFileProvider();
49269
+ await provider.mkDir(absPath);
49270
+ ctx.body = { ok: true };
49271
+ } catch (err) {
49272
+ handleError(ctx, err);
49273
+ }
49274
+ });
49275
+ fileRoutes.post("/api/hermes/files/copy", async (ctx) => {
49276
+ const { srcPath, destPath } = ctx.request.body;
49277
+ if (!srcPath || !destPath) {
49278
+ ctx.status = 400;
49279
+ ctx.body = { error: "Missing srcPath or destPath", code: "missing_path" };
49280
+ return;
49281
+ }
49282
+ try {
49283
+ const absSrc = resolveHermesPath(srcPath);
49284
+ const absDest = resolveHermesPath(destPath);
49285
+ const provider = await createFileProvider();
49286
+ await provider.copyFile(absSrc, absDest);
49287
+ ctx.body = { ok: true };
49288
+ } catch (err) {
49289
+ handleError(ctx, err);
49290
+ }
49291
+ });
49292
+ fileRoutes.post("/api/hermes/files/upload", async (ctx) => {
49293
+ const targetDir = ctx.query.path || "";
49294
+ const contentType = ctx.get("content-type") || "";
49295
+ if (!contentType.startsWith("multipart/form-data")) {
49296
+ ctx.status = 400;
49297
+ ctx.body = { error: "Expected multipart/form-data", code: "invalid_request" };
49298
+ return;
49299
+ }
49300
+ const boundary = "--" + contentType.split("boundary=")[1];
49301
+ if (!boundary || boundary === "--undefined") {
49302
+ ctx.status = 400;
49303
+ ctx.body = { error: "Missing boundary", code: "invalid_request" };
49304
+ return;
49305
+ }
49306
+ const chunks = [];
49307
+ for await (const chunk of ctx.req) chunks.push(chunk);
49308
+ const raw = Buffer.concat(chunks);
49309
+ const boundaryBuf = Buffer.from(boundary);
49310
+ const parts = splitMultipart2(raw, boundaryBuf);
49311
+ const provider = await createFileProvider();
49312
+ const results = [];
49313
+ for (const part of parts) {
49314
+ const headerEnd = part.indexOf(Buffer.from("\r\n\r\n"));
49315
+ if (headerEnd === -1) continue;
49316
+ const headerBuf = part.subarray(0, headerEnd);
49317
+ const header = headerBuf.toString("utf-8");
49318
+ const data = part.subarray(headerEnd + 4, part.length - 2);
49319
+ let filename = "";
49320
+ const filenameStarMatch = header.match(/filename\*=UTF-8''(.+)/i);
49321
+ if (filenameStarMatch) {
49322
+ filename = decodeURIComponent(filenameStarMatch[1]);
49323
+ } else {
49324
+ const filenameMatch = header.match(/filename="([^"]+)"/);
49325
+ if (!filenameMatch) continue;
49326
+ filename = filenameMatch[1];
49327
+ }
49328
+ if (data.length > MAX_EDIT_SIZE) {
49329
+ ctx.status = 413;
49330
+ ctx.body = { error: `File ${filename} too large`, code: "file_too_large" };
49331
+ return;
49332
+ }
49333
+ const filePath = targetDir ? `${targetDir}/${filename}` : filename;
49334
+ if (isSensitivePath(filePath)) {
49335
+ ctx.status = 403;
49336
+ ctx.body = { error: `Cannot overwrite sensitive file: ${filename}`, code: "permission_denied" };
49337
+ return;
49338
+ }
49339
+ const absPath = resolveHermesPath(filePath);
49340
+ await provider.writeFile(absPath, data);
49341
+ results.push({ name: filename, path: filePath });
49342
+ }
49343
+ ctx.body = { files: results };
49344
+ });
49345
+ function splitMultipart2(raw, boundary) {
49346
+ const parts = [];
49347
+ let start4 = 0;
49348
+ while (true) {
49349
+ const idx = raw.indexOf(boundary, start4);
49350
+ if (idx === -1) break;
49351
+ if (start4 > 0) {
49352
+ const partStart = start4 + 2;
49353
+ parts.push(raw.subarray(partStart, idx));
49354
+ }
49355
+ start4 = idx + boundary.length;
49356
+ }
49357
+ return parts;
49358
+ }
49359
+
49360
+ // packages/server/src/routes/hermes/download.ts
49361
+ var import_path18 = require("path");
49362
+ var downloadRoutes = new router_default();
49363
+ var MIME_MAP = {
49364
+ ".txt": "text/plain",
49365
+ ".html": "text/html",
49366
+ ".htm": "text/html",
49367
+ ".css": "text/css",
49368
+ ".js": "application/javascript",
49369
+ ".json": "application/json",
49370
+ ".xml": "application/xml",
49371
+ ".csv": "text/csv",
49372
+ ".md": "text/markdown",
49373
+ ".pdf": "application/pdf",
49374
+ ".zip": "application/zip",
49375
+ ".gz": "application/gzip",
49376
+ ".tar": "application/x-tar",
49377
+ ".png": "image/png",
49378
+ ".jpg": "image/jpeg",
49379
+ ".jpeg": "image/jpeg",
49380
+ ".gif": "image/gif",
49381
+ ".svg": "image/svg+xml",
49382
+ ".webp": "image/webp",
49383
+ ".mp3": "audio/mpeg",
49384
+ ".wav": "audio/wav",
49385
+ ".mp4": "video/mp4",
49386
+ ".webm": "video/webm",
49387
+ ".doc": "application/msword",
49388
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
49389
+ ".xls": "application/vnd.ms-excel",
49390
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
49391
+ ".ppt": "application/vnd.ms-powerpoint",
49392
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
49393
+ ".py": "text/x-python",
49394
+ ".ts": "text/typescript",
49395
+ ".tsx": "text/typescript",
49396
+ ".rs": "text/x-rust",
49397
+ ".go": "text/x-go",
49398
+ ".java": "text/x-java",
49399
+ ".c": "text/x-c",
49400
+ ".cpp": "text/x-c++",
49401
+ ".h": "text/x-c",
49402
+ ".sh": "text/x-shellscript",
49403
+ ".yaml": "text/yaml",
49404
+ ".yml": "text/yaml",
49405
+ ".toml": "text/toml",
49406
+ ".log": "text/plain"
49407
+ };
49408
+ function getMimeType(fileName) {
49409
+ const ext = (0, import_path18.extname)(fileName).toLowerCase();
49410
+ return MIME_MAP[ext] || "application/octet-stream";
49411
+ }
49412
+ downloadRoutes.get("/api/hermes/download", async (ctx) => {
49413
+ const filePath = ctx.query.path;
49414
+ const fileName = ctx.query.name;
49415
+ if (!filePath) {
49416
+ ctx.status = 400;
49417
+ ctx.body = { error: "Missing path parameter", code: "missing_path" };
49418
+ return;
49419
+ }
49420
+ try {
49421
+ const validPath = filePath.startsWith("/") ? validatePath(filePath) : resolveHermesPath(filePath);
49422
+ let data;
49423
+ if (isInUploadDir(validPath)) {
49424
+ data = await localProvider.readFile(validPath);
49425
+ } else {
49426
+ const provider = await createFileProvider();
49427
+ data = await provider.readFile(validPath);
49428
+ }
49429
+ const name = fileName || (0, import_path18.basename)(validPath);
49430
+ const mime = getMimeType(name);
49431
+ ctx.set("Content-Type", mime);
49432
+ ctx.set("Content-Disposition", `attachment; filename="${encodeURIComponent(name)}"; filename*=UTF-8''${encodeURIComponent(name)}`);
49433
+ ctx.set("Content-Length", String(data.length));
49434
+ ctx.set("Cache-Control", "no-cache");
49435
+ ctx.body = data;
49436
+ } catch (err) {
49437
+ const code = err.code || "unknown";
49438
+ const statusMap = {
49439
+ missing_path: 400,
49440
+ invalid_path: 400,
49441
+ not_found: 404,
49442
+ ENOENT: 404,
49443
+ file_too_large: 413,
49444
+ unsupported_backend: 501,
49445
+ backend_error: 502,
49446
+ backend_timeout: 504
49447
+ };
49448
+ ctx.status = statusMap[code] || 500;
49449
+ ctx.body = { error: err.message, code };
49450
+ }
49451
+ });
49452
+
47653
49453
  // packages/server/src/routes/hermes/proxy-handler.ts
47654
49454
  init_usage_store();
47655
49455
  function getGatewayManager() {
@@ -47680,7 +49480,7 @@ async function waitForGatewayReady(upstream, timeoutMs = 5e3) {
47680
49480
  if (res.ok) return true;
47681
49481
  } catch {
47682
49482
  }
47683
- await new Promise((resolve10) => setTimeout(resolve10, 250));
49483
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
47684
49484
  }
47685
49485
  return false;
47686
49486
  }
@@ -47883,8 +49683,11 @@ function registerRoutes(app, requireAuth2) {
47883
49683
  app.use(configRoutes.routes());
47884
49684
  app.use(logRoutes.routes());
47885
49685
  app.use(codexAuthRoutes.routes());
49686
+ app.use(nousAuthRoutes.routes());
47886
49687
  app.use(gatewayRoutes.routes());
47887
49688
  app.use(weixinRoutes.routes());
49689
+ app.use(fileRoutes.routes());
49690
+ app.use(downloadRoutes.routes());
47888
49691
  app.use(proxyRoutes.routes());
47889
49692
  return proxyMiddleware;
47890
49693
  }
@@ -47894,13 +49697,13 @@ var import_cors = __toESM(require_cors());
47894
49697
  var import_koa_static = __toESM(require_koa_static());
47895
49698
  var import_koa_send = __toESM(require_koa_send());
47896
49699
  var import_os12 = __toESM(require("os"));
47897
- var import_path17 = require("path");
47898
- var import_promises14 = require("fs/promises");
47899
- var import_fs15 = require("fs");
49700
+ var import_path19 = require("path");
49701
+ var import_promises15 = require("fs/promises");
49702
+ var import_fs17 = require("fs");
47900
49703
  init_logger();
47901
- var APP_VERSION = true ? "0.4.3" : (() => {
49704
+ var APP_VERSION = true ? "0.4.4" : (() => {
47902
49705
  try {
47903
- return JSON.parse(readFileSync9((0, import_path17.resolve)(__dirname, "../../package.json"), "utf-8")).version;
49706
+ return JSON.parse(readFileSync11((0, import_path19.resolve)(__dirname, "../../package.json"), "utf-8")).version;
47904
49707
  } catch {
47905
49708
  return "dev";
47906
49709
  }
@@ -47915,8 +49718,8 @@ process.on("unhandledRejection", (reason) => {
47915
49718
  var server = null;
47916
49719
  async function bootstrap() {
47917
49720
  console.log(`hermes-web-ui v${APP_VERSION} starting...`);
47918
- await (0, import_promises14.mkdir)(config.uploadDir, { recursive: true });
47919
- await (0, import_promises14.mkdir)(config.dataDir, { recursive: true });
49721
+ await (0, import_promises15.mkdir)(config.uploadDir, { recursive: true });
49722
+ await (0, import_promises15.mkdir)(config.dataDir, { recursive: true });
47920
49723
  const authToken = await getToken();
47921
49724
  const app = new koa_default();
47922
49725
  await initGatewayManager();
@@ -47934,7 +49737,7 @@ async function bootstrap() {
47934
49737
  console.log(`Auth enabled \u2014 token: ${authToken}`);
47935
49738
  logger.info("Auth enabled \u2014 token: %s", authToken);
47936
49739
  }
47937
- const distDir = (0, import_path17.resolve)(__dirname, "..", "client");
49740
+ const distDir = (0, import_path19.resolve)(__dirname, "..", "client");
47938
49741
  app.use((0, import_koa_static.default)(distDir));
47939
49742
  app.use(async (ctx) => {
47940
49743
  if (!ctx.path.startsWith("/api") && ctx.path !== "/health" && ctx.path !== "/upload" && ctx.path !== "/webhook") {