@ghfs/cli 0.1.0 → 0.1.1

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 (327) hide show
  1. package/dist/cli.mjs +36 -15
  2. package/dist/{factory-DypZ8oi9.mjs → factory-DmX3S7tf.mjs} +324 -5
  3. package/dist/index.d.mts +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/dist/{provider-BFJGpjCs.d.mts → provider-DCIsHVeA.d.mts} +47 -1
  6. package/dist/server/index.d.mts +45 -2
  7. package/dist/server/index.mjs +1 -1
  8. package/dist/{server-n1FLF8Xo.mjs → server-BwSU4kqr.mjs} +252 -65
  9. package/dist/ui/200.html +1 -1
  10. package/dist/ui/404.html +1 -1
  11. package/dist/ui/_nuxt/2UxHyX5q.js +1 -0
  12. package/dist/ui/_nuxt/32ctXXKs.js +1 -0
  13. package/dist/ui/_nuxt/3e1v2bzS.js +1 -0
  14. package/dist/ui/_nuxt/4A_iFExJ.js +1 -0
  15. package/dist/ui/_nuxt/5VeTt0Ye.js +1 -0
  16. package/dist/ui/_nuxt/5i3qLPDT.js +1 -0
  17. package/dist/ui/_nuxt/85-TOEBH.js +1 -0
  18. package/dist/ui/_nuxt/8syuri0t.js +1 -0
  19. package/dist/ui/_nuxt/B0m2ddpp.js +1 -0
  20. package/dist/ui/_nuxt/B1dDrJ26.js +1 -0
  21. package/dist/ui/_nuxt/B1yitclQ.js +1 -0
  22. package/dist/ui/_nuxt/B5q1GTce.js +1 -0
  23. package/dist/ui/_nuxt/B6aJPvgy.js +1 -0
  24. package/dist/ui/_nuxt/B6eN_cS4.js +1 -0
  25. package/dist/ui/_nuxt/B7c-h3xW.js +1 -0
  26. package/dist/ui/_nuxt/B7mTdjB0.js +1 -0
  27. package/dist/ui/_nuxt/BA47KaF1.js +1 -0
  28. package/dist/ui/_nuxt/BBf5iR-q.js +1 -0
  29. package/dist/ui/_nuxt/BEDo0Tqx.js +1 -0
  30. package/dist/ui/_nuxt/BERRCDM3.js +1 -0
  31. package/dist/ui/_nuxt/BETggiCN.js +1 -0
  32. package/dist/ui/_nuxt/BEwlwnbL.js +1 -0
  33. package/dist/ui/_nuxt/BFfxhgS-.js +1 -0
  34. package/dist/ui/_nuxt/BGJmEYvX.js +1 -0
  35. package/dist/ui/_nuxt/BH7IYjvW.js +1 -0
  36. package/dist/ui/_nuxt/BIGW1oBm.js +1 -0
  37. package/dist/ui/_nuxt/BIv1doCn.js +1 -0
  38. package/dist/ui/_nuxt/BJDFO7_C.js +1 -0
  39. package/dist/ui/_nuxt/BLtJtn59.js +1 -0
  40. package/dist/ui/_nuxt/BM1_JUlF.js +1 -0
  41. package/dist/ui/_nuxt/BMWR74SV.js +1 -0
  42. package/dist/ui/_nuxt/BPQ3VLAy.js +1 -0
  43. package/dist/ui/_nuxt/BQ8w6xss.js +1 -0
  44. package/dist/ui/_nuxt/BRHolxvo.js +1 -0
  45. package/dist/ui/_nuxt/BRZ36xJF.js +1 -0
  46. package/dist/ui/_nuxt/BTJTHyun.js +1 -0
  47. package/dist/ui/_nuxt/BTifaqeh.js +1 -0
  48. package/dist/ui/_nuxt/BUtzH8cE.js +1 -0
  49. package/dist/ui/_nuxt/BUw7H-hv.js +1 -0
  50. package/dist/ui/_nuxt/BV7otONQ.js +1 -0
  51. package/dist/ui/_nuxt/BVQ-GDCI.js +1 -0
  52. package/dist/ui/_nuxt/BVkGXMyj.js +1 -0
  53. package/dist/ui/_nuxt/BWvSN4gD.js +1 -0
  54. package/dist/ui/_nuxt/BXkSAIEj.js +1 -0
  55. package/dist/ui/_nuxt/BYunw83y.js +1 -0
  56. package/dist/ui/_nuxt/BZvkOJ9d.js +1 -0
  57. package/dist/ui/_nuxt/B_m7g4N7.js +1 -0
  58. package/dist/ui/_nuxt/BcOcwvcX.js +1 -0
  59. package/dist/ui/_nuxt/BcVCzyr7.js +1 -0
  60. package/dist/ui/_nuxt/BcllPdc-.js +1 -0
  61. package/dist/ui/_nuxt/BdImnpbu.js +1 -0
  62. package/dist/ui/_nuxt/BdnUsdx6.js +1 -0
  63. package/dist/ui/_nuxt/BeJSdlF9.js +1 -0
  64. package/dist/ui/_nuxt/BfHTSMKl.js +1 -0
  65. package/dist/ui/_nuxt/BfSCyJF4.js +1 -0
  66. package/dist/ui/_nuxt/BfjtVDDH.js +1 -0
  67. package/dist/ui/_nuxt/BgDCqdQA.js +1 -0
  68. package/dist/ui/_nuxt/BhOHFoWU.js +1 -0
  69. package/dist/ui/_nuxt/BhrAK1vL.js +1 -0
  70. package/dist/ui/_nuxt/BkioyH1T.js +1 -0
  71. package/dist/ui/_nuxt/Bkuqu6BP.js +1 -0
  72. package/dist/ui/_nuxt/BmXAJ9_W.js +1 -0
  73. package/dist/ui/_nuxt/Bmn6On1c.js +1 -0
  74. package/dist/ui/_nuxt/Bp3cYrEr.js +1 -0
  75. package/dist/ui/_nuxt/Bp6g37R7.js +1 -0
  76. package/dist/ui/_nuxt/BqNa2AkI.js +1 -0
  77. package/dist/ui/_nuxt/BqTXFGrv.js +1 -0
  78. package/dist/ui/_nuxt/BqYA7rlc.js +1 -0
  79. package/dist/ui/_nuxt/Br6cN0cg.js +1 -0
  80. package/dist/ui/_nuxt/BsS91CYL.js +1 -0
  81. package/dist/ui/_nuxt/BshV_Xbc.js +1 -0
  82. package/dist/ui/_nuxt/BspZqrRM.js +1 -0
  83. package/dist/ui/_nuxt/BtCnVYZw.js +1 -0
  84. package/dist/ui/_nuxt/BtOb2qkB.js +1 -0
  85. package/dist/ui/_nuxt/BthQWCQV.js +1 -0
  86. package/dist/ui/_nuxt/BtqSS_iP.js +1 -0
  87. package/dist/ui/_nuxt/Buea-lGh.js +1 -0
  88. package/dist/ui/_nuxt/Bv_4Rxtq.js +1 -0
  89. package/dist/ui/_nuxt/BvzEVeQv.js +1 -0
  90. package/dist/ui/_nuxt/Bw305WKR.js +1 -0
  91. package/dist/ui/_nuxt/BxgE0vQu.js +1 -0
  92. package/dist/ui/_nuxt/BzJJZx-M.js +1 -0
  93. package/dist/ui/_nuxt/C-HG3fhB.js +1 -0
  94. package/dist/ui/_nuxt/C-SQnVFl.js +1 -0
  95. package/dist/ui/_nuxt/C0HS_06l.js +1 -0
  96. package/dist/ui/_nuxt/C0hk2d4L.js +1 -0
  97. package/dist/ui/_nuxt/C151Ov-r.js +1 -0
  98. package/dist/ui/_nuxt/C27-OAKa.js +1 -0
  99. package/dist/ui/_nuxt/C2t-YnRu.js +1 -0
  100. package/dist/ui/_nuxt/C39BiMTA.js +1 -0
  101. package/dist/ui/_nuxt/C3B-1QV4.js +1 -0
  102. package/dist/ui/_nuxt/C3Wv6jpd.js +1 -0
  103. package/dist/ui/_nuxt/C3mMm8J8.js +1 -0
  104. package/dist/ui/_nuxt/C4EeE6gA.js +1 -0
  105. package/dist/ui/_nuxt/C4IJs8-o.js +1 -0
  106. package/dist/ui/_nuxt/C4gqWexZ.js +1 -0
  107. package/dist/ui/_nuxt/{BMIwt_GL.js → C4zNGwhW.js} +1 -1
  108. package/dist/ui/_nuxt/C5BYcBs_.js +1 -0
  109. package/dist/ui/_nuxt/C5YyOfLZ.js +1 -0
  110. package/dist/ui/_nuxt/C7UmGho8.js +1 -0
  111. package/dist/ui/_nuxt/C7zT0LnQ.js +1 -0
  112. package/dist/ui/_nuxt/C8M2exoo.js +1 -0
  113. package/dist/ui/_nuxt/C8lEn-DE.js +1 -0
  114. package/dist/ui/_nuxt/C98Dy4si.js +1 -0
  115. package/dist/ui/_nuxt/C9dUb6Cb.js +1 -0
  116. package/dist/ui/_nuxt/C9oPPf7i.js +1 -0
  117. package/dist/ui/_nuxt/C9tS-k6U.js +1 -0
  118. package/dist/ui/_nuxt/CAFt9gP4.js +1 -0
  119. package/dist/ui/_nuxt/CANp3yme.js +1 -0
  120. package/dist/ui/_nuxt/CBaQQc7g.js +1 -0
  121. package/dist/ui/_nuxt/CDBrVQLm.js +1 -0
  122. package/dist/ui/_nuxt/CDVJQ6XC.js +1 -0
  123. package/dist/ui/_nuxt/CDx5xZoG.js +1 -0
  124. package/dist/ui/_nuxt/CEL-wOlO.js +1 -0
  125. package/dist/ui/_nuxt/CEu0bR-o.js +1 -0
  126. package/dist/ui/_nuxt/CFHQjOhq.js +1 -0
  127. package/dist/ui/_nuxt/CFbOZP3I.js +75 -0
  128. package/dist/ui/_nuxt/CG6Dc4jp.js +1 -0
  129. package/dist/ui/_nuxt/CG8Ifv2g.js +1 -0
  130. package/dist/ui/_nuxt/CH1njM8p.js +1 -0
  131. package/dist/ui/_nuxt/CHLpvVh8.js +1 -0
  132. package/dist/ui/_nuxt/CHM0blh-.js +1 -0
  133. package/dist/ui/_nuxt/CJc9bBzg.js +1 -0
  134. package/dist/ui/_nuxt/CKIfxQSi.js +1 -0
  135. package/dist/ui/_nuxt/CLj8gQPS.js +1 -0
  136. package/dist/ui/_nuxt/CLxacb5B.js +1 -0
  137. package/dist/ui/_nuxt/CMTm3GFP.js +1 -0
  138. package/dist/ui/_nuxt/CO1LY3CK.js +1 -0
  139. package/dist/ui/_nuxt/COcwbKMJ.js +1 -0
  140. package/dist/ui/_nuxt/COkxafJQ.js +1 -0
  141. package/dist/ui/_nuxt/COt5Ahok.js +1 -0
  142. package/dist/ui/_nuxt/CRBrlGZW.js +1 -0
  143. package/dist/ui/_nuxt/CS3Unz2-.js +1 -0
  144. package/dist/ui/_nuxt/CSXwinHm.js +1 -0
  145. package/dist/ui/_nuxt/CTRr51gU.js +1 -0
  146. package/dist/ui/_nuxt/CUuTKBJd.js +1 -0
  147. package/dist/ui/_nuxt/CVO1_9PV.js +1 -0
  148. package/dist/ui/_nuxt/CVdnzihN.js +1 -0
  149. package/dist/ui/_nuxt/CXtECtnM.js +1 -0
  150. package/dist/ui/_nuxt/CXvaQtF9.js +1 -0
  151. package/dist/ui/_nuxt/CYsAdtH9.js +1 -0
  152. package/dist/ui/_nuxt/CafNBF8u.js +1 -0
  153. package/dist/ui/_nuxt/CbFg5uaA.js +1 -0
  154. package/dist/ui/_nuxt/CbfX1IO0.js +1 -0
  155. package/dist/ui/_nuxt/CcsQSqEB.js +1 -0
  156. package/dist/ui/_nuxt/CeAyd5Ju.js +1 -0
  157. package/dist/ui/_nuxt/CeZK1NFH.js +1 -0
  158. package/dist/ui/_nuxt/CenWIFCC.js +1 -0
  159. package/dist/ui/_nuxt/CfQXZHmo.js +1 -0
  160. package/dist/ui/_nuxt/Cg-RD9OK.js +1 -0
  161. package/dist/ui/_nuxt/ChMvpjG-.js +1 -0
  162. package/dist/ui/_nuxt/Cj5Yp3dK.js +1 -0
  163. package/dist/ui/_nuxt/CkByrt1z.js +1 -0
  164. package/dist/ui/_nuxt/CkXjmgJE.js +1 -0
  165. package/dist/ui/_nuxt/CklMAg4u.js +1 -0
  166. package/dist/ui/_nuxt/Cmh6b_Ma.js +1 -0
  167. package/dist/ui/_nuxt/CnnmHF94.js +1 -0
  168. package/dist/ui/_nuxt/CnsnAmq5.js +1 -0
  169. package/dist/ui/_nuxt/Co6uUVPk.js +1 -0
  170. package/dist/ui/_nuxt/CoDkCxhg.js +1 -0
  171. package/dist/ui/_nuxt/Cp-IABpG.js +1 -0
  172. package/dist/ui/_nuxt/Cp8Y5tLI.js +1 -0
  173. package/dist/ui/_nuxt/Cq5zzVJU.js +1 -0
  174. package/dist/ui/_nuxt/CquLrc37.js +1 -0
  175. package/dist/ui/_nuxt/Cs0ovY-E.js +1 -0
  176. package/dist/ui/_nuxt/CsfeWuGM.js +1 -0
  177. package/dist/ui/_nuxt/Csfq5Kiy.js +1 -0
  178. package/dist/ui/_nuxt/CuPHTKiy.js +1 -0
  179. package/dist/ui/_nuxt/CufHLc7y.js +1 -0
  180. package/dist/ui/_nuxt/Cuk6v7N8.js +1 -0
  181. package/dist/ui/_nuxt/Cvjx9yec.js +1 -0
  182. package/dist/ui/_nuxt/CwoSXNpI.js +1 -0
  183. package/dist/ui/_nuxt/CxGSJlkm.js +1 -0
  184. package/dist/ui/_nuxt/CxbxFI8M.js +1 -0
  185. package/dist/ui/_nuxt/CyktbL80.js +1 -0
  186. package/dist/ui/_nuxt/CylS5w8V.js +1 -0
  187. package/dist/ui/_nuxt/Cz2AlsmD.js +1 -0
  188. package/dist/ui/_nuxt/CzTSHFRz.js +1 -0
  189. package/dist/ui/_nuxt/D-2ljcwZ.js +1 -0
  190. package/dist/ui/_nuxt/D0YGMca9.js +1 -0
  191. package/dist/ui/_nuxt/D0r3Knsf.js +1 -0
  192. package/dist/ui/_nuxt/D17OF-Vu.js +1 -0
  193. package/dist/ui/_nuxt/D1j8_8rp.js +1 -0
  194. package/dist/ui/_nuxt/D2j5LXpq.js +1 -0
  195. package/dist/ui/_nuxt/D3apom_0.js +1 -0
  196. package/dist/ui/_nuxt/D3lLCCz7.js +1 -0
  197. package/dist/ui/_nuxt/{BXG6gk4R.js → D4Qn4bBI.js} +1 -1
  198. package/dist/ui/_nuxt/D4_iv3hh.js +1 -0
  199. package/dist/ui/_nuxt/D4h5O-jR.js +1 -0
  200. package/dist/ui/_nuxt/D5-asLiD.js +1 -0
  201. package/dist/ui/_nuxt/D53aC0YG.js +1 -0
  202. package/dist/ui/_nuxt/D5KoaKCx.js +1 -0
  203. package/dist/ui/_nuxt/D7o27uSR.js +1 -0
  204. package/dist/ui/_nuxt/D7oLnXFd.js +1 -0
  205. package/dist/ui/_nuxt/D82EKSYY.js +1 -0
  206. package/dist/ui/_nuxt/D82vCrfD.js +1 -0
  207. package/dist/ui/_nuxt/D87Tk5Gz.js +1 -0
  208. package/dist/ui/_nuxt/D8_7TLub.js +1 -0
  209. package/dist/ui/_nuxt/D8l8udqQ.js +1 -0
  210. package/dist/ui/_nuxt/D8rZpOte.js +1 -0
  211. package/dist/ui/_nuxt/D93ZcfNL.js +1 -0
  212. package/dist/ui/_nuxt/D97Zzqfu.js +1 -0
  213. package/dist/ui/_nuxt/DAi9KRSo.js +1 -0
  214. package/dist/ui/_nuxt/DElX3lK9.js +153 -0
  215. package/dist/ui/_nuxt/DFQXde-d.js +1 -0
  216. package/dist/ui/_nuxt/DFWUc33u.js +1 -0
  217. package/dist/ui/_nuxt/DFXneXwc.js +1 -0
  218. package/dist/ui/_nuxt/DGztddWO.js +1 -0
  219. package/dist/ui/_nuxt/DH5Ifo-i.js +1 -0
  220. package/dist/ui/_nuxt/DHCkPAjA.js +1 -0
  221. package/dist/ui/_nuxt/DHJKELXO.js +1 -0
  222. package/dist/ui/_nuxt/DHQR4-dF.js +1 -0
  223. package/dist/ui/_nuxt/DM8c43g1.js +1 -0
  224. package/dist/ui/_nuxt/DMk3OuwW.js +1 -0
  225. package/dist/ui/_nuxt/DMzUqQB5.js +1 -0
  226. package/dist/ui/_nuxt/DN-Z_aST.js +1 -0
  227. package/dist/ui/_nuxt/DQyhUUbL.js +1 -0
  228. package/dist/ui/_nuxt/DRg8JJMk.js +1 -0
  229. package/dist/ui/_nuxt/DRw_LuNl.js +1 -0
  230. package/dist/ui/_nuxt/DSSpBswy.js +1 -0
  231. package/dist/ui/_nuxt/DT3CNIhV.js +1 -0
  232. package/dist/ui/_nuxt/DU1UobuO.js +1 -0
  233. package/dist/ui/_nuxt/DUszq2jm.js +1 -0
  234. package/dist/ui/_nuxt/DV7GczEv.js +1 -0
  235. package/dist/ui/_nuxt/DVFEvuxE.js +1 -0
  236. package/dist/ui/_nuxt/DVMEJ2y_.js +1 -0
  237. package/dist/ui/_nuxt/DVxCFoDh.js +1 -0
  238. package/dist/ui/_nuxt/DWX1VroF.js +1 -0
  239. package/dist/ui/_nuxt/DWedfzmr.js +1 -0
  240. package/dist/ui/_nuxt/DWrx1Km3.js +1 -0
  241. package/dist/ui/_nuxt/DXbdFlpD.js +1 -0
  242. package/dist/ui/_nuxt/DXmwc3jG.js +1 -0
  243. package/dist/ui/_nuxt/DXvB9xmW.js +1 -0
  244. package/dist/ui/_nuxt/DYE7WIF3.js +1 -0
  245. package/dist/ui/_nuxt/DZ9PSxVF.js +1 -0
  246. package/dist/ui/_nuxt/DZxFcAj9.js +1 -0
  247. package/dist/ui/_nuxt/D_Q5rh1f.js +1 -0
  248. package/dist/ui/_nuxt/Da5cRb03.js +1 -0
  249. package/dist/ui/_nuxt/DbWOdLaN.js +1 -0
  250. package/dist/ui/_nuxt/Dc-5oQ3p.js +1 -0
  251. package/dist/ui/_nuxt/DcWK9jms.js +1 -0
  252. package/dist/ui/_nuxt/DcaNXYhu.js +1 -0
  253. package/dist/ui/_nuxt/Dd19v3D-.js +1 -0
  254. package/dist/ui/_nuxt/DdkO51Og.js +1 -0
  255. package/dist/ui/_nuxt/Ddv68eIx.js +1 -0
  256. package/dist/ui/_nuxt/Des-eS-w.js +1 -0
  257. package/dist/ui/_nuxt/Df6bDoY_.js +1 -0
  258. package/dist/ui/_nuxt/DfNjGIrv.js +1 -0
  259. package/dist/ui/_nuxt/DhaVEd23.js +1 -0
  260. package/dist/ui/_nuxt/DjAJT7YJ.js +1 -0
  261. package/dist/ui/_nuxt/DkFqJrB1.js +1 -0
  262. package/dist/ui/_nuxt/DkwncUOv.js +1 -0
  263. package/dist/ui/_nuxt/DnF83RMp.js +1 -0
  264. package/dist/ui/_nuxt/DnULxvSX.js +1 -0
  265. package/dist/ui/_nuxt/Dpen1YoG.js +1 -0
  266. package/dist/ui/_nuxt/Dph4kLrZ.js +1 -0
  267. package/dist/ui/_nuxt/DqQDbK_p.js +1 -0
  268. package/dist/ui/_nuxt/DqwNpetd.js +1 -0
  269. package/dist/ui/_nuxt/DsOJ9woJ.js +1 -0
  270. package/dist/ui/_nuxt/Dspwwk_N.js +1 -0
  271. package/dist/ui/_nuxt/Dx-B1_4e.js +1 -0
  272. package/dist/ui/_nuxt/DyxjwDmM.js +1 -0
  273. package/dist/ui/_nuxt/E3gJ1_iC.js +1 -0
  274. package/dist/ui/_nuxt/GsRaNv29.js +1 -0
  275. package/dist/ui/_nuxt/IF9eRakj.js +1 -0
  276. package/dist/ui/_nuxt/IeuSbFQv.js +1 -0
  277. package/dist/ui/_nuxt/JZbLTBME.js +1 -0
  278. package/dist/ui/_nuxt/L9t79GZl.js +1 -0
  279. package/dist/ui/_nuxt/MzD3tlZU.js +1 -0
  280. package/dist/ui/_nuxt/P80f7IUj.js +1 -0
  281. package/dist/ui/_nuxt/Pmp26Uib.js +1 -0
  282. package/dist/ui/_nuxt/QIJgUcNo.js +1 -0
  283. package/dist/ui/_nuxt/VOosw3JB.js +1 -0
  284. package/dist/ui/_nuxt/Ve4PFQV2.js +1 -0
  285. package/dist/ui/_nuxt/W9tJ9s81.js +1 -0
  286. package/dist/ui/_nuxt/Yzrsuije.js +1 -0
  287. package/dist/ui/_nuxt/_H4v1dQx.js +1 -0
  288. package/dist/ui/_nuxt/_ykCGR6B.js +1 -0
  289. package/dist/ui/_nuxt/bCR0ucgS.js +1 -0
  290. package/dist/ui/_nuxt/bE4Kk8sk.js +1 -0
  291. package/dist/ui/_nuxt/bN70gL4F.js +1 -0
  292. package/dist/ui/_nuxt/builds/latest.json +1 -1
  293. package/dist/ui/_nuxt/builds/meta/12d68071-f4db-447f-b929-9033d66eadc3.json +1 -0
  294. package/dist/ui/_nuxt/dwOrl1Do.js +1 -0
  295. package/dist/ui/_nuxt/entry.DfrFFNxd.css +1 -0
  296. package/dist/ui/_nuxt/eo99z4R2.js +1 -0
  297. package/dist/ui/_nuxt/error-404.C93cll2q.css +1 -0
  298. package/dist/ui/_nuxt/error-500.CPQqaJsC.css +1 -0
  299. package/dist/ui/_nuxt/fuZLfV_i.js +1 -0
  300. package/dist/ui/_nuxt/g9-lgVsj.js +1 -0
  301. package/dist/ui/_nuxt/gcz8RCvz.js +1 -0
  302. package/dist/ui/_nuxt/hJgmCMqR.js +1 -0
  303. package/dist/ui/_nuxt/hegEt444.js +1 -0
  304. package/dist/ui/_nuxt/k_qm7-4y.js +1 -0
  305. package/dist/ui/_nuxt/lBpI9LM0.js +1 -0
  306. package/dist/ui/_nuxt/lXgVvXCa.js +1 -0
  307. package/dist/ui/_nuxt/mWjccvbQ.js +1 -0
  308. package/dist/ui/_nuxt/n2N0HUVH.js +1 -0
  309. package/dist/ui/_nuxt/oH_c3LbQ.js +1 -0
  310. package/dist/ui/_nuxt/qdsjHGoJ.js +1 -0
  311. package/dist/ui/_nuxt/rGO070M0.js +1 -0
  312. package/dist/ui/_nuxt/rZm6bMo-.js +1 -0
  313. package/dist/ui/_nuxt/rgL8RFrC.js +1 -0
  314. package/dist/ui/_nuxt/u5AG7uiY.js +1 -0
  315. package/dist/ui/_nuxt/uYugtg8r.js +1 -0
  316. package/dist/ui/_nuxt/vE_lwT2v.js +1 -0
  317. package/dist/ui/_nuxt/vGWfd6FD.js +1 -0
  318. package/dist/ui/_nuxt/wDzz0qaB.js +1 -0
  319. package/dist/ui/_nuxt/wEQ09or8.js +1 -0
  320. package/dist/ui/_nuxt/yv6CvBhz.js +1 -0
  321. package/dist/ui/index.html +1 -1
  322. package/package.json +6 -2
  323. package/dist/ui/_nuxt/DA9k4Rdg.js +0 -69
  324. package/dist/ui/_nuxt/builds/meta/64045338-3c37-4c7d-a0df-5b21000f8b0a.json +0 -1
  325. package/dist/ui/_nuxt/entry.B5oa46-c.css +0 -1
  326. package/dist/ui/_nuxt/error-404.CktHaldI.css +0 -1
  327. package/dist/ui/_nuxt/error-500.DVdbZfrj.css +0 -1
