@qwen-code/qwen-code 0.19.5 → 0.19.6-nightly.20260705.015ee4248

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 (264) hide show
  1. package/bundled/dataviz/SKILL.md +50 -0
  2. package/bundled/dataviz/references/anti-patterns.md +12 -0
  3. package/bundled/dataviz/references/choosing-a-form.md +16 -0
  4. package/bundled/dataviz/references/palette.md +57 -0
  5. package/bundled/dataviz/scripts/validate_palette.js +328 -0
  6. package/bundled/loop/SKILL.md +1 -1
  7. package/bundled/qc-helper/docs/configuration/settings.md +14 -8
  8. package/bundled/qc-helper/docs/features/headless.md +2 -2
  9. package/bundled/qc-helper/docs/features/scheduled-tasks.md +4 -2
  10. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +1 -1
  11. package/bundled/review/DESIGN.md +23 -0
  12. package/bundled/review/SKILL.md +65 -8
  13. package/chunks/{MaxSizedBox-5JV77KRA.js → MaxSizedBox-PRXTXIGC.js} +31 -30
  14. package/chunks/{StandaloneSessionPicker-MGUGB6PH.js → StandaloneSessionPicker-PV7BSC5D.js} +42 -41
  15. package/chunks/{acpAgent-4F36XM3X.js → acpAgent-F34HNAM3.js} +939 -424
  16. package/chunks/{agent-IWBUZI6A.js → agent-XSQDKLST.js} +26 -25
  17. package/chunks/{agent-headless-JUTICAYO.js → agent-headless-B63XCKWX.js} +26 -25
  18. package/chunks/{anthropicContentGenerator-WL3LJOUB.js → anthropicContentGenerator-INXXI4PW.js} +7 -7
  19. package/chunks/{artifact-tool-W76WC2JX.js → artifact-tool-H2TNPNP5.js} +16 -3
  20. package/chunks/{askUserQuestion-J3P6TH3V.js → askUserQuestion-MKL5ZTMC.js} +2 -2
  21. package/chunks/{bridge-DHZHQ4UV.js → bridge-NCZDJBRF.js} +34 -32
  22. package/chunks/{channel-worker-supervisor-EVPAYNZ5.js → channel-worker-supervisor-JUYQ5Z4R.js} +5 -5
  23. package/chunks/{chunk-AVQDCKNF.js → chunk-22MNNNXE.js} +4 -0
  24. package/chunks/chunk-3RW4AZJV.js +5063 -0
  25. package/chunks/chunk-3VJ7MT3N.js +111 -0
  26. package/chunks/{chunk-JKGCBO3O.js → chunk-3VRMGS3A.js} +4 -4
  27. package/chunks/{chunk-TN6RT6EJ.js → chunk-3WOJO5EJ.js} +16 -4
  28. package/chunks/{chunk-G7OQ3RFJ.js → chunk-42XGFRJS.js} +3 -3
  29. package/chunks/{chunk-MOUXUCXQ.js → chunk-4KJ2BPIT.js} +1 -1
  30. package/chunks/{chunk-PPFWEV7G.js → chunk-4RQIB5UZ.js} +62 -62
  31. package/chunks/{chunk-JJ6B3ZD3.js → chunk-544UZQBD.js} +3 -3
  32. package/chunks/{chunk-B236XPGF.js → chunk-5UDYETKK.js} +1 -1
  33. package/chunks/{chunk-7DMQRPC7.js → chunk-6BEOH4KK.js} +1 -1
  34. package/chunks/{chunk-CXBG27SF.js → chunk-6IAWPIQ6.js} +3 -2
  35. package/chunks/{chunk-MDBNFHIO.js → chunk-6MDY7FX3.js} +5 -5
  36. package/chunks/{chunk-RM3PGSGL.js → chunk-6SHO7WFF.js} +15 -2
  37. package/chunks/{chunk-YCU7QV7Q.js → chunk-73WGF3NW.js} +34 -1
  38. package/chunks/{chunk-T42ACHFI.js → chunk-7LTB54MK.js} +1 -1
  39. package/chunks/{chunk-SJVPSHXU.js → chunk-7U6J224Z.js} +132 -25
  40. package/chunks/{chunk-CSPSJU5R.js → chunk-7WLJPMWU.js} +17 -17
  41. package/chunks/{chunk-R6RI2HIC.js → chunk-ACD5DFUY.js} +41 -14
  42. package/chunks/{chunk-EWALXUAD.js → chunk-AGHU5VRK.js} +8 -0
  43. package/chunks/{chunk-GLPV75ES.js → chunk-AHNJGLFV.js} +2 -2
  44. package/chunks/{chunk-DRS2HTNT.js → chunk-AOAFX4PL.js} +5 -5
  45. package/chunks/{chunk-QHYITL6P.js → chunk-CK7IUFOB.js} +63 -22
  46. package/chunks/{chunk-RSBQS6M4.js → chunk-CODWJXQA.js} +1 -1
  47. package/chunks/{chunk-LWGLBVWA.js → chunk-CSOTA7KX.js} +1 -1
  48. package/chunks/{chunk-UJT42DB6.js → chunk-DFH4T5IQ.js} +6 -6
  49. package/chunks/{chunk-DX3TKXNT.js → chunk-DJACOX4C.js} +2 -2
  50. package/chunks/{chunk-KKQWC6WS.js → chunk-DNV4FSN5.js} +1 -1
  51. package/chunks/{chunk-YPCPZSZB.js → chunk-DT3B47QP.js} +1 -1
  52. package/chunks/{chunk-NIOPRZNN.js → chunk-E7KNELIZ.js} +1 -1
  53. package/chunks/{chunk-DG573EOO.js → chunk-FEJ2FZ3U.js} +1 -1
  54. package/chunks/{chunk-M5ITDKSM.js → chunk-FHGQFG2K.js} +1 -1
  55. package/chunks/{chunk-HISPEX42.js → chunk-FSXFNDTI.js} +7 -7
  56. package/chunks/{chunk-LHMZCIKL.js → chunk-FUW7YGJU.js} +3 -1
  57. package/chunks/{chunk-Y4UQT3PM.js → chunk-FV5SBNNC.js} +1 -1
  58. package/chunks/{chunk-YTFBURQD.js → chunk-GB6HDZIK.js} +10 -2
  59. package/chunks/{chunk-D5KISTLW.js → chunk-H6EMK6QK.js} +1 -1
  60. package/chunks/{chunk-2Z43HUXT.js → chunk-HLKG6CZN.js} +3 -2
  61. package/chunks/{chunk-VXGPYF7U.js → chunk-IFEWJXFS.js} +1 -1
  62. package/chunks/{chunk-TENOUWY2.js → chunk-IJRL2S3D.js} +3 -3
  63. package/chunks/{chunk-OQHLUA2Y.js → chunk-IL6ZEDZ2.js} +4 -4
  64. package/chunks/{chunk-2CAII5HD.js → chunk-J7XUJALJ.js} +1 -1
  65. package/chunks/chunk-JFFOH2XO.js +2472 -0
  66. package/chunks/{chunk-NNEJEBCF.js → chunk-K3FZXSTO.js} +95 -107
  67. package/chunks/{chunk-NDY7OENU.js → chunk-KB4ICCA5.js} +3 -3
  68. package/chunks/{chunk-MNOXKSM2.js → chunk-LFFF2SPV.js} +3 -3
  69. package/chunks/{chunk-J3ERRYYI.js → chunk-LTMDKOZC.js} +2 -2
  70. package/chunks/{chunk-R3UWLLRQ.js → chunk-M7AGQP5D.js} +1 -1
  71. package/chunks/{chunk-CBJE2PLG.js → chunk-MLB5AB2I.js} +4 -4
  72. package/chunks/{chunk-YHTNWGRR.js → chunk-MZ7BABX3.js} +1 -1
  73. package/chunks/{chunk-SJBIFVD2.js → chunk-NFE3DQ4R.js} +7 -3
  74. package/chunks/{chunk-BC4R5C5R.js → chunk-NLD2WKE3.js} +55 -12
  75. package/chunks/{chunk-ALX6BUYW.js → chunk-NUGPZXAZ.js} +35 -1
  76. package/chunks/{chunk-NSSVORTQ.js → chunk-NYKWPUAE.js} +17 -13
  77. package/chunks/{chunk-K4I4STSL.js → chunk-OGEJMKN5.js} +2 -2
  78. package/chunks/{chunk-HTWHAN44.js → chunk-PC4ZXHU2.js} +1 -1
  79. package/chunks/{chunk-2YH27UNF.js → chunk-QLBBV7C6.js} +1 -1
  80. package/chunks/chunk-QT7XKZT7.js +293 -0
  81. package/chunks/{chunk-NPQWQYU6.js → chunk-QYNNN7BK.js} +1 -1
  82. package/chunks/chunk-R4N3OALZ.js +5631 -0
  83. package/chunks/{chunk-G4M7FPNY.js → chunk-RB5GAQR6.js} +2 -2
  84. package/chunks/{chunk-SBMHB6N5.js → chunk-RPHMD5UC.js} +15 -15
  85. package/chunks/{chunk-CHY5C5T4.js → chunk-SJ2CTIYH.js} +185 -88
  86. package/chunks/chunk-SLQXGMYY.js +949 -0
  87. package/chunks/{chunk-BZHLWC6T.js → chunk-SUAKHHK7.js} +2 -2
  88. package/chunks/{chunk-IMAMNLY6.js → chunk-SWV4CVYG.js} +158 -3
  89. package/chunks/{chunk-XKSCTXPK.js → chunk-TDGF35EN.js} +4 -3
  90. package/chunks/{chunk-TOAUDIS7.js → chunk-TLWA7TPR.js} +6 -2
  91. package/chunks/{chunk-WALEWZ44.js → chunk-UVHL5TCO.js} +1 -1
  92. package/chunks/{chunk-ZISMVA6U.js → chunk-VDMM5LVR.js} +1566 -37
  93. package/chunks/{chunk-BPFJQGY7.js → chunk-VEB3NYSO.js} +164 -5
  94. package/chunks/{chunk-L7OJ3ZO3.js → chunk-VZ7HY3YU.js} +1 -1
  95. package/chunks/{chunk-6KPZJJ6U.js → chunk-W4I6PLEG.js} +131 -38
  96. package/chunks/{chunk-QOMAHFYI.js → chunk-W7EEOR7D.js} +3 -3
  97. package/chunks/{chunk-6QVQZAW6.js → chunk-WKP5QZOP.js} +1 -1
  98. package/chunks/{chunk-YXK4GPYO.js → chunk-WMPVYQ4P.js} +30 -1
  99. package/chunks/{chunk-DM4E337C.js → chunk-WNTS5A2R.js} +5 -5
  100. package/chunks/{chunk-6QTCOQX7.js → chunk-WOG7QWIT.js} +3086 -2635
  101. package/chunks/{chunk-UY2TCIZS.js → chunk-X265R5C6.js} +3 -3
  102. package/chunks/{chunk-LKWAVAB5.js → chunk-X2XNQQJI.js} +2 -2
  103. package/chunks/{chunk-MTNTVOJR.js → chunk-X3YGAX7V.js} +6 -3
  104. package/chunks/{chunk-EROWZQN7.js → chunk-XD3OLPII.js} +6 -6
  105. package/chunks/{chunk-RNGAT2Y2.js → chunk-YYL6HROQ.js} +1 -1
  106. package/chunks/{chunk-XKZXGIRM.js → chunk-YZ2LNTHO.js} +2 -2
  107. package/chunks/{chunk-Z7XNVNPM.js → chunk-YZ5ANQMR.js} +3 -3
  108. package/chunks/{chunk-4MCC4XHH.js → chunk-Z7EYROOJ.js} +3568 -5508
  109. package/chunks/{chunk-5B2WNM6V.js → chunk-ZI4MGBB5.js} +1 -1
  110. package/chunks/{chunk-WZ724G6K.js → chunk-ZPGE42V7.js} +6 -6
  111. package/chunks/{computer-use-ON3JQUHW.js → computer-use-5I2UHVNY.js} +26 -25
  112. package/chunks/{contextCommand-OGCG7W6N.js → contextCommand-3NWY7AJG.js} +28 -27
  113. package/chunks/{cron-create-6YTCOX6P.js → cron-create-O6ZHD3JN.js} +22 -7
  114. package/chunks/{cron-delete-E3NIFSUK.js → cron-delete-BFD5B2XX.js} +4 -4
  115. package/chunks/{cron-list-Q64MNQNE.js → cron-list-KI6FV4KN.js} +4 -4
  116. package/chunks/{daemon-EEB2RYOL.js → daemon-DRUMLVFP.js} +140 -0
  117. package/chunks/daemon-status-provider-A2DK3ZTO.js +74 -0
  118. package/chunks/{dist-AP5V4WYU.js → dist-AAO65DPC.js} +2 -2
  119. package/chunks/{dist-X4ZDE726.js → dist-ABQ7VWRR.js} +3 -3
  120. package/chunks/{dist-SNXOUPYS.js → dist-AW5ZYMUI.js} +2 -2
  121. package/chunks/{dist-Z57Q4YF5.js → dist-DN6M6TJ5.js} +525 -95
  122. package/chunks/{dist-IZP2VV4C.js → dist-JPSVN367.js} +2 -2
  123. package/chunks/{earlyInputCapture-DAFHSGVW.js → earlyInputCapture-5TMSSPQ5.js} +27 -26
  124. package/chunks/{edit-3QFNCSZH.js → edit-V4ITLSUD.js} +27 -26
  125. package/chunks/{en-M4EBUBNU.js → en-AXARKOWO.js} +2 -0
  126. package/chunks/{enter-worktree-62EQQMLD.js → enter-worktree-7ULPRMTJ.js} +26 -25
  127. package/chunks/{enterPlanMode-VUQSE4EG.js → enterPlanMode-YSHMLHJZ.js} +26 -25
  128. package/chunks/{errors-PW75PZXE.js → errors-TCUTD7NF.js} +28 -27
  129. package/chunks/{exit-worktree-VVNH7OVY.js → exit-worktree-JZDCKR6A.js} +26 -25
  130. package/chunks/{exitPlanMode-RUYRCYZW.js → exitPlanMode-GOQBN6SG.js} +26 -25
  131. package/chunks/{fast-path-TFRJRTTR.js → fast-path-F2HGAKO2.js} +3 -3
  132. package/chunks/{fast-path-settings-UQLRFDQP.js → fast-path-settings-RCRXH2JG.js} +2 -2
  133. package/chunks/{gemini-XW7ZDUVR.js → gemini-3M7ECKNW.js} +86 -80
  134. package/chunks/{geminiContentGenerator-MZDVHVZH.js → geminiContentGenerator-5EG3QEJM.js} +4 -4
  135. package/chunks/{glob-WAY2PUWA.js → glob-2DBDTLR4.js} +54 -29
  136. package/chunks/{grep-W6CBKSYC.js → grep-R27DLGWT.js} +26 -25
  137. package/chunks/{initializer-HK2XE6P2.js → initializer-OXB6BJZU.js} +32 -31
  138. package/chunks/{keychain-token-storage-GPAKRDKQ.js → keychain-token-storage-UJV5XP4Z.js} +2 -2
  139. package/chunks/{list-RVLIIKKL.js → list-HLCOEOSF.js} +33 -32
  140. package/chunks/{loadedSettingsAdapter-C63OUYZC.js → loadedSettingsAdapter-JHTVH3YO.js} +31 -30
  141. package/chunks/{loop-wakeup-G2EHBRGR.js → loop-wakeup-CUVIY2JY.js} +5 -5
  142. package/chunks/{ls-IDHUVSAG.js → ls-L654WOAT.js} +4 -4
  143. package/chunks/{lsp-FSRYXGFT.js → lsp-M35KE54Y.js} +2 -2
  144. package/chunks/mcp-2JWEFAIN.js +67 -0
  145. package/chunks/{monitor-FOG36ABM.js → monitor-5QKFZFDX.js} +26 -25
  146. package/chunks/nonInteractiveCli-W5W5PIHI.js +112 -0
  147. package/chunks/{notebook-edit-GC6NXRCX.js → notebook-edit-XAFBWORI.js} +27 -26
  148. package/chunks/{openaiContentGenerator-EXR3ZL3Z.js → openaiContentGenerator-NULJROYV.js} +13 -12
  149. package/chunks/{pidfile-FNZM2DDH.js → pidfile-3LT7PZSW.js} +27 -26
  150. package/chunks/{qwenContentGenerator-A7B6J4U7.js → qwenContentGenerator-KLSURVNH.js} +28 -27
  151. package/chunks/{qwenOAuth2-LWLA6MQG.js → qwenOAuth2-ZV7YLMND.js} +5 -5
  152. package/chunks/{read-file-6JL4ULMY.js → read-file-HDAM3RHJ.js} +8 -8
  153. package/chunks/{read-mcp-resource-PIJF24RO.js → read-mcp-resource-CNQHBSJM.js} +2 -2
  154. package/chunks/record-artifact-PP3LKHTS.js +343 -0
  155. package/chunks/{ripGrep-DIUGLJE5.js → ripGrep-W36NLR7M.js} +26 -25
  156. package/chunks/{run-qwen-serve-CME3AKM4.js → run-qwen-serve-IMI2CQB5.js} +72 -28
  157. package/chunks/{scheduler-L7F6GDDT.js → scheduler-I5NKE5UJ.js} +26 -25
  158. package/chunks/{send-message-33PYFMCT.js → send-message-OA6MV4EU.js} +3 -3
  159. package/chunks/{serve-SRCBOJGP.js → serve-JMHMOYBO.js} +33 -32
  160. package/chunks/{server-QSQ45QFR.js → server-QIYIN34N.js} +1358 -492
  161. package/chunks/{session-5DG6NXHZ.js → session-BLL6HB35.js} +68 -65
  162. package/chunks/{settings-3EEQI4MN.js → settings-ABECXCTY.js} +30 -29
  163. package/chunks/{shell-B7FNYF5S.js → shell-A2TQI3U4.js} +26 -25
  164. package/chunks/{skill-AAOGHD5O.js → skill-4GTWZZWR.js} +10 -10
  165. package/chunks/{spawnChannel-3CBN3ZLK.js → spawnChannel-DFUVGP53.js} +30 -29
  166. package/chunks/{src-T5A7P7FS.js → src-ZORBMUM7.js} +77 -43
  167. package/chunks/{startInteractiveUI-2FGEQ6AS.js → startInteractiveUI-FH5MVXUE.js} +449 -175
  168. package/chunks/{syntheticOutput-YOSWIHDJ.js → syntheticOutput-F7LSDCAR.js} +3 -3
  169. package/chunks/{task-create-NHS2NGB3.js → task-create-RPFZNB4B.js} +7 -7
  170. package/chunks/{task-list-5UIB564R.js → task-list-TGGJX7EA.js} +5 -5
  171. package/chunks/{task-stop-HGXZ2VZ3.js → task-stop-W7NGTMYQ.js} +2 -2
  172. package/chunks/{task-update-IYYWUILG.js → task-update-5WUG5MVQ.js} +7 -7
  173. package/chunks/{team-create-KDF6W6PV.js → team-create-F76QOR6H.js} +26 -25
  174. package/chunks/{team-delete-FEKJCU4P.js → team-delete-UHQQ2QQX.js} +5 -5
  175. package/chunks/{team-plan-approval-PSFKQX7M.js → team-plan-approval-OKM7YZC2.js} +26 -25
  176. package/chunks/{theme-manager-5XOA2AO7.js → theme-manager-6R7EVWHW.js} +27 -26
  177. package/chunks/{todoWrite-TKMVZ2HT.js → todoWrite-C4ZAMSR3.js} +4 -4
  178. package/chunks/{tool-search-LFRILZXC.js → tool-search-UWXDKI7D.js} +9 -9
  179. package/chunks/{trustedFolders-7HQY6T6X.js → trustedFolders-DHASVVUP.js} +27 -26
  180. package/chunks/{validateNonInterActiveAuth-UC27B7BA.js → validateNonInterActiveAuth-56J7MOOP.js} +62 -59
  181. package/chunks/version-NE2I4PBN.js +10 -0
  182. package/chunks/{web-fetch-J4PIW36Q.js → web-fetch-UYGMOHW4.js} +5 -5
  183. package/chunks/{workflow-KUTESS6L.js → workflow-HGF3URV3.js} +35 -27
  184. package/chunks/{workspace-providers-status-LJT5AQDS.js → workspace-providers-status-KXB2OZFQ.js} +33 -32
  185. package/chunks/{workspace-service-YOBYVDXH.js → workspace-service-NSTI55BC.js} +39 -38
  186. package/chunks/workspace-skills-status-X5S6JGQZ.js +69 -0
  187. package/chunks/{write-file-FJYBZUHP.js → write-file-HVKT5VTX.js} +27 -26
  188. package/chunks/yargs-B64EYTCF.js +10 -0
  189. package/chunks/{zh-SLZNSSZB.js → zh-RS3HZHFH.js} +2 -0
  190. package/chunks/{zh-TW-P53C2SL5.js → zh-TW-L5GRQ4S4.js} +2 -0
  191. package/cli-entry.js +81 -8
  192. package/cli.js +348 -55
  193. package/locales/en.js +2 -0
  194. package/locales/zh-TW.js +2 -0
  195. package/locales/zh.js +2 -0
  196. package/node_modules/@qwen-code/audio-capture/package.json +1 -1
  197. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  198. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  199. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  200. package/package.json +3 -3
  201. package/web-shell/assets/{arc-D_rAuMDd.js → arc-Csx4m4N0.js} +1 -1
  202. package/web-shell/assets/{architectureDiagram-3BPJPVTR-DUCzbHVo.js → architectureDiagram-3BPJPVTR-BEa0vCM7.js} +1 -1
  203. package/web-shell/assets/{blockDiagram-GPEHLZMM-BEEBt1LL.js → blockDiagram-GPEHLZMM-BPzbKnn3.js} +1 -1
  204. package/web-shell/assets/{c4Diagram-AAUBKEIU-5ZJ_DeFL.js → c4Diagram-AAUBKEIU-B8YO71yP.js} +1 -1
  205. package/web-shell/assets/channel-QU1XUuVe.js +1 -0
  206. package/web-shell/assets/{chunk-2J33WTMH-Cfw7EiLn.js → chunk-2J33WTMH-32XhwSHt.js} +1 -1
  207. package/web-shell/assets/{chunk-4BX2VUAB-FGuZNCZY.js → chunk-4BX2VUAB-Bmoyo6PS.js} +1 -1
  208. package/web-shell/assets/{chunk-55IACEB6-CaBwYPBF.js → chunk-55IACEB6-TwH6PFhs.js} +1 -1
  209. package/web-shell/assets/{chunk-727SXJPM-BlR04OFz.js → chunk-727SXJPM-RI_IVUtZ.js} +1 -1
  210. package/web-shell/assets/{chunk-AQP2D5EJ-D3_mYJH5.js → chunk-AQP2D5EJ-DH6GIAZD.js} +1 -1
  211. package/web-shell/assets/{chunk-FMBD7UC4-7D4q4SbB.js → chunk-FMBD7UC4-DeD3k3D5.js} +1 -1
  212. package/web-shell/assets/{chunk-ND2GUHAM-BjX_Iwmr.js → chunk-ND2GUHAM-BLPb8nv3.js} +1 -1
  213. package/web-shell/assets/{chunk-QZHKN3VN-C3Hz_ZQh.js → chunk-QZHKN3VN-PZpyglW1.js} +1 -1
  214. package/web-shell/assets/classDiagram-4FO5ZUOK-fv1EWO-L.js +1 -0
  215. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-fv1EWO-L.js +1 -0
  216. package/web-shell/assets/{cose-bilkent-S5V4N54A-Ax4UycaT.js → cose-bilkent-S5V4N54A-Jsd0yKfz.js} +1 -1
  217. package/web-shell/assets/{dagre-BM42HDAG-C6hmPtGt.js → dagre-BM42HDAG-B-zADciZ.js} +1 -1
  218. package/web-shell/assets/{diagram-2AECGRRQ-tXZnxjmw.js → diagram-2AECGRRQ-Cn6GDxoo.js} +1 -1
  219. package/web-shell/assets/{diagram-5GNKFQAL-99dwIzQG.js → diagram-5GNKFQAL-udLgyJxO.js} +1 -1
  220. package/web-shell/assets/{diagram-KO2AKTUF-Bqhn0-2s.js → diagram-KO2AKTUF-EcLpfzy3.js} +1 -1
  221. package/web-shell/assets/{diagram-LMA3HP47-DzThVSvo.js → diagram-LMA3HP47-D-YFbYsJ.js} +1 -1
  222. package/web-shell/assets/{diagram-OG6HWLK6-DPE8vjln.js → diagram-OG6HWLK6-C8oRUATa.js} +1 -1
  223. package/web-shell/assets/{erDiagram-TEJ5UH35-KzUKgQCV.js → erDiagram-TEJ5UH35-DPH5nStc.js} +1 -1
  224. package/web-shell/assets/{flowDiagram-I6XJVG4X-DBN-DXw5.js → flowDiagram-I6XJVG4X-CSOTwkAt.js} +1 -1
  225. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DuBsP9u8.js → ganttDiagram-6RSMTGT7-D0L988t0.js} +1 -1
  226. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BjWHMyKR.js → gitGraphDiagram-PVQCEYII-B9Oo7gxS.js} +1 -1
  227. package/web-shell/assets/index-BYZZL5N7.css +5 -0
  228. package/web-shell/assets/index-C_oTyz0s.js +753 -0
  229. package/web-shell/assets/{infoDiagram-5YYISTIA-BVux0vP6.js → infoDiagram-5YYISTIA-Ddj4YN2P.js} +1 -1
  230. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-2qzw7f--.js → ishikawaDiagram-YF4QCWOH-CBjafcl7.js} +1 -1
  231. package/web-shell/assets/{journeyDiagram-JHISSGLW-Dnl65sxL.js → journeyDiagram-JHISSGLW-Bn3XD99u.js} +1 -1
  232. package/web-shell/assets/{kanban-definition-UN3LZRKU-BElSQYtY.js → kanban-definition-UN3LZRKU-D7PBPJmE.js} +1 -1
  233. package/web-shell/assets/{linear-BjoycSSY.js → linear-Bmfo22rZ.js} +1 -1
  234. package/web-shell/assets/{mermaid.core-xe6bvMRz.js → mermaid.core-xRkAI-EI.js} +5 -5
  235. package/web-shell/assets/{mindmap-definition-RKZ34NQL-D8DQgI4U.js → mindmap-definition-RKZ34NQL-B30zRinm.js} +1 -1
  236. package/web-shell/assets/{pieDiagram-4H26LBE5-Dwh7Gp7c.js → pieDiagram-4H26LBE5-DblnKR9Z.js} +1 -1
  237. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BXKNBln2.js → quadrantDiagram-W4KKPZXB-COkHFKjF.js} +1 -1
  238. package/web-shell/assets/{requirementDiagram-4Y6WPE33-BzaC3cIA.js → requirementDiagram-4Y6WPE33-DDU3MMyn.js} +1 -1
  239. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-DP2t7eZk.js → sankeyDiagram-5OEKKPKP-Dt4lqEYv.js} +1 -1
  240. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-XlFiWEYv.js → sequenceDiagram-3UESZ5HK-BRzby5gN.js} +1 -1
  241. package/web-shell/assets/{stateDiagram-AJRCARHV-CupgUMJO.js → stateDiagram-AJRCARHV-CylzByc3.js} +1 -1
  242. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BKWZIKkM.js +1 -0
  243. package/web-shell/assets/{timeline-definition-PNZ67QCA-DstuGywa.js → timeline-definition-PNZ67QCA-BSzaNx6w.js} +1 -1
  244. package/web-shell/assets/{vennDiagram-CIIHVFJN-CnbNp6zu.js → vennDiagram-CIIHVFJN-BbzeKzCo.js} +1 -1
  245. package/web-shell/assets/{wardley-L42UT6IY-DnvoHq6R.js → wardley-L42UT6IY-BRJwCgE_.js} +1 -1
  246. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Cz0xHEWB.js → wardleyDiagram-YWT4CUSO-BmAs0mJ-.js} +1 -1
  247. package/web-shell/assets/{xychartDiagram-2RQKCTM6-p36gfo88.js → xychartDiagram-2RQKCTM6-DqywSqVW.js} +1 -1
  248. package/web-shell/index.html +2 -2
  249. package/bundled/loop/SKILL.test.ts +0 -119
  250. package/bundled/loop/autonomous-loop.test.ts +0 -59
  251. package/bundled/loop/loop-task-file.test.ts +0 -1064
  252. package/bundled/loop/loop-tick-resolver.test.ts +0 -906
  253. package/chunks/chunk-EJ7BN3EN.js +0 -11396
  254. package/chunks/chunk-L7QPM2YD.js +0 -481
  255. package/chunks/daemon-status-provider-P72STMLB.js +0 -72
  256. package/chunks/nonInteractiveCli-6BYQSJTB.js +0 -109
  257. package/chunks/workspace-skills-status-ONEPXJV6.js +0 -62
  258. package/web-shell/assets/channel-B5ynH0q8.js +0 -1
  259. package/web-shell/assets/classDiagram-4FO5ZUOK-CK3ibywp.js +0 -1
  260. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CK3ibywp.js +0 -1
  261. package/web-shell/assets/index-9qfvU0_r.css +0 -5
  262. package/web-shell/assets/index-CWzDaQT5.js +0 -717
  263. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-By3E4QwN.js +0 -1
  264. package/chunks/{chunk-UFC57OYT.js → chunk-VRDMOSQS.js} +54 -54
