@tequila99/githuman 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +26 -0
  2. package/dist/cli/commands/export.js +2 -1
  3. package/dist/cli/server-runtime.js +13 -1
  4. package/dist/cli/startup-message.js +3 -2
  5. package/dist/server/adapters/agents/event-mapper.js +140 -0
  6. package/dist/server/app.js +21 -12
  7. package/dist/server/config/agents.js +141 -0
  8. package/dist/server/errors/agents.js +12 -0
  9. package/dist/server/errors/comments.js +2 -0
  10. package/dist/server/errors/export.js +2 -0
  11. package/dist/server/errors/http.js +4 -0
  12. package/dist/server/errors/reviews.js +3 -0
  13. package/dist/server/hooks/agents/local-origin.js +33 -0
  14. package/dist/server/repositories/review.repo.js +1 -3
  15. package/dist/server/routes/agent.js +135 -0
  16. package/dist/server/routes/comments.js +17 -67
  17. package/dist/server/routes/diff.js +5 -6
  18. package/dist/server/routes/events.js +6 -1
  19. package/dist/server/routes/export.js +6 -15
  20. package/dist/server/routes/git.js +12 -21
  21. package/dist/server/routes/reviews.js +11 -43
  22. package/dist/server/services/agent/agent-session.js +497 -0
  23. package/dist/server/services/agent/context-builder.js +137 -0
  24. package/dist/server/services/agent/file-index.js +58 -0
  25. package/dist/server/services/agent/session-registry.js +100 -0
  26. package/dist/server/services/comment.service.js +1 -2
  27. package/dist/server/services/diff.service.js +2 -1
  28. package/dist/server/services/export.service.js +1 -2
  29. package/dist/server/services/git.service.js +6 -7
  30. package/dist/server/services/review.service.js +3 -3
  31. package/dist/server/utils/executable.js +26 -0
  32. package/dist/server/utils/file-name.js +6 -0
  33. package/dist/server/utils/sse.js +11 -0
  34. package/dist/server/utils/text.js +29 -0
  35. package/dist/shared/agents/chat-names.js +17 -0
  36. package/dist/shared/agents/constants.js +6 -0
  37. package/dist/shared/agents/context-format.js +17 -0
  38. package/dist/shared/agents/file-search.js +48 -0
  39. package/dist/shared/agents/schemas.js +51 -0
  40. package/dist/shared/agents/types.js +11 -0
  41. package/dist/shared/app/types.js +1 -0
  42. package/dist/shared/comments/types.js +1 -0
  43. package/dist/shared/diff/types.js +4 -0
  44. package/dist/shared/{types.js → events/types.js} +0 -3
  45. package/dist/shared/git/types.js +1 -0
  46. package/dist/shared/http/types.js +1 -0
  47. package/dist/shared/network/loopback.js +4 -0
  48. package/dist/shared/reviews/types.js +1 -0
  49. package/dist/shared/utils/error-message.js +3 -0
  50. package/dist/shared/utils/guards.js +4 -0
  51. package/dist/web/assets/AppPage-CSb8txs5.js +1 -0
  52. package/dist/web/assets/CreateReviewFabButton-B18DLuH6.js +1 -0
  53. package/dist/web/assets/CreateReviewFabButton-Cufd8hVJ.css +1 -0
  54. package/dist/web/assets/{ErrorNotFound-BuL12Ld8.js → ErrorNotFound-B5uYICL4.js} +1 -1
  55. package/dist/web/assets/IndexPage-B-hkrnvt.css +1 -0
  56. package/dist/web/assets/IndexPage-Cm_ssBeC.js +1 -0
  57. package/dist/web/assets/MainLayout-ChxXEt_Q.css +1 -0
  58. package/dist/web/assets/MainLayout-ClBPF545.js +7 -0
  59. package/dist/web/assets/QBtn-E32fUOKx.js +1 -0
  60. package/dist/web/assets/QItemLabel-Co6oCEUr.js +1 -0
  61. package/dist/web/assets/QMenu-BZ1eK_rS.js +1 -0
  62. package/dist/web/assets/QSelect-D1V4tbDr.js +1 -0
  63. package/dist/web/assets/ReviewDetailPage-BWa3EEkv.css +1 -0
  64. package/dist/web/assets/ReviewDetailPage-Ct0hXwZL.js +1 -0
  65. package/dist/web/assets/ReviewsPage-CbLAU6OM.js +1 -0
  66. package/dist/web/assets/StatusSwitcher-C0k4efwK.js +4 -0
  67. package/dist/web/assets/StatusSwitcher-CZYtI0ID.css +1 -0
  68. package/dist/web/assets/abnfDiagram-O67JEVCF-DkOrqZLn.js +1 -0
  69. package/dist/web/assets/agent-icon-BKoq2a6T.js +17 -0
  70. package/dist/web/assets/agent-icon-BUd-vCRS.css +1 -0
  71. package/dist/web/assets/agent-store-CEQ6MmTC.js +1 -0
  72. package/dist/web/assets/app-info-store-CIqmSeWK.js +1 -0
  73. package/dist/web/assets/arc-BALAYY3f.js +1 -0
  74. package/dist/web/assets/architecture-7GRP2DOG-CTkghkmX.js +1 -0
  75. package/dist/web/assets/architectureDiagram-NJMV4G6O-C-xtrMea.js +36 -0
  76. package/dist/web/assets/array-BifhSqXX.js +1 -0
  77. package/dist/web/assets/blockDiagram-BEXU5L5S-DYo9Os-m.js +140 -0
  78. package/dist/web/assets/c4Diagram-YGBWAQC7-BpSFjUAX.js +38 -0
  79. package/dist/web/assets/channel-f9cE6NV9.js +1 -0
  80. package/dist/web/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  81. package/dist/web/assets/chunk-3FUC2YCW-DtUqbu5K.js +2 -0
  82. package/dist/web/assets/chunk-5DYCD2WN-DeYTIM8k.js +1 -0
  83. package/dist/web/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  84. package/dist/web/assets/chunk-742MDFTN-8BfKAsu6.js +1 -0
  85. package/dist/web/assets/chunk-7INBJB4K-PXK092EZ.js +62 -0
  86. package/dist/web/assets/chunk-7M6MHVWA-Db9reT-V.js +213 -0
  87. package/dist/web/assets/chunk-7PRAP22T-CNFpjNaH.js +1 -0
  88. package/dist/web/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
  89. package/dist/web/assets/chunk-FOHPRMQF-CoA4358r.js +161 -0
  90. package/dist/web/assets/chunk-GTNCS2PH-C5gqOp1W.js +88 -0
  91. package/dist/web/assets/chunk-GWA4HPMP-BquHLG8L.js +1 -0
  92. package/dist/web/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
  93. package/dist/web/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  94. package/dist/web/assets/chunk-MBY4JIJT-DyOEFgCh.js +72 -0
  95. package/dist/web/assets/chunk-NETBCI7D-Bd3ij3-b.js +1 -0
  96. package/dist/web/assets/chunk-O7XYJQB3-DQvIvDe6.js +126 -0
  97. package/dist/web/assets/chunk-UA2S7LBM-BDIHwgCZ.js +1 -0
  98. package/dist/web/assets/chunk-WEXAMYUT-DwQKTsK-.js +1 -0
  99. package/dist/web/assets/chunk-XXDRQBXY-DTdiON6C.js +1 -0
  100. package/dist/web/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  101. package/dist/web/assets/chunk-Z7XXMR3K-CIvnaGnU.js +10 -0
  102. package/dist/web/assets/chunk-ZIGJFQKS-BdT_T5CV.js +2 -0
  103. package/dist/web/assets/classDiagram-v2-NBCMYWYE-BUoclHlO.js +217 -0
  104. package/dist/web/assets/{core-Ruj7F7dx.js → core-B8kUiZoM.js} +1 -1
  105. package/dist/web/assets/cose-bilkent-JH36ORCC-C16eW6pc.js +1 -0
  106. package/dist/web/assets/create-B9ZqyTxV.js +1 -0
  107. package/dist/web/assets/cynefin-OW5HDTMX-1mS7ZeoM.js +1 -0
  108. package/dist/web/assets/cynefinDiagram-VND7K2PF-D1PC4YT4.js +62 -0
  109. package/dist/web/assets/cytoscape.esm-B-1iW2ft.js +321 -0
  110. package/dist/web/assets/dagre-6A5THRUB-amODOP74.js +4 -0
  111. package/dist/web/assets/debounce-CDIE7CV6.js +1 -0
  112. package/dist/web/assets/defaultLocale-BFoDCU3G.js +1 -0
  113. package/dist/web/assets/diagram-22UHCM2B-wUvcsN_B.js +200 -0
  114. package/dist/web/assets/diagram-3UASUU5V-CLiOVs2l.js +24 -0
  115. package/dist/web/assets/diagram-ATOU4E4O-Cs5cFGgz.js +3 -0
  116. package/dist/web/assets/diagram-CDSNMT55-C8Jb-YeE.js +30 -0
  117. package/dist/web/assets/diagram-MLGK6HIB-DA6C9fVB.js +24 -0
  118. package/dist/web/assets/diagram-MPIPVDR6-BOaFKuUi.js +41 -0
  119. package/dist/web/assets/dist-DuFVAX6Y.js +1 -0
  120. package/dist/web/assets/ebnfDiagram-ZINNZB2B-e5jvn-EE.js +1 -0
  121. package/dist/web/assets/elk-276RUBZZ-D7Gcu17D.js +27 -0
  122. package/dist/web/assets/engine-oniguruma-HbxpIAu4.js +1 -0
  123. package/dist/web/assets/erDiagram-OPXOYQCR-Cn1bBUF8.js +99 -0
  124. package/dist/web/assets/event-rR76ioXz.js +1 -0
  125. package/dist/web/assets/eventmodeling-NTZA5JFV-BjGpd42n.js +1 -0
  126. package/dist/web/assets/export-file-Di_2jvjP.js +1 -0
  127. package/dist/web/assets/fira-code-symbols2-400-normal-9X26I2LK.woff2 +0 -0
  128. package/dist/web/assets/fira-code-symbols2-500-normal-B5s_njw3.woff2 +0 -0
  129. package/dist/web/assets/fira-code-symbols2-600-normal-Bu3RnO39.woff2 +0 -0
  130. package/dist/web/assets/flowDiagram-KWPJA3E3-a3N8MVB8.js +1 -0
  131. package/dist/web/assets/ganttDiagram-FUAMR5RP-C3U8jeJB.js +292 -0
  132. package/dist/web/assets/gitGraph-4MIJSDKK-C165DC0H.js +1 -0
  133. package/dist/web/assets/gitGraphDiagram-X574FWY7-CVHdT1OC.js +106 -0
  134. package/dist/web/assets/golos-text-cyrillic-400-normal-BwL4n7Pb.woff +0 -0
  135. package/dist/web/assets/golos-text-cyrillic-400-normal-C7us6pn1.woff2 +0 -0
  136. package/dist/web/assets/golos-text-cyrillic-500-normal-BSLQUuP1.woff2 +0 -0
  137. package/dist/web/assets/golos-text-cyrillic-500-normal-hXinzVVQ.woff +0 -0
  138. package/dist/web/assets/golos-text-cyrillic-ext-400-normal-Bo67NYBq.woff2 +0 -0
  139. package/dist/web/assets/golos-text-cyrillic-ext-400-normal-D592xEk3.woff +0 -0
  140. package/dist/web/assets/golos-text-cyrillic-ext-500-normal-CLsu_eDI.woff2 +0 -0
  141. package/dist/web/assets/golos-text-cyrillic-ext-500-normal-InHNvB7v.woff +0 -0
  142. package/dist/web/assets/golos-text-latin-400-normal-Coi1FYaD.woff2 +0 -0
  143. package/dist/web/assets/golos-text-latin-400-normal-DOuJOmdK.woff +0 -0
  144. package/dist/web/assets/golos-text-latin-500-normal-BQo4s7Kn.woff +0 -0
  145. package/dist/web/assets/golos-text-latin-500-normal-BznAvurO.woff2 +0 -0
  146. package/dist/web/assets/golos-text-latin-ext-400-normal-BXgyX_iE.woff +0 -0
  147. package/dist/web/assets/golos-text-latin-ext-400-normal-BjKcJWKY.woff2 +0 -0
  148. package/dist/web/assets/golos-text-latin-ext-500-normal-9vZPKadr.woff2 +0 -0
  149. package/dist/web/assets/golos-text-latin-ext-500-normal-BmtMVntR.woff +0 -0
  150. package/dist/web/assets/graphlib-DS17s2tU.js +1 -0
  151. package/dist/web/assets/i18n-CyUPETur.js +1 -0
  152. package/dist/web/assets/{index-JAYe_SFI.css → index-C6ArNnKs.css} +1 -1
  153. package/dist/web/assets/index-C_B6Z2lc.js +2 -0
  154. package/dist/web/assets/info-A6RAGUB7-cbWtF3FJ.js +1 -0
  155. package/dist/web/assets/infoDiagram-VRGFBTTK-C_kWn3Ai.js +2 -0
  156. package/dist/web/assets/init-C-OQMol4.js +1 -0
  157. package/dist/web/assets/init-app-DnfYD-0k.js +1 -0
  158. package/dist/web/assets/is-ChHvR1Z-.js +1 -0
  159. package/dist/web/assets/ishikawaDiagram-OU5B5YK6-Xb9cDRr7.js +70 -0
  160. package/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-Bh0R7Dhr.woff +0 -0
  161. package/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-C_uLvvQ5.woff2 +0 -0
  162. package/dist/web/assets/jetbrains-mono-cyrillic-ext-500-normal-C9ShMxGR.woff2 +0 -0
  163. package/dist/web/assets/jetbrains-mono-cyrillic-ext-500-normal-CEVyPk4Y.woff +0 -0
  164. package/dist/web/assets/jetbrains-mono-cyrillic-ext-600-normal-DVvC-yKp.woff +0 -0
  165. package/dist/web/assets/jetbrains-mono-cyrillic-ext-600-normal-Dj6eZy5f.woff2 +0 -0
  166. package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-ByoDsISC.woff2 +0 -0
  167. package/dist/web/assets/jetbrains-mono-vietnamese-500-normal-BvH7FW2L.woff2 +0 -0
  168. package/dist/web/assets/jetbrains-mono-vietnamese-600-normal-Dtizs43-.woff2 +0 -0
  169. package/dist/web/assets/journeyDiagram-ZHPQQLJL-6eZcefap.js +139 -0
  170. package/dist/web/assets/kanban-definition-PNTS6WVX-D_z_AsKR.js +89 -0
  171. package/dist/web/assets/katex-ZlcWpGUi.js +257 -0
  172. package/dist/web/assets/line-v7JtZ-Za.js +1 -0
  173. package/dist/web/assets/linear-hp1KWmiC.js +1 -0
  174. package/dist/web/assets/mermaid-parser.core-Cwwk5NqO.js +7 -0
  175. package/dist/web/assets/mermaid.core-BjPJhwW0.js +44 -0
  176. package/dist/web/assets/mindmap-definition-NLK3R4M7-lQohhDXq.js +96 -0
  177. package/dist/web/assets/ordinal-BDEzSJ7C.js +1 -0
  178. package/dist/web/assets/packet-AYTQ26CC-DxiGe6nt.js +1 -0
  179. package/dist/web/assets/path-fybaL0A-.js +1 -0
  180. package/dist/web/assets/pegDiagram-GJSIUBJH-XZRpQTLx.js +1 -0
  181. package/dist/web/assets/pie-WAS4IAKB-fxN0O90k.js +1 -0
  182. package/dist/web/assets/pieDiagram-5QR66LMP-M_bBKE-n.js +39 -0
  183. package/dist/web/assets/pinia-0B8sIOgD.js +1 -0
  184. package/dist/web/assets/pinia-DbmXdZbT.js +1 -0
  185. package/dist/web/assets/quadrantDiagram-O4NWA36T-BNxVPrq3.js +7 -0
  186. package/dist/web/assets/radar-RG4KPBEZ-Cd-5aokk.js +1 -0
  187. package/dist/web/assets/railroad-74A4TZTK-BvSKL8Ze.js +1 -0
  188. package/dist/web/assets/railroad-abnf-HS5TGJTU-CB32K25L.js +1 -0
  189. package/dist/web/assets/railroad-ebnf-LZEXJU2U-CqQR3zRl.js +1 -0
  190. package/dist/web/assets/railroad-peg-WCYAUIDC-DRSdB-oL.js +1 -0
  191. package/dist/web/assets/railroadDiagram-XR7U4H2S-D664lPSL.js +1 -0
  192. package/dist/web/assets/requirementDiagram-PLB6GJNP-B_1Dl0-3.js +84 -0
  193. package/dist/web/assets/rough.esm-Dy-Kn_BL.js +1 -0
  194. package/dist/web/assets/runtime-core.esm-bundler-Carm8LUR.js +1 -0
  195. package/dist/web/assets/safe-storage-CWaD6Dq3.js +1 -0
  196. package/dist/web/assets/sankeyDiagram-IPEJSGJF-BvFmMC_F.js +40 -0
  197. package/dist/web/assets/sequenceDiagram-PO4LG4MO-DMK1ey4g.js +169 -0
  198. package/dist/web/assets/single-flight-r8B7stt1.js +1 -0
  199. package/dist/web/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  200. package/dist/web/assets/src-Cy0hT8a0.js +1 -0
  201. package/dist/web/assets/stateDiagram-v2-GCMORJYK-VVElU-_E.js +291 -0
  202. package/dist/web/assets/swimlanes-2SLR337P-DyfYJvHL.js +1 -0
  203. package/dist/web/assets/swimlanesDiagram-TC7HE7FX-BQ0mK2BI.js +8 -0
  204. package/dist/web/assets/theme-BFceB3b9.js +1 -0
  205. package/dist/web/assets/timeline-definition-EJHVYXUP-DBoRb7uC.js +120 -0
  206. package/dist/web/assets/treeView-Q6P3EWNA-D8AoZg1Y.js +1 -0
  207. package/dist/web/assets/treemap-WGGIJYW6-DhcVtZsu.js +1 -0
  208. package/dist/web/assets/use-app-theme-DxZW-eOR.js +1 -0
  209. package/dist/web/assets/use-panel-width-CY75Fomr.js +1 -0
  210. package/dist/web/assets/usecaseDiagram-POWQR4AR-BCfvWOH4.js +328 -0
  211. package/dist/web/assets/vennDiagram-UO4OBE2U-BIk6-FLo.js +34 -0
  212. package/dist/web/assets/{vue-i18n.runtime-CxBM6QPV.js → vue-i18n.runtime-BQwnBdmC.js} +2 -2
  213. package/dist/web/assets/wardley-WFR3VGLG-BMHH70A3.js +1 -0
  214. package/dist/web/assets/wardleyDiagram-VNRHLVJA-DB-cxlSq.js +78 -0
  215. package/dist/web/assets/xychartDiagram-PMCCYNJV-BejE-3gi.js +7 -0
  216. package/dist/web/index.html +8 -6
  217. package/package.json +12 -3
  218. package/dist/web/assets/AppPage-B9tWPrzn.js +0 -1
  219. package/dist/web/assets/CreateReviewFabButton-BqWdgfEf.css +0 -1
  220. package/dist/web/assets/CreateReviewFabButton-DcXpOlBP.js +0 -1
  221. package/dist/web/assets/IndexPage-CsgdLXZh.css +0 -1
  222. package/dist/web/assets/IndexPage-y9DcUqW9.js +0 -1
  223. package/dist/web/assets/MainLayout-BRPoh8y0.css +0 -1
  224. package/dist/web/assets/MainLayout-fQytypS5.js +0 -1
  225. package/dist/web/assets/Platform-DDGYwfzl.js +0 -1
  226. package/dist/web/assets/QBtn-DGiC5uLo.js +0 -1
  227. package/dist/web/assets/QTooltip-CPN6UvuX.js +0 -1
  228. package/dist/web/assets/ReviewDetailPage-CL6A5zjH.css +0 -1
  229. package/dist/web/assets/ReviewDetailPage-aMMuYtax.js +0 -1
  230. package/dist/web/assets/ReviewsPage-B1CTHU13.js +0 -1
  231. package/dist/web/assets/StatusSwitcher-Bj-XCwSr.js +0 -3
  232. package/dist/web/assets/StatusSwitcher-BydQq1LI.css +0 -1
  233. package/dist/web/assets/app-info-store-Dw8pPU-w.js +0 -1
  234. package/dist/web/assets/client-De34x_P_.js +0 -1
  235. package/dist/web/assets/engine-oniguruma-Bon2Icja.js +0 -1
  236. package/dist/web/assets/event-D0kaqRwq.js +0 -1
  237. package/dist/web/assets/format-Bb6ahGqi.js +0 -1
  238. package/dist/web/assets/i18n-Dw0eMaZf.js +0 -1
  239. package/dist/web/assets/index-i1Dlwasy.js +0 -2
  240. package/dist/web/assets/init-app-CPTVCTFc.js +0 -1
  241. package/dist/web/assets/pinia-ClnoFqXt.js +0 -1
  242. package/dist/web/assets/pinia-jMX0pzvu.js +0 -1
  243. package/dist/web/assets/runtime-core.esm-bundler-Db5Q9Gsb.js +0 -1
  244. package/dist/web/assets/theme-CgDsrcvS.js +0 -1
  245. package/dist/web/assets/use-app-theme-D0Pl-VfI.js +0 -1
  246. package/dist/web/assets/use-server-events-pJWjsMIC.js +0 -1