@@ -1,8 +1,9 @@
1
- import { a as formatIssueNumber, n as normalizeReactions, t as createRepositoryProvider } from "./factory-DypZ8oi9.mjs";
1
+ import { a as formatIssueNumber, c as CodedError, d as diagnostics, l as formatInline, n as normalizeReactions, t as createRepositoryProvider, u as log } from "./factory-DmX3S7tf.mjs";
2
2
  import { distDir } from "./dir.mjs";
3
3
  import process from "node:process";
4
4
  import { basename, dirname, isAbsolute, join, resolve } from "pathe";
5
- import { spawn } from "node:child_process";
5
+ import { execFile, spawn } from "node:child_process";
6
+ import { promisify } from "node:util";
6
7
  import { existsSync } from "node:fs";
7
8
  import { createJiti } from "jiti";
8
9
  import { access, mkdir, readFile, readdir, rename, rm, stat, watch, writeFile } from "node:fs/promises";
@@ -16,6 +17,7 @@ import { getPort } from "get-port-please";
16
17
  import { createApp, createRouter, eventHandler, serveStatic, setResponseHeader, setResponseStatus, toNodeListener } from "h3";
17
18
  import { parse as parse$1, stringify as stringify$1 } from "structured-clone-es";
18
19
  import { WebSocketServer } from "ws";