@@ -0,0 +1,2472 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ require_undici
5
+ } from "./chunk-54YZOP7P.js";
6
+ import {
7
+ writeStderrLine
8
+ } from "./chunk-Y6Z2O3WR.js";
9
+ import {
10
+ getActiveGoal
11
+ } from "./chunk-WOG7QWIT.js";
12
+ import {
13
+ ToolNames
14
+ } from "./chunk-X3YGAX7V.js";
15
+ import {
16
+ createDebugLogger
17
+ } from "./chunk-22MNNNXE.js";
18
+ import {
19
+ init_esbuild_shims
20
+ } from "./chunk-A4BMJM77.js";
21
+ import {
22
+ __name,
23
+ __toESM
24
+ } from "./chunk-J2S4EL5Y.js";
25
+
26
+ // packages/cli/src/acp-integration/session/HistoryReplayer.ts
27
+ init_esbuild_shims();
28
+
29
+ // packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
30
+ init_esbuild_shims();
31
+
32
+ // packages/cli/src/acp-integration/session/emitters/BaseEmitter.ts
33
+ init_esbuild_shims();
34
+ var BaseEmitter = class {
35
+ constructor(ctx) {
36
+ this.ctx = ctx;
37
+ }
38
+ static {
39
+ __name(this, "BaseEmitter");
40
+ }
41
+ /**
42
+ * Converts an ISO timestamp string or epoch ms to epoch ms number.
43
+ * Returns undefined if the input is not a valid timestamp.
44
+ */
45
+ static toEpochMs(ts) {
46
+ if (typeof ts === "number") {
47
+ return Number.isFinite(ts) ? ts : void 0;
48
+ }
49
+ if (typeof ts === "string") {
50
+ const ms = new Date(ts).getTime();
51
+ return Number.isFinite(ms) ? ms : void 0;
52
+ }
53
+ return void 0;
54
+ }
55
+ /**
56
+ * Sends a session update to the ACP client.
57
+ * If a message rewriter is configured, updates pass through it first
58
+ * (original messages are sent as-is, rewritten versions are appended).
59
+ */
60
+ async sendUpdate(update) {
61
+ if (this.ctx.messageRewriter) {
62
+ return this.ctx.messageRewriter.interceptUpdate(update);
63
+ }
64
+ return this.ctx.sendUpdate(update);
65
+ }
66
+ /**
67
+ * Gets the session configuration.
68
+ */
69
+ get config() {
70
+ return this.ctx.config;
71
+ }
72
+ /**
73
+ * Gets the session ID.
74
+ */
75
+ get sessionId() {
76
+ return this.ctx.sessionId;
77
+ }
78
+ };
79
+
80
+ // packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
81
+ var MessageEmitter = class extends BaseEmitter {
82
+ static {
83
+ __name(this, "MessageEmitter");
84
+ }
85
+ /**
86
+ * Emits a StopHookLoop event when Stop hooks create a loop.
87
+ * This informs the client that Stop hooks have been executed multiple times.
88
+ *
89
+ * @param iterationCount - The current iteration count
90
+ * @param reasons - Array of reasons from each Stop hook execution
91
+ * @param stopHookCount - Number of Stop hooks that were executed
92
+ */
93
+ async emitStopHookLoop(iterationCount, reasons, stopHookCount) {
94
+ const activeGoal = getActiveGoal(this.sessionId);
95
+ await this.sendUpdate({
96
+ sessionUpdate: "agent_message_chunk",
97
+ content: { type: "text", text: "" },
98
+ _meta: {
99
+ stopHookLoop: {
100
+ iterationCount,
101
+ reasons,
102
+ stopHookCount,
103
+ ...activeGoal ? {
104
+ goal: {
105
+ condition: activeGoal.condition,
106
+ iterations: activeGoal.iterations,
107
+ setAt: activeGoal.setAt,
108
+ lastReason: activeGoal.lastReason
109
+ }
110
+ } : {}
111
+ }
112
+ }
113
+ });
114
+ }
115
+ async emitGoalTerminal(event) {
116
+ await this.sendUpdate({
117
+ sessionUpdate: "agent_message_chunk",
118
+ content: { type: "text", text: "" },
119
+ _meta: {
120
+ goalTerminal: event
121
+ }
122
+ });
123
+ }
124
+ async emitGoalStatus(status) {
125
+ await this.sendUpdate({
126
+ sessionUpdate: "agent_message_chunk",
127
+ content: { type: "text", text: "" },
128
+ _meta: {
129
+ goalStatus: status
130
+ }
131
+ });
132
+ }
133
+ /**
134
+ * Emits a user message chunk.
135
+ *
136
+ * @param text - The user message text content
137
+ * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
138
+ */
139
+ async emitUserMessage(text, timestamp) {
140
+ const epochMs = BaseEmitter.toEpochMs(timestamp);
141
+ await this.sendUpdate({
142
+ sessionUpdate: "user_message_chunk",
143
+ content: { type: "text", text },
144
+ ...epochMs != null && { _meta: { timestamp: epochMs } }
145
+ });
146
+ }
147
+ /**
148
+ * Emits an agent thought chunk.
149
+ *
150
+ * @param text - The thought text content
151
+ * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
152
+ */
153
+ async emitAgentThought(text, timestamp, subagentMeta) {
154
+ const _meta = this.buildChunkMeta(
155
+ BaseEmitter.toEpochMs(timestamp),
156
+ subagentMeta
157
+ );
158
+ await this.sendUpdate({
159
+ sessionUpdate: "agent_thought_chunk",
160
+ content: { type: "text", text },
161
+ ..._meta ? { _meta } : {}
162
+ });
163
+ }
164
+ /**
165
+ * Emits an agent message chunk.
166
+ *
167
+ * @param text - The agent message text content
168
+ * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
169
+ */
170
+ async emitAgentMessage(text, timestamp, subagentMeta) {
171
+ const _meta = this.buildChunkMeta(
172
+ BaseEmitter.toEpochMs(timestamp),
173
+ subagentMeta
174
+ );
175
+ await this.sendUpdate({
176
+ sessionUpdate: "agent_message_chunk",
177
+ content: { type: "text", text },
178
+ ..._meta ? { _meta } : {}
179
+ });
180
+ }
181
+ /**
182
+ * Emits usage metadata.
183
+ */
184
+ async emitUsageMetadata(usageMetadata, text = "", durationMs, subagentMeta) {
185
+ const usage = {
186
+ inputTokens: usageMetadata.promptTokenCount ?? 0,
187
+ outputTokens: usageMetadata.candidatesTokenCount ?? 0,
188
+ totalTokens: usageMetadata.totalTokenCount ?? 0,
189
+ thoughtTokens: usageMetadata.thoughtsTokenCount,
190
+ cachedReadTokens: usageMetadata.cachedContentTokenCount
191
+ };
192
+ const cumulative = this.ctx.cumulativeUsage;
193
+ if (cumulative) {
194
+ const addFinite = /* @__PURE__ */ __name((total, value) => typeof value === "number" && Number.isFinite(value) ? total + value : total, "addFinite");
195
+ cumulative.promptTokens = addFinite(
196
+ cumulative.promptTokens,
197
+ usage.inputTokens
198
+ );
199
+ cumulative.candidateTokens = addFinite(
200
+ cumulative.candidateTokens,
201
+ usage.outputTokens
202
+ );
203
+ cumulative.cachedTokens = addFinite(
204
+ cumulative.cachedTokens,
205
+ usage.cachedReadTokens
206
+ );
207
+ cumulative.apiTimeMs = addFinite(cumulative.apiTimeMs, durationMs);
208
+ }
209
+ const meta = typeof durationMs === "number" ? { usage, durationMs, ...subagentMeta } : { usage, ...subagentMeta };
210
+ await this.sendUpdate({
211
+ sessionUpdate: "agent_message_chunk",
212
+ content: { type: "text", text },
213
+ _meta: meta
214
+ });
215
+ }
216
+ /**
217
+ * Emits a message chunk based on role and thought flag.
218
+ * This is the unified method that handles all message types.
219
+ *
220
+ * @param text - The message text content
221
+ * @param role - Whether this is a user or assistant message
222
+ * @param isThought - Whether this is an assistant thought (only applies to assistant role)
223
+ * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
224
+ */
225
+ async emitMessage(text, role, isThought = false, timestamp, subagentMeta) {
226
+ if (role === "user") {
227
+ return this.emitUserMessage(text, timestamp);
228
+ }
229
+ return isThought ? this.emitAgentThought(text, timestamp, subagentMeta) : this.emitAgentMessage(text, timestamp, subagentMeta);
230
+ }
231
+ buildChunkMeta(epochMs, subagentMeta) {
232
+ const meta = {
233
+ ...subagentMeta?.parentToolCallId ? { parentToolCallId: subagentMeta.parentToolCallId } : {},
234
+ ...subagentMeta?.subagentType ? { subagentType: subagentMeta.subagentType } : {},
235
+ ...epochMs != null ? { timestamp: epochMs } : {}
236
+ };
237
+ return Object.keys(meta).length > 0 ? meta : void 0;
238
+ }
239
+ };
240
+
241
+ // packages/cli/src/acp-integration/session/emitters/ToolCallEmitter.ts
242
+ init_esbuild_shims();
243
+
244
+ // packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
245
+ init_esbuild_shims();
246
+ var PlanEmitter = class extends BaseEmitter {
247
+ static {
248
+ __name(this, "PlanEmitter");
249
+ }
250
+ /**
251
+ * Emits a plan update with the given todo items.
252
+ *
253
+ * @param todos - Array of todo items to send as plan entries
254
+ */
255
+ async emitPlan(todos) {
256
+ const entries = todos.map((todo) => ({
257
+ content: todo.content,
258
+ priority: "medium",
259
+ // Default priority since todos don't have priority
260
+ status: todo.status
261
+ }));
262
+ const cumulative = this.ctx.cumulativeUsage;
263
+ await this.sendUpdate({
264
+ sessionUpdate: "plan",
265
+ entries,
266
+ ...cumulative ? { _meta: { stats: { ...cumulative } } } : {}
267
+ });
268
+ }
269
+ /**
270
+ * Extracts todos from tool result display or args.
271
+ * Tries multiple sources in priority order:
272
+ * 1. Result display object with type 'todo_list'
273
+ * 2. Result display as JSON string
274
+ * 3. Args with 'todos' array
275
+ *
276
+ * @param resultDisplay - The tool result display (object, string, or undefined)
277
+ * @param args - The tool call arguments (fallback source)
278
+ * @returns Array of todos if found, null otherwise
279
+ */
280
+ extractTodos(resultDisplay, args) {
281
+ const fromDisplay = this.extractFromResultDisplay(resultDisplay);
282
+ if (fromDisplay) return fromDisplay;
283
+ if (args && Array.isArray(args["todos"])) {
284
+ return args["todos"];
285
+ }
286
+ return null;
287
+ }
288
+ /**
289
+ * Extracts todos from a result display value.
290
+ * Handles both object and JSON string formats.
291
+ */
292
+ extractFromResultDisplay(resultDisplay) {
293
+ if (!resultDisplay) return null;
294
+ if (typeof resultDisplay === "object") {
295
+ const obj = resultDisplay;
296
+ if (obj["type"] === "todo_list" && Array.isArray(obj["todos"])) {
297
+ return obj["todos"];
298
+ }
299
+ }
300
+ if (typeof resultDisplay === "string") {
301
+ try {
302
+ const parsed = JSON.parse(resultDisplay);
303
+ if (parsed?.["type"] === "todo_list" && Array.isArray(parsed["todos"])) {
304
+ return parsed["todos"];
305
+ }
306
+ } catch {
307
+ }
308
+ }
309
+ return null;
310
+ }
311
+ };
312
+
313
+ // packages/cli/src/utils/truncatedDiffPreview.ts
314
+ init_esbuild_shims();
315
+ function buildTruncatedDiffPreviewText(display) {
316
+ const fileName = typeof display["fileName"] === "string" ? display["fileName"] : "the edited file";
317
+ const fileDiffLength = typeof display["fileDiffLength"] === "number" ? ` Original fileDiff length: ${display["fileDiffLength"]} chars.` : "";
318
+ if (display["fileDiffTruncated"] === true) {
319
+ return `Full diff omitted from saved session history for ${fileName}.${fileDiffLength}`;
320
+ }
321
+ return `Saved session preview only for ${fileName}; full original and new file contents are unavailable.`;
322
+ }
323
+ __name(buildTruncatedDiffPreviewText, "buildTruncatedDiffPreviewText");
324
+
325
+ // packages/cli/src/acp-integration/session/emitters/ToolCallEmitter.ts
326
+ var KIND_MAP = {
327
+ ["read" /* Read */]: "read",
328
+ ["edit" /* Edit */]: "edit",
329
+ ["delete" /* Delete */]: "delete",
330
+ ["move" /* Move */]: "move",
331
+ ["search" /* Search */]: "search",
332
+ ["execute" /* Execute */]: "execute",
333
+ ["think" /* Think */]: "think",
334
+ ["fetch" /* Fetch */]: "fetch",
335
+ // ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
336
+ // 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
337
+ // and session/request_permission from the `qwen --acp` child before fanning out
338
+ // to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
339
+ // dropped. Map the internal Kind.Agent to 'other' on the wire to stay
340
+ // protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
341
+ // in a follow-up rather than via a kind the protocol can't carry.
342
+ ["agent" /* Agent */]: "other",
343
+ ["other" /* Other */]: "other"
344
+ };
345
+ var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
346
+ static {
347
+ __name(this, "ToolCallEmitter");
348
+ }
349
+ planEmitter;
350
+ constructor(ctx) {
351
+ super(ctx);
352
+ this.planEmitter = new PlanEmitter(ctx);
353
+ }
354
+ /**
355
+ * Emits a tool call start event.
356
+ *
357
+ * @param params - Tool call start parameters
358
+ * @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
359
+ */
360
+ async emitStart(params) {
361
+ if (this.isTodoWriteTool(params.toolName)) {
362
+ return false;
363
+ }
364
+ const { title, locations, kind } = this.resolveToolMetadata(
365
+ params.toolName,
366
+ params.args
367
+ );
368
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
369
+ params.toolName,
370
+ params.subagentMeta
371
+ );
372
+ await this.sendUpdate({
373
+ sessionUpdate: "tool_call",
374
+ toolCallId: params.callId,
375
+ status: params.status || "pending",
376
+ title,
377
+ content: [],
378
+ locations,
379
+ kind,
380
+ rawInput: params.args ?? {},
381
+ _meta: {
382
+ toolName: params.toolName,
383
+ ...params.subagentMeta,
384
+ provenance: provenance.provenance,
385
+ ...provenance.serverId ? { serverId: provenance.serverId } : {},
386
+ ...BaseEmitter.toEpochMs(params.timestamp) != null && {
387
+ timestamp: BaseEmitter.toEpochMs(params.timestamp)
388
+ }
389
+ }
390
+ });
391
+ return true;
392
+ }
393
+ /**
394
+ * Emits a tool call result event.
395
+ * Handles TodoWriteTool specially by routing to plan updates.
396
+ *
397
+ * @param params - Tool call result parameters
398
+ */
399
+ async emitResult(params) {
400
+ if (this.isTodoWriteTool(params.toolName)) {
401
+ const todos = this.planEmitter.extractTodos(
402
+ params.resultDisplay,
403
+ params.args
404
+ );
405
+ if (todos && todos.length > 0) {
406
+ await this.planEmitter.emitPlan(todos);
407
+ } else if (params.args && Array.isArray(params.args["todos"])) {
408
+ await this.planEmitter.emitPlan([]);
409
+ }
410
+ return;
411
+ }
412
+ let contentArray = [];
413
+ const diffContent = this.extractDiffContent(params.resultDisplay);
414
+ if (diffContent) {
415
+ contentArray = [diffContent];
416
+ } else if (params.error) {
417
+ contentArray = [
418
+ {
419
+ type: "content",
420
+ content: { type: "text", text: params.error.message }
421
+ }
422
+ ];
423
+ } else {
424
+ contentArray = this.transformPartsToToolCallContent(params.message);
425
+ }
426
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
427
+ params.toolName,
428
+ params.subagentMeta
429
+ );
430
+ const update = {
431
+ sessionUpdate: "tool_call_update",
432
+ toolCallId: params.callId,
433
+ status: params.success ? "completed" : "failed",
434
+ content: contentArray,
435
+ _meta: {
436
+ toolName: params.toolName,
437
+ ...params.subagentMeta,
438
+ provenance: provenance.provenance,
439
+ ...provenance.serverId ? { serverId: provenance.serverId } : {},
440
+ ...BaseEmitter.toEpochMs(params.timestamp) != null && {
441
+ timestamp: BaseEmitter.toEpochMs(params.timestamp)
442
+ },
443
+ ...params.artifacts && params.artifacts.length > 0 ? { artifacts: params.artifacts } : {}
444
+ }
445
+ };
446
+ if (params.resultDisplay !== void 0 && !this.isTruncatedSessionDiffDisplay(params.resultDisplay)) {
447
+ update["rawOutput"] = params.resultDisplay;
448
+ }
449
+ await this.sendUpdate(update);
450
+ }
451
+ /**
452
+ * Emits a tool call error event.
453
+ * Use this for explicit error handling when not using emitResult.
454
+ *
455
+ * @param callId - The tool call ID
456
+ * @param toolName - The tool name
457
+ * @param error - The error that occurred
458
+ * @param subagentMeta - Optional subagent metadata
459
+ */
460
+ async emitError(callId, toolName, error, subagentMeta) {
461
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
462
+ toolName,
463
+ subagentMeta
464
+ );
465
+ await this.sendUpdate({
466
+ sessionUpdate: "tool_call_update",
467
+ toolCallId: callId,
468
+ status: "failed",
469
+ content: [
470
+ { type: "content", content: { type: "text", text: error.message } }
471
+ ],
472
+ _meta: {
473
+ toolName,
474
+ ...subagentMeta,
475
+ provenance: provenance.provenance,
476
+ ...provenance.serverId ? { serverId: provenance.serverId } : {}
477
+ }
478
+ });
479
+ }
480
+ /**
481
+ * Resolve a tool's provenance for UI dispatch on tool_call events.
482
+ * The SDK reads `_meta.
483
+ * provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
484
+ * subagent-block differently. Without this stamping, the SDK falls
485
+ * back to string-matching the toolName which can't reliably
486
+ * distinguish builtin from subagent.
487
+ *
488
+ * Resolution rules:
489
+ * - `subagentMeta` present → `'subagent'` (a Task tool / Codex
490
+ * subagent / etc. wrapping its own tool calls)
491
+ * - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
492
+ * `serverId: <server>`. Naming convention from
493
+ * `packages/core/src/tools/mcp-tool.ts` in the
494
+ * `@qwen-code/qwen-code-core` package — mirrors the SDK's same
495
+ * heuristic fallback so SDK consumers stay consistent with
496
+ * daemon classification.
497
+ * - everything else → `'builtin'`
498
+ *
499
+ * Static + pure so it can be unit-tested without an emitter
500
+ * instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
501
+ */
502
+ static resolveToolProvenance(toolName, subagentMeta) {
503
+ if (subagentMeta !== void 0) {
504
+ return { provenance: "subagent" };
505
+ }
506
+ if (toolName.startsWith("mcp__")) {
507
+ const parts = toolName.split("__");
508
+ if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
509
+ return { provenance: "mcp", serverId: parts[1] };
510
+ }
511
+ }
512
+ return { provenance: "builtin" };
513
+ }
514
+ // ==================== Public Utilities ====================
515
+ /**
516
+ * Checks if a tool name is the TodoWriteTool.
517
+ * Exposed for external use in components that need to check this.
518
+ */
519
+ isTodoWriteTool(toolName) {
520
+ return toolName === ToolNames.TODO_WRITE;
521
+ }
522
+ /**
523
+ * Checks if a tool name is the ExitPlanModeTool.
524
+ */
525
+ isExitPlanModeTool(toolName) {
526
+ return toolName === ToolNames.EXIT_PLAN_MODE;
527
+ }
528
+ /**
529
+ * Checks if a tool name is the EnterPlanModeTool.
530
+ */
531
+ isEnterPlanModeTool(toolName) {
532
+ return toolName === ToolNames.ENTER_PLAN_MODE;
533
+ }
534
+ /**
535
+ * Resolves tool metadata from the registry.
536
+ * Falls back to defaults if tool not found or build fails.
537
+ *
538
+ * @param toolName - Name of the tool
539
+ * @param args - Tool call arguments (used to build invocation)
540
+ */
541
+ resolveToolMetadata(toolName, args) {
542
+ const toolRegistry = this.config.getToolRegistry();
543
+ const tool = toolRegistry.getTool(toolName);
544
+ let title = tool?.displayName ?? toolName;
545
+ let locations = [];
546
+ let kind = "other";
547
+ if (tool && args) {
548
+ try {
549
+ const invocation = tool.build(args);
550
+ title = `${title}: ${invocation.getDescription()}`;
551
+ locations = invocation.toolLocations().map((loc) => ({
552
+ path: loc.path,
553
+ line: loc.line ?? null
554
+ }));
555
+ kind = this.mapToolKind(tool.kind, toolName);
556
+ } catch {
557
+ if (typeof args["description"] === "string") {
558
+ title = `${title}: ${args["description"]}`;
559
+ }
560
+ if (tool.kind) {
561
+ kind = this.mapToolKind(tool.kind, toolName);
562
+ }
563
+ }
564
+ }
565
+ return { title, locations, kind };
566
+ }
567
+ /**
568
+ * Maps core Tool Kind enum to ACP ToolKind string literals.
569
+ *
570
+ * @param kind - The core Kind enum value
571
+ * @param toolName - Optional tool name to handle special cases like exit_plan_mode
572
+ */
573
+ mapToolKind(kind, toolName) {
574
+ if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
575
+ return "switch_mode";
576
+ }
577
+ return KIND_MAP[kind] ?? "other";
578
+ }
579
+ // ==================== Private Helpers ====================
580
+ /**
581
+ * Extracts diff content from resultDisplay if it's a diff type (edit tool result).
582
+ * Returns null if not a diff.
583
+ */
584
+ extractDiffContent(resultDisplay) {
585
+ if (!resultDisplay || typeof resultDisplay !== "object") return null;
586
+ const obj = resultDisplay;
587
+ if ("fileName" in obj && "newContent" in obj) {
588
+ if (this.isTruncatedSessionDiffDisplay(resultDisplay)) {
589
+ return {
590
+ type: "content",
591
+ content: {
592
+ type: "text",
593
+ text: buildTruncatedDiffPreviewText(obj)
594
+ }
595
+ };
596
+ }
597
+ return {
598
+ type: "diff",
599
+ path: obj["fileName"],
600
+ oldText: obj["originalContent"] ?? "",
601
+ newText: obj["newContent"]
602
+ };
603
+ }
604
+ return null;
605
+ }
606
+ isTruncatedSessionDiffDisplay(resultDisplay) {
607
+ if (!resultDisplay || typeof resultDisplay !== "object") return false;
608
+ const obj = resultDisplay;
609
+ return obj["truncatedForSession"] === true && "fileName" in obj && "newContent" in obj;
610
+ }
611
+ /**
612
+ * Transforms Part[] to ToolCallContent[].
613
+ * Extracts text from functionResponse parts and text parts.
614
+ */
615
+ transformPartsToToolCallContent(parts) {
616
+ const result = [];
617
+ for (const part of parts) {
618
+ if ("text" in part && part.text) {
619
+ result.push({
620
+ type: "content",
621
+ content: { type: "text", text: part.text }
622
+ });
623
+ }
624
+ if ("functionResponse" in part && part.functionResponse) {
625
+ try {
626
+ const resp = part.functionResponse.response;
627
+ const outputField = resp["output"];
628
+ const errorField = resp["error"];
629
+ const responseText = typeof outputField === "string" ? outputField : typeof errorField === "string" ? errorField : JSON.stringify(resp);
630
+ result.push({
631
+ type: "content",
632
+ content: { type: "text", text: responseText }
633
+ });
634
+ } catch {
635
+ }
636
+ }
637
+ }
638
+ return result;
639
+ }
640
+ };
641
+
642
+ // packages/cli/src/utils/chat-record-tool-call-id.ts
643
+ init_esbuild_shims();
644
+ function getToolResultCallId(record) {
645
+ return getExplicitToolResultCallId(record) ?? record.uuid;
646
+ }
647
+ __name(getToolResultCallId, "getToolResultCallId");
648
+ function getExplicitToolResultCallId(record) {
649
+ const resultCallId = record.toolCallResult?.callId;
650
+ if (typeof resultCallId === "string" && resultCallId.length > 0) {
651
+ return resultCallId;
652
+ }
653
+ return extractFunctionResponseId(record);
654
+ }
655
+ __name(getExplicitToolResultCallId, "getExplicitToolResultCallId");
656
+ function extractFunctionResponseId(record) {
657
+ if (!record.message?.parts) {
658
+ return void 0;
659
+ }
660
+ for (const part of record.message.parts) {
661
+ const id = "functionResponse" in part ? part.functionResponse?.id : void 0;
662
+ if (typeof id === "string" && id.length > 0) {
663
+ return id;
664
+ }
665
+ }
666
+ return void 0;
667
+ }
668
+ __name(extractFunctionResponseId, "extractFunctionResponseId");
669
+
670
+ // packages/cli/src/acp-integration/session/HistoryReplayer.ts
671
+ var MISSING_TOOL_RESULT_MESSAGE = "Tool result missing from saved history; the previous run likely ended before this tool completed.";
672
+ var HistoryReplayer = class {
673
+ static {
674
+ __name(this, "HistoryReplayer");
675
+ }
676
+ ctx;
677
+ messageEmitter;
678
+ toolCallEmitter;
679
+ pendingReplayToolCalls = /* @__PURE__ */ new Map();
680
+ constructor(ctx) {
681
+ this.ctx = ctx;
682
+ this.messageEmitter = new MessageEmitter(ctx);
683
+ this.toolCallEmitter = new ToolCallEmitter(ctx);
684
+ }
685
+ /**
686
+ * Replays all chat records from a loaded session.
687
+ *
688
+ * @param records - Array of chat records to replay
689
+ */
690
+ async replay(records) {
691
+ this.pendingReplayToolCalls.clear();
692
+ try {
693
+ let replayError;
694
+ try {
695
+ for (const record of records) {
696
+ await this.replayRecord(record);
697
+ }
698
+ } catch (error) {
699
+ replayError = error;
700
+ }
701
+ let danglingError;
702
+ try {
703
+ await this.failDanglingToolCalls();
704
+ } catch (error) {
705
+ danglingError = error;
706
+ }
707
+ if (replayError && danglingError) {
708
+ throw new AggregateError(
709
+ [replayError, danglingError],
710
+ "Replay and dangling-cleanup both failed"
711
+ );
712
+ }
713
+ if (replayError) {
714
+ throw replayError;
715
+ }
716
+ if (danglingError) {
717
+ throw danglingError;
718
+ }
719
+ } finally {
720
+ this.pendingReplayToolCalls.clear();
721
+ this.setActiveRecordId(null);
722
+ }
723
+ }
724
+ /**
725
+ * Replays a single chat record.
726
+ */
727
+ async replayRecord(record) {
728
+ this.setActiveRecordId(record.uuid, record.timestamp);
729
+ try {
730
+ switch (record.type) {
731
+ case "user":
732
+ if (record.subtype === "notification" || record.subtype === "cron") {
733
+ const displayText = record.systemPayload?.displayText;
734
+ if (displayText) {
735
+ await this.messageEmitter.emitUserMessage(
736
+ displayText,
737
+ record.timestamp
738
+ );
739
+ }
740
+ break;
741
+ }
742
+ if (record.subtype === "mid_turn_user_message") {
743
+ const displayText = record.systemPayload?.displayText;
744
+ if (displayText) {
745
+ await this.messageEmitter.emitUserMessage(
746
+ displayText,
747
+ record.timestamp
748
+ );
749
+ } else if (record.message) {
750
+ await this.replayContent(
751
+ record.message,
752
+ "user",
753
+ record.timestamp,
754
+ record.uuid
755
+ );
756
+ }
757
+ break;
758
+ }
759
+ if (record.message) {
760
+ await this.replayContent(
761
+ record.message,
762
+ "user",
763
+ record.timestamp,
764
+ record.uuid
765
+ );
766
+ }
767
+ break;
768
+ case "assistant":
769
+ if (record.message) {
770
+ await this.replayContent(
771
+ record.message,
772
+ "assistant",
773
+ record.timestamp,
774
+ record.uuid
775
+ );
776
+ }
777
+ if (record.usageMetadata) {
778
+ await this.replayUsageMetadata(record.usageMetadata);
779
+ }
780
+ break;
781
+ case "tool_result":
782
+ await this.replayToolResult(record);
783
+ break;
784
+ case "system":
785
+ if (record.subtype === "slash_command") {
786
+ await this.replaySlashCommandResult(record);
787
+ }
788
+ break;
789
+ default:
790
+ break;
791
+ }
792
+ } finally {
793
+ this.setActiveRecordId(null);
794
+ }
795
+ }
796
+ /**
797
+ * Replays content from a message (user or assistant).
798
+ * Handles text parts, thought parts, and function calls.
799
+ *
800
+ * @param content - The content to replay
801
+ * @param role - The role (user or assistant)
802
+ * @param timestamp - Optional server-side timestamp from the JSONL record
803
+ */
804
+ async replayContent(content, role, timestamp, recordId) {
805
+ for (const part of content.parts ?? []) {
806
+ if ("text" in part && part.text) {
807
+ const isThought = part.thought ?? false;
808
+ await this.messageEmitter.emitMessage(
809
+ part.text,
810
+ role,
811
+ isThought,
812
+ timestamp
813
+ );
814
+ }
815
+ if ("functionCall" in part && part.functionCall) {
816
+ const functionName = part.functionCall.name ?? "";
817
+ const sourceCallId = part.functionCall.id;
818
+ const callId = sourceCallId ?? `${functionName}-${Date.now()}`;
819
+ const emitted = await this.toolCallEmitter.emitStart({
820
+ toolName: functionName,
821
+ callId,
822
+ args: part.functionCall.args,
823
+ status: "in_progress",
824
+ timestamp
825
+ });
826
+ if (emitted && role === "assistant" && recordId && sourceCallId) {
827
+ this.pendingReplayToolCalls.set(callId, {
828
+ callId,
829
+ toolName: functionName,
830
+ timestamp,
831
+ recordId
832
+ });
833
+ }
834
+ }
835
+ }
836
+ }
837
+ /**
838
+ * Replays usage metadata.
839
+ * @param usageMetadata - The usage metadata to replay
840
+ */
841
+ async replayUsageMetadata(usageMetadata) {
842
+ await this.messageEmitter.emitUsageMetadata(usageMetadata);
843
+ }
844
+ /**
845
+ * Replays a tool result record.
846
+ */
847
+ async replayToolResult(record) {
848
+ if (!record.message?.parts) {
849
+ return;
850
+ }
851
+ const result = record.toolCallResult;
852
+ const callId = getToolResultCallId(record);
853
+ this.pendingReplayToolCalls.delete(callId);
854
+ const toolName = this.extractToolNameFromRecord(record);
855
+ await this.toolCallEmitter.emitResult({
856
+ toolName,
857
+ callId,
858
+ success: !result?.error,
859
+ message: record.message.parts,
860
+ resultDisplay: result?.resultDisplay,
861
+ // For TodoWriteTool fallback, try to extract args from the record
862
+ // Note: args aren't stored in tool_result records by default
863
+ args: void 0,
864
+ timestamp: record.timestamp
865
+ });
866
+ const { resultDisplay } = result ?? {};
867
+ if (!!resultDisplay && typeof resultDisplay === "object" && "type" in resultDisplay && resultDisplay.type === "task_execution") {
868
+ await this.emitTaskUsageFromResultDisplay(
869
+ resultDisplay
870
+ );
871
+ }
872
+ }
873
+ async failDanglingToolCalls() {
874
+ let firstError;
875
+ for (const pending of this.pendingReplayToolCalls.values()) {
876
+ this.setActiveRecordId(pending.recordId, pending.timestamp);
877
+ try {
878
+ await this.toolCallEmitter.emitResult({
879
+ toolName: pending.toolName,
880
+ callId: pending.callId,
881
+ success: false,
882
+ message: [],
883
+ error: new Error(MISSING_TOOL_RESULT_MESSAGE),
884
+ timestamp: pending.timestamp
885
+ });
886
+ } catch (error) {
887
+ firstError ??= error;
888
+ } finally {
889
+ this.setActiveRecordId(null);
890
+ }
891
+ }
892
+ if (firstError) {
893
+ throw firstError;
894
+ }
895
+ }
896
+ /**
897
+ * Emits token usage from a AgentResultDisplay execution summary, if present.
898
+ */
899
+ async emitTaskUsageFromResultDisplay(resultDisplay) {
900
+ const summary = resultDisplay.executionSummary;
901
+ if (!summary) {
902
+ return;
903
+ }
904
+ const usageMetadata = {};
905
+ if (Number.isFinite(summary.inputTokens)) {
906
+ usageMetadata.promptTokenCount = summary.inputTokens;
907
+ }
908
+ if (Number.isFinite(summary.outputTokens)) {
909
+ usageMetadata.candidatesTokenCount = summary.outputTokens;
910
+ }
911
+ if (Number.isFinite(summary.thoughtTokens)) {
912
+ usageMetadata.thoughtsTokenCount = summary.thoughtTokens;
913
+ }
914
+ if (Number.isFinite(summary.cachedTokens)) {
915
+ usageMetadata.cachedContentTokenCount = summary.cachedTokens;
916
+ }
917
+ if (Number.isFinite(summary.totalTokens)) {
918
+ usageMetadata.totalTokenCount = summary.totalTokens;
919
+ }
920
+ if (Object.keys(usageMetadata).length > 0) {
921
+ await this.messageEmitter.emitUsageMetadata(usageMetadata);
922
+ }
923
+ }
924
+ /**
925
+ * Replays a slash_command system record by re-emitting its output as an
926
+ * agent message chunk. This allows Zed to reconstruct the correct turn
927
+ * structure (user → agent) on session resume without polluting model context.
928
+ */
929
+ async replaySlashCommandResult(record) {
930
+ const payload = record.systemPayload;
931
+ if (payload?.phase !== "result" || !payload.outputHistoryItems?.length) {
932
+ return;
933
+ }
934
+ for (const item of payload.outputHistoryItems) {
935
+ const text = typeof item["text"] === "string" ? item["text"] : "";
936
+ if (text) {
937
+ await this.messageEmitter.emitAgentMessage(
938
+ text.replace(/\n/g, " \n"),
939
+ record.timestamp
940
+ );
941
+ }
942
+ }
943
+ }
944
+ /**
945
+ * Extracts tool name from a chat record's function response.
946
+ */
947
+ extractToolNameFromRecord(record) {
948
+ if (record.message?.parts) {
949
+ for (const part of record.message.parts) {
950
+ if ("functionResponse" in part && part.functionResponse?.name) {
951
+ return part.functionResponse.name;
952
+ }
953
+ }
954
+ }
955
+ return "";
956
+ }
957
+ setActiveRecordId(recordId, timestamp) {
958
+ const context = this.ctx;
959
+ if (typeof context.setActiveRecordId === "function") {
960
+ context.setActiveRecordId(recordId, timestamp);
961
+ }
962
+ }
963
+ };
964
+
965
+ // packages/cli/src/services/setup-github.ts
966
+ init_esbuild_shims();
967
+ var import_undici2 = __toESM(require_undici(), 1);
968
+ import { promises as fsp } from "node:fs";
969
+ import * as path from "node:path";
970
+
971
+ // packages/cli/src/utils/gitUtils.ts
972
+ init_esbuild_shims();
973
+ var import_undici = __toESM(require_undici(), 1);
974
+ import * as childProcess from "node:child_process";
975
+ var debugLogger = createDebugLogger("GIT");
976
+ async function runGit(args, opts = {}) {
977
+ return await new Promise((resolve2, reject) => {
978
+ childProcess.execFile(
979
+ "git",
980
+ args,
981
+ {
982
+ encoding: "utf-8",
983
+ ...opts.cwd ? { cwd: opts.cwd } : {}
984
+ },
985
+ (err, stdout) => {
986
+ if (err) {
987
+ reject(err);
988
+ return;
989
+ }
990
+ resolve2(String(stdout ?? "").trim());
991
+ }
992
+ );
993
+ });
994
+ }
995
+ __name(runGit, "runGit");
996
+ var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
997
+ try {
998
+ const remotes = await runGit(["remote", "-v"], opts);
999
+ return remotes.split("\n").some((line) => {
1000
+ const remoteUrl = line.trim().split(/\s+/)[1];
1001
+ return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
1002
+ });
1003
+ } catch (_error) {
1004
+ debugLogger.debug(`Failed to get git remote:`, _error);
1005
+ return false;
1006
+ }
1007
+ }, "isGitHubRepositoryAsync");
1008
+ function isGitHubRemoteUrl(remoteUrl) {
1009
+ if (remoteUrl.startsWith("git@github.com:")) {
1010
+ return true;
1011
+ }
1012
+ if (remoteUrl.startsWith("git@")) {
1013
+ return false;
1014
+ }
1015
+ try {
1016
+ return new URL(remoteUrl).hostname === "github.com";
1017
+ } catch {
1018
+ return false;
1019
+ }
1020
+ }
1021
+ __name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
1022
+ var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
1023
+ const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
1024
+ if (!gitRepoRoot) {
1025
+ throw new Error(`Git repo returned empty value`);
1026
+ }
1027
+ return gitRepoRoot;
1028
+ }, "getGitRepoRootAsync");
1029
+ var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
1030
+ try {
1031
+ const controller = new AbortController();
1032
+ const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
1033
+ const response = await fetch(endpoint, {
1034
+ method: "GET",
1035
+ headers: {
1036
+ Accept: "application/vnd.github+json",
1037
+ "Content-Type": "application/json",
1038
+ "X-GitHub-Api-Version": "2022-11-28"
1039
+ },
1040
+ dispatcher: proxy ? new import_undici.ProxyAgent(proxy) : void 0,
1041
+ signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
1042
+ });
1043
+ if (!response.ok) {
1044
+ throw new Error(
1045
+ `Invalid response code: ${response.status} - ${response.statusText}`
1046
+ );
1047
+ }
1048
+ const releaseTag = (await response.json()).tag_name;
1049
+ if (!releaseTag) {
1050
+ throw new Error(`Response did not include tag_name field`);
1051
+ }
1052
+ return releaseTag;
1053
+ } catch (_error) {
1054
+ debugLogger.debug(
1055
+ `Failed to determine latest qwen-code-action release:`,
1056
+ _error
1057
+ );
1058
+ throw new Error(
1059
+ `Unable to determine the latest qwen-code-action release on GitHub.`
1060
+ );
1061
+ }
1062
+ }, "getLatestGitHubRelease");
1063
+ async function getGitHubRepoInfoAsync(opts = {}) {
1064
+ return parseGitHubRepoInfo(
1065
+ await runGit(["remote", "get-url", "origin"], opts)
1066
+ );
1067
+ }
1068
+ __name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
1069
+ function parseGitHubRepoInfo(remoteUrl) {
1070
+ let urlToParse = remoteUrl;
1071
+ if (remoteUrl.startsWith("git@github.com:")) {
1072
+ urlToParse = remoteUrl.replace("git@github.com:", "");
1073
+ } else if (remoteUrl.startsWith("git@")) {
1074
+ throw new Error(
1075
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1076
+ );
1077
+ }
1078
+ let parsedUrl;
1079
+ try {
1080
+ parsedUrl = new URL(urlToParse, "https://github.com");
1081
+ } catch {
1082
+ throw new Error(
1083
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1084
+ );
1085
+ }
1086
+ if (parsedUrl.hostname !== "github.com") {
1087
+ throw new Error(
1088
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1089
+ );
1090
+ }
1091
+ const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
1092
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
1093
+ throw new Error(
1094
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1095
+ );
1096
+ }
1097
+ return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
1098
+ }
1099
+ __name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
1100
+
1101
+ // packages/cli/src/services/setup-github.ts
1102
+ var debugLogger2 = createDebugLogger("SETUP_GITHUB");
1103
+ var GITHUB_WORKFLOW_PATHS = [
1104
+ "qwen-dispatch/qwen-dispatch.yml",
1105
+ "qwen-assistant/qwen-invoke.yml",
1106
+ "issue-triage/qwen-triage.yml",
1107
+ "issue-triage/qwen-scheduled-triage.yml",
1108
+ "pr-review/qwen-review.yml"
1109
+ ];
1110
+ var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
1111
+ var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
1112
+ var SetupGithubError = class extends Error {
1113
+ static {
1114
+ __name(this, "SetupGithubError");
1115
+ }
1116
+ code;
1117
+ status;
1118
+ partial;
1119
+ partialResult;
1120
+ constructor(code, message, status, partialResult) {
1121
+ super(message);
1122
+ this.name = "SetupGithubError";
1123
+ this.code = code;
1124
+ this.status = status;
1125
+ this.partial = partialResult !== void 0;
1126
+ this.partialResult = partialResult;
1127
+ }
1128
+ };
1129
+ var nodeFileOps = {
1130
+ assertCanWrite() {
1131
+ },
1132
+ async ensureWorkflowDirectory(gitRepoRoot) {
1133
+ await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
1134
+ recursive: true
1135
+ });
1136
+ },
1137
+ async writeTextFile(gitRepoRoot, relativePath, content) {
1138
+ const target = path.join(gitRepoRoot, relativePath);
1139
+ await fsp.writeFile(target, content, { mode: 420 });
1140
+ return { sizeBytes: Buffer.byteLength(content, "utf8") };
1141
+ },
1142
+ async readTextFile(gitRepoRoot, relativePath) {
1143
+ try {
1144
+ return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
1145
+ } catch (error) {
1146
+ if (error.code === "ENOENT") {
1147
+ return void 0;
1148
+ }
1149
+ throw error;
1150
+ }
1151
+ }
1152
+ };
1153
+ async function setupGithub(options = {}) {
1154
+ const cwd = options.cwd ?? process.cwd();
1155
+ const fileOps = options.fileOps ?? nodeFileOps;
1156
+ if (!await isGitHubRepositoryAsync({ cwd })) {
1157
+ throw new SetupGithubError(
1158
+ "github_repository_not_found",
1159
+ "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
1160
+ 400
1161
+ );
1162
+ }
1163
+ let gitRepoRoot;
1164
+ try {
1165
+ gitRepoRoot = await getGitRepoRootAsync({ cwd });
1166
+ } catch (error) {
1167
+ debugLogger2.debug("Failed to get git repo root:", error);
1168
+ throw new SetupGithubError(
1169
+ "github_repository_not_found",
1170
+ "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
1171
+ 400
1172
+ );
1173
+ }
1174
+ if (options.workspaceRoot) {
1175
+ const [gitRootReal, workspaceReal] = await Promise.all([
1176
+ realpathOrResolve(gitRepoRoot),
1177
+ realpathOrResolve(options.workspaceRoot)
1178
+ ]);
1179
+ if (gitRootReal !== workspaceReal) {
1180
+ throw new SetupGithubError(
1181
+ "github_git_root_mismatch",
1182
+ "The Git repository root must match the daemon workspace root.",
1183
+ 400
1184
+ );
1185
+ }
1186
+ }
1187
+ fileOps.assertCanWrite?.();
1188
+ let releaseTag;
1189
+ try {
1190
+ releaseTag = await getLatestGitHubRelease(options.proxy);
1191
+ } catch (error) {
1192
+ writeStderrLine(
1193
+ `qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
1194
+ );
1195
+ debugLogger2.debug(
1196
+ "Failed to determine latest qwen-code-action release:",
1197
+ error
1198
+ );
1199
+ throw new SetupGithubError(
1200
+ "github_release_lookup_failed",
1201
+ "Unable to determine the latest qwen-code-action release on GitHub.",
1202
+ 502
1203
+ );
1204
+ }
1205
+ const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
1206
+ const secretsUrl = await resolveSecretsUrl(cwd);
1207
+ const downloads = await downloadWorkflows({
1208
+ releaseTag,
1209
+ proxy: options.proxy,
1210
+ abortSignal: options.abortSignal,
1211
+ fetchImpl: options.fetchImpl ?? fetch
1212
+ });
1213
+ const result = {
1214
+ kind: "github_setup",
1215
+ workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
1216
+ gitRepoRoot,
1217
+ releaseTag,
1218
+ readmeUrl,
1219
+ ...secretsUrl ? { secretsUrl } : {},
1220
+ workflows: [],
1221
+ gitignore: { path: ".gitignore", status: "skipped" },
1222
+ warnings: []
1223
+ };
1224
+ result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
1225
+ if (result.gitignore.status === "failed") {
1226
+ result.warnings.push("Failed to update .gitignore.");
1227
+ }
1228
+ try {
1229
+ await fileOps.ensureWorkflowDirectory(gitRepoRoot);
1230
+ for (const workflow of downloads) {
1231
+ const relativePath = path.posix.join(
1232
+ ".github",
1233
+ "workflows",
1234
+ path.posix.basename(workflow.sourcePath)
1235
+ );
1236
+ try {
1237
+ const write = await fileOps.writeTextFile(
1238
+ gitRepoRoot,
1239
+ relativePath,
1240
+ workflow.content
1241
+ );
1242
+ result.workflows.push({
1243
+ sourcePath: workflow.sourcePath,
1244
+ path: relativePath,
1245
+ status: "written",
1246
+ sizeBytes: write.sizeBytes
1247
+ });
1248
+ } catch (error) {
1249
+ result.partial = true;
1250
+ result.workflows.push({
1251
+ sourcePath: workflow.sourcePath,
1252
+ path: relativePath,
1253
+ status: "failed",
1254
+ error: error instanceof Error ? error.message : String(error)
1255
+ });
1256
+ throw new SetupGithubError(
1257
+ "github_workflow_write_failed",
1258
+ `Unable to write ${relativePath}.`,
1259
+ 500,
1260
+ result
1261
+ );
1262
+ }
1263
+ }
1264
+ } catch (error) {
1265
+ if (error instanceof SetupGithubError) throw error;
1266
+ throw new SetupGithubError(
1267
+ "github_workflow_write_failed",
1268
+ "Unable to create .github/workflows.",
1269
+ 500,
1270
+ result
1271
+ );
1272
+ }
1273
+ return result;
1274
+ }
1275
+ __name(setupGithub, "setupGithub");
1276
+ async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
1277
+ try {
1278
+ const existingContent = await fileOps.readTextFile(
1279
+ gitRepoRoot,
1280
+ ".gitignore"
1281
+ );
1282
+ if (existingContent === void 0) {
1283
+ const content = GITIGNORE_ENTRIES.join("\n") + "\n";
1284
+ await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
1285
+ return {
1286
+ path: ".gitignore",
1287
+ status: "created",
1288
+ added: [...GITIGNORE_ENTRIES]
1289
+ };
1290
+ }
1291
+ const missingEntries = GITIGNORE_ENTRIES.filter(
1292
+ (entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
1293
+ );
1294
+ if (missingEntries.length === 0) {
1295
+ return { path: ".gitignore", status: "unchanged" };
1296
+ }
1297
+ const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
1298
+ await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
1299
+ return {
1300
+ path: ".gitignore",
1301
+ status: "updated",
1302
+ added: missingEntries
1303
+ };
1304
+ } catch (error) {
1305
+ debugLogger2.debug("Failed to update .gitignore:", error);
1306
+ return {
1307
+ path: ".gitignore",
1308
+ status: "failed",
1309
+ error: error instanceof Error ? error.message : String(error)
1310
+ };
1311
+ }
1312
+ }
1313
+ __name(updateGitignore, "updateGitignore");
1314
+ async function downloadWorkflows(options) {
1315
+ const internalAbort = new AbortController();
1316
+ try {
1317
+ const dispatcher = options.proxy ? new import_undici2.ProxyAgent(options.proxy) : void 0;
1318
+ return await Promise.all(
1319
+ GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
1320
+ const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
1321
+ const response = await options.fetchImpl(endpoint, {
1322
+ method: "GET",
1323
+ dispatcher,
1324
+ signal: AbortSignal.any([
1325
+ AbortSignal.timeout(3e4),
1326
+ internalAbort.signal,
1327
+ ...options.abortSignal ? [options.abortSignal] : []
1328
+ ])
1329
+ });
1330
+ if (!response.ok) {
1331
+ throw new Error(
1332
+ `Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
1333
+ );
1334
+ }
1335
+ return {
1336
+ sourcePath: workflow,
1337
+ content: await readResponseTextWithLimit(response, workflow)
1338
+ };
1339
+ })
1340
+ );
1341
+ } catch (error) {
1342
+ internalAbort.abort();
1343
+ const message = error instanceof Error ? error.message : String(error);
1344
+ debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
1345
+ throw new SetupGithubError(
1346
+ "github_workflow_download_failed",
1347
+ `Unable to download qwen-code-action workflows from GitHub. ${message}`,
1348
+ 502
1349
+ );
1350
+ }
1351
+ }
1352
+ __name(downloadWorkflows, "downloadWorkflows");
1353
+ async function readResponseTextWithLimit(response, sourcePath) {
1354
+ const contentLength = response.headers.get("content-length");
1355
+ if (contentLength !== null) {
1356
+ const parsedLength = Number(contentLength);
1357
+ if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
1358
+ throw new Error(
1359
+ `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
1360
+ );
1361
+ }
1362
+ }
1363
+ if (!response.body) return "";
1364
+ const reader = response.body.getReader();
1365
+ const chunks = [];
1366
+ let totalBytes = 0;
1367
+ try {
1368
+ while (true) {
1369
+ const { done, value } = await reader.read();
1370
+ if (done) break;
1371
+ if (!value) continue;
1372
+ totalBytes += value.byteLength;
1373
+ if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
1374
+ await reader.cancel().catch(() => {
1375
+ });
1376
+ throw new Error(
1377
+ `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
1378
+ );
1379
+ }
1380
+ chunks.push(value);
1381
+ }
1382
+ } finally {
1383
+ reader.releaseLock();
1384
+ }
1385
+ const body = new Uint8Array(totalBytes);
1386
+ let offset = 0;
1387
+ for (const chunk of chunks) {
1388
+ body.set(chunk, offset);
1389
+ offset += chunk.byteLength;
1390
+ }
1391
+ return new TextDecoder().decode(body);
1392
+ }
1393
+ __name(readResponseTextWithLimit, "readResponseTextWithLimit");
1394
+ async function resolveSecretsUrl(cwd) {
1395
+ try {
1396
+ const repoInfo = await getGitHubRepoInfoAsync({ cwd });
1397
+ return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
1398
+ } catch {
1399
+ return void 0;
1400
+ }
1401
+ }
1402
+ __name(resolveSecretsUrl, "resolveSecretsUrl");
1403
+ async function realpathOrResolve(input) {
1404
+ try {
1405
+ return await fsp.realpath(input);
1406
+ } catch {
1407
+ return path.resolve(input);
1408
+ }
1409
+ }
1410
+ __name(realpathOrResolve, "realpathOrResolve");
1411
+
1412
+ // packages/cli/src/ui/utils/export/collect.ts
1413
+ init_esbuild_shims();
1414
+ import { randomUUID } from "node:crypto";
1415
+ function extractToolNameFromRecord(record) {
1416
+ if (!record.message?.parts) {
1417
+ return void 0;
1418
+ }
1419
+ for (const part of record.message.parts) {
1420
+ if ("functionResponse" in part && part.functionResponse?.name) {
1421
+ return part.functionResponse.name;
1422
+ }
1423
+ }
1424
+ return void 0;
1425
+ }
1426
+ __name(extractToolNameFromRecord, "extractToolNameFromRecord");
1427
+ function normalizeFunctionCallArgs(args) {
1428
+ if (args && typeof args === "object") {
1429
+ return args;
1430
+ }
1431
+ if (typeof args === "string") {
1432
+ try {
1433
+ const parsed = JSON.parse(args);
1434
+ if (parsed && typeof parsed === "object") {
1435
+ return parsed;
1436
+ }
1437
+ } catch {
1438
+ }
1439
+ }
1440
+ return void 0;
1441
+ }
1442
+ __name(normalizeFunctionCallArgs, "normalizeFunctionCallArgs");
1443
+ function buildToolCallArgsIndex(records) {
1444
+ const byId = /* @__PURE__ */ new Map();
1445
+ const byName = /* @__PURE__ */ new Map();
1446
+ for (const record of records) {
1447
+ if (record.type !== "assistant" || !record.message?.parts) continue;
1448
+ for (const part of record.message.parts) {
1449
+ if (!("functionCall" in part) || !part.functionCall?.name) continue;
1450
+ const normalizedArgs = normalizeFunctionCallArgs(part.functionCall.args);
1451
+ if (!normalizedArgs) continue;
1452
+ const toolName = part.functionCall.name;
1453
+ const callId = typeof part.functionCall.id === "string" ? part.functionCall.id : null;
1454
+ if (callId) {
1455
+ byId.set(callId, normalizedArgs);
1456
+ }
1457
+ const queue = byName.get(toolName) ?? [];
1458
+ queue.push(normalizedArgs);
1459
+ byName.set(toolName, queue);
1460
+ }
1461
+ }
1462
+ return { byId, byName };
1463
+ }
1464
+ __name(buildToolCallArgsIndex, "buildToolCallArgsIndex");
1465
+ function calculateFileStats(records) {
1466
+ const argsIndex = buildToolCallArgsIndex(records);
1467
+ const byNameCursor = /* @__PURE__ */ new Map();
1468
+ const stats = {
1469
+ filesWritten: 0,
1470
+ linesAdded: 0,
1471
+ linesRemoved: 0,
1472
+ writtenFilePaths: /* @__PURE__ */ new Set()
1473
+ };
1474
+ for (const record of records) {
1475
+ if (record.type !== "tool_result" || !record.toolCallResult) continue;
1476
+ const toolName = extractToolNameFromRecord(record);
1477
+ const callId = getExplicitToolResultCallId(record);
1478
+ const argsFromId = callId && argsIndex.byId.has(callId) ? argsIndex.byId.get(callId) : void 0;
1479
+ let args = argsFromId;
1480
+ if (!args && toolName) {
1481
+ const queue = argsIndex.byName.get(toolName);
1482
+ if (queue && queue.length > 0) {
1483
+ const cursor = byNameCursor.get(toolName) ?? 0;
1484
+ args = queue[cursor];
1485
+ byNameCursor.set(toolName, cursor + 1);
1486
+ }
1487
+ }
1488
+ const { resultDisplay } = record.toolCallResult;
1489
+ if (resultDisplay && typeof resultDisplay === "object" && "fileName" in resultDisplay) {
1490
+ const display = resultDisplay;
1491
+ const hasOriginalContent = "originalContent" in display;
1492
+ const hasNewContent = "newContent" in display;
1493
+ let filePath;
1494
+ if (typeof display.fileName === "string") {
1495
+ filePath = args?.["file_path"] || display.fileName;
1496
+ } else {
1497
+ filePath = "unknown";
1498
+ }
1499
+ if (hasOriginalContent || hasNewContent) {
1500
+ stats.filesWritten++;
1501
+ stats.writtenFilePaths.add(filePath);
1502
+ if (display.diffStat) {
1503
+ stats.linesAdded += display.diffStat.model_added_lines ?? 0;
1504
+ stats.linesRemoved += display.diffStat.model_removed_lines ?? 0;
1505
+ } else if (!display.truncatedForSession) {
1506
+ const oldText = String(display.originalContent ?? "");
1507
+ const newText = String(display.newContent ?? "");
1508
+ const oldLines = oldText.split("\n").filter((line) => line.length > 0).length;
1509
+ const newLines = newText.split("\n").filter((line) => line.length > 0).length;
1510
+ stats.linesAdded += newLines;
1511
+ stats.linesRemoved += oldLines;
1512
+ }
1513
+ }
1514
+ }
1515
+ }
1516
+ return stats;
1517
+ }
1518
+ __name(calculateFileStats, "calculateFileStats");
1519
+ function extractTaskToolTokens(record) {
1520
+ if (record.type !== "tool_result" || !record.toolCallResult?.resultDisplay) {
1521
+ return 0;
1522
+ }
1523
+ const { resultDisplay } = record.toolCallResult;
1524
+ if (typeof resultDisplay === "object" && "type" in resultDisplay && resultDisplay.type === "task_execution" && "executionSummary" in resultDisplay) {
1525
+ const summary = resultDisplay.executionSummary;
1526
+ if (typeof summary.totalTokens === "number") {
1527
+ return summary.totalTokens;
1528
+ }
1529
+ return (summary.inputTokens ?? 0) + (summary.outputTokens ?? 0) + (summary.thoughtTokens ?? 0) + (summary.cachedTokens ?? 0);
1530
+ }
1531
+ return 0;
1532
+ }
1533
+ __name(extractTaskToolTokens, "extractTaskToolTokens");
1534
+ function calculateTokenStats(records) {
1535
+ let totalTokens = 0;
1536
+ let lastValidRecord = null;
1537
+ for (const record of records) {
1538
+ if (record.type === "assistant") {
1539
+ if (record.usageMetadata) {
1540
+ totalTokens += record.usageMetadata.totalTokenCount ?? 0;
1541
+ }
1542
+ if (record.usageMetadata?.totalTokenCount !== void 0 && record.contextWindowSize !== void 0) {
1543
+ lastValidRecord = {
1544
+ totalTokenCount: record.usageMetadata.totalTokenCount,
1545
+ contextWindowSize: record.contextWindowSize
1546
+ };
1547
+ }
1548
+ }
1549
+ const taskTokens = extractTaskToolTokens(record);
1550
+ if (taskTokens > 0) {
1551
+ totalTokens += taskTokens;
1552
+ }
1553
+ }
1554
+ if (lastValidRecord) {
1555
+ const percent = lastValidRecord.totalTokenCount / lastValidRecord.contextWindowSize * 100;
1556
+ return {
1557
+ totalTokens,
1558
+ contextUsagePercent: Math.round(percent * 10) / 10,
1559
+ contextWindowSize: lastValidRecord.contextWindowSize
1560
+ };
1561
+ }
1562
+ const lastAssistantRecord = [...records].reverse().find((r) => r.type === "assistant" && r.contextWindowSize !== void 0);
1563
+ return {
1564
+ totalTokens,
1565
+ contextWindowSize: lastAssistantRecord?.contextWindowSize
1566
+ };
1567
+ }
1568
+ __name(calculateTokenStats, "calculateTokenStats");
1569
+ function createExportSessionConfig(config) {
1570
+ const supportedConfig = {
1571
+ ...config,
1572
+ getToolRegistry: /* @__PURE__ */ __name(() => {
1573
+ const registry = config.getToolRegistry?.();
1574
+ return {
1575
+ getTool: /* @__PURE__ */ __name((toolName) => registry?.getTool?.(toolName) ?? null, "getTool")
1576
+ };
1577
+ }, "getToolRegistry")
1578
+ };
1579
+ return new Proxy(supportedConfig, {
1580
+ get(target, prop, receiver) {
1581
+ if (prop in target) {
1582
+ return Reflect.get(target, prop, receiver);
1583
+ }
1584
+ if (typeof prop === "symbol") {
1585
+ return void 0;
1586
+ }
1587
+ throw new Error(
1588
+ `Export session replay config does not implement ${prop}`
1589
+ );
1590
+ }
1591
+ });
1592
+ }
1593
+ __name(createExportSessionConfig, "createExportSessionConfig");
1594
+ async function extractMetadata(conversation, config) {
1595
+ const { sessionId, startTime, messages } = conversation;
1596
+ const firstRecord = messages[0];
1597
+ const cwd = firstRecord?.cwd ?? "";
1598
+ const gitBranch = firstRecord?.gitBranch;
1599
+ let gitRepo;
1600
+ if (cwd) {
1601
+ const { getGitRepoName } = await import("./src-ZORBMUM7.js");
1602
+ gitRepo = getGitRepoName(cwd);
1603
+ }
1604
+ let model;
1605
+ for (const record of messages) {
1606
+ if (record.type === "assistant" && record.model) {
1607
+ model = record.model;
1608
+ break;
1609
+ }
1610
+ }
1611
+ const channel = config.getChannel?.();
1612
+ const promptCount = messages.filter((m) => m.type === "user").length;
1613
+ const fileStats = calculateFileStats(messages);
1614
+ const tokenStats = calculateTokenStats(messages);
1615
+ return {
1616
+ sessionId,
1617
+ startTime,
1618
+ exportTime: (/* @__PURE__ */ new Date()).toISOString(),
1619
+ cwd,
1620
+ gitRepo,
1621
+ gitBranch,
1622
+ model,
1623
+ channel,
1624
+ promptCount,
1625
+ contextUsagePercent: tokenStats.contextUsagePercent,
1626
+ contextWindowSize: tokenStats.contextWindowSize,
1627
+ totalTokens: tokenStats.totalTokens,
1628
+ filesWritten: fileStats.writtenFilePaths.size,
1629
+ linesAdded: fileStats.linesAdded,
1630
+ linesRemoved: fileStats.linesRemoved,
1631
+ uniqueFiles: Array.from(fileStats.writtenFilePaths)
1632
+ };
1633
+ }
1634
+ __name(extractMetadata, "extractMetadata");
1635
+ var ExportSessionContext = class {
1636
+ static {
1637
+ __name(this, "ExportSessionContext");
1638
+ }
1639
+ sessionId;
1640
+ config;
1641
+ messages = [];
1642
+ currentMessage = null;
1643
+ activeRecordId = null;
1644
+ activeRecordTimestamp = null;
1645
+ toolCallMap = /* @__PURE__ */ new Map();
1646
+ constructor(sessionId, config) {
1647
+ this.sessionId = sessionId;
1648
+ this.config = createExportSessionConfig(config);
1649
+ }
1650
+ async sendUpdate(update) {
1651
+ switch (update.sessionUpdate) {
1652
+ case "user_message_chunk":
1653
+ this.handleMessageChunk("user", update.content);
1654
+ break;
1655
+ case "agent_message_chunk": {
1656
+ const usageMeta = update._meta;
1657
+ const usageMetadata = usageMeta?.usage ? {
1658
+ promptTokenCount: usageMeta.usage.inputTokens,
1659
+ candidatesTokenCount: usageMeta.usage.outputTokens,
1660
+ totalTokenCount: usageMeta.usage.totalTokens,
1661
+ thoughtsTokenCount: usageMeta.usage.thoughtTokens,
1662
+ cachedContentTokenCount: usageMeta.usage.cachedReadTokens
1663
+ } : void 0;
1664
+ this.handleMessageChunk(
1665
+ "assistant",
1666
+ update.content,
1667
+ "assistant",
1668
+ usageMetadata
1669
+ );
1670
+ break;
1671
+ }
1672
+ case "agent_thought_chunk":
1673
+ this.handleMessageChunk("assistant", update.content, "thinking");
1674
+ break;
1675
+ case "tool_call":
1676
+ this.flushCurrentMessage();
1677
+ this.handleToolCallStart(update);
1678
+ break;
1679
+ case "tool_call_update":
1680
+ this.handleToolCallUpdate(update);
1681
+ break;
1682
+ case "plan":
1683
+ this.flushCurrentMessage();
1684
+ this.handlePlanUpdate(update);
1685
+ break;
1686
+ default:
1687
+ break;
1688
+ }
1689
+ }
1690
+ setActiveRecordId(recordId, timestamp) {
1691
+ this.activeRecordId = recordId;
1692
+ this.activeRecordTimestamp = timestamp ?? null;
1693
+ }
1694
+ getMessageTimestamp() {
1695
+ return this.activeRecordTimestamp ?? (/* @__PURE__ */ new Date()).toISOString();
1696
+ }
1697
+ getMessageUuid() {
1698
+ return this.activeRecordId ?? randomUUID();
1699
+ }
1700
+ handleMessageChunk(role, content, messageRole = role, usageMetadata) {
1701
+ if (content.type !== "text" || !content.text) return;
1702
+ if (this.currentMessage && (this.currentMessage.type !== role || this.currentMessage.role !== messageRole)) {
1703
+ this.flushCurrentMessage();
1704
+ }
1705
+ if (this.currentMessage && this.currentMessage.type === role && this.currentMessage.role === messageRole) {
1706
+ this.currentMessage.parts.push({ text: content.text });
1707
+ if (usageMetadata && role === "assistant") {
1708
+ this.currentMessage.usageMetadata = usageMetadata;
1709
+ }
1710
+ } else {
1711
+ this.currentMessage = {
1712
+ type: role,
1713
+ role: messageRole,
1714
+ parts: [{ text: content.text }],
1715
+ timestamp: Date.now(),
1716
+ ...usageMetadata && role === "assistant" ? { usageMetadata } : {}
1717
+ };
1718
+ }
1719
+ }
1720
+ handleToolCallStart(update) {
1721
+ const toolCall = {
1722
+ toolCallId: update.toolCallId,
1723
+ kind: update.kind || "other",
1724
+ title: typeof update.title === "string" ? update.title : update.title || "",
1725
+ status: update.status || "pending",
1726
+ rawInput: update.rawInput,
1727
+ locations: update.locations,
1728
+ timestamp: Date.now()
1729
+ };
1730
+ this.toolCallMap.set(update.toolCallId, toolCall);
1731
+ const uuid = this.getMessageUuid();
1732
+ this.messages.push({
1733
+ uuid,
1734
+ sessionId: this.sessionId,
1735
+ timestamp: this.getMessageTimestamp(),
1736
+ type: "tool_call",
1737
+ toolCall
1738
+ });
1739
+ }
1740
+ handleToolCallUpdate(update) {
1741
+ const toolCall = this.toolCallMap.get(update.toolCallId);
1742
+ if (toolCall) {
1743
+ if (update.status) toolCall.status = update.status;
1744
+ if (update.content) toolCall.content = update.content;
1745
+ if (update.title)
1746
+ toolCall.title = typeof update.title === "string" ? update.title : "";
1747
+ }
1748
+ }
1749
+ handlePlanUpdate(update) {
1750
+ const uuid = this.getMessageUuid();
1751
+ const timestamp = this.getMessageTimestamp();
1752
+ const todoText = update.entries.map((entry) => {
1753
+ const checkbox = entry.status === "completed" ? "[x]" : entry.status === "in_progress" ? "[-]" : "[ ]";
1754
+ return `- ${checkbox} ${entry.content}`;
1755
+ }).join("\n");
1756
+ const todoContent = [
1757
+ {
1758
+ type: "content",
1759
+ content: {
1760
+ type: "text",
1761
+ text: todoText
1762
+ }
1763
+ }
1764
+ ];
1765
+ this.messages.push({
1766
+ uuid,
1767
+ sessionId: this.sessionId,
1768
+ timestamp,
1769
+ type: "tool_call",
1770
+ toolCall: {
1771
+ toolCallId: uuid,
1772
+ // Use the same uuid as toolCallId for plan updates
1773
+ kind: "todowrite",
1774
+ title: "TodoList",
1775
+ status: "completed",
1776
+ content: todoContent,
1777
+ timestamp: Date.parse(timestamp)
1778
+ }
1779
+ });
1780
+ }
1781
+ flushCurrentMessage() {
1782
+ if (!this.currentMessage) return;
1783
+ const uuid = this.getMessageUuid();
1784
+ const exportMessage = {
1785
+ uuid,
1786
+ sessionId: this.sessionId,
1787
+ timestamp: this.getMessageTimestamp(),
1788
+ type: this.currentMessage.type,
1789
+ message: {
1790
+ role: this.currentMessage.role,
1791
+ parts: this.currentMessage.parts
1792
+ }
1793
+ };
1794
+ if (this.currentMessage.type === "assistant" && this.currentMessage.usageMetadata) {
1795
+ exportMessage.usageMetadata = this.currentMessage.usageMetadata;
1796
+ }
1797
+ this.messages.push(exportMessage);
1798
+ this.currentMessage = null;
1799
+ }
1800
+ flushMessages() {
1801
+ this.flushCurrentMessage();
1802
+ }
1803
+ getMessages() {
1804
+ return this.messages;
1805
+ }
1806
+ };
1807
+ async function collectSessionData(conversation, config) {
1808
+ const exportContext = new ExportSessionContext(
1809
+ conversation.sessionId,
1810
+ config
1811
+ );
1812
+ const replayer = new HistoryReplayer(exportContext);
1813
+ await replayer.replay(conversation.messages);
1814
+ exportContext.flushMessages();
1815
+ const messages = exportContext.getMessages();
1816
+ const metadata = await extractMetadata(conversation, config);
1817
+ return {
1818
+ sessionId: conversation.sessionId,
1819
+ startTime: conversation.startTime,
1820
+ messages,
1821
+ metadata
1822
+ };
1823
+ }
1824
+ __name(collectSessionData, "collectSessionData");
1825
+
1826
+ // packages/cli/src/ui/utils/export/normalize.ts
1827
+ init_esbuild_shims();
1828
+ function normalizeSessionData(sessionData, originalRecords, config) {
1829
+ const normalized = [...sessionData.messages];
1830
+ const toolCallIndexById = /* @__PURE__ */ new Map();
1831
+ normalized.forEach((message, index) => {
1832
+ if (message.type === "tool_call" && message.toolCall?.toolCallId) {
1833
+ toolCallIndexById.set(message.toolCall.toolCallId, index);
1834
+ }
1835
+ });
1836
+ const assistantMessageIndexByUuid = /* @__PURE__ */ new Map();
1837
+ normalized.forEach((message, index) => {
1838
+ if (message.type === "assistant") {
1839
+ assistantMessageIndexByUuid.set(message.uuid, index);
1840
+ }
1841
+ });
1842
+ for (const record of originalRecords) {
1843
+ if (record.type !== "tool_result") continue;
1844
+ const toolCallMessage = buildToolCallMessageFromResult(record, config);
1845
+ if (!toolCallMessage?.toolCall) continue;
1846
+ const existingIndex = toolCallIndexById.get(
1847
+ toolCallMessage.toolCall.toolCallId
1848
+ );
1849
+ if (existingIndex === void 0) {
1850
+ toolCallIndexById.set(
1851
+ toolCallMessage.toolCall.toolCallId,
1852
+ normalized.length
1853
+ );
1854
+ normalized.push(toolCallMessage);
1855
+ continue;
1856
+ }
1857
+ const existingMessage = normalized[existingIndex];
1858
+ if (existingMessage.type !== "tool_call" || !existingMessage.toolCall) {
1859
+ continue;
1860
+ }
1861
+ mergeToolCallData(existingMessage.toolCall, toolCallMessage.toolCall);
1862
+ }
1863
+ for (const record of originalRecords) {
1864
+ if (record.type !== "assistant") continue;
1865
+ if (!record.usageMetadata) continue;
1866
+ const existingIndex = assistantMessageIndexByUuid.get(record.uuid);
1867
+ if (existingIndex !== void 0) {
1868
+ if (!normalized[existingIndex].usageMetadata) {
1869
+ normalized[existingIndex].usageMetadata = record.usageMetadata;
1870
+ }
1871
+ }
1872
+ }
1873
+ return {
1874
+ ...sessionData,
1875
+ messages: normalized
1876
+ };
1877
+ }
1878
+ __name(normalizeSessionData, "normalizeSessionData");
1879
+ function mergeToolCallData(existing, incoming) {
1880
+ if (!existing.content || existing.content.length === 0) {
1881
+ existing.content = incoming.content;
1882
+ }
1883
+ if (existing.status === "pending" || existing.status === "in_progress") {
1884
+ existing.status = incoming.status;
1885
+ }
1886
+ if (!existing.rawInput && incoming.rawInput) {
1887
+ existing.rawInput = incoming.rawInput;
1888
+ }
1889
+ if (!existing.kind || existing.kind === "other") {
1890
+ existing.kind = incoming.kind;
1891
+ }
1892
+ if ((!existing.title || existing.title === "") && incoming.title) {
1893
+ existing.title = incoming.title;
1894
+ }
1895
+ if ((!existing.locations || existing.locations.length === 0) && incoming.locations && incoming.locations.length > 0) {
1896
+ existing.locations = incoming.locations;
1897
+ }
1898
+ }
1899
+ __name(mergeToolCallData, "mergeToolCallData");
1900
+ function buildToolCallMessageFromResult(record, config) {
1901
+ const toolCallResult = record.toolCallResult;
1902
+ const toolName = extractToolNameFromRecord2(record);
1903
+ if (toolName === ToolNames.TODO_WRITE) {
1904
+ return null;
1905
+ }
1906
+ const toolCallId = getToolResultCallId(record);
1907
+ const functionCallArgs = extractFunctionCallArgs(record);
1908
+ const { kind, title, locations } = resolveToolMetadata(
1909
+ config,
1910
+ toolName,
1911
+ functionCallArgs ?? toolCallResult?.args
1912
+ );
1913
+ const rawInput = normalizeRawInput(
1914
+ functionCallArgs ?? toolCallResult?.args
1915
+ );
1916
+ const content = extractDiffContent(toolCallResult?.resultDisplay) ?? transformPartsToToolCallContent(record.message?.parts ?? []);
1917
+ return {
1918
+ uuid: record.uuid,
1919
+ parentUuid: record.parentUuid,
1920
+ sessionId: record.sessionId,
1921
+ timestamp: record.timestamp,
1922
+ type: "tool_call",
1923
+ toolCall: {
1924
+ toolCallId,
1925
+ kind,
1926
+ title,
1927
+ status: toolCallResult?.error ? "failed" : "completed",
1928
+ rawInput,
1929
+ content,
1930
+ locations,
1931
+ timestamp: Date.parse(record.timestamp)
1932
+ }
1933
+ };
1934
+ }
1935
+ __name(buildToolCallMessageFromResult, "buildToolCallMessageFromResult");
1936
+ function extractToolNameFromRecord2(record) {
1937
+ if (!record.message?.parts) {
1938
+ return "";
1939
+ }
1940
+ for (const part of record.message.parts) {
1941
+ if ("functionResponse" in part && part.functionResponse?.name) {
1942
+ return part.functionResponse.name;
1943
+ }
1944
+ }
1945
+ return "";
1946
+ }
1947
+ __name(extractToolNameFromRecord2, "extractToolNameFromRecord");
1948
+ function extractFunctionCallArgs(record) {
1949
+ if (!record.message?.parts) {
1950
+ return void 0;
1951
+ }
1952
+ for (const part of record.message.parts) {
1953
+ if ("functionCall" in part && part.functionCall?.args) {
1954
+ return part.functionCall.args;
1955
+ }
1956
+ }
1957
+ return void 0;
1958
+ }
1959
+ __name(extractFunctionCallArgs, "extractFunctionCallArgs");
1960
+ function resolveToolMetadata(config, toolName, args) {
1961
+ const toolRegistry = config.getToolRegistry?.();
1962
+ const tool = toolName ? toolRegistry?.getTool?.(toolName) : void 0;
1963
+ let title = tool?.displayName ?? toolName ?? "tool_call";
1964
+ let locations;
1965
+ const kind = mapToolKind(tool?.kind, toolName);
1966
+ if (tool?.build && args) {
1967
+ try {
1968
+ const invocation = tool.build(args);
1969
+ title = `${title}: ${invocation.getDescription()}`;
1970
+ locations = invocation.toolLocations().map((loc) => ({
1971
+ path: loc.path,
1972
+ line: loc.line ?? null
1973
+ }));
1974
+ } catch {
1975
+ }
1976
+ }
1977
+ return { kind, title, locations };
1978
+ }
1979
+ __name(resolveToolMetadata, "resolveToolMetadata");
1980
+ function mapToolKind(kind, toolName) {
1981
+ if (toolName && (toolName === ToolNames.EXIT_PLAN_MODE || toolName === ToolNames.ENTER_PLAN_MODE)) {
1982
+ return "switch_mode";
1983
+ }
1984
+ if (toolName && toolName === ToolNames.TODO_WRITE) {
1985
+ return "todowrite";
1986
+ }
1987
+ const allowedKinds = /* @__PURE__ */ new Set([
1988
+ "read",
1989
+ "edit",
1990
+ "delete",
1991
+ "move",
1992
+ "search",
1993
+ "execute",
1994
+ "think",
1995
+ "fetch",
1996
+ "other"
1997
+ ]);
1998
+ if (kind && allowedKinds.has(kind)) {
1999
+ return kind;
2000
+ }
2001
+ return "other";
2002
+ }
2003
+ __name(mapToolKind, "mapToolKind");
2004
+ function extractDiffContent(resultDisplay) {
2005
+ if (!resultDisplay || typeof resultDisplay !== "object") {
2006
+ return null;
2007
+ }
2008
+ const display = resultDisplay;
2009
+ if ("fileName" in display && "newContent" in display) {
2010
+ if (display["truncatedForSession"] === true) {
2011
+ return [
2012
+ {
2013
+ type: "content",
2014
+ content: {
2015
+ type: "text",
2016
+ text: buildTruncatedDiffPreviewText(display)
2017
+ }
2018
+ }
2019
+ ];
2020
+ }
2021
+ return [
2022
+ {
2023
+ type: "diff",
2024
+ path: display["fileName"],
2025
+ oldText: display["originalContent"] ?? "",
2026
+ newText: display["newContent"]
2027
+ }
2028
+ ];
2029
+ }
2030
+ return null;
2031
+ }
2032
+ __name(extractDiffContent, "extractDiffContent");
2033
+ function normalizeRawInput(value) {
2034
+ if (typeof value === "string") return value;
2035
+ if (typeof value === "object" && value !== null) return value;
2036
+ return void 0;
2037
+ }
2038
+ __name(normalizeRawInput, "normalizeRawInput");
2039
+ function transformPartsToToolCallContent(parts) {
2040
+ const content = [];
2041
+ for (const part of parts) {
2042
+ if ("text" in part && part.text) {
2043
+ content.push({
2044
+ type: "content",
2045
+ content: { type: "text", text: part.text }
2046
+ });
2047
+ continue;
2048
+ }
2049
+ if ("functionResponse" in part && part.functionResponse) {
2050
+ const response = part.functionResponse.response;
2051
+ const outputField = response?.["output"];
2052
+ const errorField = response?.["error"];
2053
+ const responseText = typeof outputField === "string" ? outputField : typeof errorField === "string" ? errorField : JSON.stringify(response);
2054
+ content.push({
2055
+ type: "content",
2056
+ content: { type: "text", text: responseText }
2057
+ });
2058
+ }
2059
+ }
2060
+ return content;
2061
+ }
2062
+ __name(transformPartsToToolCallContent, "transformPartsToToolCallContent");
2063
+
2064
+ // packages/cli/src/ui/utils/export/formatters/markdown.ts
2065
+ init_esbuild_shims();
2066
+ function toMarkdown(sessionData) {
2067
+ const lines = [];
2068
+ const metadata = sessionData.metadata;
2069
+ lines.push("# Chat Session Export\n");
2070
+ lines.push(`- **Session ID**: \`${sanitizeText(sessionData.sessionId)}\``);
2071
+ lines.push(`- **Start Time**: ${sanitizeText(sessionData.startTime)}`);
2072
+ lines.push(
2073
+ `- **Exported**: ${sanitizeText(metadata?.exportTime ?? (/* @__PURE__ */ new Date()).toISOString())}`
2074
+ );
2075
+ lines.push("");
2076
+ if (metadata?.cwd) {
2077
+ lines.push(`- **Working Directory**: \`${sanitizeText(metadata.cwd)}\``);
2078
+ }
2079
+ if (metadata?.gitRepo) {
2080
+ lines.push(`- **Git Repository**: ${sanitizeText(metadata.gitRepo)}`);
2081
+ }
2082
+ if (metadata?.gitBranch) {
2083
+ lines.push(`- **Git Branch**: \`${sanitizeText(metadata.gitBranch)}\``);
2084
+ }
2085
+ lines.push("");
2086
+ if (metadata?.model) {
2087
+ lines.push(`- **Model**: ${sanitizeText(metadata.model)}`);
2088
+ }
2089
+ if (metadata?.channel) {
2090
+ lines.push(`- **Channel**: ${sanitizeText(metadata.channel)}`);
2091
+ }
2092
+ if (metadata?.promptCount !== void 0) {
2093
+ lines.push(`- **Prompt Count**: ${metadata.promptCount}`);
2094
+ }
2095
+ lines.push("");
2096
+ if (metadata?.totalTokens !== void 0) {
2097
+ lines.push(`- **Total Tokens**: ${metadata.totalTokens}`);
2098
+ }
2099
+ if (metadata?.contextWindowSize !== void 0) {
2100
+ lines.push(`- **Context Window Size**: ${metadata.contextWindowSize}`);
2101
+ }
2102
+ if (metadata?.contextUsagePercent !== void 0) {
2103
+ lines.push(`- **Context Usage**: ${metadata.contextUsagePercent}%`);
2104
+ }
2105
+ lines.push("");
2106
+ if (metadata?.filesWritten !== void 0) {
2107
+ lines.push(`- **Files Written**: ${metadata.filesWritten}`);
2108
+ }
2109
+ if (metadata?.linesAdded !== void 0) {
2110
+ lines.push(`- **Lines Added**: ${metadata.linesAdded}`);
2111
+ }
2112
+ if (metadata?.linesRemoved !== void 0) {
2113
+ lines.push(`- **Lines Removed**: ${metadata.linesRemoved}`);
2114
+ }
2115
+ if (metadata?.uniqueFiles && metadata.uniqueFiles.length > 0) {
2116
+ lines.push("");
2117
+ lines.push("<details>");
2118
+ lines.push(
2119
+ `<summary><strong>Unique Files Referenced (${metadata.uniqueFiles.length})</strong></summary>`
2120
+ );
2121
+ lines.push("");
2122
+ for (const file of metadata.uniqueFiles) {
2123
+ lines.push(`- \`${sanitizeText(file)}\``);
2124
+ }
2125
+ lines.push("</details>");
2126
+ }
2127
+ lines.push("\n---\n");
2128
+ for (const message of sessionData.messages) {
2129
+ if (message.type === "user") {
2130
+ lines.push("## User\n");
2131
+ lines.push(formatMessageContent(message));
2132
+ } else if (message.type === "assistant") {
2133
+ lines.push("## Assistant\n");
2134
+ lines.push(formatMessageContent(message));
2135
+ } else if (message.type === "tool_call") {
2136
+ lines.push(formatToolCall(message));
2137
+ } else if (message.type === "system") {
2138
+ lines.push("### System\n");
2139
+ const text = formatMessageContent(message);
2140
+ lines.push(`> ${text.replace(/\n/g, "\n> ")}`);
2141
+ }
2142
+ lines.push("\n");
2143
+ }
2144
+ return lines.join("\n");
2145
+ }
2146
+ __name(toMarkdown, "toMarkdown");
2147
+ function formatMessageContent(message) {
2148
+ const text = extractTextFromMessage(message);
2149
+ const processedText = text.replace(
2150
+ /--- Content from referenced files ---\n([\s\S]*?)\n--- End of content ---/g,
2151
+ (match, content) => `
2152
+ > **Referenced Files:**
2153
+
2154
+ ${createCodeBlock(content)}
2155
+ `
2156
+ );
2157
+ return processedText;
2158
+ }
2159
+ __name(formatMessageContent, "formatMessageContent");
2160
+ function formatToolCall(message) {
2161
+ if (!message.toolCall) return "";
2162
+ const lines = [];
2163
+ const { title, status, rawInput, content, locations } = message.toolCall;
2164
+ const titleStr = typeof title === "string" ? title : JSON.stringify(title);
2165
+ lines.push(`### Tool: ${sanitizeText(titleStr)}`);
2166
+ lines.push(`**Status**: ${sanitizeText(status)}
2167
+ `);
2168
+ if (rawInput) {
2169
+ lines.push("**Input:**");
2170
+ const inputStr = typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput, null, 2);
2171
+ lines.push(createCodeBlock(inputStr, "json"));
2172
+ lines.push("");
2173
+ }
2174
+ if (locations && locations.length > 0) {
2175
+ lines.push("**Affected Files:**");
2176
+ for (const loc of locations) {
2177
+ const lineSuffix = loc.line ? `:${loc.line}` : "";
2178
+ lines.push(`- \`${sanitizeText(loc.path)}${lineSuffix}\``);
2179
+ }
2180
+ lines.push("");
2181
+ }
2182
+ if (content && content.length > 0) {
2183
+ lines.push("**Output:**");
2184
+ for (const item of content) {
2185
+ if (item.type === "content" && item["content"]) {
2186
+ const contentData = item["content"];
2187
+ if (contentData.type === "text" && contentData.text) {
2188
+ let language = "";
2189
+ if (locations && locations.length === 1 && locations[0].path) {
2190
+ language = getLanguageFromPath(locations[0].path);
2191
+ }
2192
+ lines.push(createCodeBlock(contentData.text, language));
2193
+ }
2194
+ } else if (item.type === "diff") {
2195
+ const path2 = item["path"];
2196
+ const diffText = item["newText"];
2197
+ lines.push(`
2198
+ *Diff for \`${sanitizeText(path2)}\`:*`);
2199
+ lines.push(createCodeBlock(diffText, "diff"));
2200
+ }
2201
+ }
2202
+ }
2203
+ return lines.join("\n");
2204
+ }
2205
+ __name(formatToolCall, "formatToolCall");
2206
+ function extractTextFromMessage(message) {
2207
+ if (!message.message?.parts) return "";
2208
+ const textParts = [];
2209
+ for (const part of message.message.parts) {
2210
+ if ("text" in part) {
2211
+ textParts.push(part.text);
2212
+ }
2213
+ }
2214
+ return textParts.join("\n");
2215
+ }
2216
+ __name(extractTextFromMessage, "extractTextFromMessage");
2217
+ function createCodeBlock(content, language = "") {
2218
+ const fence = buildFence(content);
2219
+ return `${fence}${language}
2220
+ ${content}
2221
+ ${fence}`;
2222
+ }
2223
+ __name(createCodeBlock, "createCodeBlock");
2224
+ function sanitizeText(value) {
2225
+ return (value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;");
2226
+ }
2227
+ __name(sanitizeText, "sanitizeText");
2228
+ function buildFence(value) {
2229
+ const matches = (value ?? "").match(/`+/g);
2230
+ const maxRun = matches ? Math.max(...matches.map((match) => match.length)) : 0;
2231
+ const fenceLength = Math.max(3, maxRun + 1);
2232
+ return "`".repeat(fenceLength);
2233
+ }
2234
+ __name(buildFence, "buildFence");
2235
+ function getLanguageFromPath(path2) {
2236
+ const ext = path2.split(".").pop()?.toLowerCase();
2237
+ switch (ext) {
2238
+ case "ts":
2239
+ case "tsx":
2240
+ return "typescript";
2241
+ case "js":
2242
+ case "jsx":
2243
+ case "mjs":
2244
+ case "cjs":
2245
+ return "javascript";
2246
+ case "py":
2247
+ return "python";
2248
+ case "rb":
2249
+ return "ruby";
2250
+ case "go":
2251
+ return "go";
2252
+ case "rs":
2253
+ return "rust";
2254
+ case "java":
2255
+ return "java";
2256
+ case "c":
2257
+ case "cpp":
2258
+ case "h":
2259
+ case "hpp":
2260
+ return "cpp";
2261
+ case "cs":
2262
+ return "csharp";
2263
+ case "html":
2264
+ return "html";
2265
+ case "css":
2266
+ return "css";
2267
+ case "json":
2268
+ return "json";
2269
+ case "md":
2270
+ return "markdown";
2271
+ case "sh":
2272
+ case "bash":
2273
+ case "zsh":
2274
+ return "bash";
2275
+ case "yaml":
2276
+ case "yml":
2277
+ return "yaml";
2278
+ case "xml":
2279
+ return "xml";
2280
+ case "sql":
2281
+ return "sql";
2282
+ default:
2283
+ return "";
2284
+ }
2285
+ }
2286
+ __name(getLanguageFromPath, "getLanguageFromPath");
2287
+
2288
+ // packages/cli/src/ui/utils/export/formatters/html.ts
2289
+ init_esbuild_shims();
2290
+
2291
+ // packages/web-templates/src/index.ts
2292
+ init_esbuild_shims();
2293
+
2294
+ // packages/web-templates/src/generated/insightTemplate.ts
2295
+ init_esbuild_shims();
2296
+ var INSIGHT_JS = '(function(e,B){"use strict";function U({data:t}){const{totalMessages:n=0,totalLinesAdded:l=0,totalLinesRemoved:s=0,totalFiles:r=0}=t,a=Object.keys(t.heatmap||{});let o=0;if(a.length>0){const c=a.map(x=>new Date(x)).map(x=>x.getTime()),d=new Date(Math.min(...c)),g=new Date(Math.max(...c)),E=Math.abs(g.getTime()-d.getTime());o=Math.ceil(E/(1e3*60*60*24))+1}const i=o>0?Math.round(n/o):0;return e.createElement("div",{className:"stats-row"},e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},n),e.createElement("div",{className:"stat-label"},"Messages")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},"+",l,"/-",s),e.createElement("div",{className:"stat-label"},"Lines")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},r),e.createElement("div",{className:"stat-label"},"Files")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},o),e.createElement("div",{className:"stat-label"},"Days")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},i),e.createElement("div",{className:"stat-label"},"Msgs/Day")))}function K({insights:t}){return e.createElement("div",{className:"grid gap-4 md:grid-cols-2 md:gap-6"},e.createElement(J,{activeHours:t.activeHours,cardClass:"glass-card p-6",sectionTitleClass:"text-lg font-semibold tracking-tight text-slate-900"}))}function J({activeHours:t,cardClass:n,sectionTitleClass:l}){const r=[{label:"Morning",time:"06:00 - 12:00",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12:00 - 18:00",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18:00 - 22:00",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22:00 - 06:00",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(o=>{const i=o.hours.reduce((m,c)=>m+(t[c]||0),0);return{...o,total:i}}),a=Math.max(...r.map(o=>o.total));return e.createElement("div",{className:`${n} h-full flex flex-col min-h-[320px]`},e.createElement("div",{className:"flex items-center justify-between mb-4"},e.createElement("h3",{className:l},"Active Hours")),e.createElement("div",{className:"flex-1 flex flex-col justify-center gap-4"},r.map(o=>e.createElement("div",{key:o.label,className:"space-y-2"},e.createElement("div",{className:"flex justify-between items-center text-sm"},e.createElement("div",{className:"flex items-center gap-2"},e.createElement("span",{className:"rounded-full",style:{width:"12px",height:"12px",backgroundColor:o.color}}),e.createElement("span",{className:"font-medium text-slate-700"},o.label),e.createElement("span",{className:"text-xs text-slate-400 hidden xl:inline"},o.time)),e.createElement("span",{className:"font-semibold text-slate-900"},o.total)),e.createElement("div",{className:"w-full rounded-full overflow-hidden",style:{height:"12px",backgroundColor:"#e2e8f0"}},e.createElement("div",{className:"h-full rounded-full",style:{width:`${a>0?o.total/a*100:0}%`,backgroundColor:o.color}}))))))}function V({heatmap:t}){return e.createElement("div",{className:"glass-card p-6 mt-4 md:mt-6"},e.createElement("div",{className:"mb-3"},e.createElement("h3",{className:"text-lg font-semibold tracking-tight text-slate-900"},"Activity Heatmap"),e.createElement("p",{className:"text-xs text-slate-500"},"Showing past year of activity")),e.createElement("div",{className:"heatmap-container"},e.createElement("div",{className:"min-w-[720px] rounded-xl bg-white/70"},e.createElement(X,{heatmapData:t}))),e.createElement(Z,null))}function X({heatmapData:t}){const a=new Date,o=new Date(a);o.setFullYear(a.getFullYear()-1);const i=[],m=new Date(o);for(;m<=a;)i.push(new Date(m)),m.setDate(m.getDate()+1);const c=[0,2,4,10,20],d=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];function g(u){if(u===0)return d[0];for(let f=c.length-1;f>=1;f--)if(u>=c[f])return d[f];return d[1]}const E=50,x=20,A=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],w=o.getDay(),W=[];let h=-1,T=-100;return i.forEach((u,f)=>{const C=f+w,_=Math.floor(C/7),v=E+_*16,N=u.getMonth();N!==h&&(v-T>30&&(W.push({x:v,text:A[N]}),T=v),h=N)}),e.createElement("svg",{className:"heatmap-svg",width:1e3,height:130,viewBox:"0 0 1000 130"},i.map((u,f)=>{const C=f+w,_=Math.floor(C/7),v=u.getDay(),N=E+_*16,j=x+v*16,k=u.toISOString().split("T")[0],S=t[k]||0,L=g(S);return e.createElement("rect",{key:k,className:"heatmap-day",x:N,y:j,width:14,height:14,rx:"2",fill:L,"data-date":k,"data-count":S},e.createElement("title",null,k,": ",S," activities"))}),W.map((u,f)=>e.createElement("text",{key:f,x:u.x,y:"15",fontSize:"12",fill:"#64748b"},u.text)))}function Z(){const t=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];return e.createElement("div",{className:"flex items-center gap-2 mt-4"},e.createElement("span",{className:"text-xs text-slate-500"},"Less"),t.map((n,l)=>e.createElement("span",{key:l,className:"inline-block rounded",style:{width:"10px",height:"10px",backgroundColor:n}})),e.createElement("span",{className:"text-xs text-slate-500"},"More"))}function p({children:t}){if(!t||typeof t!="string")return t;const n=t.split(/(\\*\\*.*?\\*\\*)/g);return e.createElement(e.Fragment,null,n.map((l,s)=>l.startsWith("**")&&l.endsWith("**")&&l.length>=4?e.createElement("strong",{key:s},l.slice(2,-2)):l))}function F({text:t,label:n="Copy"}){const[l,s]=e.useState(!1),r=()=>{navigator.clipboard.writeText(t).then(()=>{s(!0),setTimeout(()=>s(!1),2e3)})};return e.createElement("button",{className:"copy-btn",onClick:r},l?"Copied!":n)}function R(t){return typeof t=="string"&&t.trim().length>0}function ee({qualitative:t,targetSections:n}){const{atAGlance:l}=t;if(!l)return null;const s=[{key:"wins",label:"What\'s working:",body:l.whats_working,href:"#section-wins",link:"Impressive Things You Did \u2192",showLink:n.wins},{key:"friction",label:"What\'s hindering you:",body:l.whats_hindering,href:"#section-friction",link:"Where Things Go Wrong \u2192",showLink:n.friction},{key:"features",label:"Quick wins to try:",body:l.quick_wins,href:"#section-features",link:"Features to Try \u2192",showLink:n.features},{key:"horizon",label:"Ambitious workflows:",body:l.ambitious_workflows,href:"#section-horizon",link:"On the Horizon \u2192",showLink:n.horizon}].filter(r=>R(r.body));return s.length===0?null:e.createElement("div",{className:"at-a-glance"},e.createElement("div",{className:"glance-title"},"At a Glance"),e.createElement("div",{className:"glance-sections"},s.map(r=>e.createElement("div",{key:r.key,className:"glance-section"},e.createElement("strong",null,r.label)," ",e.createElement(p,null,r.body),r.showLink&&e.createElement("a",{href:r.href,className:"see-more"},r.link)))))}function te({sections:t}){return t.length===0?null:e.createElement("nav",{className:"nav-toc"},t.map(n=>e.createElement("a",{key:n.href,href:n.href},n.label)))}function ne({qualitative:t,topGoals:n,topTools:l}){const{projectAreas:s}=t,r=Array.isArray(l)?Object.fromEntries(l):l;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-work",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"What You Work On"),Array.isArray(s==null?void 0:s.areas)&&s.areas.length>0&&e.createElement("div",{className:"project-areas mb-6"},s.areas.map((a,o)=>e.createElement("div",{key:o,className:"project-area"},e.createElement("div",{className:"area-header"},e.createElement("span",{className:"area-name"},a.name),e.createElement("span",{className:"area-count"},"~",a.session_count," sessions")),e.createElement("div",{className:"area-desc"},e.createElement(p,null,a.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"What You Wanted",color:"#0ea5e9"}),r&&Object.keys(r).length>0&&e.createElement(D,{data:r,title:"Top Tools Used",color:"#6366f1"})))}function le({qualitative:t,insights:n}){const{interactionStyle:l}=t;return l?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-usage",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"How You Use Qwen Code"),e.createElement("div",{className:"narrative"},e.createElement("p",null,e.createElement(p,null,l.narrative)),l.key_pattern&&e.createElement("div",{className:"key-insight"},e.createElement("strong",null,"Key pattern:")," ",e.createElement(p,null,l.key_pattern))),e.createElement(K,{insights:n}),e.createElement(V,{heatmap:n.heatmap})):null}function re({qualitative:t,primarySuccess:n,outcomes:l}){const s=t==null?void 0:t.impressiveWorkflows;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-wins",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Impressive Things You Did"),(s==null?void 0:s.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,s.intro)),s&&e.createElement("div",{className:"big-wins"},Array.isArray(s.impressive_workflows)&&s.impressive_workflows.map((r,a)=>e.createElement("div",{key:a,className:"big-win"},e.createElement("div",{className:"big-win-title"},r.title),e.createElement("div",{className:"big-win-desc"},e.createElement(p,null,r.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"What Helped Most (Qwen\'s Capabilities)",color:"#3b82f6",allowedKeys:["fast_accurate_search","correct_code_edits","good_explanations","proactive_help","multi_file_changes","good_debugging"]}),l&&Object.keys(l).length>0&&e.createElement(D,{data:l,title:"Outcomes",color:"#8b5cf6",allowedKeys:["fully_achieved","mostly_achieved","partially_achieved","not_achieved","unclear_from_transcript"]})))}function se(t){return t==="unclear_from_transcript"?"Unclear":t.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function D({data:t,title:n,color:l="#3b82f6",allowedKeys:s=null}){if(!t||Object.keys(t).length===0)return null;let r=Object.entries(t).filter(([,o])=>Number.isFinite(o)&&o!==0);if(s&&(r=r.filter(([o])=>s.includes(o))),r.sort((o,i)=>i[1]-o[1]),r=r.slice(0,10),r.length===0)return null;const a=Math.max(...r.map(([,o])=>o));return e.createElement("div",{className:"bar-chart-card",style:{flex:1,minWidth:0,backgroundColor:"#ffffff",borderRadius:"12px",padding:"20px",boxShadow:"0 1px 3px rgba(0, 0, 0, 0.08)",border:"1px solid #e2e8f0"}},e.createElement("h3",{style:{fontSize:"13px",fontWeight:700,color:"#64748b",marginTop:0,marginBottom:"16px",textTransform:"uppercase",letterSpacing:"0.5px"}},n),e.createElement("div",{className:"bar-chart",style:{display:"flex",flexDirection:"column",gap:"10px"}},r.map(([o,i])=>{const m=a>0?i/a*100:0;return e.createElement("div",{key:o,className:"bar-row",style:{display:"flex",alignItems:"center",gap:"12px"}},e.createElement("div",{className:"bar-label",style:{width:"130px",fontSize:"13px",color:"#475569",textAlign:"left",flexShrink:0,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}},se(o)),e.createElement("div",{className:"bar-wrapper",style:{flex:1,display:"flex",alignItems:"center",gap:"10px",minWidth:0}},e.createElement("div",{className:"bar-bg",style:{flex:1,height:"8px",backgroundColor:"#f1f5f9",borderRadius:"4px",overflow:"hidden"}},e.createElement("div",{className:"bar-fill",style:{width:`${m}%`,height:"100%",backgroundColor:l,borderRadius:"4px",transition:"width 0.3s ease"}})),e.createElement("span",{className:"bar-value",style:{fontSize:"13px",fontWeight:600,color:"#475569",minWidth:"24px",textAlign:"right"}},i)))})))}function ae({qualitative:t,satisfaction:n,friction:l}){const s=t==null?void 0:t.frictionPoints;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-friction",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Where Things Go Wrong"),(s==null?void 0:s.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,s.intro)),s&&e.createElement("div",{className:"friction-categories"},Array.isArray(s.categories)&&s.categories.map((r,a)=>e.createElement("div",{key:a,className:"friction-category"},e.createElement("div",{className:"friction-title"},r.category),e.createElement("div",{className:"friction-desc"},e.createElement(p,null,r.description)),Array.isArray(r.examples)&&r.examples.length>0&&e.createElement("ul",{className:"friction-examples"},r.examples.map((o,i)=>e.createElement("li",{key:i},e.createElement(p,null,o))))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},l&&Object.keys(l).length>0&&e.createElement(D,{data:l,title:"Primary Friction Types",color:"#ef4444",allowedKeys:["misunderstood_request","wrong_approach","buggy_code","user_rejected_action","excessive_changes"]}),n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"Inferred Satisfaction (model-estimated)",color:"#10b981",allowedKeys:["happy","satisfied","likely_satisfied","dissatisfied","frustrated"]})))}function oe({additions:t}){const[n,l]=e.useState(new Array(t.length).fill(!0)),[s,r]=e.useState(!1),a=m=>{const c=n.map((d,g)=>g===m?!d:d);l(c)},o=()=>{const m=t.filter((c,d)=>n[d]).map(c=>c.addition).join(`\n\n`);m&&navigator.clipboard.writeText(m).then(()=>{r(!0),setTimeout(()=>r(!1),2e3)})},i=n.filter(Boolean).length;return e.createElement("div",{className:"qwen-md-section"},e.createElement("h3",null,"Suggested QWEN.md Additions"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code to add it to your QWEN.md."),e.createElement("div",{className:"qwen-md-actions",style:{marginBottom:"12px"}},e.createElement("button",{className:`copy-all-btn ${s?"copied":""}`,onClick:o,disabled:i===0},s?"Copied All!":`Copy All Checked (${i})`)),t.map((m,c)=>e.createElement("div",{key:c,className:"qwen-md-item"},e.createElement("input",{type:"checkbox",checked:n[c],onChange:()=>a(c),className:"cmd-checkbox"}),e.createElement("div",{style:{flex:1}},e.createElement("code",{className:"cmd-code"},m.addition),e.createElement("div",{className:"cmd-why"},e.createElement(p,null,m.why))),e.createElement(F,{text:m.addition}))))}function ie({qualitative:t}){const{improvements:n}=t;if(!n)return null;const l=Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0||Array.isArray(n.features_to_try)&&n.features_to_try.length>0,s=Array.isArray(n.usage_patterns)&&n.usage_patterns.length>0;return!l&&!s?null:e.createElement(e.Fragment,null,l&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-features",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Existing Qwen Code Features to Try"),Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0&&e.createElement(oe,{additions:n.Qwen_md_additions}),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll set it up for you."),e.createElement("div",{className:"features-section"},Array.isArray(n.features_to_try)&&n.features_to_try.map((r,a)=>e.createElement("div",{key:a,className:"feature-card"},e.createElement("div",{className:"feature-title"},r.feature),e.createElement("div",{className:"feature-oneliner"},e.createElement(p,null,r.one_liner)),e.createElement("div",{className:"feature-why"},e.createElement("strong",null,"Why for you:")," ",e.createElement(p,null,r.why_for_you)),e.createElement("div",{className:"feature-examples"},e.createElement("div",{className:"feature-example"},e.createElement("div",{className:"example-code-row"},e.createElement("code",{className:"example-code"},r.example_code),e.createElement(F,{text:r.example_code})))))))),s&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-patterns",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"New Ways to Use Qwen Code"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll walk you through it."),e.createElement("div",{className:"patterns-section"},Array.isArray(n.usage_patterns)&&n.usage_patterns.map((r,a)=>e.createElement("div",{key:a,className:"pattern-card"},e.createElement("div",{className:"pattern-title"},r.title),e.createElement("div",{className:"pattern-summary"},e.createElement(p,null,r.suggestion)),e.createElement("div",{className:"pattern-detail"},e.createElement(p,null,r.detail)),e.createElement("div",{className:"copyable-prompt-section"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{className:"copyable-prompt-row"},e.createElement("code",{className:"copyable-prompt"},r.copyable_prompt),e.createElement(F,{text:r.copyable_prompt}))))))))}function me({qualitative:t}){const{futureOpportunities:n}=t;return n?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-horizon",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"On the Horizon"),n.intro&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,n.intro)),e.createElement("div",{className:"horizon-section"},Array.isArray(n.opportunities)&&n.opportunities.map((l,s)=>e.createElement("div",{key:s,className:"horizon-card"},e.createElement("div",{className:"horizon-title"},l.title),e.createElement("div",{className:"horizon-possible"},e.createElement(p,null,l.whats_possible)),e.createElement("div",{className:"horizon-tip"},e.createElement("strong",null,"Getting started:")," ",e.createElement(p,null,l.how_to_try)),e.createElement("div",{className:"pattern-prompt"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"}},e.createElement("code",{style:{flex:1}},l.copyable_prompt),e.createElement(F,{text:l.copyable_prompt}))))))):null}function ce({qualitative:t}){const{memorableMoment:n}=t;return n?e.createElement("div",{className:"fun-ending"},e.createElement("div",{className:"fun-headline"},\'"\',n.headline,\'"\'),e.createElement("div",{className:"fun-detail"},e.createElement(p,null,n.detail))):null}const de={light:{background:"linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)",textPrimary:"#0f172a",textSecondary:"#475569",textMuted:"#64748b",cardBackground:"rgba(255,255,255,0.7)",cardBackgroundSecondary:"rgba(255,255,255,0.5)",borderColor:"#e2e8f0",heatmapColors:["#9be9a8","#40c463","#30a14e","#216e39"],heatmapEmpty:"#ebedf0"},dark:{background:"linear-gradient(135deg, #0f172a 0%, #1e293b 100%)",textPrimary:"#f8fafc",textSecondary:"#e2e8f0",textMuted:"#94a3b8",cardBackground:"rgba(255,255,255,0.05)",cardBackgroundSecondary:"rgba(255,255,255,0.04)",borderColor:"rgba(255,255,255,0.08)",heatmapColors:["#0e4429","#006d32","#26a641","#39d353"],heatmapEmpty:"#2d333b"}};function pe({data:t,theme:n="light"}){var h,T,u,f,C,_;const l=de[n],{totalMessages:s=0,totalSessions:r=0,totalLinesAdded:a=0,totalLinesRemoved:o=0,totalFiles:i=0,currentStreak:m=0,longestStreak:c=0,activeHours:d={}}=t,g=Object.keys(t.heatmap||{});let E=0,x="";if(g.length>0){E=g.length;const v=g.map(S=>new Date(S).getTime()),N=new Date(Math.min(...v)),j=new Date(Math.max(...v)),k=S=>S.toISOString().split("T")[0];x=`${k(N)} \u2014 ${k(j)}`}const A=(u=(T=(h=t.qualitative)==null?void 0:h.interactionStyle)==null?void 0:T.key_pattern)!=null?u:null,w=(_=(C=(f=t.qualitative)==null?void 0:f.memorableMoment)==null?void 0:C.headline)!=null?_:null,W=fe(t.heatmap||{},l);return e.createElement("div",{id:"share-card",style:{width:"1200px",background:l.background,color:l.textPrimary,fontFamily:\'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"\',display:"flex",flexDirection:"column",padding:"48px 56px",position:"absolute",left:"-9999px",top:"-9999px",overflow:"hidden",boxSizing:"border-box"}},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"32px"}},e.createElement("div",null,e.createElement("div",{style:{fontSize:"32px",fontWeight:700,letterSpacing:"-0.02em",lineHeight:1.2}},"Qwen Code Insights"),e.createElement("div",{style:{fontSize:"14px",color:l.textMuted,marginTop:"6px"}},x)),e.createElement("div",{style:{fontSize:"11px",color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.15em",paddingTop:"8px"}},"qwen.ai")),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(6, 1fr)",gap:"16px",marginBottom:"32px"}},e.createElement(M,{value:String(s),label:"Messages",theme:l}),e.createElement(M,{value:String(r),label:"Sessions",theme:l}),e.createElement(M,{value:`+${a}/-${o}`,label:"Lines Changed",small:!0,theme:l}),e.createElement(M,{value:String(i),label:"Files",theme:l}),e.createElement(M,{value:`${m}d`,label:"Streak",theme:l}),e.createElement(M,{value:`${c}d`,label:"Best Streak",theme:l})),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"24px",marginBottom:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Activity \xB7 ",E," active days"),e.createElement("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center"}},e.createElement(ge,{cells:W})),e.createElement(ye,{theme:l})),e.createElement("div",{style:{display:"flex",flexDirection:"column",gap:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Active Hours"),e.createElement("div",{style:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",gap:"10px"}},e.createElement(ue,{activeHours:d,theme:l}))),e.createElement("div",{style:{background:l.cardBackgroundSecondary,borderRadius:"12px",padding:"16px 16px",position:"relative"}},e.createElement("div",{style:{position:"absolute",left:"12px",fontSize:"64px",fontWeight:700,color:n==="light"?"rgba(99,102,241,0.15)":"rgba(99,102,241,0.2)",lineHeight:1,fontFamily:\'Georgia, "Times New Roman", serif\',userSelect:"none",pointerEvents:"none"}},"\u201C"),e.createElement("div",{style:{paddingLeft:"40px",position:"relative"}},A&&e.createElement("div",{style:{fontSize:"13px",color:l.textSecondary,lineHeight:1.6,marginBottom:w?"8px":0}},A),w&&e.createElement("div",{style:{fontSize:"12px",color:l.textMuted,lineHeight:1.5,fontStyle:"italic"}},w))))),e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:"auto",paddingTop:"24px",borderTop:`1px solid ${l.borderColor}`,flexShrink:0}},e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"Generated by Qwen Code \xB7 ",new Date().toISOString().split("T")[0]),e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"github.com/QwenLM/qwen-code")))}function M({value:t,label:n,small:l,theme:s}){return e.createElement("div",{style:{textAlign:"center"}},e.createElement("div",{style:{fontSize:l?"18px":"28px",fontWeight:700,color:s.textPrimary,lineHeight:1.2}},t),e.createElement("div",{style:{fontSize:"11px",color:s.textMuted,textTransform:"uppercase",letterSpacing:"0.05em",marginTop:"4px"}},n))}function ue({activeHours:t,theme:n}){const s=[{label:"Morning",time:"06\u201312",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12\u201318",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18\u201322",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22\u201306",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(a=>({...a,total:a.hours.reduce((o,i)=>o+(t[i]||0),0)})),r=Math.max(...s.map(a=>a.total),1);return e.createElement(e.Fragment,null,s.map(a=>{const o=r>0?a.total/r*100:0;return e.createElement("div",{key:a.label},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",fontSize:"12px",marginBottom:"4px"}},e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"6px"}},e.createElement("span",{style:{width:"8px",height:"8px",borderRadius:"50%",backgroundColor:a.color,display:"inline-block",flexShrink:0}}),e.createElement("span",{style:{color:n.textSecondary,fontWeight:500}},a.label),e.createElement("span",{style:{color:n.textMuted,fontSize:"11px"}},a.time)),e.createElement("span",{style:{color:n.textMuted,fontWeight:600}},a.total)),e.createElement("div",{style:{height:"6px",background:n.borderColor,borderRadius:"3px",overflow:"hidden"}},e.createElement("div",{style:{width:`${o}%`,height:"100%",backgroundColor:a.color,borderRadius:"3px"}})))}))}function fe(t,n){const l=new Date,r=26*7,a=new Date(l);a.setDate(a.getDate()-r+1),a.setDate(a.getDate()-a.getDay());const o=[],i=new Date(l);i.setDate(i.getDate()+(6-i.getDay()));const m=new Date(a);for(;m<=i;){const c=m.toISOString().split("T")[0],d=t[c]||0;o.push({color:he(d,n)}),m.setDate(m.getDate()+1)}return o}function he(t,n){return t===0?n.heatmapEmpty:t<2?n.heatmapColors[0]:t<4?n.heatmapColors[1]:t<10?n.heatmapColors[2]:n.heatmapColors[3]}function ge({cells:t}){const l=Math.ceil(t.length/7),s=14,r=3,a=l*(s+r),o=7*(s+r);return e.createElement("svg",{width:a,height:o,viewBox:`0 0 ${a} ${o}`},t.map((i,m)=>{const c=Math.floor(m/7),d=m%7;return e.createElement("rect",{key:m,x:c*(s+r),y:d*(s+r),width:s,height:s,rx:2,fill:i.color})}))}function ye({theme:t}){return e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"8px",marginTop:"12px"}},e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"Less"),[t.heatmapEmpty,t.heatmapColors[0],t.heatmapColors[1],t.heatmapColors[2],t.heatmapColors[3]].map((n,l)=>e.createElement("span",{key:l,style:{width:"10px",height:"10px",borderRadius:"2px",backgroundColor:n,display:"inline-block"}})),e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"More"))}function b(t){return typeof t=="string"?t.trim().length>0:typeof t=="number"?Number.isFinite(t)&&t!==0:typeof t=="boolean"?t:Array.isArray(t)?t.some(n=>b(n)):t&&typeof t=="object"?Object.values(t).some(n=>b(n)):!1}function z(t){return Array.isArray(t)?t.some(([,n])=>Number.isFinite(n)&&n!==0):!!t&&Object.values(t).some(n=>Number.isFinite(n)&&n!==0)}function H(t){return Array.isArray(t)&&t.some(n=>b(n))}function xe({data:t}){var u,f,C,_,v,N,j,k,S,L,G,Y;const[n,l]=e.useState("dark"),s=e.useRef(!1),r=async()=>{const q=document.getElementById("share-card");if(!q||!window.html2canvas){alert("Export functionality is not available.");return}try{const y=q.cloneNode(!0);y.style.position="fixed",y.style.left="-9999px",y.style.top="0",y.style.pointerEvents="none",document.body.appendChild(y);const Q=await window.html2canvas(y,{scale:2,useCORS:!0,logging:!1,width:1200,height:y.scrollHeight});document.body.removeChild(y);const P=Q.toDataURL("image/png"),I=document.createElement("a");I.href=P,I.download=`qwen-insights-card-${new Date().toISOString().slice(0,10)}.png`,I.click()}catch(y){console.error("Export card error:",y),alert("Failed to export card. Please try again.")}};e.useEffect(()=>{s.current&&(s.current=!1,r())},[n]);const a=q=>{q===n?r():(s.current=!0,l(q))};if(!t)return e.createElement("div",{className:"text-center text-slate-600"},"No insight data available");const o=Object.keys(t.heatmap||{});let i="";if(o.length>0){const y=o.map(O=>new Date(O)).map(O=>O.getTime()),Q=new Date(Math.min(...y)),P=new Date(Math.max(...y)),I=O=>O.toISOString().split("T")[0];i=`${I(Q)} to ${I(P)}`}const m=b((u=t.qualitative)==null?void 0:u.atAGlance),c=!!t.qualitative&&(b(t.qualitative.projectAreas)||z(t.topGoals)||z(t.topTools)),d=b((f=t.qualitative)==null?void 0:f.interactionStyle),g=!!t.qualitative&&(b(t.qualitative.impressiveWorkflows)||z(t.primarySuccess)||z(t.outcomes)),E=!!t.qualitative&&(b(t.qualitative.frictionPoints)||z(t.satisfaction)||z(t.friction)),x=!!t.qualitative&&(H((C=t.qualitative.improvements)==null?void 0:C.Qwen_md_additions)||H((_=t.qualitative.improvements)==null?void 0:_.features_to_try)),A=!!t.qualitative&&H((v=t.qualitative.improvements)==null?void 0:v.usage_patterns),w=b((N=t.qualitative)==null?void 0:N.futureOpportunities),W=b((j=t.qualitative)==null?void 0:j.memorableMoment),h=[];c&&h.push({href:"#section-work",label:"What You Work On"}),d&&h.push({href:"#section-usage",label:"How You Use Qwen Code"}),g&&h.push({href:"#section-wins",label:"Impressive Things"}),E&&h.push({href:"#section-friction",label:"Where Things Go Wrong"}),x&&h.push({href:"#section-features",label:"Features to Try"}),A&&h.push({href:"#section-patterns",label:"New Usage Patterns"}),w&&h.push({href:"#section-horizon",label:"On the Horizon"});const T={wins:g,friction:E,features:x,horizon:w};return e.createElement("div",null,e.createElement("header",{className:"insights-header"},e.createElement("div",{className:"header-content"},e.createElement("div",{className:"header-title-section"},e.createElement("h1",{className:"header-title"},"Qwen Code Insights"),e.createElement("p",{className:"header-subtitle"},t.totalMessages?`${t.totalMessages.toLocaleString()} messages across ${(k=t.totalSessions)==null?void 0:k.toLocaleString()} sessions`:"Your personalized coding journey and patterns",i&&` \xB7 ${i}`)),e.createElement(Ee,{onExport:a}))),m&&t.qualitative&&e.createElement(ee,{qualitative:t.qualitative,targetSections:T}),h.length>0&&e.createElement(te,{sections:h}),e.createElement(U,{data:t}),c&&t.qualitative&&e.createElement(ne,{qualitative:t.qualitative,topGoals:t.topGoals,topTools:t.topTools}),d&&t.qualitative&&e.createElement(le,{qualitative:t.qualitative,insights:t}),g&&e.createElement(re,{qualitative:t.qualitative,primarySuccess:(S=t.primarySuccess)!=null?S:{},outcomes:(L=t.outcomes)!=null?L:{}}),E&&e.createElement(ae,{qualitative:t.qualitative,satisfaction:(G=t.satisfaction)!=null?G:{},friction:(Y=t.friction)!=null?Y:{}}),(x||A)&&t.qualitative&&e.createElement(ie,{qualitative:t.qualitative}),w&&t.qualitative&&e.createElement(me,{qualitative:t.qualitative}),W&&t.qualitative&&e.createElement(ce,{qualitative:t.qualitative}),e.createElement(pe,{data:t,theme:n}))}function Ee({onExport:t}){const[n,l]=e.useState(!1),s=e.useRef(null);e.useEffect(()=>{if(!n)return;const a=o=>{s.current&&!s.current.contains(o.target)&&l(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[n]);const r=a=>{l(!1),t(a)};return e.createElement("div",{className:"export-dropdown-wrapper",ref:s},e.createElement("button",{className:"export-card-btn",onClick:()=>l(!n)},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"}),e.createElement("polyline",{points:"16 6 12 2 8 6"}),e.createElement("line",{x1:"12",y1:"2",x2:"12",y2:"15"})),e.createElement("span",null,"Export Card"),e.createElement("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:`export-chevron ${n?"open":""}`},e.createElement("polyline",{points:"6 9 12 15 18 9"}))),n&&e.createElement("div",{className:"export-dropdown"},e.createElement("button",{className:"export-dropdown-item",onClick:()=>r("light")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("circle",{cx:"12",cy:"12",r:"5"}),e.createElement("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),e.createElement("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),e.createElement("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),e.createElement("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),e.createElement("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),e.createElement("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),e.createElement("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),e.createElement("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})),e.createElement("span",null,"Light Theme")),e.createElement("button",{className:"export-dropdown-item",onClick:()=>r("dark")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})),e.createElement("span",null,"Dark Theme"))))}const $=document.getElementById("react-root");$&&window.INSIGHT_DATA&&B?B.createRoot($).render(e.createElement(xe,{data:window.INSIGHT_DATA})):console.error("Failed to mount React app:",{container:!!$,data:!!window.INSIGHT_DATA,ReactDOM:!!B})})(React,ReactDOM);';
2297
+ var INSIGHT_CSS = '*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #3b82f680;--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content: ""}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}body{line-height:inherit;margin:0;background-image:linear-gradient(to bottom right,var(--tw-gradient-stops));--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to);--tw-text-opacity: 1;min-height:100vh;color:rgb(15 23 42 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glass-card{--tw-border-opacity: 1;border-width:1px;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1));--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-backdrop-blur: blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);background-color:#fff9;border-radius:1rem}.col-span-2{grid-column:span 2 / span 2}.mx-auto{margin-left:auto;margin-right:auto}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-56{height:14rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.min-w-\\[720px\\]{min-width:720px}.max-w-6xl{max-width:72rem}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(226 232 240 / var(--tw-divide-opacity, 1))}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:9999px}.rounded-xl{border-radius:1.25rem}.border{border-width:1px}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.bg-emerald-50{--tw-bg-opacity: 1;background-color:rgb(236 253 245 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-white\\/70{background-color:#ffffff73}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-slate-50{--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f8fafc00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-white{--tw-gradient-to: #ffffff00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-slate-100{--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position)}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-\\[0\\.2em\\]{letter-spacing:.2em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-rose-700{--tw-text-opacity: 1;color:rgb(190 18 60 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 #0000000d;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-slate-100{--tw-shadow-color: #f1f5f9;--tw-shadow: var(--tw-shadow-colored)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\\:-translate-y-\\[1px\\]:hover{--tw-translate-y: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus-visible\\:outline:focus-visible{outline-style:solid}.focus-visible\\:outline-2:focus-visible{outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-slate-400:focus-visible{outline-color:#94a3b8}.active\\:translate-y-\\[1px\\]:active{--tw-translate-y: 1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\\:translate-x-0\\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media (min-width: 768px){.md\\:mt-6{margin-top:1.5rem}.md\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\\:gap-6{gap:1.5rem}.md\\:py-12{padding-top:3rem;padding-bottom:3rem}.md\\:text-4xl{font-size:2.25rem;line-height:2.5rem}}.heatmap-container{width:100%;overflow-x:auto}.heatmap-svg{min-width:720px}.heatmap-day{cursor:pointer}.heatmap-day:hover{stroke:#00000024;stroke-width:1px}.heatmap-legend{display:flex;align-items:center;gap:4px;font-size:12px;color:#64748b;margin-top:8px}.heatmap-legend-item{width:10px;height:10px;border-radius:2px}.nav-toc{display:flex;flex-wrap:wrap;gap:8px;margin:24px 0 32px;padding:16px;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.nav-toc a{font-size:12px;color:#64748b;text-decoration:none;padding:6px 12px;border-radius:6px;background:#f1f5f9;transition:all .15s}.nav-toc a:hover{background:#e2e8f0;color:#334155}.at-a-glance{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #f59e0b;border-radius:12px;padding:20px 24px;margin-bottom:32px}.glance-title{font-size:16px;font-weight:700;color:#92400e;margin-bottom:16px}.glance-sections{display:flex;flex-direction:column;gap:12px}.glance-section{font-size:14px;color:#78350f;line-height:1.6}.glance-section strong{color:#92400e;font-weight:700}.see-more{color:#b45309;text-decoration:none;font-size:13px;white-space:nowrap;margin-left:4px}.see-more:hover{text-decoration:underline}.project-areas{display:flex;flex-direction:column;gap:12px;margin-bottom:32px}.project-area{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:16px}.area-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.area-name{font-weight:600;font-size:15px;color:#0f172a}.area-count{font-size:12px;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:4px}.area-desc{font-size:14px;color:#475569;line-height:1.5}.narrative{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:20px;margin-bottom:24px}.narrative p{margin-top:0;margin-bottom:12px;font-size:14px;color:#475569;line-height:1.7}.key-insight{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:12px 16px;margin-top:12px;font-size:14px;color:#166534}.section-intro{font-size:14px;color:#64748b;margin-bottom:16px}.big-wins{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.big-win{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:16px}.big-win-title{font-weight:600;font-size:15px;color:#166534;margin-bottom:8px}.big-win-desc{font-size:14px;color:#15803d;line-height:1.5}.friction-categories{display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.friction-category{background:#fef2f2;border:1px solid #fca5a5;border-radius:8px;padding:16px}.friction-title{font-weight:600;font-size:15px;color:#991b1b;margin-bottom:6px}.friction-desc{font-size:13px;color:#7f1d1d;margin-bottom:10px}.friction-examples{margin:0 0 0 10px;padding:0;font-size:13px;color:#334155;list-style-type:disc}.friction-examples li{margin-bottom:4px}.qwen-md-section{background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px;margin-bottom:20px}.qwen-md-section h3{font-size:13px;font-weight:600;color:#1e40af;margin:0 0 8px}.qwen-md-actions{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid #dbeafe}.copy-all-btn{background:#2563eb;color:#fff;border:none;border-radius:4px;padding:4px 10px;font-size:11px;cursor:pointer;font-weight:500;transition:all .2s}.copy-all-btn:hover{background:#1d4ed8}.copy-all-btn.copied{background:#16a34a}.qwen-md-item{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;padding:8px 0;border-bottom:1px solid #dbeafe}.qwen-md-item:last-child{border-bottom:none}.cmd-checkbox{margin-top:2px}.cmd-code{background:#fff;padding:6px 10px;border-radius:4px;font-size:11px;color:#1e40af;border:1px solid #bfdbfe;font-family:monospace;display:block;white-space:pre-wrap;word-break:break-word;flex:1}.cmd-why{font-size:11px;color:#64748b;width:100%;padding-left:20px;margin-top:4px}.features-section,.patterns-section{display:flex;flex-direction:column;gap:12px;margin:16px 0}.feature-card{background:#f0fdf4;border:1px solid #86efac;border-radius:8px;padding:16px}.pattern-card{background:#f0f9ff;border:1px solid #7dd3fc;border-radius:8px;padding:16px}.feature-title,.pattern-title{font-weight:600;font-size:15px;color:#0f172a;margin-bottom:6px}.feature-oneliner,.pattern-summary{font-size:14px;color:#475569;margin-bottom:8px}.feature-why,.pattern-detail{font-size:13px;color:#334155;line-height:1.5}.feature-examples{margin-top:12px}.feature-example{padding:8px 0;border-top:1px solid #d1fae5}.feature-example:first-child{border-top:none}.example-code-row,.copyable-prompt-row{display:flex;align-items:flex-start;gap:8px}.example-code{flex:1;background:#f1f5f9;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;overflow-x:auto;white-space:pre-wrap}.copyable-prompt-section{margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.copyable-prompt{flex:1;background:#f8fafc;padding:10px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;border:1px solid #e2e8f0;white-space:pre-wrap;line-height:1.5}.prompt-label{font-size:11px;font-weight:600;text-transform:uppercase;color:#64748b;margin-bottom:6px}.copy-btn{background:#e2e8f0;border:none;border-radius:4px;padding:4px 8px;font-size:11px;cursor:pointer;color:#475569;flex-shrink:0;transition:all .2s}.copy-btn:hover{background:#cbd5e1}.horizon-section{display:flex;flex-direction:column;gap:16px}.horizon-card{background:linear-gradient(135deg,#faf5ff,#f5f3ff);border:1px solid #c4b5fd;border-radius:8px;padding:16px}.horizon-title{font-weight:600;font-size:15px;color:#5b21b6;margin-bottom:8px}.horizon-possible{font-size:14px;color:#334155;margin-bottom:10px;line-height:1.5}.horizon-tip{font-size:13px;color:#6b21a8;background:#fff9;padding:8px 12px;border-radius:4px}.pattern-prompt{background:#f8fafc;padding:12px;border-radius:6px;margin-top:12px;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:8px}.pattern-prompt code{font-family:monospace;font-size:12px;color:#334155;display:block;white-space:pre-wrap}.fun-ending{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #fbbf24;border-radius:12px;padding:24px;margin-top:40px;text-align:center}.fun-headline{font-size:18px;font-weight:600;color:#78350f;margin-bottom:8px}.fun-detail{font-size:14px;color:#92400e}.stats-row{display:flex;gap:24px;margin-bottom:40px;padding:20px 0;border-top:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.stat{text-align:center}.stat-value{font-size:24px;font-weight:700;color:#0f172a}.stat-label{font-size:11px;color:#64748b;text-transform:uppercase}@media (max-width: 640px){.stats-row{justify-content:center}}.header-with-action{position:relative}.insights-header{margin-bottom:2rem;padding:1.5rem 0;border-bottom:1px solid #e2e8f0}.header-content{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}.header-title-section{flex:1;min-width:0}.header-title{font-size:1.75rem;font-weight:700;color:#0f172a;letter-spacing:-.02em;margin:0 0 .375rem;line-height:1.2}.header-subtitle{font-size:.875rem;color:#64748b;margin:0;font-weight:400}.export-dropdown-wrapper{position:relative}.export-card-btn{display:inline-flex;align-items:center;gap:.5rem;height:36px;padding:0 .875rem;border:1px solid #e2e8f0;border-radius:8px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500;cursor:pointer;transition:all .15s ease}.export-card-btn:hover{background:#f8fafc;border-color:#cbd5e1}.export-card-btn:active{background:#f1f5f9}.export-chevron{transition:transform .15s ease;opacity:.5}.export-chevron.open{transform:rotate(180deg)}.export-dropdown{position:absolute;top:calc(100% + 4px);right:0;min-width:160px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 16px #00000014;padding:4px;z-index:50}.export-dropdown-item{display:flex;align-items:center;gap:.5rem;width:100%;padding:.5rem .75rem;border:none;border-radius:6px;background:none;color:#334155;font-size:.8125rem;font-weight:400;cursor:pointer;transition:background .1s ease}.export-dropdown-item:hover{background:#f1f5f9}.export-dropdown-item:active{background:#e2e8f0}@media (max-width: 640px){.header-content{flex-direction:column;align-items:flex-start;gap:1rem}.header-title{font-size:1.5rem}}';
2298
+
2299
+ // packages/web-templates/src/generated/exportHtmlTemplate.ts
2300
+ init_esbuild_shims();
2301
+ var HTML_TEMPLATE = '<!doctype html>\n<html lang="en" class="dark">\n <head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <link\n rel="icon"\n type="image/svg+xml"\n href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20141.38%20140%22%3E%0A%20%20%3Cpath%0A%20%20%20%20fill%3D%22%23000000%22%0A%20%20%20%20d%3D%22m140.93%2085-16.35-28.33-1.93-3.34%208.66-15a3.323%203.323%200%200%200%200-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33%203.33%200%200%200-2.89-1.67H51.43c-.59%200-1.17.16-1.66.45-.5.29-.92.71-1.22%201.22L32.19%2029.98l-1.92%203.33H12.96c-.59%200-1.17.16-1.66.45-.5.29-.93.71-1.22%201.22L.45%2051.66a3.323%203.323%200%200%200%200%203.34l18.28%2031.67-8.66%2015a3.32%203.32%200%200%200%200%203.34l9.62%2016.67c.3.51.72.93%201.22%201.22s1.07.45%201.67.45h36.56l8.66%2015a3.35%203.35%200%200%200%202.89%201.67h19.25a3.34%203.34%200%200%200%202.89-1.67l18.28-31.67h17.32c.6%200%201.17-.16%201.67-.45s.92-.71%201.22-1.22l9.62-16.67a3.323%203.323%200%200%200%200-3.34ZM51.44%203.33%2061.07%2020l-9.63%2016.66h76.98l-9.62%2016.66H45.67l-11.54-20zM57.21%20120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62%2016.67L68.78%20100l-11.55%2020Zm61.59-33.34-9.62-16.67-38.49%2066.67-9.63-16.67%209.63-16.66%2026.94-46.67h23.1l17.32%2030z%22%0A%20%20%2F%3E%0A%3C%2Fsvg%3E"\n />\n <script\n crossorigin\n src="https://unpkg.com/react@18.2.0/umd/react.production.min.js"\n ></script>\n <script\n crossorigin\n src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js"\n ></script>\n <script>\n const withKey = (props, key) =>\n key == null ? props : Object.assign({}, props, { key });\n const jsx = (type, props, key) =>\n React.createElement(type, withKey(props, key));\n const jsxRuntime = {\n Fragment: React.Fragment,\n jsx,\n jsxs: jsx,\n jsxDEV: jsx,\n };\n window.ReactJSXRuntime = jsxRuntime;\n window[\'react/jsx-runtime\'] = jsxRuntime;\n window[\'react/jsx-dev-runtime\'] = jsxRuntime;\n </script>\n <script src="https://unpkg.com/@qwen-code/webui@latest/dist/index.umd.js"></script>\n <link\n rel="stylesheet"\n href="https://unpkg.com/@qwen-code/webui@latest/dist/styles.css"\n />\n <title>Qwen Code Chat Export</title>\n <script>\n // Pre-hydrate FOUC guard: must run before <style> below applies layout.\n // The storage key \'qwen-export-theme\' is duplicated here verbatim and\n // MUST stay in sync with EXPORT_THEME_STORAGE_KEY in\n // src/components/useExportTheme.ts.\n (function () {\n try {\n var stored = window.localStorage.getItem(\'qwen-export-theme\');\n var theme = stored === \'light\' || stored === \'dark\' ? stored : \'dark\';\n var root = document.documentElement;\n // Toggle-style writes mirror the React hook\'s effect, so the two\n // code paths converge on identical class state.\n root.classList.toggle(\'light\', theme === \'light\');\n root.classList.toggle(\'dark\', theme === \'dark\');\n } catch (e) {\n // localStorage may be unavailable (private mode, file:// sandbox);\n // the static class="dark" attribute on <html> remains the default.\n }\n })();\n </script>\n <style>\n @font-face {\n font-family: "Press Start 2P";\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url("data:font/woff2;base64,d09GMgABAAAAAALQAAwAAAAABfwAAAKBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCgGYABUEQgKgkSCDAsOAAE2AiQDDgQgBYRKByAb4QTIBB76Oev9JKW02x5ClpELSxHm1M0JQ+OBJAtDpAAVUQ7i///V+A/YgLVswlGo/7a+lmW3sfnUvoBFcUKzUFEnKo08S0F2T8TiAAJQieDvSGUVdW3smBv2LuCGjSpG3jQTD/m9OI5lTDomdQG1hkoMkCJu1ZYsmL42dEu7W8q5gUan/J6yyO+FX5NO5qQPxaqGnEINZ2q7kDf0+i4UigAXdiQUNMppoJnOzcxnDMwX5lXzinnJPDtkzhQFwjTx0DGrx1zkoNhIYr5LTKHjclcs+z3Frrh2ue3Kvk6bxzoRJLsIQpWcQhW27bgJwoUHYXNi2WWnVRUWaVNS0XMJ1eIUHlSX0l3l7BZOOos1ySk7NUWl6+eobG3Nfpj96g8EvukB3Qjouo4+O6svG9/0b8ZyKmfoZj9gzBqq8I2MS7Pf2JquL9vZwHJ51djyD01vbVHRDxSslvFBZwMHjQvexMxIvz3oyftul2+k9yBS+xGM+l+d+Pvo/zH5fVXMRvsHhG4u9/dRsgQyF67l9+jYgZuy+Ath2O6EUzU7E6BxF41nQk2cgkN8IIlOPKecMgWccSrE4XdaOECf00oUaeTm34EpvHhZIodEEllllBWmWcJLyQmsPjNHAousMEkijVRQR5OgNc4qq7TiZZg89pJCE/G0MM4kPuYqqIOKrQw3WmQBjVQSSLLm1H1NiGmCN21uwK/JpZRuWignd/klmbWXFEtZZIn1o8cmkaDqX5JIJgWNNqYYR9s0GsRFZhhntKJSjI+KTaFDZ+MoRllkjHWK2ADCxilLQGTkJZo4NAJMDwhAiK0CJD+jjKFRwWBapYFh5rdzfogQC/m1XLplXiEFEwAA") format("woff2");\n }\n :root{--bg-primary: #18181b;--bg-secondary: #27272a;--text-primary: #f4f4f5;--text-secondary: #a1a1aa;--border-color: #3f3f46;--accent-color: #3b82f6;--header-bg: rgba(24, 24, 27, .95);--scrollbar-thumb-hover: #52525b}:root.light{--bg-primary: #ffffff;--bg-secondary: #f3f4f6;--text-primary: #1f2937;--text-secondary: #6b7280;--border-color: #e5e7eb;--accent-color: #2563eb;--header-bg: rgba(249, 250, 251, .95);--scrollbar-thumb-hover: #d1d5db;--app-primary-foreground: #1f2937;--app-secondary-foreground: #6b7280;--app-background: #ffffff;--app-primary-background: #ffffff;--app-background-secondary: #f3f4f6;--app-background-tertiary: #e5e7eb;--app-foreground: #1f2937;--app-foreground-secondary: #6b7280;--app-foreground-muted: #9ca3af;--app-border: #e5e7eb;--app-primary-border-color: #e5e7eb;--app-input-background: #ffffff;--app-input-border: #d1d5db;--app-input-placeholder-foreground: #9ca3af;--app-ghost-button-hover-background: rgba(0, 0, 0, .05);--app-header-background: #f9fafb;--app-list-hover-background: rgba(0, 0, 0, .05);--app-list-active-background: #3b82f6;--app-menu-background: #ffffff;--app-menu-border: #e5e7eb;--app-menu-foreground: #1f2937;--app-tool-background: #ffffff;--app-code-background: #f3f4f6;--app-secondary-background: #f3f4f6;--app-input-secondary-background: #f3f4f6;--app-input-foreground: #1f2937;--app-button-background: #e5e7eb;--app-button-secondary-background: #f3f4f6;--app-button-foreground: #1f2937;--app-transparent-inner-border: rgba(0, 0, 0, .1);--app-warning-foreground: #b45309}body{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;margin:0;padding:0;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.6;-webkit-font-smoothing:antialiased}.page-wrapper{min-height:100vh;display:flex;flex-direction:column;align-items:center}.header{width:100%;padding:16px 24px;border-bottom:1px solid var(--border-color);background-color:var(--header-bg);backdrop-filter:blur(8px);position:sticky;top:0;z-index:100;display:flex;justify-content:space-between;align-items:center;box-sizing:border-box}.header-left{display:flex;align-items:center;gap:12px}.header-right{display:flex;align-items:center;gap:8px}.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid var(--border-color);border-radius:999px;color:var(--text-secondary);cursor:pointer;transition:background-color .15s ease,color .15s ease,border-color .15s ease}.theme-toggle:hover{background-color:var(--bg-secondary);color:var(--text-primary)}.theme-toggle:focus-visible{outline:2px solid var(--accent-color);outline-offset:2px}.theme-toggle:active{transform:scale(.95)}.logo-icon{width:24px;height:24px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.logo-icon svg{width:100%;height:100%}.logo{display:flex;flex-direction:column;line-height:1}.logo-text{font-family:"Press Start 2P",cursive;font-weight:400;font-size:24px;letter-spacing:-.05em;position:relative;color:#fff}.logo-text-inner{background:linear-gradient(to right,#60a5fa,#a855f7);-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.logo-text:before,.logo-text:after{content:attr(data-text);position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;background:none;-webkit-text-fill-color:transparent;-webkit-text-stroke:1px rgba(96,165,250,.3)}.logo-text:before{transform:translate(2px,2px);-webkit-text-stroke:1px rgba(168,85,247,.3)}.logo-text:after{transform:translate(4px,4px);opacity:.4}.logo-sub{font-size:11px;font-weight:600;color:var(--text-secondary);letter-spacing:.05em;text-transform:uppercase;margin-top:4px}.badge{font-size:11px;padding:2px 8px;border-radius:999px;background-color:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--border-color);font-weight:500}.meta{display:flex;gap:24px;font-size:13px;color:var(--text-secondary)}.meta-item{display:flex;align-items:center;gap:8px}.meta-label{color:var(--text-secondary)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:var(--bg-primary)}::-webkit-scrollbar-thumb{background:var(--bg-secondary);border-radius:5px;border:2px solid var(--bg-primary)}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-thumb-hover)}@media (max-width: 768px){.chat-container{max-width:100%;padding:20px 16px}.header{padding:12px 16px}.meta{width:100%;flex-direction:column;gap:6px}}@media (max-width: 480px){.chat-container{padding:16px 12px}}.content-wrapper{display:flex;width:100%;max-width:1600px;height:calc(100vh - 73px)}.chat-container{flex:1;min-width:0;overflow-y:auto;padding:24px;box-sizing:border-box}.metadata-sidebar{width:320px;min-width:320px;padding:12px;border-right:1px solid var(--border-color);background-color:var(--bg-secondary);display:flex;flex-direction:column;gap:12px;overflow-y:auto;height:100%;box-sizing:border-box}.metadata-section{display:flex;flex-direction:column;gap:8px}.metadata-section-title{font-size:10px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin:0;padding-bottom:4px;border-bottom:1px solid var(--border-color)}.metadata-section-small{margin-top:auto;padding-top:12px;border-top:1px solid var(--border-color)}.metadata-item{display:flex;flex-direction:column;gap:2px}.metadata-item-empty{font-size:12px;color:var(--text-secondary);margin:0;padding:4px 0}.metadata-content{display:flex;flex-direction:column;gap:2px;min-width:0}.metadata-content .metadata-label{font-size:10px;color:var(--text-secondary)}.metadata-content .metadata-value{font-size:12px;color:var(--text-primary);word-break:break-all;line-height:1.3;cursor:pointer}.metadata-content .metadata-value.multiline{white-space:pre-wrap}.metadata-content .metadata-value.text-green{color:#22c55e}.metadata-content .metadata-value.text-red{color:#ef4444}.metadata-value-with-copy{display:flex;align-items:center;gap:8px}.metadata-value-with-copy .metadata-value{flex:1;min-width:0}.copy-button{display:inline-flex;align-items:center;justify-content:center;padding:4px;background:transparent;border:1px solid var(--border-color, #3f3f46);border-radius:4px;color:var(--text-secondary, #a1a1aa);cursor:pointer;transition:all .15s ease;flex-shrink:0}.copy-button:hover{background:var(--bg-hover, #27272a);color:var(--text-primary, #f4f4f5);border-color:var(--border-hover, #52525b)}.copy-button:active{transform:scale(.95)}@media (max-width: 1024px){.metadata-sidebar{width:320px;min-width:320px;padding:10px}}@media (max-width: 768px){.content-wrapper{flex-direction:column;height:auto}.chat-container{height:auto;min-height:50vh}.metadata-sidebar{width:100%;min-width:100%;height:auto;max-height:none;border-right:none;border-top:1px solid var(--border-color);padding:12px;gap:12px}.metadata-section{flex-direction:row;flex-wrap:wrap;gap:12px}.metadata-section-title{width:100%;border-bottom:none;padding-bottom:0}.metadata-item{flex:1;min-width:140px}.metadata-section-small{margin-top:0;padding-top:0;border-top:none}}.modal-overlay{position:fixed;inset:0;z-index:1000;background-color:#0009;display:flex;align-items:center;justify-content:center;padding:24px}.modal-container{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:12px;width:100%;max-width:800px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 25px 50px -12px #00000080}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border-color);flex-shrink:0}.modal-title{font-size:13px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.modal-close{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:6px;line-height:1;transition:background-color .15s,color .15s}.modal-close:hover{background-color:var(--border-color);color:var(--text-primary)}.modal-content{margin:0;padding:16px;overflow:auto;font-size:13px;line-height:1.6;color:var(--text-primary);white-space:pre-wrap;word-break:break-word}\n </style>\n </head>\n <body>\n <div id="app"></div>\n\n <script id="chat-data" type="application/json"></script>\n <script>\n (()=>{var f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.38 140">\n <path\n fill="#000000"\n d="m140.93 85-16.35-28.33-1.93-3.34 8.66-15a3.323 3.323 0 0 0 0-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33 3.33 0 0 0-2.89-1.67H51.43c-.59 0-1.17.16-1.66.45-.5.29-.92.71-1.22 1.22L32.19 29.98l-1.92 3.33H12.96c-.59 0-1.17.16-1.66.45-.5.29-.93.71-1.22 1.22L.45 51.66a3.323 3.323 0 0 0 0 3.34l18.28 31.67-8.66 15a3.32 3.32 0 0 0 0 3.34l9.62 16.67c.3.51.72.93 1.22 1.22s1.07.45 1.67.45h36.56l8.66 15a3.35 3.35 0 0 0 2.89 1.67h19.25a3.34 3.34 0 0 0 2.89-1.67l18.28-31.67h17.32c.6 0 1.17-.16 1.67-.45s.92-.71 1.22-1.22l9.62-16.67a3.323 3.323 0 0 0 0-3.34ZM51.44 3.33 61.07 20l-9.63 16.66h76.98l-9.62 16.66H45.67l-11.54-20zM57.21 120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62 16.67L68.78 100l-11.55 20Zm61.59-33.34-9.62-16.67-38.49 66.67-9.63-16.67 9.63-16.66 26.94-46.67h23.1l17.32 30z"\n />\n</svg>\n`;var l=window.React,h=({state:e,onClose:t})=>(l.useEffect(()=>{if(e.visible){let o=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=o}}},[e.visible]),e.visible?l.createElement("div",{className:"modal-overlay",onClick:t},l.createElement("div",{className:"modal-container",onClick:o=>o.stopPropagation()},l.createElement("div",{className:"modal-header"},l.createElement("span",{className:"modal-title font-mono"},e.fileName),l.createElement("button",{className:"modal-close",onClick:t,"aria-label":"Close"},"\\u2715")),l.createElement("pre",{className:"modal-content"},e.content))):null),x=()=>{let[e,t]=l.useState({visible:!1,content:"",fileName:""}),o=l.useCallback((n,p="temp")=>{t({visible:!0,content:n,fileName:p})},[]),i=l.useCallback(()=>{t(n=>({...n,visible:!1}))},[]);return{modalState:e,openModal:o,closeModal:i}};var z=window.React,b=()=>{let{modalState:e,openModal:t,closeModal:o}=x();return{platformContext:z.useMemo(()=>({platform:"web",postMessage:n=>{console.log("Posted message:",n)},onMessage:n=>(window.addEventListener("message",n),()=>window.removeEventListener("message",n)),openFile:n=>{console.log("Opening file:",n)},openTempFile:t,getResourceUrl:()=>{},features:{canOpenFile:!1,canOpenTempFile:!0,canCopy:!0}}),[t]),modalState:e,closeModal:o}};var a=({label:e,value:t,valueClass:o})=>t==null||t===""?null:React.createElement("div",{className:"metadata-item"},React.createElement("div",{className:"metadata-content"},React.createElement("span",{className:"metadata-label"},e),React.createElement("span",{className:`metadata-value ${o||""}`,title:typeof t=="string"?t:void 0},t)));var v=e=>!!e&&typeof e=="object",w=()=>{let e=document.getElementById("chat-data");if(!(e!=null&&e.textContent))return{};try{let t=JSON.parse(e.textContent);return t&&typeof t=="object"?t:{}}catch(t){return console.error("Failed to parse chat data.",t),{}}};var y=e=>{if(!e)return"-";try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch(t){return e}},k=e=>{if(!e)return"-";try{let o=new Date(e).getTime();if(Number.isNaN(o))return"-";let n=Math.max(0,new Date().getTime()-o),p=Math.floor(n/1e3),c=Math.floor(p/60),d=Math.floor(c/60),s=Math.floor(d/24),m=Math.floor(s/7),g=Math.floor(s/30),u=Math.floor(s/365);return p<60?"just now":c<60?`${c} minute${c===1?"":"s"} ago`:d<24?`${d} hour${d===1?"":"s"} ago`:s<7?`${s} day${s===1?"":"s"} ago`:m<4?`${m} week${m===1?"":"s"} ago`:g<12?`${g} month${g===1?"":"s"} ago`:`${u} year${u===1?"":"s"} ago`}catch(t){return"-"}};var M=e=>{if(e!=null)return e>=1e6?`${(e/1e6).toFixed(e%1e6===0?0:1)}m`:e>=1e3?`${(e/1e3).toFixed(e%1e3===0?0:1)}k`:e.toString()};var T=({metadata:e})=>React.createElement("aside",{className:"metadata-sidebar"},React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Session Info"),React.createElement(a,{label:"Session created",value:k(e.startTime)}),React.createElement(a,{label:"Project",value:e.cwd,valueClass:"multiline"}),e.gitRepo&&React.createElement(a,{label:"Repository",value:e.gitRepo}),e.gitBranch&&React.createElement(a,{label:"Branch",value:e.gitBranch}),e.model&&React.createElement(a,{label:"Model",value:e.model}),e.channel&&React.createElement(a,{label:"Channel",value:e.channel})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Statistics"),React.createElement(a,{label:"Prompts",value:e.promptCount}),e.contextUsagePercent!==void 0&&e.contextWindowSize!==void 0&&React.createElement(a,{label:"Context",value:`${e.contextUsagePercent>100?">100":e.contextUsagePercent}% of ${M(e.contextWindowSize)}`,valueClass:e.contextUsagePercent>100?"text-red":void 0}),e.totalTokens!==void 0&&React.createElement(a,{label:"Tokens",value:e.totalTokens.toLocaleString()})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"File Operations"),e.filesWritten!==void 0&&e.filesWritten>0&&React.createElement(a,{label:"Files modified",value:e.filesWritten}),e.linesAdded!==void 0&&e.linesAdded>0&&React.createElement(a,{label:"Added",value:`+${e.linesAdded}`,valueClass:"text-green"}),e.linesRemoved!==void 0&&e.linesRemoved>0&&React.createElement(a,{label:"Removed",value:`-${e.linesRemoved}`,valueClass:"text-red"}),(e.filesWritten===void 0||e.filesWritten===0)&&(e.linesAdded===void 0||e.linesAdded===0)&&(e.linesRemoved===void 0||e.linesRemoved===0)&&React.createElement("p",{className:"metadata-item metadata-item-empty"},"No file changes")),React.createElement("div",{className:"metadata-section metadata-section-small"},React.createElement(a,{label:"Session ID",value:e.sessionId,valueClass:"font-mono"}),React.createElement(a,{label:"Export Time",value:y(e.exportTime)})));var $=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("circle",{cx:"12",cy:"12",r:"4"}),React.createElement("path",{d:"M12 2v2"}),React.createElement("path",{d:"M12 20v2"}),React.createElement("path",{d:"m4.93 4.93 1.41 1.41"}),React.createElement("path",{d:"m17.66 17.66 1.41 1.41"}),React.createElement("path",{d:"M2 12h2"}),React.createElement("path",{d:"M20 12h2"}),React.createElement("path",{d:"m6.34 17.66-1.41 1.41"}),React.createElement("path",{d:"m19.07 4.93-1.41 1.41"})),D=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"})),C=({theme:e,onToggle:t})=>{let o=e==="light",i=o?"Switch to dark theme":"Switch to light theme";return React.createElement("button",{type:"button",className:"theme-toggle","aria-label":i,"aria-pressed":o,title:i,onClick:t},React.createElement(o?D:$,null))};var L=window.React,{useCallback:j,useEffect:I,useState:W}=L,N="qwen-export-theme",R=e=>e==="light"||e==="dark",F=()=>{try{let e=window.localStorage.getItem(N);if(R(e))return e}catch(e){}return"dark"},O=e=>{let t=document.documentElement;t.classList.toggle("light",e==="light"),t.classList.toggle("dark",e==="dark")},S=()=>{let[e,t]=W(F);I(()=>{O(e);try{window.localStorage.setItem(N,e)}catch(i){}},[e]);let o=j(()=>{t(i=>i==="light"?"dark":"light")},[]);return{theme:e,toggleTheme:o}};var A=window.ReactDOM,r=window.React,{ChatViewer:U,PlatformProvider:V}=QwenCodeWebUI,B=f?f.replace(/<svg([^>]*)>/,\'<svg$1><defs><linearGradient id="qwen-logo-gradient" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#60a5fa" /><stop offset="100%" stop-color="#a855f7" /></linearGradient></defs>\').replace(/fill="[^"]*"/,\'fill="url(#qwen-logo-gradient)"\'):f,H=()=>{let e=w(),o=(Array.isArray(e.messages)?e.messages:[]).filter(v).filter(m=>m.type!=="system"),i=e.metadata,{platformContext:n,modalState:p,closeModal:c}=b(),{theme:d,toggleTheme:s}=S();return r.createElement("div",{className:"page-wrapper"},r.createElement("header",{className:"header"},r.createElement("div",{className:"header-left"},r.createElement("div",{className:"logo-icon","aria-hidden":"true",dangerouslySetInnerHTML:{__html:B}}),r.createElement("div",{className:"logo"},r.createElement("div",{className:"logo-text","data-text":"QWEN"},r.createElement("span",{className:"logo-text-inner"},"QWEN")))),r.createElement("div",{className:"header-right"},r.createElement(C,{theme:d,onToggle:s}))),r.createElement("div",{className:"content-wrapper"},r.createElement("div",{className:"chat-container"},r.createElement(V,{value:n},r.createElement(U,{messages:o,autoScroll:!1,theme:d}))),i&&r.createElement(T,{metadata:i})),r.createElement(h,{state:p,onClose:c}))},E=document.getElementById("app");E?A.createRoot(E).render(r.createElement(H,null)):console.error("App container not found.");})();;\n </script>\n </body>\n</html>\n';
2302
+
2303
+ // packages/cli/src/ui/utils/export/formatters/html.ts
2304
+ function escapeJsonForHtml(json) {
2305
+ return json.replace(/<\/script/gi, "<\\/script").replace(/&/g, "\\u0026").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
2306
+ }
2307
+ __name(escapeJsonForHtml, "escapeJsonForHtml");
2308
+ function loadHtmlTemplate() {
2309
+ return HTML_TEMPLATE;
2310
+ }
2311
+ __name(loadHtmlTemplate, "loadHtmlTemplate");
2312
+ function injectDataIntoHtmlTemplate(template, data) {
2313
+ const jsonData = JSON.stringify(data, null, 2);
2314
+ const escapedJsonData = escapeJsonForHtml(jsonData);
2315
+ const idAttribute = 'id="chat-data"';
2316
+ const idIndex = template.indexOf(idAttribute);
2317
+ if (idIndex === -1) {
2318
+ return template;
2319
+ }
2320
+ const openTagStart = template.lastIndexOf("<script", idIndex);
2321
+ if (openTagStart === -1) {
2322
+ return template;
2323
+ }
2324
+ const openTagEnd = template.indexOf(">", idIndex);
2325
+ if (openTagEnd === -1) {
2326
+ return template;
2327
+ }
2328
+ const closeTagStart = template.indexOf("</script>", openTagEnd);
2329
+ if (closeTagStart === -1) {
2330
+ return template;
2331
+ }
2332
+ const lineStart = template.lastIndexOf("\n", openTagStart);
2333
+ const lineIndent = lineStart === -1 ? "" : template.slice(lineStart + 1, openTagStart);
2334
+ const indentedJson = escapedJsonData.split("\n").map((line) => `${lineIndent}${line}`).join("\n");
2335
+ const before = template.slice(0, openTagEnd + 1);
2336
+ const after = template.slice(closeTagStart);
2337
+ return `${before}
2338
+ ${indentedJson}
2339
+ ${after}`;
2340
+ }
2341
+ __name(injectDataIntoHtmlTemplate, "injectDataIntoHtmlTemplate");
2342
+ function toHtml(sessionData) {
2343
+ const template = loadHtmlTemplate();
2344
+ return injectDataIntoHtmlTemplate(template, sessionData);
2345
+ }
2346
+ __name(toHtml, "toHtml");
2347
+
2348
+ // packages/cli/src/ui/utils/export/formatters/json.ts
2349
+ init_esbuild_shims();
2350
+ function toJson(sessionData) {
2351
+ return JSON.stringify(sessionData, null, 2);
2352
+ }
2353
+ __name(toJson, "toJson");
2354
+
2355
+ // packages/cli/src/ui/utils/export/formatters/jsonl.ts
2356
+ init_esbuild_shims();
2357
+ function toJsonl(sessionData) {
2358
+ const lines = [];
2359
+ const sourceMetadata = sessionData.metadata;
2360
+ const metadata = {
2361
+ type: "session_metadata",
2362
+ sessionId: sessionData.sessionId,
2363
+ startTime: sessionData.startTime
2364
+ };
2365
+ if (sourceMetadata?.exportTime) {
2366
+ metadata["exportTime"] = sourceMetadata.exportTime;
2367
+ }
2368
+ if (sourceMetadata?.cwd) {
2369
+ metadata["cwd"] = sourceMetadata.cwd;
2370
+ }
2371
+ if (sourceMetadata?.gitRepo) {
2372
+ metadata["gitRepo"] = sourceMetadata.gitRepo;
2373
+ }
2374
+ if (sourceMetadata?.gitBranch) {
2375
+ metadata["gitBranch"] = sourceMetadata.gitBranch;
2376
+ }
2377
+ if (sourceMetadata?.model) {
2378
+ metadata["model"] = sourceMetadata.model;
2379
+ }
2380
+ if (sourceMetadata?.channel) {
2381
+ metadata["channel"] = sourceMetadata.channel;
2382
+ }
2383
+ if (sourceMetadata?.promptCount !== void 0) {
2384
+ metadata["promptCount"] = sourceMetadata.promptCount;
2385
+ }
2386
+ if (sourceMetadata?.contextUsagePercent !== void 0) {
2387
+ metadata["contextUsagePercent"] = sourceMetadata.contextUsagePercent;
2388
+ }
2389
+ if (sourceMetadata?.contextWindowSize !== void 0) {
2390
+ metadata["contextWindowSize"] = sourceMetadata.contextWindowSize;
2391
+ }
2392
+ if (sourceMetadata?.totalTokens !== void 0) {
2393
+ metadata["totalTokens"] = sourceMetadata.totalTokens;
2394
+ }
2395
+ if (sourceMetadata?.filesWritten !== void 0) {
2396
+ metadata["filesWritten"] = sourceMetadata.filesWritten;
2397
+ }
2398
+ if (sourceMetadata?.linesAdded !== void 0) {
2399
+ metadata["linesAdded"] = sourceMetadata.linesAdded;
2400
+ }
2401
+ if (sourceMetadata?.linesRemoved !== void 0) {
2402
+ metadata["linesRemoved"] = sourceMetadata.linesRemoved;
2403
+ }
2404
+ if (sourceMetadata?.uniqueFiles && sourceMetadata.uniqueFiles.length > 0) {
2405
+ metadata["uniqueFiles"] = sourceMetadata.uniqueFiles;
2406
+ }
2407
+ lines.push(JSON.stringify(metadata));
2408
+ for (const message of sessionData.messages) {
2409
+ lines.push(JSON.stringify(message));
2410
+ }
2411
+ return lines.join("\n");
2412
+ }
2413
+ __name(toJsonl, "toJsonl");
2414
+
2415
+ // packages/cli/src/ui/utils/export/utils.ts
2416
+ init_esbuild_shims();
2417
+ function generateExportFilename(extension) {
2418
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2419
+ return `qwen-code-export-${timestamp}.${extension}`;
2420
+ }
2421
+ __name(generateExportFilename, "generateExportFilename");
2422
+
2423
+ // packages/cli/src/ui/utils/export/index.ts
2424
+ init_esbuild_shims();
2425
+
2426
+ export {
2427
+ GITHUB_WORKFLOW_PATHS,
2428
+ SetupGithubError,
2429
+ setupGithub,
2430
+ MessageEmitter,
2431
+ PlanEmitter,
2432
+ ToolCallEmitter,
2433
+ HistoryReplayer,
2434
+ collectSessionData,
2435
+ normalizeSessionData,
2436
+ toMarkdown,
2437
+ INSIGHT_JS,
2438
+ INSIGHT_CSS,
2439
+ toHtml,
2440
+ toJson,
2441
+ toJsonl,
2442
+ generateExportFilename
2443
+ };
2444
+ /**
2445
+ * @license
2446
+ * Copyright 2025 Qwen
2447
+ * SPDX-License-Identifier: Apache-2.0
2448
+ */
2449
+ /**
2450
+ * @license
2451
+ * Copyright 2025 Qwen Team
2452
+ * SPDX-License-Identifier: Apache-2.0
2453
+ */
2454
+ /**
2455
+ * @license
2456
+ * Copyright 2025 Google LLC
2457
+ * SPDX-License-Identifier: Apache-2.0
2458
+ */
2459
+ /**
2460
+ * @license
2461
+ * Copyright 2025 Qwen Team
2462
+ * SPDX-License-Identifier: Apache-2.0
2463
+ *
2464
+ * This file is code-generated; do not edit manually.
2465
+ */
2466
+ /**
2467
+ * @license
2468
+ * Copyright 2025 Qwen Team
2469
+ * SPDX-License-Identifier: Apache-2.0
2470
+ *
2471
+ * This HTML template is code-generated; do not edit manually.
2472
+ */