@@ -0,0 +1,100 @@
1
+ import { UnknownAgentPresetError, TooManyAgentSessionsError } from "../../errors/agents.js";
2
+ import { MAX_AGENT_SESSIONS } from "../../../shared/agents/constants.js";
3
+ import { uniqueChatName } from "../../../shared/agents/chat-names.js";
4
+ import { AgentSession } from "./agent-session.js";
5
+ import { describePreset } from "../../config/agents.js";
6
+ export function createSessionRegistry(options) {
7
+ const sessions = new Map();
8
+ const unsubscribeSession = new Map();
9
+ const listeners = new Set();
10
+ let lastEventId = 0;
11
+ function broadcast(message) {
12
+ for (const listener of listeners) {
13
+ listener(message);
14
+ }
15
+ }
16
+ function drop(id) {
17
+ unsubscribeSession.get(id)?.();
18
+ unsubscribeSession.delete(id);
19
+ sessions.delete(id);
20
+ }
21
+ function closeAll() {
22
+ for (const session of sessions.values()) {
23
+ session.close();
24
+ }
25
+ for (const id of sessions.keys()) {
26
+ drop(id);
27
+ }
28
+ }
29
+ return {
30
+ listPresets: () => options.presets.map(describePreset),
31
+ create(presetId, reviewId, name) {
32
+ const preset = options.presets.find(p => p.id === presetId);
33
+ if (!preset) {
34
+ throw new UnknownAgentPresetError(`Unknown agent "${presetId}"`);
35
+ }
36
+ if (sessions.size >= MAX_AGENT_SESSIONS) {
37
+ throw new TooManyAgentSessionsError(`At most ${MAX_AGENT_SESSIONS} chats can be open at once`);
38
+ }
39
+ const session = new AgentSession({
40
+ preset,
41
+ // Open chats are told apart by name: a taken one gets "(1)", "(2)", …
42
+ name: uniqueChatName(name?.trim() || preset.title, [...sessions.values()].map(s => s.name)),
43
+ cwd: options.repositoryPath,
44
+ reviewId,
45
+ nextEventId: () => ++lastEventId,
46
+ ...(options.bufferLimit === undefined
47
+ ? {}
48
+ : { bufferLimit: options.bufferLimit })
49
+ });
50
+ sessions.set(session.id, session);
51
+ unsubscribeSession.set(session.id, session.onEvent(envelope => {
52
+ broadcast({
53
+ type: 'event',
54
+ envelope: { ...envelope, sessionId: session.id }
55
+ });
56
+ }));
57
+ broadcast({ type: 'sessions' });
58
+ void session.start();
59
+ return session;
60
+ },
61
+ get: id => sessions.get(id),
62
+ list: () => [...sessions.values()].map(s => s.info()),
63
+ close(id) {
64
+ const session = sessions.get(id);
65
+ if (!session) {
66
+ return false;
67
+ }
68
+ session.close();
69
+ drop(id);
70
+ broadcast({ type: 'sessions' });
71
+ return true;
72
+ },
73
+ closeAll,
74
+ subscribe(listener, afterId = 0) {
75
+ const replays = [...sessions.values()].map(session => ({
76
+ sessionId: session.id,
77
+ ...session.replay(afterId)
78
+ }));
79
+ for (const { sessionId, gap } of replays) {
80
+ if (gap) {
81
+ listener({ type: 'gap', sessionId });
82
+ }
83
+ // The buffer starts late for a new client or after a gap, so it may
84
+ // lack the events that set the status, settings and open requests.
85
+ if (gap || afterId === 0) {
86
+ const state = sessions.get(sessionId)?.state();
87
+ if (state) {
88
+ listener({ type: 'state', state });
89
+ }
90
+ }
91
+ }
92
+ replays
93
+ .flatMap(({ sessionId, envelopes }) => envelopes.map(envelope => ({ ...envelope, sessionId })))
94
+ .sort((a, b) => a.id - b.id)
95
+ .forEach(envelope => listener({ type: 'event', envelope }));
96
+ listeners.add(listener);
97
+ return () => listeners.delete(listener);
98
+ }
99
+ };
100
+ }
@@ -1,6 +1,5 @@
1
+ import { ValidationError } from "../errors/comments.js";
1
2
  import { createComment as insertComment, findCommentById, listCommentsByReview, updateComment as updateCommentRepo, deleteComment as deleteCommentRepo, setCommentResolved } from "../repositories/comment.repo.js";