20
+ import { fileURLToPath } from "node:url";
19
21
  import { hash } from "ohash";
20
22
  //#region src/constants.ts
21
23
  const CONFIG_FILE_CANDIDATES = [
@@ -359,7 +361,7 @@ async function readAndValidateExecuteFileWithSource(path) {
359
361
  try {
360
362
  parsed = parse(raw || "[]") || [];
361
363
  } catch (error) {
362
- throw new Error(`Failed to parse execute YAML: ${error.message}`);
364
+ throw new CodedError(log.GHFS0105({ detail: error.message }, { cause: error }));
363
365
  }
364
366
  const parsedResult = v.safeParse(executeFileSchema, parsed);
365
367
  if (!parsedResult.success) {
@@ -367,12 +369,12 @@ async function readAndValidateExecuteFileWithSource(path) {
367
369
  const path = issue.path?.map((segment) => String(segment.key)).join(".");
368
370
  return `${path ? `${path}: ` : ""}${issue.message}`;
369
371
  }).join("; ");
370
- throw new Error(`Invalid execute file: ${message}`);
372
+ throw new CodedError(log.GHFS0106({ detail: message }));
371
373
  }
372
374
  const { pending, sourceActions, actionErrors } = normalizeActionInputs(parsedResult.output);
373
- if (actionErrors.length) throw new Error(`Invalid execute file: ${actionErrors.join("; ")}`);
375
+ if (actionErrors.length) throw new CodedError(log.GHFS0107({ detail: actionErrors.join("; ") }));
374
376
  const customErrors = validateExecuteRules(pending);
375
- if (customErrors.length) throw new Error(`Invalid execute file: ${customErrors.join("; ")}`);
377
+ if (customErrors.length) throw new CodedError(log.GHFS0108({ detail: customErrors.join("; ") }));
376
378
  return {
377
379
  ops: pending,
378
380
  sourceActions
@@ -470,14 +472,14 @@ function parseExecuteMdLine(line) {
470
472
  const tokens = tokenizeCommand(trimmed);
471
473
  if (!tokens) return {
472
474
  kind: "warning",
473
- message: "invalid quoted string syntax"
475
+ message: formatInline(diagnostics.GHFS0150())
474
476
  };
475
477
  if (tokens.length === 0) return void 0;
476
478
  const [commandInput, ...args] = tokens;
477
479
  const command = resolveActionName(commandInput);
478
480
  if (!command) return {
479
481
  kind: "warning",
480
- message: `unrecognized action pattern: ${commandInput}`
482
+ message: formatInline(diagnostics.GHFS0151({ command: commandInput }))
481
483
  };
482
484
  if (command === "set-title") return parseSetTitle(args);
483
485
  if (command === "add-labels") return parseAddLabels(args, commandInput);
@@ -487,7 +489,7 @@ function parseExecuteMdLine(line) {
487
489
  if (MULTI_SIMPLE_ACTIONS.has(command)) return parseMultiSimpleAction(command, args, commandInput);
488
490
  return {
489
491
  kind: "warning",
490
- message: `unrecognized action pattern: ${commandInput}`
492
+ message: formatInline(diagnostics.GHFS0151({ command: commandInput }))
491
493
  };
492
494
  }
493
495
  async function readExecuteMdFile(path) {
@@ -584,12 +586,15 @@ function stringifyExecuteMd(parsed, remainingOpIndexes) {
584
586
  function parseSetTitle(args) {
585
587
  if (args.length !== 2) return {
586
588
  kind: "warning",
587
- message: "set-title expects: set-title #<number> \"<title>\""
589
+ message: formatInline(diagnostics.GHFS0152({
590
+ command: "set-title",
591
+ syntax: "set-title #<number> \"<title>\""
592
+ }))
588
593
  };
589
594
  const number = parseIssueRef(args[0]);
590
595
  if (!number) return {
591
596
  kind: "warning",
592
- message: "set-title expects a single issue reference (#123)"
597
+ message: formatInline(diagnostics.GHFS0153({ command: "set-title" }))
593
598
  };
594
599
  return {
595
600
  kind: "single",
@@ -603,17 +608,20 @@ function parseSetTitle(args) {
603
608
  function parseAddLabels(args, command) {
604
609
  if (args.length < 2) return {
605
610
  kind: "warning",
606
- message: `${command} expects: ${command} #<number> <label1, label2>`
611
+ message: formatInline(diagnostics.GHFS0152({
612
+ command,
613
+ syntax: `${command} #<number> <label1, label2>`
614
+ }))
607
615
  };
608
616
  const number = parseIssueRef(args[0]);
609
617
  if (!number) return {
610
618
  kind: "warning",
611
- message: `${command} expects a single issue reference (#123)`
619
+ message: formatInline(diagnostics.GHFS0153({ command }))
612
620
  };
613
621
  const labels = args.slice(1).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean);
614
622
  if (labels.length === 0) return {
615
623
  kind: "warning",
616
- message: `${command} requires at least one label`
624
+ message: formatInline(diagnostics.GHFS0154({ command }))
617
625
  };
618
626
  return {
619
627
  kind: "single",
@@ -627,17 +635,20 @@ function parseAddLabels(args, command) {
627
635
  function parseAddAssignees(args, command) {
628
636
  if (args.length < 2) return {
629
637
  kind: "warning",
630
- message: `${command} expects: ${command} #<number> <assignee1, assignee2>`
638
+ message: formatInline(diagnostics.GHFS0152({
639
+ command,
640
+ syntax: `${command} #<number> <assignee1, assignee2>`
641
+ }))
631
642
  };
632
643
  const number = parseIssueRef(args[0]);
633
644
  if (!number) return {
634
645
  kind: "warning",
635
- message: `${command} expects a single issue reference (#123)`
646
+ message: formatInline(diagnostics.GHFS0153({ command }))
636
647
  };
637
648
  const assignees = args.slice(1).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean);
638
649
  if (assignees.length === 0) return {
639
650
  kind: "warning",
640
- message: `${command} requires at least one assignee`
651
+ message: formatInline(diagnostics.GHFS0155({ command }))
641
652
  };
642
653
  return {
643
654
  kind: "single",
@@ -651,17 +662,20 @@ function parseAddAssignees(args, command) {
651
662
  function parseAddComment(args, command) {
652
663
  if (args.length < 2) return {
653
664
  kind: "warning",
654
- message: `${command} expects: ${command} #<number> "<comment>"`
665
+ message: formatInline(diagnostics.GHFS0152({
666
+ command,
667
+ syntax: `${command} #<number> "<comment>"`
668
+ }))
655
669
  };
656
670
  const number = parseIssueRef(args[0]);
657
671
  if (!number) return {
658
672
  kind: "warning",
659
- message: `${command} expects a single issue reference (#123)`
673
+ message: formatInline(diagnostics.GHFS0153({ command }))
660
674
  };
661
675
  const body = args.slice(1).join(" ").trim();
662
676
  if (!body) return {
663
677
  kind: "warning",
664
- message: `${command} requires a non-empty comment`
678
+ message: formatInline(diagnostics.GHFS0156({ command }))
665
679
  };
666
680
  return {
667
681
  kind: "single",
@@ -675,17 +689,20 @@ function parseAddComment(args, command) {
675
689
  function parseCloseWithComment(args, command) {
676
690
  if (args.length < 2) return {
677
691
  kind: "warning",
678
- message: `${command} expects: ${command} #<number> "<comment>"`
692
+ message: formatInline(diagnostics.GHFS0152({
693
+ command,
694
+ syntax: `${command} #<number> "<comment>"`
695
+ }))
679
696
  };
680
697
  const number = parseIssueRef(args[0]);
681
698
  if (!number) return {
682
699
  kind: "warning",
683
- message: `${command} expects a single issue reference (#123)`
700
+ message: formatInline(diagnostics.GHFS0153({ command }))
684
701
  };
685
702
  const body = args.slice(1).join(" ").trim();
686
703
  if (!body) return {
687
704
  kind: "warning",
688
- message: `${command} requires a non-empty comment`
705
+ message: formatInline(diagnostics.GHFS0156({ command }))
689
706
  };
690
707
  return {
691
708
  kind: "single",
@@ -700,7 +717,7 @@ function parseMultiSimpleAction(action, args, command) {
700
717
  const numbers = args.map(parseIssueRef);
701
718
  if (numbers.length === 0 || numbers.some((number) => !number)) return {
702
719
  kind: "warning",
703
- message: `${command} expects one or more issue references (#123 #456)`
720
+ message: formatInline(diagnostics.GHFS0157({ command }))
704
721
  };
705
722
  return {
706
723
  kind: "multi",
@@ -759,7 +776,7 @@ function isCommentLine(trimmed) {
759
776
  }
760
777
  //#endregion
761
778
  //#region package.json
762
- var version = "0.1.0";
779
+ var version = "0.1.1";
763
780
  //#endregion
764
781
  //#region src/meta.ts
765
782
  const GHFS_NAME = "ghfs";
@@ -841,6 +858,8 @@ function normalizeItem(item) {
841
858
  if (!item.data || !item.data.item) return void 0;
842
859
  const comments = Array.isArray(item.data.comments) ? item.data.comments : [];
843
860
  const rawItem = item.data.item;
861
+ const commits = Array.isArray(item.data.commits) ? item.data.commits : void 0;
862
+ const timeline = Array.isArray(item.data.timeline) ? item.data.timeline : void 0;
844
863
  return {
845
864
  ...item,
846
865
  data: {
@@ -854,7 +873,9 @@ function normalizeItem(item) {
854
873
  comments: comments.filter((comment) => comment && typeof comment === "object").map((comment) => ({
855
874
  ...comment,
856
875
  reactions: normalizeReactions(comment.reactions)
857
- }))
876
+ })),
877
+ ...commits ? { commits } : {},
878
+ ...timeline ? { timeline } : {}
858
879
  }
859
880
  };
860
881
  }
@@ -868,12 +889,15 @@ async function loadPerItemSource(storageDir) {
868
889
  for (const tracked of Object.values(syncState.items)) {
869
890
  const markdownPath = join(storageDir, tracked.filePath);
870
891
  if (!await pathExists(markdownPath)) {
871
- warnings.push(`per-item: missing markdown for ${formatIssueNumber(tracked.number, { repo })} (${tracked.filePath})`);
892
+ warnings.push(formatInline(diagnostics.GHFS0160({
893
+ issue: formatIssueNumber(tracked.number, { repo }),
894
+ path: tracked.filePath
895
+ })));
872
896
  continue;
873
897
  }
874
898
  const frontmatter = parseFrontmatter(await readFile(markdownPath, "utf8"));
875
899
  if (!frontmatter) {
876
- warnings.push(`per-item: invalid or missing frontmatter for ${formatIssueNumber(tracked.number, { repo })}`);
900
+ warnings.push(formatInline(diagnostics.GHFS0161({ issue: formatIssueNumber(tracked.number, { repo }) })));
877
901
  continue;
878
902
  }
879
903
  const trackedItem = tracked.data.item;
@@ -1022,7 +1046,7 @@ async function loadExecuteSources(executeFilePath) {
1022
1046
  ...perItem.ops
1023
1047
  ];
1024
1048
  const customErrors = validateExecuteRules(mergedOps);
1025
- if (customErrors.length) throw new Error(`Invalid execute file: ${customErrors.join("; ")}`);
1049
+ if (customErrors.length) throw new CodedError(log.GHFS0108({ detail: customErrors.join("; ") }));
1026
1050
  return {
1027
1051
  ops: mergedOps,
1028
1052
  warnings: [...executeMd.warnings, ...perItem.warnings],
@@ -1044,14 +1068,11 @@ async function loadExecuteSources(executeFilePath) {
1044
1068
  }
1045
1069
  //#endregion
1046
1070
  //#region src/execute/index.ts
1047
- var ExecuteCancelledError = class extends Error {
1048
- constructor() {
1049
- super("Execution cancelled");
1050
- this.name = "ExecuteCancelledError";
1051
- }
1052
- };
1071
+ function createCancelledError() {
1072
+ return new CodedError(log.GHFS0102());
1073
+ }
1053
1074
  function isExecuteCancelledError(error) {
1054
- return error instanceof ExecuteCancelledError;
1075
+ return error instanceof CodedError && error.diagnostic.code === "GHFS0102";
1055
1076
  }
1056
1077
  async function executePendingChanges(options) {
1057
1078
  try {
@@ -1070,7 +1091,7 @@ async function executePendingChanges(options) {
1070
1091
  details: []
1071
1092
  };
1072
1093
  const interactive = process.stdin.isTTY && !options.nonInteractive;
1073
- if (interactive && !options.prompts) throw new Error("Interactive execute prompts are unavailable. Use --non-interactive or provide prompts.");
1094
+ if (interactive && !options.prompts) throw new CodedError(log.GHFS0100());
1074
1095
  const selected = Array.isArray(options.selectedIndexes) ? selectOperationsByIndexes(allOps, options.selectedIndexes) : interactive ? await selectOperations(allOps, options.prompts) : allOps.map((op, index) => ({
1075
1096
  op,
1076
1097
  index
@@ -1119,7 +1140,7 @@ async function executePendingChanges(options) {
1119
1140
  return result;
1120
1141
  }
1121
1142
  if (interactive) {
1122
- if (!await confirmApply(selected.length, options.prompts)) throw new ExecuteCancelledError();
1143
+ if (!await confirmApply(selected.length, options.prompts)) throw createCancelledError();
1123
1144
  }
1124
1145
  const provider = options.provider ?? createRepositoryProvider({
1125
1146
  token: options.token,
@@ -1200,7 +1221,7 @@ async function applyOperation(provider, op) {
1200
1221
  const isPull = item.kind === "pull";
1201
1222
  if (op.ifUnchangedSince) {
1202
1223
  const remoteUpdatedAt = item.updatedAt;
1203
- if (remoteUpdatedAt && new Date(remoteUpdatedAt).getTime() > new Date(op.ifUnchangedSince).getTime()) throw new Error(`Operation conflict: remote updated_at=${remoteUpdatedAt}`);
1224
+ if (remoteUpdatedAt && new Date(remoteUpdatedAt).getTime() > new Date(op.ifUnchangedSince).getTime()) throw new CodedError(log.GHFS0101({ remoteUpdatedAt }));
1204
1225
  }
1205
1226
  switch (op.action) {
1206
1227
  case "close":
@@ -1268,7 +1289,7 @@ async function applyOperation(provider, op) {
1268
1289
  ensurePullAction(op.action, op.number, isPull);
1269
1290
  await provider.actionConvertToDraft(op.number);
1270
1291
  break;
1271
- default: throw new Error(`Unsupported action: ${String(op.action)}`);
1292
+ default: throw new CodedError(log.GHFS0103({ action: String(op.action) }));
1272
1293
  }
1273
1294
  return item.kind;
1274
1295
  }
@@ -1277,7 +1298,7 @@ function createRunId() {
1277
1298
  }
1278
1299
  async function selectOperations(ops, prompts) {
1279
1300
  const selectedIndexes = await prompts.selectOperations(ops);
1280
- if (!selectedIndexes) throw new ExecuteCancelledError();
1301
+ if (!selectedIndexes) throw createCancelledError();
1281
1302
  const selectedIndexesSet = new Set(selectedIndexes);
1282
1303
  return ops.map((op, index) => ({
1283
1304
  op,
@@ -1298,7 +1319,10 @@ function selectOperationsByIndexes(ops, selectedIndexes) {
1298
1319
  })).filter((item) => selectedSet.has(item.index));
1299
1320
  }
1300
1321
  function ensurePullAction(action, number, isPull) {
1301
- if (!isPull) throw new Error(`Action ${action} requires #${number} to be a pull request`);
1322
+ if (!isPull) throw new CodedError(log.GHFS0104({
1323
+ action,
1324
+ issue: `#${number}`
1325
+ }));
1302
1326
  }
1303
1327
  function describeExecutionAction(action, number) {
1304
1328
  return `${action} #${number}`;
@@ -1522,6 +1546,10 @@ function resolvePatchPlan(patchesMode, kind, state) {
1522
1546
  shouldDeletePatch: !shouldWritePatch
1523
1547
  };
1524
1548
  }
1549
+ function shouldSyncPrDetails(sync, kind, state) {
1550
+ if (kind === "issue") return true;
1551
+ return sync.patches === "all" || sync.patches === "open" && state === "open";
1552
+ }
1525
1553
  function relativeToStorage(storageDirAbsolute, absolutePath) {
1526
1554
  if (absolutePath.startsWith(storageDirAbsolute)) return absolutePath.slice(storageDirAbsolute.length + 1);
1527
1555
  return basename(absolutePath);
@@ -1683,7 +1711,8 @@ async function prepareIssueCandidateSync(context, issue) {
1683
1711
  patchPlan
1684
1712
  };
1685
1713
  }
1686
- const hasCanonicalData = Boolean(tracked?.data && (kind !== "pull" || tracked.data.pull));
1714
+ const needsDetails = shouldSyncPrDetails(context.config.sync, kind, state);
1715
+ const hasCanonicalData = Boolean(tracked?.data && (kind !== "pull" || tracked.data.pull) && (!needsDetails || tracked.data.timeline && (kind !== "pull" || tracked.data.commits)));
1687
1716
  const shouldRefetch = !tracked || tracked.lastUpdatedAt !== issue.updatedAt || !hasCanonicalData;
1688
1717
  const data = shouldRefetch ? await fetchCanonicalData(context, issue) : tracked.data;
1689
1718
  updateTrackedItem(context, number, kind, state, issue.updatedAt, paths.targetPath, patchPlan.shouldWritePatch ? paths.patchPath : void 0, data);
@@ -1726,10 +1755,10 @@ async function materializePreparedIssue(context, candidate) {
1726
1755
  };
1727
1756
  }
1728
1757
  const tracked = context.syncState.items[String(number)];
1729
- if (!tracked) throw new Error(`Missing tracked canonical data for ${formatIssueNumber(number, {
1758
+ if (!tracked) throw new CodedError(log.GHFS0401({ issue: formatIssueNumber(number, {
1730
1759
  repo: context.repoSlug,
1731
1760
  kind
1732
- })}`);
1761
+ }) }));
1733
1762
  const markdown = buildTrackedMarkdown(context, tracked);
1734
1763
  const moved = await moveMarkdownByState(paths, state);
1735
1764
  await writeFileEnsured(paths.targetPath, markdown);
@@ -1794,10 +1823,19 @@ function resolveSyncAction(shouldRefetch, paths, state) {
1794
1823
  return "create";
1795
1824
  }
1796
1825
  async function fetchCanonicalData(context, issue) {
1826
+ const includeDetails = shouldSyncPrDetails(context.config.sync, issue.kind, issue.state);
1827
+ const [comments, pull, commits, timeline] = await Promise.all([
1828
+ context.provider.fetchComments(issue.number),
1829
+ issue.kind === "pull" ? context.provider.fetchPullMetadata(issue.number) : Promise.resolve(void 0),
1830
+ issue.kind === "pull" && includeDetails ? context.provider.fetchPullCommits(issue.number) : Promise.resolve(void 0),
1831
+ includeDetails ? context.provider.fetchTimeline(issue.number) : Promise.resolve(void 0)
1832
+ ]);
1797
1833
  return {
1798
1834
  item: issue,
1799
- comments: await context.provider.fetchComments(issue.number),
1800
- pull: issue.kind === "pull" ? await context.provider.fetchPullMetadata(issue.number) : void 0
1835
+ comments,
1836
+ pull,
1837
+ commits,
1838
+ timeline
1801
1839
  };
1802
1840
  }
1803
1841
  async function syncPatchByPlan(context, number, patchPath, patchPlan) {
@@ -2253,7 +2291,7 @@ async function syncRepository(options) {
2253
2291
  }
2254
2292
  }
2255
2293
  function assertContext(context) {
2256
- if (!context) throw new Error("Sync context was not initialized");
2294
+ if (!context) throw new CodedError(log.GHFS0400());
2257
2295
  }
2258
2296
  function createSyncRunId() {
2259
2297
  return `sync_${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "")}_${randomBytes(3).toString("hex")}`;
@@ -2385,6 +2423,66 @@ function createRemotePoller(options) {
2385
2423
  };
2386
2424
  }
2387
2425
  //#endregion
2426
+ //#region src/server/portless.ts
2427
+ const execFileAsync = promisify(execFile);
2428
+ function slugifyRepoName(repo) {
2429
+ return (repo.includes("/") ? repo.slice(repo.lastIndexOf("/") + 1) : repo).toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "app";
2430
+ }
2431
+ function resolvePortlessCliPath() {
2432
+ try {
2433
+ return resolve(dirname(fileURLToPath(import.meta.resolve("portless"))), "cli.js");
2434
+ } catch {
2435
+ return;
2436
+ }
2437
+ }
2438
+ async function runPortless(args) {
2439
+ const cliPath = resolvePortlessCliPath();
2440
+ if (!cliPath) throw new CodedError(log.GHFS0206({ detail: "portless package is not installed" }));
2441
+ try {
2442
+ const { stdout } = await execFileAsync(process.execPath, [cliPath, ...args], { env: {
2443
+ ...process.env,
2444
+ FORCE_COLOR: "0"
2445
+ } });
2446
+ return stdout;
2447
+ } catch (error) {
2448
+ const err = error;
2449
+ const detail = (err.stderr || err.stdout || err.message || "").toString().trim();
2450
+ throw new CodedError(log.GHFS0206({ detail: detail ? `portless failed: ${detail}` : "portless failed" }, { cause: error }));
2451
+ }
2452
+ }
2453
+ async function registerPortlessRoute(options) {
2454
+ const namespace = options.namespace ?? "ghfs";
2455
+ const tld = options.tld ?? "localhost";
2456
+ const hostname = `${options.subdomain}.${namespace}`;
2457
+ const fallbackUrl = `https://${hostname}.${tld}`;
2458
+ await runPortless([
2459
+ "alias",
2460
+ hostname,
2461
+ String(options.port)
2462
+ ]);
2463
+ let url = fallbackUrl;
2464
+ try {
2465
+ const resolved = (await runPortless(["get", hostname])).trim().split(/\r?\n/).pop()?.trim();
2466
+ if (resolved && /^https?:\/\//.test(resolved)) url = resolved;
2467
+ } catch {}
2468
+ let unregistered = false;
2469
+ return {
2470
+ hostname,
2471
+ url,
2472
+ async unregister() {
2473
+ if (unregistered) return;
2474
+ unregistered = true;
2475
+ try {
2476
+ await runPortless([
2477
+ "alias",
2478
+ "--remove",
2479
+ hostname
2480
+ ]);
2481
+ } catch {}
2482
+ }
2483
+ };
2484
+ }
2485
+ //#endregion
2388
2486
  //#region src/server/queue-builder.ts
2389
2487
  async function buildQueueState(options) {
2390
2488
  const { storageDirAbsolute, executeFilePath } = options;
@@ -2472,7 +2570,7 @@ function createEditorHandler(ctx) {
2472
2570
  function createExecuteHandler(ctx) {
2473
2571
  let running = false;
2474
2572
  return async function executeQueue(options) {
2475
- if (running) throw new Error("An execute is already in progress");
2573
+ if (running) throw new CodedError(log.GHFS0201());
2476
2574
  running = true;
2477
2575
  try {
2478
2576
  const token = await ctx.getToken();
@@ -2838,15 +2936,15 @@ async function addQueueOp(options, op) {
2838
2936
  }
2839
2937
  async function removeQueueOp(options, id) {
2840
2938
  const entry = (await buildQueueState(options)).entries.find((e) => e.id === id);
2841
- if (!entry) throw new Error(`Queue entry not found: ${id}`);
2842
- if (entry.source === "per-item") throw new Error(`Cannot remove a per-item edit from the queue. Edit ${entry.filePath ?? "the markdown file"} directly to adjust it.`);
2939
+ if (!entry) throw new CodedError(log.GHFS0202({ id }));
2940
+ if (entry.source === "per-item") throw new CodedError(log.GHFS0203({ target: entry.filePath ?? "the markdown file" }));
2843
2941
  if (entry.source === "execute.yml") {
2844
2942
  const next = (await readAndValidateExecuteFileWithSource(options.executeFilePath)).ops.filter((_, index) => index !== entry.index);
2845
2943
  await writeExecuteFile(options.executeFilePath, next);
2846
2944
  return buildQueueState(options);
2847
2945
  }
2848
2946
  const mdPath = join(options.storageDirAbsolute, EXECUTE_MD_FILE_NAME);
2849
- if (!await pathExists(mdPath)) throw new Error("execute.md not found; cannot remove op");
2947
+ if (!await pathExists(mdPath)) throw new CodedError(log.GHFS0204());
2850
2948
  const parsed = await readExecuteMdFile(mdPath);
2851
2949
  const remaining = /* @__PURE__ */ new Set();
2852
2950
  for (let i = 0; i < parsed.ops.length; i += 1) if (i !== entry.index) remaining.add(i);
@@ -2855,8 +2953,8 @@ async function removeQueueOp(options, id) {
2855
2953
  }
2856
2954
  async function updateQueueOp(options, id, op) {
2857
2955
  const entry = (await buildQueueState(options)).entries.find((e) => e.id === id);
2858
- if (!entry) throw new Error(`Queue entry not found: ${id}`);
2859
- if (entry.source !== "execute.yml") throw new Error(`Cannot edit ${entry.source} ops from the queue panel`);
2956
+ if (!entry) throw new CodedError(log.GHFS0202({ id }));
2957
+ if (entry.source !== "execute.yml") throw new CodedError(log.GHFS0205({ source: entry.source }));
2860
2958
  const replaced = (await readAndValidateExecuteFileWithSource(options.executeFilePath)).ops.map((existing, index) => index === entry.index ? op : existing);
2861
2959
  await writeExecuteFile(options.executeFilePath, compressOps(replaced));
2862
2960
  return buildQueueState(options);
@@ -2888,11 +2986,33 @@ function createRemoteHandler(ctx) {
2888
2986
  };
2889
2987
  }
2890
2988
  //#endregion
2989
+ //#region src/sync/repo-snapshot.ts
2990
+ async function loadRepoSnapshot(storageDirAbsolute) {
2991
+ try {
2992
+ const raw = await readFile(join(storageDirAbsolute, REPO_SNAPSHOT_FILE_NAME), "utf8");
2993
+ return JSON.parse(raw);
2994
+ } catch {
2995
+ return null;
2996
+ }
2997
+ }
2998
+ //#endregion
2891
2999
  //#region src/server/ui-state.ts
2892
3000
  const UI_STATE_FILE = ".ui.json";
2893
3001
  function createEmptyUiState() {
2894
3002
  return { drafts: {} };
2895
3003
  }
3004
+ function normalizePrTab(value) {
3005
+ if (value === "conversation" || value === "commits" || value === "changes") return value;
3006
+ }
3007
+ function normalizeUserOverride(value) {
3008
+ if (!value || typeof value !== "object") return void 0;
3009
+ const raw = value;
3010
+ const out = {};
3011
+ if (typeof raw.login === "string" && raw.login.trim()) out.login = raw.login.trim();
3012
+ if (typeof raw.name === "string" && raw.name.trim()) out.name = raw.name.trim();
3013
+ if (typeof raw.avatarUrl === "string" && raw.avatarUrl.startsWith("https://")) out.avatarUrl = raw.avatarUrl.trim();
3014
+ return Object.keys(out).length > 0 ? out : void 0;
3015
+ }
2896
3016
  async function loadUiState(storageDirAbsolute) {
2897
3017
  try {
2898
3018
  const raw = await readFile(join(storageDirAbsolute, UI_STATE_FILE), "utf8");
@@ -2903,7 +3023,9 @@ async function loadUiState(storageDirAbsolute) {
2903
3023
  }
2904
3024
  return {
2905
3025
  drafts,
2906
- listPaneSize: typeof parsed.listPaneSize === "number" ? parsed.listPaneSize : void 0
3026
+ listPaneSize: typeof parsed.listPaneSize === "number" ? parsed.listPaneSize : void 0,
3027
+ lastPrTab: normalizePrTab(parsed.lastPrTab),
3028
+ userOverride: normalizeUserOverride(parsed.userOverride)
2907
3029
  };
2908
3030
  } catch {
2909
3031
  return createEmptyUiState();
@@ -2911,9 +3033,13 @@ async function loadUiState(storageDirAbsolute) {
2911
3033
  }
2912
3034
  async function saveUiState(storageDirAbsolute, state) {
2913
3035
  await mkdir(storageDirAbsolute, { recursive: true });
3036
+ const tab = normalizePrTab(state.lastPrTab);
3037
+ const override = normalizeUserOverride(state.userOverride);
2914
3038
  const clean = {
2915
3039
  drafts: { ...state.drafts },
2916
- ...state.listPaneSize != null ? { listPaneSize: state.listPaneSize } : {}
3040
+ ...state.listPaneSize != null ? { listPaneSize: state.listPaneSize } : {},
3041
+ ...tab ? { lastPrTab: tab } : {},
3042
+ ...override ? { userOverride: override } : {}
2917
3043
  };
2918
3044
  await writeFile(join(storageDirAbsolute, UI_STATE_FILE), `${JSON.stringify(clean, null, 2)}\n`, "utf8");
2919
3045
  }
@@ -2948,27 +3074,69 @@ function createStateHandlers(ctx) {
2948
3074
  });
2949
3075
  }
2950
3076
  async function getInitialPayload() {
2951
- const [repo, syncState, queue, uiState] = await Promise.all([
3077
+ const [repo, syncState, queue, uiState, snapshot] = await Promise.all([
2952
3078
  getRepoMeta(),
2953
3079
  getSyncState(),
2954
3080
  getQueue(),
2955
- loadUiState(ctx.storageDirAbsolute)
3081
+ loadUiState(ctx.storageDirAbsolute),
3082
+ loadRepoSnapshot(ctx.storageDirAbsolute)
2956
3083
  ]);
3084
+ const repositoryLabels = (snapshot?.labels ?? []).map((label) => ({
3085
+ name: label.name,
3086
+ color: label.color,
3087
+ description: label.description
3088
+ }));
3089
+ const currentUser = await resolveCurrentUser(ctx, uiState);
2957
3090
  return {
2958
3091
  repo,
2959
3092
  syncState,
2960
3093
  queue,
2961
3094
  remote: ctx.poller.getCurrent(),
2962
3095
  recentExecutions: syncState.executions ?? [],
2963
- uiState
3096
+ uiState,
3097
+ repositoryLabels,
3098
+ currentUser
2964
3099
  };
2965
3100
  }
3101
+ async function getPullPatch(number) {
3102
+ const tracked = (await loadSyncState(ctx.storageDirAbsolute)).items[String(number)];
3103
+ if (!tracked?.patchPath) return null;
3104
+ try {
3105
+ return await readFile(join(ctx.storageDirAbsolute, tracked.patchPath), "utf8");
3106
+ } catch (err) {
3107
+ if (err.code === "ENOENT") return null;
3108
+ throw err;
3109
+ }
3110
+ }
2966
3111
  return {
2967
3112
  getInitialPayload,
2968
3113
  getSyncState,
2969
3114
  getQueue,
2970
3115
  getRepoMeta,
2971
- saveUiState: (state) => saveUiState(ctx.storageDirAbsolute, state)
3116
+ saveUiState: (state) => saveUiState(ctx.storageDirAbsolute, state),
3117
+ getPullPatch
3118
+ };
3119
+ }
3120
+ async function resolveCurrentUser(ctx, uiState) {
3121
+ const override = uiState.userOverride;
3122
+ let fetched = null;
3123
+ try {
3124
+ const user = await (await ctx.getProvider())?.fetchAuthenticatedUser();
3125
+ if (user) fetched = {
3126
+ login: user.login,
3127
+ name: user.name,
3128
+ avatarUrl: user.avatarUrl
3129
+ };
3130
+ } catch {
3131
+ fetched = null;
3132
+ }
3133
+ if (!override && !fetched) return null;
3134
+ const login = override?.login ?? fetched?.login;
3135
+ if (!login) return null;
3136
+ return {
3137
+ login,
3138
+ name: override?.name ?? fetched?.name ?? null,
3139
+ avatarUrl: override?.avatarUrl ?? fetched?.avatarUrl ?? `https://avatars.githubusercontent.com/${login}`
2972
3140
  };
2973
3141
  }
2974
3142
  //#endregion
@@ -2976,7 +3144,7 @@ function createStateHandlers(ctx) {
2976
3144
  function createSyncHandler(ctx) {
2977
3145
  let running = false;
2978
3146
  return async function triggerSync(options) {
2979
- if (running) throw new Error("A sync is already in progress");
3147
+ if (running) throw new CodedError(log.GHFS0200());
2980
3148
  running = true;
2981
3149
  try {
2982
3150
  const token = await ctx.getToken();
@@ -3039,7 +3207,8 @@ function createServerFunctions(ctx) {
3039
3207
  clearQueue: queue.clearQueue,
3040
3208
  checkRemote: createRemoteHandler(ctx),
3041
3209
  openInEditor: createEditorHandler(ctx),
3042
- saveUiState: state.saveUiState
3210
+ saveUiState: state.saveUiState,
3211
+ getPullPatch: state.getPullPatch
3043
3212
  };
3044
3213
  }
3045
3214
  //#endregion
@@ -3191,7 +3360,7 @@ async function createUiServer(options) {
3191
3360
  cachedToken = await options.onRequestToken();
3192
3361
  return cachedToken;
3193
3362
  }
3194
- throw new Error("Missing GitHub token");
3363
+ throw new CodedError(log.GHFS0001());
3195
3364
  }
3196
3365
  let cachedProvider;
3197
3366
  async function getProvider() {
@@ -3298,11 +3467,29 @@ async function createUiServer(options) {
3298
3467
  resolvePromise();
3299
3468
  });
3300
3469
  });
3470
+ const directUrl = `http://${options.host === "0.0.0.0" ? "localhost" : options.host}:${port}`;
3471
+ let portlessUrl;
3472
+ let portlessUnregister;
3473
+ if (options.portless?.enabled) try {
3474
+ const route = await registerPortlessRoute({
3475
+ subdomain: options.portless.subdomain,
3476
+ namespace: options.portless.namespace,
3477
+ port
3478
+ });
3479
+ portlessUrl = route.url;
3480
+ portlessUnregister = route.unregister;
3481
+ } catch (error) {
3482
+ const message = error.message || String(error);
3483
+ options.logger?.info?.(`portless unavailable (${message}); falling back to ${directUrl}`);
3484
+ }
3301
3485
  return {
3302
- url: `http://${options.host === "0.0.0.0" ? "localhost" : options.host}:${port}`,
3486
+ url: portlessUrl ?? directUrl,
3487
+ directUrl,
3488
+ portlessUrl,
3303
3489
  port,
3304
3490
  host: options.host,
3305
3491
  close: async () => {
3492
+ if (portlessUnregister) await portlessUnregister();
3306
3493
  poller.close();
3307
3494
  await watcher.close();
3308
3495
  await new Promise((resolveClose) => wss.close(() => resolveClose()));
@@ -3328,4 +3515,4 @@ function rawToString(raw) {
3328
3515
  return String(raw);
3329
3516
  }
3330
3517
  //#endregion
3331
- export { isExecuteCancelledError as a, GHFS_VERSION as c, pathExists as d, getExecuteFile as f, executePendingChanges as i, ensureExecuteArtifacts as l, resolveConfig as m, syncRepository as n, loadSyncState as o, getStorageDirAbsolute as p, appendExecutionResult as r, GHFS_NAME as s, createUiServer as t, ACTIONS_COLOR_HEX as u };
3518
+ export { executePendingChanges as a, GHFS_NAME as c, ACTIONS_COLOR_HEX as d, pathExists as f, resolveConfig as h, appendExecutionResult as i, GHFS_VERSION as l, getStorageDirAbsolute as m, slugifyRepoName as n, isExecuteCancelledError as o, getExecuteFile as p, syncRepository as r, loadSyncState as s, createUiServer as t, ensureExecuteArtifacts as u };