2
- export class ValidationError extends Error {
3
- }
4
3
  export function createComment(db, reviewId, input, eventBus) {
5
4
  if (!input.content) {
6
5
  throw new ValidationError('"content" is required');
@@ -1,5 +1,7 @@
1
1
  import { diffLines } from 'diff';
2
2
  import { assertSafeRef, getFileAtRef, getFilesAtRefBatch, listChangedPaths, listUntrackedPaths } from "./git.service.js";
3
+ /** Unchanged lines kept around each change in a hunk, as in `git diff`. */
4
+ const CONTEXT_LINES = 3;
3
5
  function splitLines(text) {
4
6
  if (text === '')
5
7
  return [];
@@ -8,7 +10,6 @@ function splitLines(text) {
8
10
  lines.pop();
9
11
  return lines;
10
12
  }
11
- const CONTEXT_LINES = 3;
12
13
  function windowHunks(lines, contextLines = CONTEXT_LINES) {
13
14
  if (lines.length === 0)
14
15
  return [];
@@ -1,8 +1,7 @@
1
+ import { ExportNotFoundError } from "../errors/export.js";
1
2
  import { findReviewById } from "../repositories/review.repo.js";
2
3
  import { listCommentsByReview } from "../repositories/comment.repo.js";
3
4
  import { getFileAtRef } from "./git.service.js";
4
- export class ExportNotFoundError extends Error {
5
- }
6
5
  const STATUS_LABELS = {
7
6
  in_progress: 'в процессе',
8
7
  approved: 'одобрено',
@@ -3,13 +3,14 @@ import { promisify } from 'node:util';
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { basename, resolve, sep } from 'node:path';
5
5
  import { simpleGit } from 'simple-git';
6
+ import { isBinaryBuffer } from "../utils/text.js";
6
7
  const execFileAsync = promisify(execFile);
7
8
  /**
8
9
  * Resolves `path` against `repoPath` and rejects anything that escapes the
9
10
  * repository root (e.g. `../../etc/passwd`), since `path` here is untrusted
10
11
  * input coming straight off the HTTP request.
11
12
  */
12
- function resolveWithinRepo(repoPath, path) {
13
+ export function resolveWithinRepo(repoPath, path) {
13
14
  const repoRoot = resolve(repoPath);
14
15
  const resolved = resolve(repoRoot, path);
15
16
  if (resolved !== repoRoot && !resolved.startsWith(repoRoot + sep)) {
@@ -62,10 +63,8 @@ export async function getFileAtRef(repoPath, ref, path) {
62
63
  try {
63
64
  const absolutePath = resolveWithinRepo(repoPath, path);
64
65
  const buffer = await readFile(absolutePath);
65
- return {
66
- content: buffer.includes(0) ? '' : buffer.toString('utf-8'),
67
- isBinary: buffer.includes(0)
68
- };
66
+ const isBinary = isBinaryBuffer(buffer);
67
+ return { content: isBinary ? '' : buffer.toString('utf-8'), isBinary };
69
68
  }
70
69
  catch {
71
70
  return { content: '', isBinary: false };
@@ -78,7 +77,7 @@ export async function getFileAtRef(repoPath, ref, path) {
78
77
  encoding: 'buffer',
79
78
  maxBuffer: 1024 * 1024 * 100
80
79
  });
81
- const isBinary = stdout.includes(0);
80
+ const isBinary = isBinaryBuffer(stdout);
82
81
  return {
83
82
  content: isBinary ? '' : stdout.toString('utf-8'),
84
83
  isBinary
@@ -119,7 +118,7 @@ function parseCatFileBatchOutput(buffer, count) {
119
118
  throw new Error('git cat-file --batch: truncated output (short content)');
120
119
  }
121
120
  offset += size + 1; // skip content + its trailing LF
122
- const isBinary = content.includes(0);
121
+ const isBinary = isBinaryBuffer(content);
123
122
  results.push({
124
123
  content: isBinary ? '' : content.toString('utf-8'),
125
124
  isBinary
@@ -1,10 +1,10 @@
1
- import { createReview as insertReview, findReviewById, listReviews, updateReviewStatus as updateReviewStatusRepo, deleteReview as deleteReviewRepo, UniqueNameError } from "../repositories/review.repo.js";
1
+ import { ValidationError } from "../errors/reviews.js";
2
+ import { createReview as insertReview, findReviewById, listReviews, updateReviewStatus as updateReviewStatusRepo, deleteReview as deleteReviewRepo } from "../repositories/review.repo.js";
3
+ import { UniqueNameError } from "../errors/reviews.js";
2
4
  import { listCommentsByReview, deleteComment } from "../repositories/comment.repo.js";
3
5
  import { insertReviewFiles, deleteReviewFiles } from "../repositories/review-file.repo.js";
4
6
  import { getStagedDiff, getUnstagedDiff, getBranchDiff, getCommitsDiff } from "./diff.service.js";
5
7
  import { getRepositoryInfo } from "./git.service.js";
6
- export class ValidationError extends Error {
7
- }
8
8
  const REVIEW_NAME_MONTHS_RU = [
9
9
  'янв',
10
10
  'февр',
@@ -0,0 +1,26 @@
1
+ import { accessSync, constants } from 'node:fs';
2
+ import { delimiter, isAbsolute, join } from 'node:path';
3
+ export function isOnPath(binary, pathEnv = process.env.PATH) {
4
+ if (isAbsolute(binary)) {
5
+ try {
6
+ accessSync(binary, constants.X_OK);
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ for (const dir of (pathEnv ?? '').split(delimiter)) {
14
+ if (dir === '') {
15
+ continue;
16
+ }
17
+ try {
18
+ accessSync(join(dir, binary), constants.X_OK);
19
+ return true;
20
+ }
21
+ catch {
22
+ // not in this directory
23
+ }
24
+ }
25
+ return false;
26
+ }
@@ -0,0 +1,6 @@
1
+ import { basename } from 'node:path';
2
+ /** The client-supplied name must not escape the directory it is written into. */
3
+ export function safeFileName(name) {
4
+ const base = basename(name.replaceAll('\\', '/')).replaceAll('\0', '');
5
+ return base === '' || base === '.' || base === '..' ? 'attachment' : base;
6
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sends one SSE message and never fails. A client can leave at any time, and
3
+ * `send` then rejects. Nothing awaits that promise, so Node would end the
4
+ * process on the unhandled rejection.
5
+ */
6
+ export function safeSend(sse, message) {
7
+ if (!sse.isConnected) {
8
+ return;
9
+ }
10
+ sse.send(message).catch(() => { });
11
+ }
@@ -0,0 +1,29 @@
1
+ /** Ends a cut text when the caller gives no marker of its own. */
2
+ const DEFAULT_TRUNCATION_MARKER = '\n… (truncated)';
3
+ /**
4
+ * Cuts `text` to `max` characters. `marker` gets the number of characters
5
+ * dropped and returns what is appended, so each caller can tell its reader
6
+ * (browser, agent) what happened.
7
+ */
8
+ export function truncateText(text, max, marker = () => DEFAULT_TRUNCATION_MARKER) {
9
+ return text.length > max
10
+ ? `${text.slice(0, max)}${marker(text.length - max)}`
11
+ : text;
12
+ }
13
+ /** True when the bytes contain a NUL: the quick test git itself uses to call a file binary. */
14
+ export function isBinaryBuffer(bytes) {
15
+ return bytes.includes(0);
16
+ }
17
+ /**
18
+ * The text of `bytes` if they are valid UTF-8 without NUL, else `null`.
19
+ * Stricter than `Buffer#toString`, which turns bad bytes into U+FFFD.
20
+ */
21
+ export function decodeText(bytes) {
22
+ try {
23
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
24
+ return text.includes('\0') ? null : text;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
@@ -0,0 +1,17 @@
1
+ const normalize = (name) => name.trim().toLowerCase();
2
+ /**
3
+ * `base` if no chat has that name yet, else `base (1)`, `base (2)`, … — the
4
+ * first free one. Names compare without regard to case or surrounding blanks,
5
+ * so open chats can always be told apart in the tabs and the menu.
6
+ */
7
+ export function uniqueChatName(base, taken) {
8
+ const used = new Set(taken.map(normalize));
9
+ const wanted = base.trim();
10
+ if (!used.has(normalize(wanted)))
11
+ return wanted;
12
+ for (let n = 1;; n++) {
13
+ const candidate = `${wanted} (${n})`;
14
+ if (!used.has(normalize(candidate)))
15
+ return candidate;
16
+ }
17
+ }
@@ -0,0 +1,6 @@
1
+ /** Chats open at once (ADR 0024); the server refuses more, the UI hides "add". */
2
+ export const MAX_AGENT_SESSIONS = 5;
3
+ /** Raw bytes per attachment; shared by the upload UI and the server. */
4
+ export const MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
5
+ export const DEFAULT_FILE_SEARCH_LIMIT = 30;
6
+ export const MAX_FILE_SEARCH_LIMIT = 100;
@@ -0,0 +1,17 @@
1
+ export function formatDiffFile(file) {
2
+ const lines = [
3
+ `--- ${file.oldPath ? `a/${file.oldPath}` : '/dev/null'}`,
4
+ `+++ ${file.newPath ? `b/${file.newPath}` : '/dev/null'}`
5
+ ];
6
+ if (file.isBinary) {
7
+ lines.push('(binary file)');
8
+ }
9
+ for (const hunk of file.hunks) {
10
+ lines.push(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`);
11
+ for (const line of hunk.lines) {
12
+ const prefix = line.type === 'added' ? '+' : line.type === 'removed' ? '-' : ' ';
13
+ lines.push(prefix + line.content);
14
+ }
15
+ }
16
+ return lines.join('\n');
17
+ }
@@ -0,0 +1,48 @@
1
+ function isSubsequence(needle, haystack) {
2
+ let at = 0;
3
+ for (const char of haystack) {
4
+ if (char === needle[at]) {
5
+ at++;
6
+ }
7
+ if (at === needle.length) {
8
+ return true;
9
+ }
10
+ }
11
+ return needle.length === 0;
12
+ }
13
+ /** Lower is better; undefined = no match. */
14
+ function score(path, query) {
15
+ const lower = path.toLowerCase();
16
+ const base = lower.slice(lower.lastIndexOf('/') + 1);
17
+ if (base === query)
18
+ return 0;
19
+ if (base.startsWith(query))
20
+ return 1;
21
+ if (base.includes(query))
22
+ return 2;
23
+ if (lower.includes(query))
24
+ return 3;
25
+ if (isSubsequence(query, lower))
26
+ return 4;
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Orders `files` by how well they match `query`: file name first (exact,
31
+ * prefix, substring), then anywhere in the path, then as scattered letters.
32
+ * Ties go to the shorter path. An empty query matches everything.
33
+ */
34
+ export function rankFiles(files, query) {
35
+ const needle = query.trim().toLowerCase();
36
+ const scored = [];
37
+ for (const path of files) {
38
+ const rank = needle === '' ? 0 : score(path, needle);
39
+ if (rank !== undefined) {
40
+ scored.push({ path, rank });
41
+ }
42
+ }
43
+ return scored
44
+ .sort((a, b) => a.rank - b.rank ||
45
+ a.path.length - b.path.length ||
46
+ a.path.localeCompare(b.path))
47
+ .map(entry => entry.path);
48
+ }
@@ -0,0 +1,51 @@
1
+ import { Type } from '@sinclair/typebox';
2
+ import { MAX_ATTACHMENT_BYTES, MAX_FILE_SEARCH_LIMIT } from "./constants.js";
3
+ export const SessionParams = Type.Object({ id: Type.String() });
4
+ export const PermissionParams = Type.Object({
5
+ id: Type.String(),
6
+ requestId: Type.String()
7
+ });
8
+ export const CreateSessionBody = Type.Object({
9
+ presetId: Type.String({ minLength: 1 }),
10
+ name: Type.Optional(Type.String({ maxLength: 60 })),
11
+ reviewId: Type.Optional(Type.String())
12
+ });
13
+ export const AutoApproveBody = Type.Object({ enabled: Type.Boolean() });
14
+ export const FileSearchQuery = Type.Object({
15
+ q: Type.Optional(Type.String({ maxLength: 200 })),
16
+ limit: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_FILE_SEARCH_LIMIT }))
17
+ });
18
+ export const ContextItem = Type.Union([
19
+ Type.Object({
20
+ kind: Type.Literal('diff'),
21
+ source: Type.Union([Type.Literal('staged'), Type.Literal('unstaged')]),
22
+ path: Type.Optional(Type.String({ minLength: 1 }))
23
+ }),
24
+ Type.Object({
25
+ kind: Type.Literal('file'),
26
+ path: Type.String({ minLength: 1 })
27
+ }),
28
+ Type.Object({ kind: Type.Literal('review'), reviewId: Type.String() }),
29
+ Type.Object({
30
+ kind: Type.Literal('attachment'),
31
+ name: Type.String({ minLength: 1, maxLength: 255 }),
32
+ mimeType: Type.String({ maxLength: 255 }),
33
+ data: Type.String({
34
+ maxLength: Math.ceil(MAX_ATTACHMENT_BYTES / 3) * 4
35
+ })
36
+ })
37
+ ]);
38
+ export const PromptBody = Type.Object({
39
+ text: Type.String({ minLength: 1 }),
40
+ context: Type.Optional(Type.Array(ContextItem, { maxItems: 20 }))
41
+ });
42
+ export const PermissionBody = Type.Object({
43
+ optionId: Type.Optional(Type.String())
44
+ });
45
+ export const ConfigBody = Type.Object({
46
+ configId: Type.String({ minLength: 1 }),
47
+ // No schema type on purpose: a Union/anyOf makes Fastify's Ajv coerce `true`
48
+ // into the string "true", and a `type` array trips Ajv's strictTypes. The
49
+ // session checks the value against the option the agent actually offered.
50
+ value: Type.Unsafe({})
51
+ });
@@ -0,0 +1,11 @@
1
+ /** The states of an ACP tool call (`ToolCallStatus`); the list lets code check a string at run time. */
2
+ export const AGENT_TOOL_STATUSES = [
3
+ 'pending',
4
+ 'in_progress',
5
+ 'completed',
6
+ 'failed'
7
+ ];
8
+ /** The status if `value` names one, else `undefined`: ACP statuses arrive as plain strings. */
9
+ export function toAgentToolStatus(value) {
10
+ return AGENT_TOOL_STATUSES.find(status => status === value);
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Shared types between server and web client
3
+ */
4
+ export {};
@@ -1,6 +1,3 @@
1
- /**
2
- * Shared types between server and web client
3
- */
4
1
  /**
5
2
  * Event names sent over the SSE stream (`GET /api/events`). A runtime list,
6
3
  * not just a type: the web client attaches one EventSource listener per
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ const LOOPBACK_HOSTNAMES = new Set(['localhost', '127.0.0.1', '::1', '[::1]']);
2
+ export function isLoopbackHost(host) {
3
+ return LOOPBACK_HOSTNAMES.has(host.toLowerCase());
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export function errorMessage(error) {
2
+ return error instanceof Error ? error.message : String(error);
3
+ }
@@ -0,0 +1,4 @@
1
+ /** A plain object: not `null`, not an array. Narrows `JSON.parse` output before its fields are read. */
2
+ export function isRecord(value) {
3
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
4
+ }
@@ -0,0 +1 @@
1
+ import{C as e,G as t,I as n,N as r,et as i,g as a,l as o,s,st as c,x as l,y as u}from"./runtime-core.esm-bundler-Carm8LUR.js";import{E as d,O as f,_ as p,j as m,t as h}from"./QBtn-E32fUOKx.js";import{t as g}from"./create-B9ZqyTxV.js";import{n as _}from"./vue-i18n.runtime-BQwnBdmC.js";import{n as v}from"./pinia-DbmXdZbT.js";import{i as y,s as b,t as x}from"./single-flight-r8B7stt1.js";function S(e){if(e.length<2||e[0]!==`"`||e[e.length-1]!==`"`)return e;let t=e.slice(1,-1),n=[];for(let e=0;e<t.length;e++){let r=t[e];r===`\\`&&/^[0-7]{3}$/.test(t.slice(e+1,e+4))?(n.push(parseInt(t.slice(e+1,e+4),8)),e+=3):r===`\\`&&t[e+1]===`"`?(n.push(34),e+=1):r===`\\`&&t[e+1]===`\\`?(n.push(92),e+=1):n.push((r??``).charCodeAt(0))}return new TextDecoder(`utf-8`).decode(new Uint8Array(n))}function C(e){return{...e,oldPath:S(e.oldPath),newPath:S(e.newPath)}}function w(e,t){let n=new Map(e.map(e=>[e.newPath||e.oldPath,e]));return t.map(e=>{let t=n.get(e.newPath||e.oldPath);return t&&JSON.stringify(t)===JSON.stringify(e)?t:e})}var T=v(`diff`,()=>{let e=i([]),t=i([]),n=i(!1),r=i(!1),a=i(null),o=s(()=>n.value&&!r.value),c=s(()=>[...e.value,...t.value].map(e=>e.newPath||e.oldPath)),l=x(u);async function u(){n.value=!0;try{let[n,r]=await Promise.all([b(`/api/diff/staged`),b(`/api/diff/unstaged`)]);e.value=w(e.value,n.map(C)),t.value=w(t.value,r.map(C)),a.value=null}catch(n){r.value||(e.value=[],t.value=[]),a.value=y(n)}finally{n.value=!1,r.value=!0}}return{stagedFiles:e,unstagedFiles:t,loading:n,initialLoading:o,error:a,changedPaths:c,fetchDiff:l}}),E=a({__name:`CancelButton`,setup(t){let{t:n}=_();return(t,i)=>(r(),o(h,e({padding:`2px 8px`},t.$attrs,{dense:``,flat:``,color:`warning`,label:c(n)(`reviews.comments.cancel`)}),null,16,[`label`]))}}),D=a({__name:`CreateButton`,setup(t){let{t:n}=_();return(t,i)=>(r(),o(h,e({padding:`2px 8px`,label:c(n)(`reviews.create.submit`)},t.$attrs,{unelevated:``,dense:``,color:`accent`}),null,16,[`label`]))}}),O=g({name:`QPage`,props:{padding:Boolean,styleFn:Function},setup(e,{slots:t}){let n=d(),r=l(m,f);if(r===f)return console.error(`QPage needs to be a deep child of QLayout`),f;if(l(`_q_pc_`,f)===f)return console.error(`QPage needs to be child of QPageContainer`),f;let i=s(()=>{let t=(r.header.space?r.header.size:0)+(r.footer.space?r.footer.size:0);if(typeof e.styleFn==`function`){let i=r.isContainer.value?r.containerHeight.value:n.screen.height;return e.styleFn(t,i)}return{minHeight:r.isContainer.value?r.containerHeight.value-t+`px`:n.screen.height===0?t===0?`100vh`:`calc(100vh - ${t}px)`:n.screen.height-t+`px`}}),a=s(()=>`q-page${e.padding?` q-layout-padding`:``}`);return()=>u(`main`,{class:a.value,style:i.value},p(t.default))}}),k=a({__name:`AppPage`,setup(e){function i(e,t){return{height:`${t-e}px`}}return(e,a)=>(r(),o(O,{"style-fn":i},{default:t(()=>[n(e.$slots,`default`)]),_:3}))}});export{S as a,T as i,D as n,E as r,k as t};
@@ -0,0 +1 @@
1
+ import{C as e,Ct as t,G as n,K as r,N as i,P as a,S as o,V as s,W as c,_ as l,c as u,d,et as f,g as p,h as m,l as h,nt as g,r as _,s as v,st as y,x as b,y as x}from"./runtime-core.esm-bundler-Carm8LUR.js";import{D as S,E as C,H as w,O as T,_ as E,d as D,h as ee,j as O,k as te,t as k}from"./QBtn-E32fUOKx.js";import{t as A}from"./create-B9ZqyTxV.js";import{J as j,K as ne,d as re,g as M,h as N,m as P,n as F,q as I,y as L}from"./index-C_B6Z2lc.js";import{n as R}from"./vue-i18n.runtime-BQwnBdmC.js";import{n as z,r as B}from"./pinia-DbmXdZbT.js";import{c as V,i as H,l as U,o as W,s as G}from"./single-flight-r8B7stt1.js";import{m as K,o as q,s as J,v as Y}from"./QMenu-BZ1eK_rS.js";import{i as ie,n as ae,r as oe}from"./AppPage-CSb8txs5.js";var X=z(`active-review`,()=>{let e=f(null),t=f([]),n=f(!1),r=v(()=>{let e=new Map;for(let n of t.value){let t=e.get(n.filePath);t?t.push(n):e.set(n.filePath,[n])}return e});async function i(){n.value=!0;try{let n=(await G(`/api/reviews`)).filter(e=>e.status===`in_progress`).sort((e,t)=>t.createdAt.localeCompare(e.createdAt));e.value=n[0]??null,t.value=e.value?await G(`/api/reviews/${e.value.id}/comments`):[]}finally{n.value=!1}}function a(n){e.value=n,t.value=[]}async function o(t){e.value&&(await V(`/api/reviews/${e.value.id}`,{status:t}),await i())}async function s(n){if(!e.value)throw Error(`No active review`);let r=await U(`/api/reviews/${e.value.id}/comments`,n);return t.value=[...t.value,r],r}async function c(e,n){let r=await V(`/api/comments/${e}`,{content:n});t.value=t.value.map(t=>t.id===e?r:t)}async function l(e){await W(`/api/comments/${e}`),t.value=t.value.filter(t=>t.id!==e)}async function u(e){let n=await V(`/api/comments/${e}/resolve`);t.value=t.value.map(t=>t.id===e?n:t)}async function d(e){let n=await V(`/api/comments/${e}/unresolve`);t.value=t.value.map(t=>t.id===e?n:t)}return{activeReview:e,comments:t,loading:n,commentsByFile:r,refresh:i,setActiveReview:a,setStatus:o,createComment:s,editComment:c,deleteComment:l,resolveComment:u,unresolveComment:d}}),se=p({__name:`SearchInput`,props:{modelValue:{},modelModifiers:{}},emits:[`update:modelValue`],setup(t){let r=s(t,`modelValue`);return(t,a)=>(i(),h(F,e({modelValue:r.value,"onUpdate:modelValue":a[0]||=e=>r.value=e},t.$attrs,{dense:``,outlined:``,clearable:``}),{prepend:n(()=>[m(D,{name:`search`,size:`xs`})]),_:1},16,[`modelValue`]))}}),ce=[`top`,`right`,`bottom`,`left`],Z={type:{type:String,default:`a`},outline:Boolean,push:Boolean,flat:Boolean,unelevated:Boolean,color:String,textColor:String,glossy:Boolean,square:Boolean,padding:String,label:{type:[String,Number],default:``},labelPosition:{type:String,default:`right`,validator:e=>ce.includes(e)},externalLabel:Boolean,hideLabel:{type:Boolean},labelClass:[Array,String,Object],labelStyle:[Array,String,Object],disable:Boolean,tabindex:[Number,String]},le=[`label`],ue=Object.keys(Z).filter(e=>!le.includes(e)&&k.props[e]!==void 0);function de(e){let t={};for(let n of ue)t[n]=e[n];return t}function fe(e,t){return{formClass:v(()=>`q-fab--form-${e.square?`square`:`rounded`}`),stacked:v(()=>!e.externalLabel&&[`top`,`bottom`].includes(e.labelPosition)),labelProps:v(()=>{if(e.externalLabel){let n=e.hideLabel===null?!t.value:e.hideLabel;return{action:`push`,data:{class:[e.labelClass,`q-fab__label q-tooltip--style q-fab__label--external q-fab__label--external-${e.labelPosition}`+(n?` q-fab__label--external-hidden`:``)],style:e.labelStyle}}}return{action:[`left`,`top`].includes(e.labelPosition)?`unshift`:`push`,data:{class:[e.labelClass,`q-fab__label q-fab__label--internal q-fab__label--internal-${e.labelPosition}`+(e.hideLabel?` q-fab__label--internal-hidden`:``)],style:e.labelStyle}}})}}var pe=[`up`,`right`,`down`,`left`],Q=[`left`,`center`,`right`],me=180,he=A({name:`QFab`,props:{...Z,...j,icon:String,activeIcon:String,hideIcon:Boolean,hideLabel:{...Z.hideLabel,default:null},direction:{type:String,default:`right`,validator:e=>pe.includes(e)},...J,persistent:Boolean,stagger:{type:Number,default:40},verticalActionsAlign:{type:String,default:`center`,validator:e=>Q.includes(e)}},emits:I,setup(e,{slots:t}){let n=g(null),r=f(e.modelValue===!0),i=re(),o=C(),{formClass:s,stacked:l,labelProps:u}=fe(e,r),d=v(()=>!e.persistent),{show:p,hide:m,toggle:h}=ne({showing:r,hideOnRouteChange:d}),_=0,{clearHoverTimer:y,hoverShow:b,hoverHide:S}=q({props:e,canShow:()=>!r.value,show:e=>{_=Date.now(),p(e)},canHide:()=>r.value,hide:m});c(r,y);function w(e){r.value&&Date.now()-_<me||h(e)}let T=v(()=>({opened:r.value})),O=v(()=>`q-fab z-fab row inline justify-center q-fab--align-${e.verticalActionsAlign} ${s.value}`+(r.value?` q-fab--opened`:` q-fab--closed`)),A=v(()=>`q-fab__actions flex no-wrap inline q-fab__actions--${e.direction} q-fab__actions--${r.value?`opened`:`closed`}`),j=v(()=>e.hover?{onPointerenter:b,onPointerleave:S}:{}),M=v(()=>{let t={id:i.value,style:`--q-fab-stagger: ${e.stagger}ms`};return r.value||(t[`aria-hidden`]=`true`),t}),N=v(()=>`q-fab__icon-holder q-fab__icon-holder--${r.value?`opened`:`closed`}`);function P(n,r){let i=t[n],a=`q-fab__${n} absolute-full`;return i===void 0?x(D,{class:a,name:e[r]||o.iconSet.fab[r]}):x(`div`,{class:a},i(T.value))}function F(){let n=[];return e.hideIcon||n.push(x(`div`,{class:N.value},[P(`icon`,`icon`),P(`active-icon`,`activeIcon`)])),(e.label!==``||t.label!==void 0)&&n[u.value.action](x(`div`,u.value.data,t.label===void 0?[e.label]:t.label(T.value))),ee(t.tooltip,n)}return a(te,{showing:r,onChildClick(e){m(e),e?.qAvoidFocus!==!0&&n.value?.$el.focus()}}),()=>x(`div`,{class:O.value,...j.value},[x(k,{ref:n,class:s.value,...de(e),noWrap:!0,stack:l.value,noCaps:!0,fab:!0,"aria-expanded":r.value?`true`:`false`,"aria-controls":i.value,onClick:w},F),x(`div`,{class:A.value,...M.value},E(t.default))])}}),ge={position:{type:String,default:`bottom-right`,validator:e=>[`top-right`,`top-left`,`bottom-right`,`bottom-left`,`top`,`right`,`bottom`,`left`].includes(e)},offset:{type:Array,validator:e=>e.length===2},expand:Boolean};function _e(){let{props:e}=l(),t=C(),n=b(O,T);if(n===T)return console.error(`QPageSticky needs to be child of QLayout`),T;let r=v(()=>{let t=e.position;return{top:t.includes(`top`),right:t.includes(`right`),bottom:t.includes(`bottom`),left:t.includes(`left`),vertical:t===`top`||t===`bottom`,horizontal:t===`left`||t===`right`}}),i=v(()=>n.header.offset),a=v(()=>n.right.offset),o=v(()=>n.footer.offset),s=v(()=>n.left.offset),c=v(()=>{let n=0,c=0,l=r.value,u=t.lang.rtl?-1:1;l.top&&i.value!==0?c=`${i.value}px`:l.bottom&&o.value!==0&&(c=`${-o.value}px`),l.left&&s.value!==0?n=`${u*s.value}px`:l.right&&a.value!==0&&(n=`${-u*a.value}px`);let d={transform:`translate(${n}, ${c})`};return e.offset&&(d.margin=`${e.offset[1]}px ${e.offset[0]}px`),l.vertical?(s.value!==0&&(d[t.lang.rtl?`right`:`left`]=`${s.value}px`),a.value!==0&&(d[t.lang.rtl?`left`:`right`]=`${a.value}px`)):l.horizontal&&(i.value!==0&&(d.top=`${i.value}px`),o.value!==0&&(d.bottom=`${o.value}px`)),d}),u=v(()=>`q-page-sticky row flex-center fixed-${e.position} q-page-sticky--${e.expand?`expand`:`shrink`}`);function d(t){let n=E(t.default);return x(`div`,{class:u.value,style:c.value},e.expand?n:[x(`div`,n)])}return{$layout:n,getStickyContent:d}}var ve=A({name:`QPageSticky`,props:ge,setup(e,{slots:t}){let{getStickyContent:n}=_e();return()=>n(t)}});function ye(e){let t=new URLSearchParams;e.search&&t.set(`search`,e.search),e.createdFrom&&t.set(`createdFrom`,e.createdFrom),e.createdTo&&t.set(`createdTo`,e.createdTo),e.files&&e.files.length>0&&t.set(`files`,e.files.join(`,`));let n=t.toString();return n?`?${n}`:``}var $=z(`reviews`,()=>{let e=f([]),t=f(!1),n=f(null);async function r(r={}){t.value=!0,n.value=null;try{e.value=await G(`/api/reviews${ye(r)}`)}catch(t){e.value=[],n.value=H(t)}finally{t.value=!1}}async function i(t){let n=await U(`/api/reviews`,t);return e.value=[n,...e.value],n}return{reviews:e,loading:t,error:n,fetchReviews:r,createReview:i}}),be={class:`text-h6`},xe=S(p({__name:`ReviewCreateDialog`,props:{modelValue:{type:Boolean,required:!0},modelModifiers:{}},emits:o([`created`,`hide`],[`update:modelValue`]),setup(e,{emit:a}){let o=s(e,`modelValue`),c=a,{t:l}=R(),d=$(),p=f(``),g=f(!1),_=f(null);function v(){p.value=``,g.value=!1,_.value=null}async function b(){g.value=!0,_.value=null;try{let e=p.value.trim(),t=await d.createReview(e?{name:e}:{});o.value=!1,v(),c(`created`,t)}catch(e){_.value=H(e)}finally{g.value=!1}}function x(){v(),c(`hide`)}return(e,a)=>(i(),h(L,{modelValue:o.value,"onUpdate:modelValue":a[1]||=e=>o.value=e,onHide:x},{default:n(()=>[m(M,{class:`review-create-dialog`},{default:n(()=>[m(N,null,{default:n(()=>[u(`div`,be,t(y(l)(`reviews.create.title`)),1)]),_:1}),m(N,{class:`q-gutter-y-md`},{default:n(()=>[m(F,{modelValue:p.value,"onUpdate:modelValue":a[0]||=e=>p.value=e,dense:``,outlined:``,label:y(l)(`reviews.create.nameLabel`),hint:y(l)(`reviews.create.nameHint`),error:!!_.value,"error-message":_.value??void 0,onKeyup:w(b,[`enter`])},null,8,[`modelValue`,`label`,`hint`,`error`,`error-message`])]),_:1}),m(P,{align:`right`},{default:n(()=>[r(m(oe,null,null,512),[[K]]),m(ae,{loading:g.value,onClick:b},null,8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`modelValue`]))}}),[[`__scopeId`,`data-v-095646d6`]]),Se=p({__name:`CreateReviewFabButton`,emits:[`created`],setup(e,{emit:t}){let a=t,o=X(),s=ie(),{activeReview:c}=B(o),{changedPaths:l}=B(s),u=f(!1),p=f(!1),h=f([18,18]),g=f(!1),y=v(()=>l.value.length===0||c.value!==null);function b(e){g.value=e.isFirst!==!0&&e.isFinal!==!0,h.value=[h.value[0]-(e.delta?.x??0),h.value[1]-(e.delta?.y??0)]}function x(e){o.setActiveReview(e),a(`created`,e)}return(e,t)=>(i(),d(_,null,[m(ve,{position:`bottom-right`,offset:h.value},{default:n(()=>[r(m(he,{modelValue:p.value,"onUpdate:modelValue":t[0]||=e=>p.value=e,icon:`add`,color:`accent`,disable:y.value||g.value,onClick:t[1]||=e=>u.value=!0},null,8,[`modelValue`,`disable`]),[[Y,b,void 0,{prevent:!0,mouse:!0}]])]),_:1},8,[`offset`]),m(xe,{modelValue:u.value,"onUpdate:modelValue":t[2]||=e=>u.value=e,onCreated:x,onHide:t[3]||=e=>p.value=!1},null,8,[`modelValue`])],64))}});export{X as i,$ as n,se as r,Se as t};
@@ -0,0 +1 @@
1
+ .review-create-dialog[data-v-095646d6]{width:420px;max-width:90vw}
@@ -1 +1 @@
1
- import{M as e,c as t,d as n,m as r}from"./runtime-core.esm-bundler-Db5Q9Gsb.js";import{C as i,t as a}from"./QBtn-DGiC5uLo.js";var o={},s={class:`fullscreen bg-blue text-white text-center q-pa-md flex flex-center`};function c(i,o){return e(),n(`div`,s,[t(`div`,null,[o[0]||=t(`div`,{style:{"font-size":`30vh`}},`404`,-1),o[1]||=t(`div`,{class:`text-h2`,style:{opacity:`0.4`}},`Oops. Nothing here...`,-1),r(a,{class:`q-mt-xl`,color:`white`,"text-color":`blue`,unelevated:``,to:`/`,label:`Go Home`,"no-caps":``})])])}var l=i(o,[[`render`,c]]);export{l as default};
1
+ import{N as e,c as t,d as n,h as r}from"./runtime-core.esm-bundler-Carm8LUR.js";import{D as i,t as a}from"./QBtn-E32fUOKx.js";var o={},s={class:`fullscreen bg-blue text-white text-center q-pa-md flex flex-center`};function c(i,o){return e(),n(`div`,s,[t(`div`,null,[o[0]||=t(`div`,{style:{"font-size":`30vh`}},`404`,-1),o[1]||=t(`div`,{class:`text-h2`,style:{opacity:`0.4`}},`Oops. Nothing here...`,-1),r(a,{class:`q-mt-xl`,color:`white`,"text-color":`blue`,unelevated:``,to:`/`,label:`Go Home`,"no-caps":``})])])}var l=i(o,[[`render`,c]]);export{l as default};
@@ -0,0 +1 @@
1
+ .file-explorer[data-v-65488178]{height:100%}[data-v-65488178] .file-explorer__panel{flex-direction:column;flex-shrink:0;min-width:0;height:100%;display:flex}[data-v-65488178] .file-explorer__content{flex-direction:column;flex-wrap:no-wrap;display:flex}.file-tree-node__icon-section[data-v-43168dd7]{min-width:0!important;padding-right:6px!important}.file-tree-node__label[data-v-43168dd7]{width:100%;min-width:0}.file-tree-node__chevron[data-v-43168dd7]{transition:transform .15s}.file-tree-node__chevron--expanded[data-v-43168dd7]{transform:rotate(90deg)}.file-tree-node--selected[data-v-43168dd7]{font-weight:500}.file-list-item__icon-section[data-v-b9210fc2]{min-width:0!important;padding-right:6px!important}.file-list-item__path-row[data-v-b9210fc2]{width:100%;min-width:0}.file-list-item__path-label[data-v-b9210fc2]{flex:0 auto;min-width:0}.file-list-item__badge[data-v-b9210fc2]{flex:none}.file-list-item--selected[data-v-b9210fc2],[data-v-b9210fc2] .file-list-item--selected{font-weight:500}.file-list-item__actions[data-v-b9210fc2]{gap:2px;flex-direction:row!important;padding:0 0 0 6px!important}.file-list-item__stats[data-v-b9210fc2]{padding-right:0!important}.file-list-panel__scroll[data-v-32cc9fb2] .q-scrollarea__content{width:100%}.active-review-bar[data-v-2b6e4bdd]{min-height:36px}
@@ -0,0 +1 @@
1
+ import{i as e,l as t,r as n,t as r}from"./agent-icon-BKoq2a6T.js";import{A as i,Ct as a,F as o,G as s,I as c,K as l,L as u,N as d,S as f,St as p,V as m,W as h,X as g,c as _,d as v,et as y,g as b,h as x,j as S,l as C,m as w,nt as T,r as E,s as D,st as O,u as k,w as A,xt as j,y as M}from"./runtime-core.esm-bundler-Carm8LUR.js";import{D as N,E as P,U as F,_ as I,d as L,h as ee,o as R,s as z,t as B}from"./QBtn-E32fUOKx.js";import{u as te}from"./event-rR76ioXz.js";import{t as ne}from"./create-B9ZqyTxV.js";import{_ as re,d as ie,p as V,t as ae,v as oe}from"./index-C_B6Z2lc.js";import{n as H}from"./vue-i18n.runtime-BQwnBdmC.js";import{n as se,r as U}from"./pinia-DbmXdZbT.js";import{i as ce,l as le,r as W,s as ue,t as de}from"./single-flight-r8B7stt1.js";import{t as fe}from"./agent-store-CEQ6MmTC.js";import{t as pe}from"./safe-storage-CWaD6Dq3.js";import{d as G,f as me,h as K,p as q,v as he}from"./QMenu-BZ1eK_rS.js";import{a as ge,i as _e,n as ve,o as ye,t as be}from"./use-panel-width-CY75Fomr.js";import{t as xe}from"./QItemLabel-Co6oCEUr.js";import{a as Se,i as J,t as Ce}from"./AppPage-CSb8txs5.js";import{a as we,c as Te,d as Ee,i as De,l as Oe,n as ke,o as Ae,r as je,s as Me,t as Ne,u as Y}from"./StatusSwitcher-C0k4efwK.js";import{i as X,r as Pe,t as Fe}from"./CreateReviewFabButton-B18DLuH6.js";function Ie(e){return e.toSorted((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1).map(e=>({...e,children:e.children?Ie(e.children):void 0}))}function Le(e,t){let n=[];for(let r of e){let e=r.split(`/`),i=n;for(let n=0;n<e.length;n++){let a=e[n];if(!a)continue;let o=n===e.length-1,s=e.slice(0,n+1).join(`/`),c=i.find(e=>e.name===a);c||(c={name:a,path:s,type:o?`file`:`directory`,isChanged:o?t.has(r):!1,children:o?void 0:[]},i.push(c)),!o&&c.children&&(i=c.children)}}return Ie(n)}function Re(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=e=>{if(e.type===`file`)return e.path.toLowerCase().includes(n)?e:null;let t=e.children?.map(r).filter(e=>e!==null);return t&&t.length>0?{...e,children:t}:e.name.toLowerCase().includes(n)?e:null};return e.map(r).filter(e=>e!==null)}function ze(){let e=y([]),t=y(!1),n=y(!1),r=y(null),i=D(()=>!n.value),a=0;async function o(i,o=[]){let s=++a;t.value=!0;try{let t=await ue(`/api/git/tree/${encodeURIComponent(i)}`);if(s!==a)return;e.value=Le(t.files.map(Se),new Set(o)),r.value=null}catch(e){if(s!==a)return;r.value=ce(e)}finally{s===a&&(t.value=!1,n.value=!0)}}function s(){++a,e.value=[],t.value=!1,n.value=!1,r.value=null}return{tree:e,loading:t,initialLoading:i,error:r,fetchTree:o,reset:s}}function Be(e){return e.type===`file`?e.isChanged:e.children?.some(Be)??!1}var Z=se(`file-explorer`,()=>{let e=J(),{tree:t,initialLoading:n,error:r,fetchTree:i,reset:a}=ze(),{lines:o,isBinary:s,loading:c,error:l,fetchContent:u,reset:d}=Ee(),f=y(`staged`),p=y(!1),m=y(``),g=y(null),_=y(new Set),v=y(new Set),b=D(()=>f.value===`staged`?e.stagedFiles:e.unstagedFiles),x=D(()=>{let e=(m.value??``).trim().toLowerCase();return e?b.value.filter(t=>Y(t).toLowerCase().includes(e)):b.value}),S=D(()=>Re(t.value,m.value??``)),C=D(()=>{let e=0,n=t=>{for(let r of t)r.type===`file`?e++:r.children&&n(r.children)};return n(t.value),e});h(t,e=>{let t=new Set,n=e=>{for(let r of e)r.type===`directory`&&r.children&&(Be(r)&&t.add(r.path),n(r.children))};n(e),_.value=t},{immediate:!0}),h(f,()=>{g.value=null,v.value=new Set}),h(g,e=>{if(p.value){if(!e){d();return}u(e,`WORKTREE`)}});function w(e){let t=new Set(_.value);t.has(e)?t.delete(e):t.add(e),_.value=t}function T(e){let t=new Set(v.value);t.has(e)?t.delete(e):t.add(e),v.value=t}function E(e){g.value=e,T(e)}function O(e){g.value=e,v.value.has(e)||(v.value=new Set(v.value).add(e))}function k(){v.value=new Set(b.value.map(Y))}function j(){v.value=new Set}function M(e){g.value=e,!p.value&&(v.value.has(e)||(v.value=new Set(v.value).add(e)),A(()=>{document.getElementById(`diff-file-${e}`)?.scrollIntoView({block:`nearest`})}))}let N=0,P=y(!1),F=de(async()=>{P.value=!0;try{await e.fetchDiff(),p.value&&(await i(`WORKTREE`,e.changedPaths),g.value&&await u(g.value,`WORKTREE`))}finally{P.value=!1}});h(p,e=>{m.value=``,g.value=null,e?F():(a(),d())});async function I(){N=Date.now(),await F()}async function L(){Date.now()-N<400||await F()}return{source:f,browseMode:p,filter:m,selectedPath:g,expandedFolders:_,expandedFiles:v,tree:t,treeInitialLoading:n,treeError:r,refreshing:P,browseFileLines:o,browseFileIsBinary:s,browseFileLoading:c,browseFileError:l,diffFiles:b,filteredDiffFiles:x,filteredTree:S,totalTreeFiles:C,toggleFolder:w,toggleFileCard:T,handleCardToggle:E,expandFile:O,expandAllFiles:k,collapseAllFiles:j,selectFile:M,refresh:I,refreshFromServerEvent:L}}),Ve=ne({name:`QSplitter`,props:{...oe,modelValue:{type:Number,required:!0},reverse:Boolean,unit:{type:String,default:`%`,validator:e=>[`%`,`px`].includes(e)},limits:{type:Array,validator:e=>e.length!==2||typeof e[0]!=`number`||typeof e[1]!=`number`?!1:e[0]>=0&&e[0]<=e[1]},emitImmediately:Boolean,horizontal:Boolean,disable:Boolean,beforeClass:[Array,String,Object],afterClass:[Array,String,Object],separatorClass:[Array,String,Object],separatorStyle:[Array,String,Object],separatorAriaLabel:String},emits:[`update:modelValue`],setup(e,{slots:t,emit:n}){let r=P(),i=re(e,r),a=T(null),o={before:T(null),after:T(null)},s=ie(),c=D(()=>`q-splitter no-wrap ${e.horizontal?`q-splitter--horizontal column`:`q-splitter--vertical row`} q-splitter--${e.disable?`disabled`:`workable`}`+(i()?` q-splitter--dark`:``)),u=D(()=>e.horizontal?`height`:`width`),d=D(()=>e.reverse?`after`:`before`),f=D(()=>e.limits===void 0?e.unit===`%`?[10,90]:[50,1/0]:e.limits);function p(t){return(e.unit===`%`?t:Math.round(t))+e.unit}let m=D(()=>({[d.value]:{[u.value]:p(e.modelValue)}})),g,_,v,y,b;function x(t){if(t.isFirst){let t=a.value.getBoundingClientRect()[u.value];g=e.horizontal?`up`:`left`,_=e.unit===`%`?100:t,v=Math.min(_,f.value[1],Math.max(f.value[0],e.modelValue)),y=(e.reverse?-1:1)*(e.horizontal?1:r.lang.rtl?-1:1)*(e.unit===`%`?t===0?0:100/t:1),a.value.classList.add(`q-splitter--active`);return}if(t.isFinal){b!==e.modelValue&&n(`update:modelValue`,b),a.value.classList.remove(`q-splitter--active`);return}let i=v+y*(t.direction===g?-1:1)*t.distance[e.horizontal?`y`:`x`];b=Math.min(_,f.value[1],Math.max(f.value[0],i)),o[d.value].value.style[u.value]=p(b),e.emitImmediately&&e.modelValue!==b&&n(`update:modelValue`,b)}let S=D(()=>[[he,e.disable?void 0:x,void 0,{[e.horizontal?`vertical`:`horizontal`]:!0,prevent:!0,stop:!0,mouse:!0,mouseAllDir:!0}]]),C=D(()=>{let t={role:`separator`,"aria-orientation":e.horizontal?`horizontal`:`vertical`,"aria-label":e.separatorAriaLabel||r.lang.label.resize};if(e.disable)t[`aria-disabled`]=`true`;else{let n=f.value;t.tabindex=0,t[`aria-controls`]=s.value,t[`aria-valuemin`]=n[0],n[1]!==1/0&&(t[`aria-valuemax`]=n[1]),t[`aria-valuenow`]=Math.round(e.modelValue*100)/100}return t}),w=null;function E(t){let{keyCode:i}=t,o=e.horizontal?[38,40]:[37,39];if(i!==13&&i!==36&&i!==35&&!o.includes(i))return;te(t);let s=f.value,c=e.unit===`%`?100:a.value.getBoundingClientRect()[u.value],l;if(i===13)e.modelValue===s[0]?l=w===null?e.modelValue:w:(w=e.modelValue,l=s[0]);else if(i===36)l=s[0];else if(i===35)l=s[1];else{let t=(i===o[0]?-1:1)*(e.reverse?-1:1)*(e.horizontal?1:r.lang.rtl?-1:1);l=e.modelValue+t*(e.unit===`%`?1:10)}let d=Math.min(c,s[1],Math.max(s[0],l));d!==e.modelValue&&n(`update:modelValue`,d)}function O(e,t){e<t[0]?n(`update:modelValue`,t[0]):e>t[1]&&n(`update:modelValue`,t[1])}return h(()=>e.modelValue,e=>{O(e,f.value)}),h(()=>e.limits,()=>{A(()=>{O(e.modelValue,f.value)})}),()=>{let n=[M(`div`,{ref:o.before,id:d.value===`before`?s.value:void 0,class:[`q-splitter__panel q-splitter__before`+(e.reverse?` col`:``),e.beforeClass],style:m.value.before},I(t.before)),M(`div`,{class:[`q-splitter__separator`,e.separatorClass],style:e.separatorStyle,...C.value,onKeydown:e.disable?void 0:E},[l(M(`div`,{class:`q-splitter__separator-area absolute-full`},I(t.separator)),S.value)]),M(`div`,{ref:o.after,id:d.value===`after`?s.value:void 0,class:[`q-splitter__panel q-splitter__after`+(e.reverse?``:` col`),e.afterClass],style:m.value.after},I(t.after))];return M(`div`,{class:c.value,ref:a},ee(t.default,n))}}}),He=`githuman.fileListWidth`,Ue=260,Q=220,$=600,We=N(b({__name:`PanelResize`,setup(e){let t=y(ve(He,Q,$)??Ue),n=D(()=>[Q,$]);function r(e){typeof e==`number`&&Number.isFinite(e)&&(t.value=be(e,Q,$),pe.set(He,String(t.value)))}return(e,i)=>(d(),C(Ve,{"model-value":t.value,limits:n.value,unit:`px`,class:`file-explorer`,"before-class":`file-explorer__panel`,"after-class":`file-explorer__content`,"onUpdate:modelValue":r},{before:s(()=>[c(e.$slots,`panel`,{},void 0,!0)]),after:s(()=>[c(e.$slots,`content`,{},void 0,!0)]),_:3},8,[`model-value`,`limits`]))}}),[[`__scopeId`,`data-v-65488178`]]),Ge={class:`row items-center no-wrap q-gutter-x-xs`},Ke={class:`row items-center no-wrap q-gutter-x-xs`},qe=b({__name:`FileExplorerTabs`,props:f({stagedFilesLength:{},unstagedFilesLength:{}},{modelValue:{default:`staged`},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=m(e,`modelValue`),{t:n}=H();return(r,i)=>(d(),C(_e,{modelValue:t.value,"onUpdate:modelValue":i[0]||=e=>t.value=e,dense:``,"no-caps":``,align:`left`,"narrow-indicator":``,class:`text-primary q-mb-sm`},{default:s(()=>[x(ge,{name:`staged`},{default:s(()=>[_(`div`,Ge,[_(`span`,null,a(O(n)(`changes.staged`)),1),x(me,{color:`positive`,rounded:``},{default:s(()=>[w(a(e.stagedFilesLength),1)]),_:1})])]),_:1}),x(ge,{name:`unstaged`},{default:s(()=>[_(`div`,Ke,[_(`span`,null,a(O(n)(`changes.unstaged`)),1),x(me,{color:`warning`,rounded:``},{default:s(()=>[w(a(e.unstagedFilesLength),1)]),_:1})])]),_:1})]),_:1},8,[`modelValue`]))}}),Je={class:`file-tree-node`},Ye={class:`row items-center no-wrap q-gutter-x-xs`},Xe={class:`ellipsis file-tree-node__label`},Ze={class:`ellipsis file-tree-node__label`},Qe={key:2},$e=N(b({__name:`FileTreeNode`,props:{node:{},selectedPath:{},expandedFolders:{},level:{}},emits:[`toggle-folder`,`file-select`],setup(t,{emit:n}){let r=t,i=n,c=8+r.level*12;return(n,r)=>{let f=u(`FileTreeNode`,!0);return d(),v(`div`,Je,[t.node.type===`directory`?l((d(),C(G,{key:0,clickable:``,dense:``,style:p({paddingLeft:`${c}px`}),onClick:r[0]||=e=>i(`toggle-folder`,t.node.path)},{default:s(()=>[x(q,{avatar:``,class:`file-tree-node__icon-section`},{default:s(()=>[_(`div`,Ye,[x(L,{name:`chevron_right`,size:`xs`,class:j([`file-tree-node__chevron`,{"file-tree-node__chevron--expanded":t.expandedFolders.has(t.node.path)}])},null,8,[`class`]),x(L,{name:t.expandedFolders.has(t.node.path)?`folder_open`:`folder`,size:`xs`,color:`warning`},null,8,[`name`])])]),_:1}),x(q,{class:`text-mono`},{default:s(()=>[_(`div`,Xe,[w(a(t.node.name)+` `,1),x(e,{anchor:`top middle`,self:`bottom middle`},{default:s(()=>[w(a(t.node.path),1)]),_:1})])]),_:1}),t.node.children?(d(),C(q,{key:0,side:``,class:`text-caption text-grey-6`},{default:s(()=>[w(a(t.node.children.length),1)]),_:1})):k(``,!0)]),_:1},8,[`style`])),[[R]]):l((d(),C(G,{key:1,clickable:``,dense:``,active:t.node.path===t.selectedPath,"active-class":`file-tree-node--selected`,style:p({paddingLeft:`${c+20}px`}),onClick:r[1]||=e=>i(`file-select`,t.node.path)},{default:s(()=>[x(q,{avatar:``,class:`file-tree-node__icon-section`},{default:s(()=>[x(L,{name:`insert_drive_file`,size:`xs`,color:`grey-6`})]),_:1}),x(q,{class:`text-mono`},{default:s(()=>[_(`div`,Ze,[w(a(t.node.name)+` `,1),x(e,{anchor:`top middle`,self:`bottom middle`},{default:s(()=>[w(a(t.node.path),1)]),_:1})])]),_:1}),t.node.isChanged?(d(),C(q,{key:0,side:``},{default:s(()=>[x(L,{name:`fiber_manual_record`,size:`8px`,color:`warning`})]),_:1})):k(``,!0)]),_:1},8,[`active`,`style`])),[[R]]),t.node.type===`directory`&&t.expandedFolders.has(t.node.path)&&t.node.children?(d(),v(`div`,Qe,[(d(!0),v(E,null,o(t.node.children,e=>(d(),C(f,{key:e.path,node:e,"selected-path":t.selectedPath,"expanded-folders":t.expandedFolders,level:t.level+1,onToggleFolder:r[2]||=e=>i(`toggle-folder`,e),onFileSelect:r[3]||=e=>i(`file-select`,e)},null,8,[`node`,`selected-path`,`expanded-folders`,`level`]))),128))])):k(``,!0)])}}}),[[`__scopeId`,`data-v-43168dd7`]]);function et(){let e=P(),{t}=H(),r=n(),i=Z(),a=X();async function o(e,n,a){try{await le(n,{paths:[e]}),await i.refresh()}catch(e){r(t(a),e)}}function s(n){let r=(a.commentsByFile.get(n)??[]).filter(e=>!e.resolved).length;if(r===0)return o(n,`/api/git/stage`,`changes.actions.stageError`);e.dialog({title:t(`changes.actions.stageUnresolvedTitle`),message:t(`changes.actions.stageUnresolvedMessage`,{path:n,count:r}),persistent:!0,ok:{label:t(`changes.actions.stageUnresolvedOk`),flat:!0},cancel:{label:t(`changes.actions.discardConfirmCancel`),flat:!0}}).onOk(()=>{o(n,`/api/git/stage`,`changes.actions.stageError`)})}function c(e){return o(e,`/api/git/unstage`,`changes.actions.unstageError`)}function l(n){e.dialog({title:t(`changes.actions.discardConfirmTitle`),message:t(`changes.actions.discardConfirmMessage`,{path:n}),persistent:!0,ok:{label:t(`changes.actions.discardConfirmOk`),color:`negative`,flat:!0},cancel:{label:t(`changes.actions.discardConfirmCancel`),flat:!0}}).onOk(()=>{o(n,`/api/git/discard`,`changes.actions.discardError`)})}return{stage:s,unstage:c,discard:l}}var tt={class:`file-list-item__path-row row no-wrap items-center`},nt={class:`ellipsis file-list-item__path-label`},rt={class:`text-caption`},it={class:`text-positive`},at={class:`text-negative q-ml-xs`},ot=N(b({__name:`FileListItem`,props:{file:{},selected:{type:Boolean},source:{}},emits:[`click`],setup(t){let n={added:`A`,modified:`M`,deleted:`D`,renamed:`R`},r={added:`positive`,modified:`warning`,deleted:`negative`,renamed:`purple`},i=t,{t:o}=H(),{stage:c,unstage:u,discard:f}=et(),p=X(),m=D(()=>p.commentsByFile.get(Y(i.file))?.length??0);return(i,p)=>l((d(),C(G,{clickable:``,dense:``,active:t.selected,"active-class":`file-list-item--selected`,onClick:p[3]||=e=>i.$emit(`click`)},{default:s(()=>[x(q,{avatar:``,class:`file-list-item__icon-section`},{default:s(()=>[_(`span`,{class:j([`text-caption text-weight-bold text-mono`,`text-${r[t.file.status]}`])},a(n[t.file.status]),3)]),_:1}),x(q,{class:`text-mono`},{default:s(()=>[_(`div`,tt,[_(`span`,nt,[w(a(O(Y)(t.file))+` `,1),x(e,{anchor:`top middle`,self:`bottom middle`},{default:s(()=>[w(a(O(Y)(t.file)),1)]),_:1})]),m.value>0?(d(),C(Oe,{key:0,compact:``,class:`file-list-item__badge`,count:m.value},null,8,[`count`])):k(``,!0)])]),_:1}),x(q,{side:``,class:`file-list-item__stats`},{default:s(()=>[_(`span`,rt,[_(`span`,it,`+`+a(t.file.additions),1),_(`span`,at,`-`+a(t.file.deletions),1)])]),_:1}),x(q,{side:``,class:`file-list-item__actions`},{default:s(()=>[t.source===`unstaged`?(d(),v(E,{key:0},[l((d(),C(B,{flat:``,dense:``,round:``,size:`sm`,icon:`undo`,"aria-label":O(o)(`changes.actions.discard`),onClick:p[0]||=F(e=>O(f)(O(Y)(t.file)),[`stop`])},{default:s(()=>[x(e,null,{default:s(()=>[w(a(O(o)(`changes.actions.discard`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[R]]),l((d(),C(B,{flat:``,dense:``,round:``,size:`sm`,icon:`add`,"aria-label":O(o)(`changes.actions.stage`),onClick:p[1]||=F(e=>O(c)(O(Y)(t.file)),[`stop`])},{default:s(()=>[x(e,null,{default:s(()=>[w(a(O(o)(`changes.actions.stage`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[R]])],64)):l((d(),C(B,{key:1,flat:``,dense:``,round:``,size:`sm`,icon:`remove`,"aria-label":O(o)(`changes.actions.unstage`),onClick:p[2]||=F(e=>O(u)(O(Y)(t.file)),[`stop`])},{default:s(()=>[x(e,null,{default:s(()=>[w(a(O(o)(`changes.actions.unstage`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[R]])]),_:1})]),_:1},8,[`active`])),[[R]])}}),[[`__scopeId`,`data-v-b9210fc2`]]),st=b({__name:`BrowseModeToggle`,props:{modelValue:{type:Boolean,default:!1},modelModifiers:{}},emits:[`update:modelValue`],setup(e){let t=m(e,`modelValue`),{t:n}=H();return(e,r)=>(d(),C(G,null,{default:s(()=>[x(q,null,{default:s(()=>[x(xe,null,{default:s(()=>[w(a(O(n)(`browse.toggle`)),1)]),_:1})]),_:1}),x(q,{side:``},{default:s(()=>[x(ae,{modelValue:t.value,"onUpdate:modelValue":r[0]||=e=>t.value=e,dense:``,size:`xs`},null,8,[`modelValue`])]),_:1})]),_:1}))}}),ct={class:`file-list-panel__header q-pa-sm`},lt={key:1,class:`text-subtitle2 q-mb-sm`},ut={key:0,class:`text-primary`},dt={key:0,class:`row justify-center q-pa-lg`},ft={key:0,class:`text-caption text-grey-6 q-px-md q-py-sm`},pt={key:0,class:`text-caption text-grey-6 q-px-md q-py-sm`},mt=N(b({__name:`FileListPanel`,setup(e){let{t}=H(),{stagedFiles:n,unstagedFiles:r,initialLoading:i,error:c}=U(J()),l=Z(),{source:u,browseMode:f,filter:p,selectedPath:m,expandedFolders:h,treeInitialLoading:y,treeError:b,filteredDiffFiles:S,filteredTree:T,totalTreeFiles:D}=U(l);return(e,A)=>(d(),v(E,null,[_(`div`,ct,[O(f)?(d(),v(`div`,lt,[w(a(O(t)(`browse.allFiles`))+` `,1),O(D)>0||!O(b)?(d(),v(`span`,ut,`(`+a(O(D))+`)`,1)):k(``,!0)])):(d(),C(qe,{key:0,modelValue:O(u),"onUpdate:modelValue":A[0]||=e=>g(u)?u.value=e:null,"staged-files-length":O(n).length,"unstaged-files-length":O(r).length},null,8,[`modelValue`,`staged-files-length`,`unstaged-files-length`])),x(Pe,{modelValue:O(p),"onUpdate:modelValue":A[1]||=e=>g(p)?p.value=e:null,placeholder:O(f)?O(t)(`browse.searchPlaceholder`):O(t)(`changes.filterPlaceholder`)},null,8,[`modelValue`,`placeholder`])]),x(V),x(K,{class:`col file-list-panel__scroll`,"content-style":`padding: 4px 0`,"content-active-style":`padding: 4px 0`},{default:s(()=>[(O(f)?O(y):O(i))?(d(),v(`div`,dt,[x(z,{color:`primary`,size:`2em`})])):O(f)?(d(),v(E,{key:1},[O(T).length===0&&(!O(b)||O(p)&&O(D)>0)?(d(),v(`p`,ft,a(O(p)?O(t)(`browse.noMatchingFiles`):O(t)(`browse.noFiles`)),1)):k(``,!0),(d(!0),v(E,null,o(O(T),e=>(d(),C($e,{key:e.path,node:e,"selected-path":O(m),"expanded-folders":O(h),level:0,onToggleFolder:O(l).toggleFolder,onFileSelect:O(l).selectFile},null,8,[`node`,`selected-path`,`expanded-folders`,`onToggleFolder`,`onFileSelect`]))),128))],64)):(d(),v(E,{key:2},[O(S).length===0&&(O(p)||!O(c))?(d(),v(`p`,pt,a(O(p)?O(t)(`browse.noMatchingFiles`):O(t)(`changes.emptyFileList`)),1)):k(``,!0),(d(!0),v(E,null,o(O(S),e=>(d(),C(ot,{key:O(Y)(e),file:e,selected:O(m)===O(Y)(e),source:O(u),onClick:t=>O(l).selectFile(O(Y)(e))},null,8,[`file`,`selected`,`source`,`onClick`]))),128))],64))]),_:1}),x(V),x(st,{modelValue:O(f),"onUpdate:modelValue":A[2]||=e=>g(f)?f.value=e:null},null,8,[`modelValue`])],64))}}),[[`__scopeId`,`data-v-32cc9fb2`]]),ht={class:`diff-status-bar row items-center q-gutter-x-md q-pa-sm text-body2`},gt={class:`text-weight-medium`},_t={class:`text-positive`},vt={class:`text-negative`},yt={key:0,class:`text-grey-6`},bt={key:1,class:`text-grey-6`},xt={key:2,class:`text-grey-6`},St={key:3,class:`text-grey-6`},Ct=b({__name:`DiffStatusBar`,props:{files:{}},emits:[`expand-all`,`collapse-all`],setup(e,{emit:n}){let r=e,i=n,{t:o}=H(),s=D(()=>{let e=r.files.reduce((e,t)=>e+t.additions,0),t=r.files.reduce((e,t)=>e+t.deletions,0),n=r.files.filter(e=>e.status===`added`).length,i=r.files.filter(e=>e.status===`modified`).length,a=r.files.filter(e=>e.status===`deleted`).length,o=r.files.filter(e=>e.status===`renamed`).length;return{total:r.files.length,additions:e,deletions:t,added:n,modified:i,deleted:a,renamed:o}});return(e,n)=>(d(),v(`div`,ht,[_(`span`,gt,a(O(o)(`changes.filesChanged`,{count:s.value.total})),1),_(`span`,_t,` +`+a(s.value.additions)+` `+a(O(o)(`changes.additions`)),1),_(`span`,vt,` -`+a(s.value.deletions)+` `+a(O(o)(`changes.deletions`)),1),s.value.added?(d(),v(`span`,yt,a(s.value.added)+` `+a(O(o)(`changes.added`)),1)):k(``,!0),s.value.modified?(d(),v(`span`,bt,a(s.value.modified)+` `+a(O(o)(`changes.modified`)),1)):k(``,!0),s.value.deleted?(d(),v(`span`,xt,a(s.value.deleted)+` `+a(O(o)(`changes.deletedPlural`)),1)):k(``,!0),s.value.renamed?(d(),v(`span`,St,a(s.value.renamed)+` `+a(O(o)(`changes.renamed`)),1)):k(``,!0),x(t),x(B,{dense:``,flat:``,"no-caps":``,size:`sm`,icon:`unfold_more`,label:O(o)(`changes.expandAll`),onClick:n[0]||=e=>i(`expand-all`)},null,8,[`label`]),x(B,{dense:``,flat:``,"no-caps":``,size:`sm`,icon:`unfold_less`,label:O(o)(`changes.collapseAll`),onClick:n[1]||=e=>i(`collapse-all`)},null,8,[`label`])]))}}),wt={key:0,class:`active-review-bar row items-center q-gutter-x-sm q-px-sm no-wrap`},Tt={class:`text-body2 ellipsis`},Et=N(b({__name:`ActiveReviewBar`,setup(e){let{t:i}=H(),o=n(),s=X(),{activeReview:c}=U(s),l=fe(),u=we();function f(e){s.setStatus(e).catch(e=>{o(i(`reviews.comments.error`),e)})}return(e,n)=>O(c)?(d(),v(`div`,wt,[x(L,{name:`rate_review`,size:`18px`,color:`primary`}),_(`span`,Tt,a(O(c).name??O(i)(`reviews.list.unnamed`)),1),x(t),O(l).enabled?(d(),C(B,{key:0,flat:``,dense:``,"no-caps":``,size:`sm`,icon:O(r),label:O(i)(`agent.context.addReview`),onClick:n[0]||=e=>O(u)({kind:`review`,reviewId:O(c).id})},null,8,[`icon`,`label`])):k(``,!0),x(Ne,{status:O(c).status,onChange:f},null,8,[`status`])])):k(``,!0)}}),[[`__scopeId`,`data-v-2b6e4bdd`]]),Dt={role:`alert`},Ot={class:`text-caption`},kt=b({__name:`LoadErrorBanner`,props:{title:{},message:{},loading:{type:Boolean}},emits:[`retry`],setup(e,{emit:t}){let n=t,{t:r}=H();return(t,i)=>(d(),C(ye,{dense:``,class:`bg-negative text-white`,role:`none`},{action:s(()=>[x(B,{flat:``,dense:``,color:`white`,label:O(r)(`changes.retry`),loading:e.loading,onClick:i[0]||=e=>n(`retry`)},null,8,[`label`,`loading`])]),default:s(()=>[_(`div`,Dt,[w(a(e.title)+` `,1),_(`div`,Ot,a(e.message),1)])]),_:1}))}}),At={key:1,class:`q-pa-md text-grey-6`},jt=b({__name:`DiffPanel`,setup(e){let{t}=H(),r=n(),i=Z(),c=X(),{diffFiles:l,expandedFiles:u}=U(i),{error:f,loading:p}=U(J()),{activeReview:m,commentsByFile:h}=U(c);async function g(e){try{await e()}catch(e){r(t(`reviews.comments.error`),e)}}function _(e){g(()=>c.createComment(e))}function y(e,t){g(()=>c.editComment(e,t))}function b(e){g(()=>c.deleteComment(e))}function S(e){g(()=>c.resolveComment(e))}function w(e){g(()=>c.unresolveComment(e))}return(e,n)=>(d(),v(E,null,[O(f)?(d(),C(kt,{key:0,title:O(t)(`changes.loadError`),message:O(f),loading:O(p),onRetry:n[0]||=e=>O(i).refresh()},null,8,[`title`,`message`,`loading`])):k(``,!0),O(l).length===0&&!O(f)?(d(),v(`div`,At,a(O(t)(`changes.emptyDiffPanel`)),1)):O(l).length>0?(d(),v(E,{key:2},[x(Et),O(m)?(d(),C(V,{key:0})):k(``,!0),x(Ct,{files:O(l),onExpandAll:O(i).expandAllFiles,onCollapseAll:O(i).collapseAllFiles},null,8,[`files`,`onExpandAll`,`onCollapseAll`]),x(V),x(K,{class:`col`,"content-style":`padding: 8px; width: 100%; max-width: 100%`,"content-active-style":`padding: 8px; width: 100%; max-width: 100%`},{default:s(()=>[(d(!0),v(E,null,o(O(l),e=>(d(),C(ke,{key:O(Y)(e),file:e,expanded:O(u).has(O(Y)(e)),"agent-source":O(i).source,commentable:!!O(m),"comments-editable":!!O(m),comments:O(h).get(O(Y)(e))??[],onToggle:t=>O(i).handleCardToggle(O(Y)(e)),onExpand:t=>O(i).expandFile(O(Y)(e)),onCreateComment:_,onEditComment:y,onDeleteComment:b,onResolveComment:S,onUnresolveComment:w},null,8,[`file`,`expanded`,`agent-source`,`commentable`,`comments-editable`,`comments`,`onToggle`,`onExpand`]))),128))]),_:1})],64)):k(``,!0),!O(m)&&O(l).length>0?(d(),C(Fe,{key:3})):k(``,!0)],64))}}),Mt={key:1,class:`q-pa-md text-grey-6`},Nt={key:0,class:`row justify-center q-pa-lg`},Pt={key:1,class:`q-pa-md text-grey-6`},Ft={class:`text-caption`},It={key:2,class:`q-pa-md text-grey-6`},Lt=b({__name:`FileContentPanel`,setup(e){let{t}=H(),n=Z(),{selectedPath:r,browseFileLines:i,browseFileIsBinary:o,browseFileLoading:c,browseFileError:l,treeError:u,refreshing:f}=U(n),{error:p}=U(J()),m=D(()=>p.value?{title:t(`changes.loadError`),message:p.value}:u.value?{title:t(`browse.treeLoadError`),message:u.value}:null),g=y(!1);return h(r,e=>{g.value=e?je(e):!1},{immediate:!0}),(e,u)=>(d(),v(E,null,[m.value?(d(),C(kt,{key:0,title:m.value.title,message:m.value.message,loading:O(f),onRetry:u[0]||=e=>O(n).refresh()},null,8,[`title`,`message`,`loading`])):k(``,!0),O(r)?(d(),C(Me,{key:2,class:`col`},{header:s(()=>[x(Ae,{path:O(r)},{default:s(()=>[x(De,{modelValue:g.value,"onUpdate:modelValue":u[1]||=e=>g.value=e,path:O(r)},null,8,[`modelValue`,`path`])]),_:1},8,[`path`])]),default:s(()=>[O(c)&&O(i).length===0&&!O(l)?(d(),v(`div`,Nt,[x(z,{color:`primary`,size:`2em`})])):O(l)?(d(),v(`div`,Pt,[w(a(O(t)(`changes.fullFileLoadError`))+` `,1),_(`div`,Ft,a(O(l)),1),x(B,{flat:``,dense:``,color:`primary`,class:`q-mt-sm`,label:O(t)(`changes.retry`),loading:O(f),onClick:u[2]||=e=>O(n).refresh()},null,8,[`label`,`loading`])])):O(o)?(d(),v(`div`,It,a(O(t)(`changes.binaryFile`)),1)):(d(),C(K,{key:3,class:`col`,"content-style":`padding: 8px`,"content-active-style":`padding: 8px`},{default:s(()=>[x(Te,{path:O(r),lines:O(i),wrap:g.value},null,8,[`path`,`lines`,`wrap`])]),_:1}))]),_:1})):(d(),v(`div`,Mt,a(O(t)(`browse.selectFile`)),1))],64))}}),Rt=b({__name:`FileExplorer`,setup(e){let t=Z(),n=X(),{browseMode:r}=U(t);i(()=>{t.refresh(),n.refresh()});let a=W([`files:changed`],()=>void t.refreshFromServerEvent());S(()=>a.close());let o=W([`review:created`,`review:updated`,`review:deleted`,`comment:created`,`comment:updated`,`comment:deleted`],()=>void n.refresh());return S(()=>o.close()),(e,t)=>(d(),C(We,null,{panel:s(()=>[x(mt)]),content:s(()=>[O(r)?(d(),C(Lt,{key:0})):(d(),C(jt,{key:1}))]),_:1}))}}),zt=b({__name:`IndexPage`,setup(e){return(e,t)=>(d(),C(Ce,null,{default:s(()=>[x(Rt)]),_:1}))}});export{zt as default};
@@ -0,0 +1 @@
1
+ .image-preview[data-v-fd1c633c]{object-fit:contain;max-width:calc(94vw - 32px);max-height:calc(92vh - 96px);margin:16px auto;display:block}.agent-item__thumb[data-v-c8e559ff]{cursor:zoom-in;width:72px;height:72px}.agent-item.q-message[data-v-fa776a7b]{font-family:var(--font-agent);min-width:0;max-width:100%;margin-bottom:0}.agent-item[data-v-fa776a7b] .q-message-text{min-height:0;padding-left:16px;padding-right:16px}.agent-item[data-v-fa776a7b] .q-message-container>*,.agent-item[data-v-fa776a7b] .q-message-text-content,.agent-item[data-v-fa776a7b] .q-message-text{min-width:0;max-width:100%}.agent-item__text[data-v-fa776a7b]{white-space:pre-wrap;overflow-wrap:anywhere;font-size:14px;line-height:1.65}.agent-item.q-message[data-v-357e63c1]{font-family:var(--font-agent);min-width:0;max-width:100%;margin-bottom:0}.agent-item[data-v-357e63c1] .q-message-text{min-height:0;padding-left:16px;padding-right:16px}.agent-item[data-v-357e63c1] .q-message-container>*,.agent-item[data-v-357e63c1] .q-message-text-content,.agent-item[data-v-357e63c1] .q-message-text{min-width:0;max-width:100%}.agent-item[data-v-357e63c1] .md-content{font-size:14px;line-height:1.65}.agent-item[data-v-357e63c1] .md-content strong,.agent-item[data-v-357e63c1] .md-content b{font-weight:500}.agent-diff[data-v-60226168]{border:1px solid var(--q-separator-color,#8080804d);border-radius:4px}.agent-diff__path[data-v-60226168]{background:var(--diff-header-bg);padding:2px 8px}.agent-diff__body[data-v-60226168]{max-width:100%;margin:0;font-size:12px;line-height:1.45;overflow-x:auto}.agent-diff__row[data-v-60226168]{white-space:pre;padding:0 8px;display:block}.agent-diff__row--added[data-v-60226168]{background:#2ea0432e}.agent-diff__row--removed[data-v-60226168]{background:#f851492e}.agent-tool[data-v-6537eaaa]{border:1px solid var(--q-separator-color,#8080804d);border-radius:6px;font-size:11px}.agent-tool[data-v-6537eaaa] .q-item{min-height:26px;padding:0 8px}.agent-tool[data-v-6537eaaa] .q-item__label{font-size:11px}.agent-tool[data-v-6537eaaa] .q-item__section--side{padding-left:6px}.agent-tool__icon[data-v-6537eaaa]{min-width:22px;padding-right:6px}.agent-tool__badge[data-v-6537eaaa]{font-size:10px}.agent-tool__caption[data-v-6537eaaa],.agent-tool__body[data-v-6537eaaa]{font-size:11px}.agent-tool__output[data-v-6537eaaa]{white-space:pre-wrap;max-height:200px;margin:0;font-size:11px;overflow:auto}.agent-thought[data-v-2bc07051]{font-size:11px}.agent-thought__text[data-v-2bc07051]{white-space:pre-wrap;font-size:11px}.agent-thought[data-v-2bc07051] .q-item{min-height:26px;padding:0 8px}.agent-thought[data-v-2bc07051] .q-item__label,.agent-thought[data-v-2bc07051] .q-item__section--main{font-size:11px}.agent-thought[data-v-2bc07051] .q-icon{font-size:14px}.agent-auto-approved[data-v-c0c0181b]{font-size:11px}.agent-auto-approved[data-v-c0c0181b] .q-icon{font-size:14px}.agent-chat-banners__banner[data-v-ece62303]{overflow-wrap:anywhere;flex:none;font-size:12px}.agent-chat-banners__banner[data-v-ece62303] .q-banner__content,.agent-chat-banners__banner[data-v-ece62303] .q-btn{font-size:12px;line-height:1.35}.agent-chat-banners__banner[data-v-ece62303] .q-banner__actions{align-self:center}.agent-mention-popup[data-v-a7a8b754]{z-index:6000;border:1px solid #80808059;border-radius:6px;width:340px;max-width:calc(100vw - 16px);max-height:260px;font-size:13px;position:fixed;overflow-y:auto}.agent-mention-popup__item[data-v-a7a8b754]{cursor:pointer;align-items:baseline;gap:8px;padding:4px 10px;display:flex}.agent-mention-popup__item--active[data-v-a7a8b754]{background:#1976d22e}.agent-mention-popup__name[data-v-a7a8b754]{flex:none;font-weight:500}.agent-mention-popup__dir[data-v-a7a8b754]{opacity:.6;text-overflow:ellipsis;white-space:nowrap;text-align:left;direction:rtl;min-width:0;font-size:11.5px;overflow:hidden}.agent-editor-wrap[data-v-d04db174]{min-width:0;position:relative}.agent-editor[data-v-d04db174]{font-family:var(--font-agent);white-space:pre-wrap;overflow-wrap:anywhere;outline:none;min-height:24px;max-height:160px;padding:5px 4px;font-size:14px;line-height:1.65;overflow-y:auto}.agent-editor[aria-disabled=true][data-v-d04db174]{cursor:not-allowed;opacity:.6}.agent-editor--empty[data-v-d04db174]:before{content:attr(data-placeholder);opacity:.5;pointer-events:none;text-overflow:ellipsis;white-space:nowrap;position:absolute;top:5px;left:4px;right:4px;overflow:hidden}.agent-editor[data-v-d04db174] .agent-mention{-webkit-user-select:none;user-select:none;white-space:nowrap;background:#1976d22e;border-radius:4px;align-items:center;margin:0 1px;padding:0 1px 0 6px;font-size:12.5px;line-height:1.6;display:inline-flex}.agent-editor[data-v-d04db174] .agent-mention__remove{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:0;padding:0 4px;font-size:14px;line-height:1}.agent-editor[data-v-d04db174] .agent-mention__remove:hover{opacity:1}.agent-attachment-thumb[data-v-b18100a3]{width:56px;height:56px;position:relative}.agent-attachment-thumb-remove[data-v-b18100a3]{position:absolute;top:-6px;right:-6px}.agent-add-menu[data-v-3c2497e7]{min-width:180px}.agent-dot[data-v-8919c3e4]{flex:none;justify-content:center;align-items:center;width:14px;height:14px;display:inline-flex}.agent-dot__mark[data-v-8919c3e4]{background:var(--q-positive);opacity:.55;border-radius:50%;width:7px;height:7px}.agent-dot__mark--attention[data-v-8919c3e4]{background:var(--q-warning);opacity:1}.agent-dot__mark--closed[data-v-8919c3e4]{background:var(--q-negative);opacity:1}.agent-cfg[data-v-bfa2d9dd]{max-width:190px;font-size:12px}.agent-cfg[data-v-bfa2d9dd] .q-btn__content{flex-wrap:nowrap}.agent-cfg[data-v-bfa2d9dd] .block{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.agent-cfg__list[data-v-bfa2d9dd]{width:340px;min-width:220px;max-width:calc(100vw - 24px);max-height:300px}.agent-composer__status[data-v-d98990df]{min-height:28px;margin-top:4px}.agent-composer__state[data-v-d98990df]{opacity:.8;padding-right:8px;font-size:12px}.agent-composer[data-v-ce7dfcde]{flex:none;padding:4px 16px 10px}.agent-composer__box[data-v-ce7dfcde]{border:1px solid #80808073;border-radius:8px}.agent-composer__box[data-v-ce7dfcde]:focus-within{border-color:var(--q-primary)}.agent-permission[data-v-31a77038]{border:1px solid #8080804d;border-left:3px solid var(--q-warning);border-radius:4px;padding:6px 10px 8px;font-size:12px}.agent-permission__head[data-v-31a77038]{opacity:.7;font-size:11px}.agent-permission__title[data-v-31a77038]{text-overflow:ellipsis;white-space:nowrap;margin-top:2px;overflow:hidden}.agent-permission__changes[data-v-31a77038]{font-size:11px}.agent-permission__changes[data-v-31a77038] .q-item{min-height:24px;padding:0}.agent-view[data-v-f3b23f81]{position:absolute;inset:0}.agent-view[data-v-f3b23f81] .q-scrollarea__content{width:100%}.agent-view__feed[data-v-f3b23f81]{flex-direction:column;gap:10px;padding:14px 16px;display:flex}.agent-empty[data-v-cb2aea04]{padding:24px}.agent-empty__hint[data-v-cb2aea04]{max-width:260px}.agent-tabs[data-v-10656440]{border-bottom:1px solid var(--q-separator-color,#8080804d);flex:none}.agent-tabs__tabs[data-v-10656440]{min-width:0}.agent-tab[data-v-10656440]{text-transform:none;padding:0 8px}.agent-tab__body[data-v-10656440]{min-width:0;max-width:180px}.agent-tab__name[data-v-10656440]{min-width:0;font-size:13px}.agent-panel__views[data-v-f30b083a]{min-height:0;position:relative}.agent-new-chat[data-v-887d90c7]{width:380px;max-width:92vw}.agent-drawer__handle[data-v-2a2eac99]{z-index:10;cursor:col-resize;touch-action:none;width:13px;position:absolute;top:0;bottom:0;left:-6px}.agent-drawer__handle[data-v-2a2eac99]:focus-visible{outline-offset:2px;outline:2px solid}.agent-drawer--dragging[data-v-2a2eac99]{-webkit-user-select:none;user-select:none;transition:none!important}.repo-info[data-v-7b82112e]{line-height:1}.agent-menu__chats[data-v-33143e23]{padding:4px 0 8px}.agent-menu__dot[data-v-33143e23]{min-width:28px;padding-left:8px}