@hienlh/ppm 0.17.16 → 0.17.18

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 (464) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/cli-reference.md +4 -4
  4. package/assets/skills/ppm/references/http-api.md +5 -1
  5. package/dist/web/assets/{ai-resource-editor-CsossqDO.js → ai-resource-editor-BgWg-ty8.js} +1 -1
  6. package/dist/web/assets/{angular-html-CkxY2iBQ.js → angular-html-2g8YGiJY.js} +1 -1
  7. package/dist/web/assets/{angular-ts-BePeGkkC.js → angular-ts-BwSmoLfh.js} +1 -1
  8. package/dist/web/assets/{api-settings-DAk7D-NP.js → api-settings-BJTjIG4U.js} +1 -1
  9. package/dist/web/assets/{api-themes-84MT-XqR.js → api-themes-DuLpbQFV.js} +1 -1
  10. package/dist/web/assets/{apl-DBS7PWvB.js → apl-B44SMKHp.js} +1 -1
  11. package/dist/web/assets/architecture-PBZL5I3N-gLlhsjM9.js +1 -0
  12. package/dist/web/assets/{astro-Clbk1k4h.js → astro-E5620wek.js} +1 -1
  13. package/dist/web/assets/{audio-preview-DIkokvPM.js → audio-preview-CLn1LTxc.js} +1 -1
  14. package/dist/web/assets/{blade-BeBsBuGS.js → blade-D-VQWAHB.js} +1 -1
  15. package/dist/web/assets/{bsl-DYigT3JZ.js → bsl-Bq5qFzpU.js} +1 -1
  16. package/dist/web/assets/{cairo-BjpO78wI.js → cairo-Cn9-ZKRa.js} +1 -1
  17. package/dist/web/assets/chat-tab-tTUVo4G3.js +13 -0
  18. package/dist/web/assets/{cobol-CpuUx69s.js → cobol-IM3E3iCH.js} +1 -1
  19. package/dist/web/assets/code-editor-DMfUjdk5.js +10 -0
  20. package/dist/web/assets/{coffee-FoFd2Cxo.js → coffee-24wG7ekn.js} +1 -1
  21. package/dist/web/assets/{conflict-editor-Dqm1bkyL.js → conflict-editor-BosR4PW3.js} +3 -3
  22. package/dist/web/assets/{cpp-CO_nPfdr.js → cpp-DH9Cqt4g.js} +1 -1
  23. package/dist/web/assets/{crystal-D-UygAAF.js → crystal-4nZYHhdi.js} +1 -1
  24. package/dist/web/assets/{csv-preview-CvP4xzug.js → csv-preview-BqszurHp.js} +1 -1
  25. package/dist/web/assets/data-grid-overlay-editor-DxdOKRAY.js +1 -0
  26. package/dist/web/assets/data-grid-types-CzEQU9PJ.js +1 -0
  27. package/dist/web/assets/database-viewer-CiomoOU6.js +1 -0
  28. package/dist/web/assets/dialog-BpkAWOy8.js +1 -0
  29. package/dist/web/assets/{diff-viewer-BfWixe_z.js → diff-viewer-aOrOaGWx.js} +1 -1
  30. package/dist/web/assets/dist-Bn3E6I4R.js +11 -0
  31. package/dist/web/assets/{docx-preview-CguUoTKe.js → docx-preview-BAzpJdua.js} +1 -1
  32. package/dist/web/assets/{edge-BSzxzX11.js → edge-DTI9d2Qi.js} +1 -1
  33. package/dist/web/assets/{elixir-DH1-Mrep.js → elixir-Ys0wioho.js} +1 -1
  34. package/dist/web/assets/{elm-B0ln5J70.js → elm-Cihc9TAz.js} +1 -1
  35. package/dist/web/assets/{erb-GIz6NnlZ.js → erb-BwYBWK2-.js} +1 -1
  36. package/dist/web/assets/{erlang-B8MgYhib.js → erlang-CzlD_Joo.js} +1 -1
  37. package/dist/web/assets/esm-JLkfN0k-.js +2 -0
  38. package/dist/web/assets/{extension-webview-DTpFt1eL.js → extension-webview-CKUUvgOr.js} +1 -1
  39. package/dist/web/assets/{fortran-fixed-form-D_-TrK6U.js → fortran-fixed-form-CT90EtSp.js} +1 -1
  40. package/dist/web/assets/{fsharp-C9cLCk2b.js → fsharp-LasxezlU.js} +1 -1
  41. package/dist/web/assets/{gdresource-CsZ3lXwY.js → gdresource-XqgPdfiE.js} +1 -1
  42. package/dist/web/assets/{git-commit-xmq0KqrA.js → git-commit-CZBgPolw.js} +1 -1
  43. package/dist/web/assets/{git-log-panel-DUX7N5tN.js → git-log-panel-B6GFWhj4.js} +1 -1
  44. package/dist/web/assets/{git-rebase-D3O-jsSX.js → git-rebase-C2VzKDB1.js} +1 -1
  45. package/dist/web/assets/gitGraph-HDMCJU4V-BKGq--Jw.js +1 -0
  46. package/dist/web/assets/glide-data-grid-z9FPvRBG.js +138 -0
  47. package/dist/web/assets/{glimmer-js-g74gESrC.js → glimmer-js-DfjWcOLD.js} +1 -1
  48. package/dist/web/assets/{glimmer-ts-DF4aDWHT.js → glimmer-ts-DBldQATc.js} +1 -1
  49. package/dist/web/assets/{glsl-D5LmfW7l.js → glsl-CzNv1NPP.js} +1 -1
  50. package/dist/web/assets/{graphql-_KI4RuXL.js → graphql-DDyLtQb4.js} +1 -1
  51. package/dist/web/assets/group-chat-tab-Bu31mwmF.js +1 -0
  52. package/dist/web/assets/{hack-B1NaTC39.js → hack-CtoYNYkC.js} +1 -1
  53. package/dist/web/assets/{haml-DDFXadZ4.js → haml-CnBVap7G.js} +1 -1
  54. package/dist/web/assets/{handlebars-Bp-Jq3K9.js → handlebars-Dg51esUH.js} +1 -1
  55. package/dist/web/assets/{html-DyB9_5Tj.js → html-Ec2_evSy.js} +1 -1
  56. package/dist/web/assets/{html-derivative-CC60wi-3.js → html-derivative-Cy-F7ZqL.js} +1 -1
  57. package/dist/web/assets/{http-C-9qngH4.js → http-C236v8Tg.js} +1 -1
  58. package/dist/web/assets/{hurl-BtxgpNDs.js → hurl-0rMD2gPU.js} +1 -1
  59. package/dist/web/assets/{hxml-DOoOS9op.js → hxml-e5uS5jTD.js} +1 -1
  60. package/dist/web/assets/{image-preview-CZg6FQ3w.js → image-preview-CaX4gpN6.js} +1 -1
  61. package/dist/web/assets/index-4M24PSHW.js +50 -0
  62. package/dist/web/assets/index-BYFXiFsa.css +2 -0
  63. package/dist/web/assets/info-3K5VOQVL-BOhGriBF.js +1 -0
  64. package/dist/web/assets/{jinja-cN-150ao.js → jinja-DybFmhfq.js} +1 -1
  65. package/dist/web/assets/{jison-CqjsqPq5.js → jison-hkHbixdZ.js} +1 -1
  66. package/dist/web/assets/{julia-C-I5m8W4.js → julia-QnxY6sRE.js} +1 -1
  67. package/dist/web/assets/{just-CgsSW9zs.js → just-1Rs-nm8g.js} +1 -1
  68. package/dist/web/assets/keybindings-store-Cv-U85V6.js +1 -0
  69. package/dist/web/assets/{latex-BFzR9N2d.js → latex-jEBQqA7u.js} +1 -1
  70. package/dist/web/assets/{liquid-BWfr-_iC.js → liquid-DfJaZpxG.js} +1 -1
  71. package/dist/web/assets/{lua-DsXVun6g.js → lua-ti0Jr6-C.js} +1 -1
  72. package/dist/web/assets/{markdown-renderer-CiQkvWP_.js → markdown-renderer-BNXJygz9.js} +3 -3
  73. package/dist/web/assets/markdown-renderer-DCsEEdo7.js +1 -0
  74. package/dist/web/assets/{marko-DWBbo09n.js → marko-DNj4AhPg.js} +1 -1
  75. package/dist/web/assets/{mdc-CUMe9LOG.js → mdc-DPFwQFe4.js} +1 -1
  76. package/dist/web/assets/mobile-bottom-sheet--5_YEewV.js +1 -0
  77. package/dist/web/assets/{nextflow-CoYbADOm.js → nextflow-BUrFV5aB.js} +1 -1
  78. package/dist/web/assets/{nginx-z-JRZREw.js → nginx-BrW9NdOb.js} +1 -1
  79. package/dist/web/assets/{nim-Ci4LHyBm.js → nim-DS_6PF2p.js} +1 -1
  80. package/dist/web/assets/notification-store-DADt1gJH.js +1 -0
  81. package/dist/web/assets/{number-overlay-editor-lnnuUpPI.js → number-overlay-editor-CReXWiQ1.js} +1 -1
  82. package/dist/web/assets/packet-RMMSAZCW-CdLFnL8a.js +1 -0
  83. package/dist/web/assets/{panel-store-D6RV_ztx.js → panel-store-DnbT1c8L.js} +1 -1
  84. package/dist/web/assets/{pdf-preview-B6ZqANpw.js → pdf-preview-DZzbm9A4.js} +1 -1
  85. package/dist/web/assets/{perl-pbDimKOO.js → perl-ytm9vKO_.js} +1 -1
  86. package/dist/web/assets/{php-B003E5v7.js → php-DWTD1Usw.js} +1 -1
  87. package/dist/web/assets/pie-UPGHQEXC-COC-h0zz.js +1 -0
  88. package/dist/web/assets/{trash-2-CbbD5QF1.js → plus-DcuJuDC3.js} +1 -1
  89. package/dist/web/assets/postgres-viewer-BxpeiVkt.js +3 -0
  90. package/dist/web/assets/{project-store-Cekcjcom.js → project-store-Sbnqc41N.js} +1 -1
  91. package/dist/web/assets/{pug-AoueAWJo.js → pug-Bt7KL3_r.js} +1 -1
  92. package/dist/web/assets/{qml-CepxioQA.js → qml-Dexdon5J.js} +1 -1
  93. package/dist/web/assets/radar-KQ55EAFF-CiCfdJNL.js +1 -0
  94. package/dist/web/assets/{razor-lIvU-Gu-.js → razor-DnYCSl0G.js} +1 -1
  95. package/dist/web/assets/{rst-Dn-dwElE.js → rst-BEFYzwF8.js} +1 -1
  96. package/dist/web/assets/{ruby-DmsD1Iz5.js → ruby-BPaXFEjN.js} +1 -1
  97. package/dist/web/assets/{sas-6IM2P4YP.js → sas-CywiNBp8.js} +1 -1
  98. package/dist/web/assets/{scss-RgYEZQqh.js → scss-CGk0L6hN.js} +1 -1
  99. package/dist/web/assets/{settings-store-BkSf4SPQ.js → settings-store-DkRZhj-g.js} +2 -2
  100. package/dist/web/assets/settings-tab-DJOhpW09.js +1 -0
  101. package/dist/web/assets/{shaderlab-B0MNEwt4.js → shaderlab-Byjk0kH7.js} +1 -1
  102. package/dist/web/assets/{shellsession-F8S4LrQI.js → shellsession-DbA70QB6.js} +1 -1
  103. package/dist/web/assets/{soy-DDlMbX7u.js → soy-Bm97kWiA.js} +1 -1
  104. package/dist/web/assets/sparkles-B3DmG8PJ.js +1 -0
  105. package/dist/web/assets/{sparql-kthmGAAe.js → sparql-CawLnniT.js} +1 -1
  106. package/dist/web/assets/{sql-query-editor-BYNM0RRl.js → sql-query-editor-9TwIPvRj.js} +1 -1
  107. package/dist/web/assets/sqlite-viewer-D-3i_x28.js +1 -0
  108. package/dist/web/assets/{stata-Tfbew8La.js → stata-RifEDtNO.js} +1 -1
  109. package/dist/web/assets/{surrealql-C0LIGqRx.js → surrealql-DGRQa5Lm.js} +1 -1
  110. package/dist/web/assets/{svelte-CfTy8CGF.js → svelte-w9Hb12aM.js} +1 -1
  111. package/dist/web/assets/system-monitor-tab-CuVVp2wt.js +1 -0
  112. package/dist/web/assets/{tab-store-CcLQfu8H.js → tab-store-vn0viMOP.js} +1 -1
  113. package/dist/web/assets/{templ-V5H1Sbfy.js → templ-BpUwjJXV.js} +1 -1
  114. package/dist/web/assets/{terminal-tab-CK3lX-0Y.js → terminal-tab-DrSqSrdX.js} +2 -2
  115. package/dist/web/assets/{tex-C3H3uMZf.js → tex-DJFSsuTD.js} +1 -1
  116. package/dist/web/assets/tool-cards-CtE_JnF-.js +7 -0
  117. package/dist/web/assets/treemap-KZPCXAKY-CZwuSCtA.js +1 -0
  118. package/dist/web/assets/{ts-tags-7AXgG5YS.js → ts-tags-vp9Qvx2O.js} +1 -1
  119. package/dist/web/assets/{twig-BSyS38T3.js → twig-CoazxjRB.js} +1 -1
  120. package/dist/web/assets/{use-blob-url-CpyRr7Cx.js → use-blob-url-DdXgVqfz.js} +1 -1
  121. package/dist/web/assets/use-is-mobile-CE6AamG6.js +1 -0
  122. package/dist/web/assets/{use-monaco-theme-Jj2OxkAE.js → use-monaco-theme-BvzqffqR.js} +1 -1
  123. package/dist/web/assets/{vendor-mermaid-DGOXKrJC.js → vendor-mermaid-DPpYkrMf.js} +193 -193
  124. package/dist/web/assets/{video-preview-BOHxkwKG.js → video-preview-DxdyVATR.js} +1 -1
  125. package/dist/web/assets/{vue-C4d_br9u.js → vue-CnshsiXd.js} +1 -1
  126. package/dist/web/assets/{vue-html-CGdoz4vW.js → vue-html-CZshynFp.js} +1 -1
  127. package/dist/web/assets/{vue-vine-CqNolQlN.js → vue-vine-C5gtp_T1.js} +1 -1
  128. package/dist/web/assets/{xml-UmCmu-Od.js → xml-BEGJasgj.js} +1 -1
  129. package/dist/web/assets/{xsl-DJG6USGh.js → xsl-DXpRLjYk.js} +1 -1
  130. package/dist/web/index.html +22 -20
  131. package/dist/web/monacoeditorwork/css.worker.bundle.js +122 -122
  132. package/dist/web/monacoeditorwork/editor.worker.bundle.js +78 -78
  133. package/dist/web/monacoeditorwork/html.worker.bundle.js +110 -110
  134. package/dist/web/monacoeditorwork/json.worker.bundle.js +108 -108
  135. package/dist/web/monacoeditorwork/ts.worker.bundle.js +81 -81
  136. package/dist/web/sw.js +1 -1
  137. package/docs/journal/binary-self-upgrade-260724.md +66 -0
  138. package/nul/docs/claude-agent-sdk-reference.md +780 -0
  139. package/nul/docs/code-standards.md +1080 -0
  140. package/nul/docs/codebase-summary.md +916 -0
  141. package/nul/docs/deployment-guide.md +702 -0
  142. package/nul/docs/design-guidelines.md +767 -0
  143. package/nul/docs/extension-development-guide.md +629 -0
  144. package/nul/docs/journals/260414-1400-ext-git-graph-port-complete.md +147 -0
  145. package/nul/docs/journals/260414-1452-git-graph-faithful-port.md +144 -0
  146. package/nul/docs/journals/260414-1810-git-graph-ui-improvements-complete.md +261 -0
  147. package/nul/docs/journals/260414-2001-bundled-extensions.md +219 -0
  148. package/nul/docs/journals/260415-frontend-memory-optimization.md +73 -0
  149. package/nul/docs/lessons-learned.md +70 -0
  150. package/nul/docs/project-changelog.md +574 -0
  151. package/nul/docs/project-overview-pdr.md +205 -0
  152. package/nul/docs/project-roadmap.md +222 -0
  153. package/nul/docs/system-architecture.md +1961 -0
  154. package/package.json +1 -1
  155. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  156. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  157. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  158. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
  159. package/spike-group-channel.mjs +156 -0
  160. package/spike-group-chat.mjs +181 -0
  161. package/src/server/routes/group-chat.ts +118 -9
  162. package/src/services/group-chat/agent-runner.ts +15 -2
  163. package/src/services/group-chat/context-window.ts +15 -0
  164. package/src/services/group-chat/group-chat.service.ts +178 -79
  165. package/src/services/group-chat/group-chat.store.ts +30 -0
  166. package/src/services/group-chat/responder-router.ts +110 -0
  167. package/src/services/group-chat/transcript-archive.ts +18 -0
  168. package/src/services/group-chat/turn-engine.ts +183 -105
  169. package/src/services/jsonl-transcript-parser.ts +36 -0
  170. package/src/types/group-chat-ws.ts +2 -2
  171. package/src/types/group-chat.ts +33 -4
  172. package/src/web/components/group-chat/group-chat-tab.tsx +109 -14
  173. package/src/web/components/group-chat/group-create-dialog.tsx +10 -3
  174. package/src/web/components/group-chat/group-full-transcript-view.tsx +9 -8
  175. package/src/web/components/group-chat/group-member-edit-dialog.tsx +108 -0
  176. package/src/web/components/group-chat/group-member-roster.tsx +51 -23
  177. package/src/web/components/group-chat/group-message-item.tsx +45 -26
  178. package/src/web/components/group-chat/group-transcript-messages.tsx +126 -0
  179. package/src/web/components/layout/cloud-share-popover.tsx +10 -2
  180. package/src/web/components/layout/mobile-drawer-tab-bar.tsx +10 -0
  181. package/src/web/components/layout/mobile-drawer.tsx +26 -9
  182. package/src/web/components/layout/nav-section-rail.tsx +8 -2
  183. package/src/web/components/layout/upgrade-button.tsx +33 -11
  184. package/src/web/hooks/use-group-chat.ts +8 -1
  185. package/src/web/lib/api-group-chat.ts +47 -4
  186. package/src/web/lib/sidebar-tabs/tab-registry.ts +3 -1
  187. package/dist/web/assets/architecture-PBZL5I3N-NAS99xy0.js +0 -1
  188. package/dist/web/assets/chat-tab-Bh6l253v.js +0 -18
  189. package/dist/web/assets/click-outside-container-DXZVmhaX.js +0 -1
  190. package/dist/web/assets/code-editor-B7F-d4DK.js +0 -10
  191. package/dist/web/assets/data-grid-overlay-editor-CUlFsD-D.js +0 -1
  192. package/dist/web/assets/database-viewer-5oNTPgjF.js +0 -1
  193. package/dist/web/assets/dist-BsziT-tR.js +0 -11
  194. package/dist/web/assets/esm-CjVeOTNQ.js +0 -2
  195. package/dist/web/assets/gitGraph-HDMCJU4V-B4I3L4Sf.js +0 -1
  196. package/dist/web/assets/glide-data-grid-7vB1SNne.js +0 -138
  197. package/dist/web/assets/group-chat-tab-CNECY-zg.js +0 -1
  198. package/dist/web/assets/index-D2G6kmTs.js +0 -50
  199. package/dist/web/assets/index-DCmrZnq0.css +0 -2
  200. package/dist/web/assets/info-3K5VOQVL-CBbbOe3C.js +0 -1
  201. package/dist/web/assets/input-24Nf_edC.js +0 -1
  202. package/dist/web/assets/keybindings-store-D8Cppv4w.js +0 -1
  203. package/dist/web/assets/notification-store-DOGxkWih.js +0 -1
  204. package/dist/web/assets/packet-RMMSAZCW-fr8-QSTF.js +0 -1
  205. package/dist/web/assets/pie-UPGHQEXC-Biu7_Pbb.js +0 -1
  206. package/dist/web/assets/postgres-viewer-B23xTCSs.js +0 -3
  207. package/dist/web/assets/radar-KQ55EAFF-CMtNRpK6.js +0 -1
  208. package/dist/web/assets/settings-tab-D5hAA1bY.js +0 -1
  209. package/dist/web/assets/sparkles-2ii4lR7b.js +0 -1
  210. package/dist/web/assets/sqlite-viewer-DW9f2Hqj.js +0 -1
  211. package/dist/web/assets/system-monitor-tab-B5f4pgdX.js +0 -1
  212. package/dist/web/assets/treemap-KZPCXAKY-ZYVFjoaN.js +0 -1
  213. package/dist/web/assets/use-websocket-DrDBgIWU.js +0 -1
  214. /package/dist/web/assets/{abap-BZ3J5hF3.js → abap-wT6fgqwv.js} +0 -0
  215. /package/dist/web/assets/{actionscript-3-CkyGfT-8.js → actionscript-3-CqcHpPYj.js} +0 -0
  216. /package/dist/web/assets/{ada-CxNLBoe7.js → ada-DWE3Hn4E.js} +0 -0
  217. /package/dist/web/assets/{andromeeda-BPN5rsDz.js → andromeeda-DpQ-y-Jt.js} +0 -0
  218. /package/dist/web/assets/{apache-C1F5wHL6.js → apache-LRTUP4r3.js} +0 -0
  219. /package/dist/web/assets/{apex-BaNixdO-.js → apex-DwVeH5_h.js} +0 -0
  220. /package/dist/web/assets/{api-client-Dvzcc_EO.js → api-client-BK4NPNoY.js} +0 -0
  221. /package/dist/web/assets/{applescript-Cl_pdcch.js → applescript-DyQiO9JU.js} +0 -0
  222. /package/dist/web/assets/{apply-theme-ORrEdHKT.js → apply-theme-DxKsrDLA.js} +0 -0
  223. /package/dist/web/assets/{ara-B6UAE7M2.js → ara-Cf-OWd2S.js} +0 -0
  224. /package/dist/web/assets/{asciidoc-D9c9Twki.js → asciidoc-gocbKcVK.js} +0 -0
  225. /package/dist/web/assets/{asm-CNmtv7Y9.js → asm-C3meb5HY.js} +0 -0
  226. /package/dist/web/assets/{aurora-x-C9z-NyzR.js → aurora-x-BYcXaCIg.js} +0 -0
  227. /package/dist/web/assets/{awk-BfLHEnKa.js → awk-BcT6nIdN.js} +0 -0
  228. /package/dist/web/assets/{ayu-dark-Bn7trkt_.js → ayu-dark-CLZPoccg.js} +0 -0
  229. /package/dist/web/assets/{ayu-light-Dpya9hPf.js → ayu-light-CTyRQdS2.js} +0 -0
  230. /package/dist/web/assets/{ayu-mirage-Cc0jfABD.js → ayu-mirage-DjqfqZdo.js} +0 -0
  231. /package/dist/web/assets/{ballerina-BtiCmN7T.js → ballerina-BCARR-zK.js} +0 -0
  232. /package/dist/web/assets/{bat-tmFM76zR.js → bat-_yaRjWOb.js} +0 -0
  233. /package/dist/web/assets/{beancount-BjPqRrcH.js → beancount-BPESBMS9.js} +0 -0
  234. /package/dist/web/assets/{berry-D0SQBxN2.js → berry-BSLE-Sf8.js} +0 -0
  235. /package/dist/web/assets/{bibtex-CkjRWQKr.js → bibtex-CvUWWCVx.js} +0 -0
  236. /package/dist/web/assets/{bicep-Bhq28Cxc.js → bicep--vcqqALZ.js} +0 -0
  237. /package/dist/web/assets/{bird2-DFGInYb3.js → bird2-Clclqgh6.js} +0 -0
  238. /package/dist/web/assets/{c-CP8cB4k_.js → c-CSC2LwTp.js} +0 -0
  239. /package/dist/web/assets/{c3-oRytyeWo.js → c3-Cl1_jUnm.js} +0 -0
  240. /package/dist/web/assets/{cadence-Inf1rGb7.js → cadence-BwAD7vSC.js} +0 -0
  241. /package/dist/web/assets/{catppuccin-frappe-DAzribQo.js → catppuccin-frappe-hr0HKoFX.js} +0 -0
  242. /package/dist/web/assets/{catppuccin-latte-B6Y_mCCQ.js → catppuccin-latte-DXEIYlFO.js} +0 -0
  243. /package/dist/web/assets/{catppuccin-macchiato-COLbYqVL.js → catppuccin-macchiato-B2zST7sA.js} +0 -0
  244. /package/dist/web/assets/{catppuccin-mocha-DKWaML1B.js → catppuccin-mocha-CvrdnYv9.js} +0 -0
  245. /package/dist/web/assets/{chevron-right-BBc6ATtm.js → chevron-right-DeUue2aK.js} +0 -0
  246. /package/dist/web/assets/{circle-question-mark-CveWaCux.js → circle-question-mark-PaJgx-3d.js} +0 -0
  247. /package/dist/web/assets/{clarity-_ZLLrrsX.js → clarity-BeQd5TQD.js} +0 -0
  248. /package/dist/web/assets/{clojure-DWGVCg_P.js → clojure-Csdo0vb_.js} +0 -0
  249. /package/dist/web/assets/{cmake-Cwh3mug7.js → cmake-Cf0q7ddg.js} +0 -0
  250. /package/dist/web/assets/{code-7ZAlTvsm.js → code-TekEnDFM.js} +0 -0
  251. /package/dist/web/assets/{codeowners-BdV6CFYi.js → codeowners-CUEzlC7R.js} +0 -0
  252. /package/dist/web/assets/{codeql-NvupDIDf.js → codeql-DxHyogQt.js} +0 -0
  253. /package/dist/web/assets/{common-lisp-B-vtBh5k.js → common-lisp-WLb-tAda.js} +0 -0
  254. /package/dist/web/assets/{coq-M8-FTfiZ.js → coq-DFtMD6Wn.js} +0 -0
  255. /package/dist/web/assets/{csharp-B7Ugdtd-.js → csharp-DEnvXVjs.js} +0 -0
  256. /package/dist/web/assets/{css-86k3Z-YA.js → css-DMPpCfkZ.js} +0 -0
  257. /package/dist/web/assets/{csv-BX5XYhfH.js → csv-DTSgNSaP.js} +0 -0
  258. /package/dist/web/assets/{csv-parser-d56Fzpwc.js → csv-parser-B_xNn07y.js} +0 -0
  259. /package/dist/web/assets/{cue-B7099gQa.js → cue-BEmVIZmd.js} +0 -0
  260. /package/dist/web/assets/{cypher-D99mWVIu.js → cypher-CncQVhvU.js} +0 -0
  261. /package/dist/web/assets/{d-CFE8oQwh.js → d-BzUSBVex.js} +0 -0
  262. /package/dist/web/assets/{dark-plus-BEeeDwdg.js → dark-plus-mysFNRq2.js} +0 -0
  263. /package/dist/web/assets/{dart-HVSWGnI5.js → dart-BBu3nkcE.js} +0 -0
  264. /package/dist/web/assets/{database-BLht7BVM.js → database-COYAMZaw.js} +0 -0
  265. /package/dist/web/assets/{dax-DjDgSJkh.js → dax-DcLVz9_9.js} +0 -0
  266. /package/dist/web/assets/{desktop-B5A3i7J1.js → desktop-DS2PdvoU.js} +0 -0
  267. /package/dist/web/assets/{diff-CpTrlaE9.js → diff-aUYk5Qys.js} +0 -0
  268. /package/dist/web/assets/{dist-BSCgJs-V.js → dist-Dxl3dqhC.js} +0 -0
  269. /package/dist/web/assets/{docker-xBhmJeHj.js → docker-12Lj1QUD.js} +0 -0
  270. /package/dist/web/assets/{dotenv-DKKhLEv5.js → dotenv-D-P4bzvl.js} +0 -0
  271. /package/dist/web/assets/{dracula-CVwQuzra.js → dracula-C-eRNn4o.js} +0 -0
  272. /package/dist/web/assets/{dracula-soft-CG6mB-lf.js → dracula-soft-CBB1BI7O.js} +0 -0
  273. /package/dist/web/assets/{dream-maker-SC-IdYY3.js → dream-maker-C_j5A0r7.js} +0 -0
  274. /package/dist/web/assets/{edit-diff-preview-C50i1H63.js → edit-diff-preview-CRMu-6r1.js} +0 -0
  275. /package/dist/web/assets/{emacs-lisp-CIBFq6W8.js → emacs-lisp-W54LT7rh.js} +0 -0
  276. /package/dist/web/assets/{everforest-dark-odRT_lec.js → everforest-dark-B_ISUDeh.js} +0 -0
  277. /package/dist/web/assets/{everforest-light-or1Voqjl.js → everforest-light-CNUYa354.js} +0 -0
  278. /package/dist/web/assets/{fennel-tQd1z3iu.js → fennel-DK82-oso.js} +0 -0
  279. /package/dist/web/assets/{file-exclamation-point-C-lL0g_E.js → file-exclamation-point-DBEC-Kst.js} +0 -0
  280. /package/dist/web/assets/{fish-DSuZQG0k.js → fish-CbJVJzQj.js} +0 -0
  281. /package/dist/web/assets/{fluent-D7xI8a8e.js → fluent-Cug5cOL1.js} +0 -0
  282. /package/dist/web/assets/{fortran-free-form-BlAtcPd3.js → fortran-free-form-amHz32Zw.js} +0 -0
  283. /package/dist/web/assets/{gdscript-VsEQXBPm.js → gdscript-t_G6VYpv.js} +0 -0
  284. /package/dist/web/assets/{gdshader-iqHMOdwW.js → gdshader-DqZaHh4E.js} +0 -0
  285. /package/dist/web/assets/{genie-C4XU4g1a.js → genie-CIJtFlZK.js} +0 -0
  286. /package/dist/web/assets/{gherkin-C4nfQzAB.js → gherkin-CalidqLY.js} +0 -0
  287. /package/dist/web/assets/{github-dark-B_pbG3CC.js → github-dark-BG2xX0wa.js} +0 -0
  288. /package/dist/web/assets/{github-dark-default-kFbx7C95.js → github-dark-default-tDp_EOBs.js} +0 -0
  289. /package/dist/web/assets/{github-dark-dimmed-CpVfQEqs.js → github-dark-dimmed-DlSfPwW2.js} +0 -0
  290. /package/dist/web/assets/{github-dark-high-contrast-DYKqQwZh.js → github-dark-high-contrast-qZM7j5KB.js} +0 -0
  291. /package/dist/web/assets/{github-light-gEYBmKaj.js → github-light-CnvWTiyb.js} +0 -0
  292. /package/dist/web/assets/{github-light-default-DVHfMPQ2.js → github-light-default-Dy6OAt2Q.js} +0 -0
  293. /package/dist/web/assets/{github-light-high-contrast-ClVJDu-q.js → github-light-high-contrast-1BHQCOPl.js} +0 -0
  294. /package/dist/web/assets/{gleam-BLaPu7ft.js → gleam-D-2cpXVX.js} +0 -0
  295. /package/dist/web/assets/{gn-BKgerUyI.js → gn-C1cC4xLc.js} +0 -0
  296. /package/dist/web/assets/{gnuplot-cqJuEFb-.js → gnuplot-2Gp459mV.js} +0 -0
  297. /package/dist/web/assets/{go-B2EHdyD8.js → go-BA1q0q8h.js} +0 -0
  298. /package/dist/web/assets/{groovy-DdImoj8s.js → groovy-BlIa-VfI.js} +0 -0
  299. /package/dist/web/assets/{gruvbox-dark-hard-DlwstAds.js → gruvbox-dark-hard-BMIwVwaJ.js} +0 -0
  300. /package/dist/web/assets/{gruvbox-dark-medium-CiYEd1vd.js → gruvbox-dark-medium-DxfuBW3n.js} +0 -0
  301. /package/dist/web/assets/{gruvbox-dark-soft-C-wEa4h4.js → gruvbox-dark-soft-_NSslDDi.js} +0 -0
  302. /package/dist/web/assets/{gruvbox-light-hard-BqYmfna-.js → gruvbox-light-hard-CP5MIsL9.js} +0 -0
  303. /package/dist/web/assets/{gruvbox-light-medium-CxmfalT2.js → gruvbox-light-medium-BTMursH0.js} +0 -0
  304. /package/dist/web/assets/{gruvbox-light-soft-DGWXXMCB.js → gruvbox-light-soft-Bv6zFoVX.js} +0 -0
  305. /package/dist/web/assets/{haskell-H_C_IuVb.js → haskell-Da8UeSv-.js} +0 -0
  306. /package/dist/web/assets/{haxe-CGNSMpeZ.js → haxe-mcKlcxBa.js} +0 -0
  307. /package/dist/web/assets/{hcl-B7bSTSQf.js → hcl-BdZcx5JX.js} +0 -0
  308. /package/dist/web/assets/{hjson-DlJ-glQZ.js → hjson-pFXYbN4t.js} +0 -0
  309. /package/dist/web/assets/{hlsl-CehW5SJN.js → hlsl-Z0II0KR8.js} +0 -0
  310. /package/dist/web/assets/{horizon-Beabcz2d.js → horizon-CufN8DyP.js} +0 -0
  311. /package/dist/web/assets/{horizon-bright-BC87RXPa.js → horizon-bright-5qoQVyIY.js} +0 -0
  312. /package/dist/web/assets/{houston-Da7RFwUy.js → houston-DOFkQwep.js} +0 -0
  313. /package/dist/web/assets/{hy-m1H70w19.js → hy-BVbDMDcG.js} +0 -0
  314. /package/dist/web/assets/{imba-MExFsdAA.js → imba-DRM6LLS5.js} +0 -0
  315. /package/dist/web/assets/{ini-CJy_zmwy.js → ini-2KCnNvmz.js} +0 -0
  316. /package/dist/web/assets/{java-DqDFvJBH.js → java-BmvH-Ou1.js} +0 -0
  317. /package/dist/web/assets/{javascript-C3Wyv22X.js → javascript-B7VhU1Yc.js} +0 -0
  318. /package/dist/web/assets/{json-DnGBw_DZ.js → json-X1pNk0n7.js} +0 -0
  319. /package/dist/web/assets/{json5-CRN-zoN4.js → json5-CJeEJPTg.js} +0 -0
  320. /package/dist/web/assets/{jsonc-CKRUZNRo.js → jsonc-C1haTBsf.js} +0 -0
  321. /package/dist/web/assets/{jsonl-CGfD6FrH.js → jsonl-wQ8-AJgs.js} +0 -0
  322. /package/dist/web/assets/{jsonnet-nbFuDj0o.js → jsonnet-BrEjY3Xh.js} +0 -0
  323. /package/dist/web/assets/{jssm-D0ShzIqD.js → jssm-C6LgYbOs.js} +0 -0
  324. /package/dist/web/assets/{jsx-D27hbRbs.js → jsx-B2cfD_Fb.js} +0 -0
  325. /package/dist/web/assets/{kanagawa-dragon-Ov3f8K0T.js → kanagawa-dragon-6UCcJpLw.js} +0 -0
  326. /package/dist/web/assets/{kanagawa-lotus-CLyOqh-g.js → kanagawa-lotus-DOmfpsRg.js} +0 -0
  327. /package/dist/web/assets/{kanagawa-wave-Kj3dzabH.js → kanagawa-wave-CpxmPE7N.js} +0 -0
  328. /package/dist/web/assets/{kdl-DFF58Gu4.js → kdl-BrLEivmb.js} +0 -0
  329. /package/dist/web/assets/{kotlin-BM4PKaB4.js → kotlin-BO2FUnDB.js} +0 -0
  330. /package/dist/web/assets/{kusto-DrvHLCv5.js → kusto-Cev1yiq9.js} +0 -0
  331. /package/dist/web/assets/{laserwave-Db6i6ZkO.js → laserwave-BlEkf-eH.js} +0 -0
  332. /package/dist/web/assets/{lean-D0hEjzwk.js → lean-BLS3Xk2w.js} +0 -0
  333. /package/dist/web/assets/{less-BEj4npGG.js → less-BXmcsqcq.js} +0 -0
  334. /package/dist/web/assets/{lib-CBdlQ75W.js → lib-CxSBdrd7.js} +0 -0
  335. /package/dist/web/assets/{light-plus-DLIIbDea.js → light-plus-DS6zriYl.js} +0 -0
  336. /package/dist/web/assets/{llvm-DMt6umsO.js → llvm-C_wLnJgX.js} +0 -0
  337. /package/dist/web/assets/{log-BopvdtPW.js → log-Cg8pvmWi.js} +0 -0
  338. /package/dist/web/assets/{logo-CYSUFPFR.js → logo-C9-kEvPW.js} +0 -0
  339. /package/dist/web/assets/{luau-XC611HNO.js → luau-NwaGugfZ.js} +0 -0
  340. /package/dist/web/assets/{make-BMYZIfBj.js → make-DBpJE-Z8.js} +0 -0
  341. /package/dist/web/assets/{markdown-BLza5nvF.js → markdown-B7ZTAu7B.js} +0 -0
  342. /package/dist/web/assets/{material-theme-Uw27UfJW.js → material-theme-BsXH-Mss.js} +0 -0
  343. /package/dist/web/assets/{material-theme-darker-dfqt8XBY.js → material-theme-darker-CW9OlIeY.js} +0 -0
  344. /package/dist/web/assets/{material-theme-lighter-CPtBTblV.js → material-theme-lighter-D2PAh0Kw.js} +0 -0
  345. /package/dist/web/assets/{material-theme-ocean-BfZgVqC-.js → material-theme-ocean-Vz6DBVi3.js} +0 -0
  346. /package/dist/web/assets/{material-theme-palenight-DAZoVYg8.js → material-theme-palenight-D-GleP3G.js} +0 -0
  347. /package/dist/web/assets/{matlab-cSzmquiW.js → matlab-C7MYlMSn.js} +0 -0
  348. /package/dist/web/assets/{mdx-Dq0kW5VM.js → mdx-FkOOX3Dq.js} +0 -0
  349. /package/dist/web/assets/{mermaid-DoIKF0yS.js → mermaid-C_9qw5it.js} +0 -0
  350. /package/dist/web/assets/{min-dark-DyraimDU.js → min-dark-BowNvxk2.js} +0 -0
  351. /package/dist/web/assets/{min-light-Co9cbcUv.js → min-light-x8oWUmbL.js} +0 -0
  352. /package/dist/web/assets/{mipsasm-ph6cKgHn.js → mipsasm-Dmi1AZOT.js} +0 -0
  353. /package/dist/web/assets/{mojo-BBT0XwmY.js → mojo-C6z7mry2.js} +0 -0
  354. /package/dist/web/assets/{monokai-IP0T5Rtg.js → monokai-BQ4e_Hn0.js} +0 -0
  355. /package/dist/web/assets/{moonbit-B8cogNXl.js → moonbit-CEeNIoB4.js} +0 -0
  356. /package/dist/web/assets/{move-DkY26NtM.js → move-bALfKUa7.js} +0 -0
  357. /package/dist/web/assets/{narrat-rBs3byG0.js → narrat-DX4JlAWT.js} +0 -0
  358. /package/dist/web/assets/{nextflow-groovy-DkO9wMLP.js → nextflow-groovy-CKQWtRkO.js} +0 -0
  359. /package/dist/web/assets/{night-owl-jVR4lFji.js → night-owl-D4PQd726.js} +0 -0
  360. /package/dist/web/assets/{night-owl-light-fBYJ7s3U.js → night-owl-light-BQo_YHll.js} +0 -0
  361. /package/dist/web/assets/{nix-WX9oavu6.js → nix-B1jThkGj.js} +0 -0
  362. /package/dist/web/assets/{nord-Cf7G21Pu.js → nord-35quHUKo.js} +0 -0
  363. /package/dist/web/assets/{nushell-DQdzcJ1H.js → nushell-L6DbJTuL.js} +0 -0
  364. /package/dist/web/assets/{objective-c-JSO2uvZ-.js → objective-c-CTZ4bR2U.js} +0 -0
  365. /package/dist/web/assets/{objective-cpp-CZMGJ9Fb.js → objective-cpp-Dm1YDIdA.js} +0 -0
  366. /package/dist/web/assets/{ocaml-C4S4NSDo.js → ocaml-B3n__LGy.js} +0 -0
  367. /package/dist/web/assets/{odin-Y2jXCgVq.js → odin-DmqZ8n3i.js} +0 -0
  368. /package/dist/web/assets/{one-dark-pro-dVIxuoJY.js → one-dark-pro-16_UaUig.js} +0 -0
  369. /package/dist/web/assets/{one-light-BQ1IKfD1.js → one-light-B-GGjWn5.js} +0 -0
  370. /package/dist/web/assets/{openscad-Bddw4I3z.js → openscad-DTFB9Sj6.js} +0 -0
  371. /package/dist/web/assets/{pascal-BKVXrzC1.js → pascal-RcT1dQYN.js} +0 -0
  372. /package/dist/web/assets/{pkl-BTd-YRsO.js → pkl-Dr4yLQ_o.js} +0 -0
  373. /package/dist/web/assets/{plastic-eiGvBIxV.js → plastic-hp2Nry0R.js} +0 -0
  374. /package/dist/web/assets/{plsql-C290tieP.js → plsql-pFcO4WZ0.js} +0 -0
  375. /package/dist/web/assets/{po-DyDwh0tx.js → po-BkZ0_HvY.js} +0 -0
  376. /package/dist/web/assets/{poimandres-B87zc_g-.js → poimandres-BcTrxj7f.js} +0 -0
  377. /package/dist/web/assets/{polar-Cdub1YMT.js → polar-DHK3q8FF.js} +0 -0
  378. /package/dist/web/assets/{postcss-BcI_3K0v.js → postcss-Bv7WzijA.js} +0 -0
  379. /package/dist/web/assets/{powerquery-OdMrkJSe.js → powerquery-DpaU_hW9.js} +0 -0
  380. /package/dist/web/assets/{powershell-C8auT6xg.js → powershell-_Rqc0MGP.js} +0 -0
  381. /package/dist/web/assets/{prisma-DIbVv8PA.js → prisma-wyegE8us.js} +0 -0
  382. /package/dist/web/assets/{prolog-DbTOH3Ld.js → prolog-DspHCURv.js} +0 -0
  383. /package/dist/web/assets/{proto-C4Cq2dCD.js → proto-BOBiNGf5.js} +0 -0
  384. /package/dist/web/assets/{puppet-DJp3uqum.js → puppet-DfLvV8h2.js} +0 -0
  385. /package/dist/web/assets/{purescript-CLsV4rPU.js → purescript-BY5ZSOZy.js} +0 -0
  386. /package/dist/web/assets/{python-2gBtEza2.js → python-B758mMeg.js} +0 -0
  387. /package/dist/web/assets/{qmldir-DfhULcua.js → qmldir-C75bpHvy.js} +0 -0
  388. /package/dist/web/assets/{qss-DK--VTTV.js → qss-DcLTlbLd.js} +0 -0
  389. /package/dist/web/assets/{r-BArBO2Sa.js → r-D0G_Y1P5.js} +0 -0
  390. /package/dist/web/assets/{racket-5mijHsVy.js → racket-DTye_5qn.js} +0 -0
  391. /package/dist/web/assets/{raku-ir0suElk.js → raku-uJXBXkV0.js} +0 -0
  392. /package/dist/web/assets/{react-J9g6e3Rq.js → react-CorNPdie.js} +0 -0
  393. /package/dist/web/assets/{red-DSecpIOT.js → red-rs3HE3re.js} +0 -0
  394. /package/dist/web/assets/{reg-Dp30FusS.js → reg-DkTIaX7a.js} +0 -0
  395. /package/dist/web/assets/{regexp-DXJnEM_6.js → regexp-4TLSs4_m.js} +0 -0
  396. /package/dist/web/assets/{rel-Dr483ozj.js → rel-B0jumCjt.js} +0 -0
  397. /package/dist/web/assets/{resolve-theme-DJORYzKu.js → resolve-theme-CCoakF2E.js} +0 -0
  398. /package/dist/web/assets/{riscv-ZfBy5IA1.js → riscv-DtaWMlo0.js} +0 -0
  399. /package/dist/web/assets/{ron-ZJ_CljGP.js → ron-BCPxwJD6.js} +0 -0
  400. /package/dist/web/assets/{rose-pine-CcW_eJ6G.js → rose-pine-CNryoqGi.js} +0 -0
  401. /package/dist/web/assets/{rose-pine-dawn-v2l_UF-j.js → rose-pine-dawn-C-gJOQVP.js} +0 -0
  402. /package/dist/web/assets/{rose-pine-moon-CNXkwf3D.js → rose-pine-moon-BdXSXpZh.js} +0 -0
  403. /package/dist/web/assets/{rosmsg-BMYMVW84.js → rosmsg-CPG8X-D5.js} +0 -0
  404. /package/dist/web/assets/{rust-BR-zJh5q.js → rust-CxfW3ePx.js} +0 -0
  405. /package/dist/web/assets/{sass-BukPOBFz.js → sass-D-7bxo_L.js} +0 -0
  406. /package/dist/web/assets/{save-DO5xjW95.js → save-BM4p9_9n.js} +0 -0
  407. /package/dist/web/assets/{scala-DUFY7D6D.js → scala-DyUsfHNc.js} +0 -0
  408. /package/dist/web/assets/{scheme-Dl-dNNxQ.js → scheme-ROgrwiO-.js} +0 -0
  409. /package/dist/web/assets/{sdbl-DdmlQhia.js → sdbl-B1EAQWpp.js} +0 -0
  410. /package/dist/web/assets/{shellscript-UyhrvGcd.js → shellscript-HhmB_Ufy.js} +0 -0
  411. /package/dist/web/assets/{shield-check-m2QzZTuZ.js → shield-check-C3qYSU8a.js} +0 -0
  412. /package/dist/web/assets/{shield-off-DNn7VzJe.js → shield-off-D5tU7gQT.js} +0 -0
  413. /package/dist/web/assets/{slack-dark-Cv6Szr-q.js → slack-dark-DnmSY72G.js} +0 -0
  414. /package/dist/web/assets/{slack-ochin-V6Ii3lAm.js → slack-ochin-q97gHjcd.js} +0 -0
  415. /package/dist/web/assets/{smalltalk-BUCv5G91.js → smalltalk-B-1waXvA.js} +0 -0
  416. /package/dist/web/assets/{snazzy-light-B67a78qi.js → snazzy-light-C8yWDN2g.js} +0 -0
  417. /package/dist/web/assets/{solarized-dark-ccWnfYyA.js → solarized-dark-ClVDEMJZ.js} +0 -0
  418. /package/dist/web/assets/{solarized-light-C3WyRO5I.js → solarized-light-Bts6CUIP.js} +0 -0
  419. /package/dist/web/assets/{solidity-BFbRPNi_.js → solidity-DYxwp0om.js} +0 -0
  420. /package/dist/web/assets/{splunk-zdpwCJLE.js → splunk-jK6-Sr06.js} +0 -0
  421. /package/dist/web/assets/{sql-B2IPUsfz.js → sql-DPpd8aUS.js} +0 -0
  422. /package/dist/web/assets/{ssh-config-Co4cXifq.js → ssh-config-Bimb9LVr.js} +0 -0
  423. /package/dist/web/assets/{stylus-CmI75XY8.js → stylus-B2DgJRJw.js} +0 -0
  424. /package/dist/web/assets/{swift-Dfks9YQI.js → swift-ChEH2nFL.js} +0 -0
  425. /package/dist/web/assets/{synthwave-84-B3LERzNS.js → synthwave-84-DwSLbgAm.js} +0 -0
  426. /package/dist/web/assets/{system-verilog-BFvldiwl.js → system-verilog-DoVBMhJ8.js} +0 -0
  427. /package/dist/web/assets/{systemd-Cu4Vvgbu.js → systemd--Ux4VAYD.js} +0 -0
  428. /package/dist/web/assets/{table-CAVmgQMT.js → table-Di8pv2Y_.js} +0 -0
  429. /package/dist/web/assets/{talonscript-Bnq32pUB.js → talonscript-DQNx9nak.js} +0 -0
  430. /package/dist/web/assets/{tasl-Nwe2K3J1.js → tasl-Bwy_Y9uD.js} +0 -0
  431. /package/dist/web/assets/{tcl-zOnpywrl.js → tcl-Drea-2jA.js} +0 -0
  432. /package/dist/web/assets/{terraform-Bc9Vj-n3.js → terraform-4rS5HoFk.js} +0 -0
  433. /package/dist/web/assets/{tokyo-night-9_KyM8M2.js → tokyo-night-C9MqaxIn.js} +0 -0
  434. /package/dist/web/assets/{toml-ByH-fxOY.js → toml-tSgOSv42.js} +0 -0
  435. /package/dist/web/assets/{tsv-DrCnDClP.js → tsv-BmL4O1Zx.js} +0 -0
  436. /package/dist/web/assets/{tsx-B8LafSYr.js → tsx-BwzeA880.js} +0 -0
  437. /package/dist/web/assets/{turtle-DuyP_QCJ.js → turtle-2DYvssFL.js} +0 -0
  438. /package/dist/web/assets/{typescript-BTBJb5RD.js → typescript-ZC-vonSh.js} +0 -0
  439. /package/dist/web/assets/{typespec-DdOFo7M5.js → typespec-DkCEO45F.js} +0 -0
  440. /package/dist/web/assets/{typst-LYvnBWQu.js → typst-DAZdb2n6.js} +0 -0
  441. /package/dist/web/assets/{utils-CTg5uAYR.js → utils-CSCvNZxE.js} +0 -0
  442. /package/dist/web/assets/{v-BuBYA1_x.js → v-B_wsb4C1.js} +0 -0
  443. /package/dist/web/assets/{vala-vRIBYYe3.js → vala-BDBNS784.js} +0 -0
  444. /package/dist/web/assets/{vb-DwGi-IYM.js → vb-CuOoJSSa.js} +0 -0
  445. /package/dist/web/assets/{vendor-xterm-i6SHFTfU.js → vendor-xterm-CImj6i6Z.js} +0 -0
  446. /package/dist/web/assets/{verilog-6B1X4G2-.js → verilog-BCcOvOcc.js} +0 -0
  447. /package/dist/web/assets/{vesper-Dw1y_Ae7.js → vesper-vN8CREK5.js} +0 -0
  448. /package/dist/web/assets/{vhdl-DK8JwBzJ.js → vhdl-CI8PoqeM.js} +0 -0
  449. /package/dist/web/assets/{viml-BTKIEIqm.js → viml-B66dNP1B.js} +0 -0
  450. /package/dist/web/assets/{vitesse-black-BqqolhEg.js → vitesse-black-0bGIaCfD.js} +0 -0
  451. /package/dist/web/assets/{vitesse-dark-B9JL5WQA.js → vitesse-dark-Dk-RSXq-.js} +0 -0
  452. /package/dist/web/assets/{vitesse-light-DYJKj2se.js → vitesse-light-BUsA5RhG.js} +0 -0
  453. /package/dist/web/assets/{vyper-D-jDI3WH.js → vyper-dNodzEa8.js} +0 -0
  454. /package/dist/web/assets/{wasm-1-GlNdpk.js → wasm-BDxaNPCj.js} +0 -0
  455. /package/dist/web/assets/{wasm-BBW4WmT2.js → wasm-d6SE2_qm.js} +0 -0
  456. /package/dist/web/assets/{wenyan-B6cM7sDO.js → wenyan-D0h8Uz55.js} +0 -0
  457. /package/dist/web/assets/{wgsl-FaHGQgko.js → wgsl-vKs_vsvQ.js} +0 -0
  458. /package/dist/web/assets/{wikitext-DtIyPUrk.js → wikitext-BIWsPJit.js} +0 -0
  459. /package/dist/web/assets/{wit-BMVRif5Y.js → wit-6vmKi2H3.js} +0 -0
  460. /package/dist/web/assets/{wolfram-DQsCGohn.js → wolfram-zoNg6F1a.js} +0 -0
  461. /package/dist/web/assets/{x-C2VSAp7O.js → x-BsFLg-T8.js} +0 -0
  462. /package/dist/web/assets/{yaml-C-Va56Gt.js → yaml-W95qP6-B.js} +0 -0
  463. /package/dist/web/assets/{zenscript-DdobKGI-.js → zenscript-BxircxDx.js} +0 -0
  464. /package/dist/web/assets/{zig-vqDFwj6q.js → zig-DD79WQtz.js} +0 -0
@@ -35,6 +35,7 @@ export function GroupCreateDialog({
35
35
  }: GroupCreateDialogProps) {
36
36
  const isMobile = useIsMobile();
37
37
  const [name, setName] = useState("");
38
+ const [cap, setCap] = useState(10); // reply-burst cap (max AI turns per message)
38
39
  const [leaderName, setLeaderName] = useState("Leader");
39
40
  const [leaderPersona, setLeaderPersona] = useState("");
40
41
  const [leaderModel, setLeaderModel] = useState<string | null>(null);
@@ -43,7 +44,7 @@ export function GroupCreateDialog({
43
44
  const [error, setError] = useState<string | null>(null);
44
45
 
45
46
  const reset = useCallback(() => {
46
- setName(""); setLeaderName("Leader"); setLeaderPersona(""); setLeaderModel(null);
47
+ setName(""); setCap(10); setLeaderName("Leader"); setLeaderPersona(""); setLeaderModel(null);
47
48
  setMembers([newMember()]); setError(null); setSubmitting(false);
48
49
  }, []);
49
50
 
@@ -79,14 +80,14 @@ export function GroupCreateDialog({
79
80
  setSubmitting(true);
80
81
  setError(null);
81
82
  try {
82
- const group = await createGroup({ projectName, projectPath, name: gName, members: roster });
83
+ const group = await createGroup({ projectName, projectPath, name: gName, maxTurns: cap, members: roster });
83
84
  onCreated(group);
84
85
  close();
85
86
  } catch (e) {
86
87
  setError(e instanceof Error ? e.message : "Failed to create group");
87
88
  setSubmitting(false);
88
89
  }
89
- }, [name, leaderName, leaderPersona, leaderModel, members, projectName, projectPath, onCreated, close]);
90
+ }, [name, cap, leaderName, leaderPersona, leaderModel, members, projectName, projectPath, onCreated, close]);
90
91
 
91
92
  const inputCls =
92
93
  "w-full min-h-[40px] rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-text-subtle focus:outline-none focus:ring-1 focus:ring-primary";
@@ -99,6 +100,12 @@ export function GroupCreateDialog({
99
100
  placeholder="e.g. Design Review" autoFocus />
100
101
  </div>
101
102
 
103
+ <div>
104
+ <label className="mb-1 block text-xs font-medium text-text-secondary">Reply cap (max AI turns per message, 1–50)</label>
105
+ <input type="number" min={1} max={50} className={inputCls} value={cap}
106
+ onChange={(e) => setCap(Math.max(1, Math.min(50, Number(e.target.value) || 1)))} />
107
+ </div>
108
+
102
109
  <div className="rounded-lg border border-border p-3">
103
110
  <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-primary">Leader</p>
104
111
  <div className="flex flex-col gap-2">
@@ -3,7 +3,8 @@ import { Loader2 } from "lucide-react";
3
3
  import { useIsMobile } from "@/hooks/use-is-mobile";
4
4
  import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
5
5
  import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
6
- import { getTranscript } from "@/lib/api-group-chat";
6
+ import { getTranscript, type TranscriptResult } from "@/lib/api-group-chat";
7
+ import { GroupTranscriptMessages } from "./group-transcript-messages";
7
8
  import type { GroupMessage } from "../../../types/group-chat";
8
9
 
9
10
  interface GroupFullTranscriptViewProps {
@@ -16,7 +17,7 @@ interface GroupFullTranscriptViewProps {
16
17
  * Adaptive: centered dialog on desktop, bottom sheet on mobile. */
17
18
  export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFullTranscriptViewProps) {
18
19
  const isMobile = useIsMobile();
19
- const [content, setContent] = useState<string | null>(null);
20
+ const [data, setData] = useState<TranscriptResult | null>(null);
20
21
  const [loading, setLoading] = useState(false);
21
22
  const [error, setError] = useState<string | null>(null);
22
23
 
@@ -25,11 +26,11 @@ export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFull
25
26
  useEffect(() => {
26
27
  if (!message || !sessionRef) return;
27
28
  let cancelled = false;
28
- setContent(null);
29
+ setData(null);
29
30
  setError(null);
30
31
  setLoading(true);
31
32
  getTranscript(groupId, sessionRef)
32
- .then((res) => { if (!cancelled) setContent(res.content); })
33
+ .then((res) => { if (!cancelled) setData(res); })
33
34
  .catch((e) => { if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load transcript"); })
34
35
  .finally(() => { if (!cancelled) setLoading(false); });
35
36
  return () => { cancelled = true; };
@@ -55,10 +56,10 @@ export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFull
55
56
  )}
56
57
  </div>
57
58
  )}
58
- {!loading && !error && content != null && (
59
- <pre className="whitespace-pre-wrap break-words rounded-md bg-surface-elevated p-3 text-xs leading-relaxed text-text-secondary">
60
- {content}
61
- </pre>
59
+ {!loading && !error && data != null && (
60
+ <div className="px-1 py-1">
61
+ <GroupTranscriptMessages messages={data.messages} config={data.config} />
62
+ </div>
62
63
  )}
63
64
  </div>
64
65
  );
@@ -0,0 +1,108 @@
1
+ import { useState, useCallback } from "react";
2
+ import { Loader2 } from "lucide-react";
3
+ import { useIsMobile } from "@/hooks/use-is-mobile";
4
+ import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
5
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
6
+ import { Button } from "@/components/ui/button";
7
+ import { ModelSelector } from "@/components/chat/model-selector";
8
+ import type { GroupMember, MemberRole } from "../../../types/group-chat";
9
+
10
+ export interface MemberFormValues {
11
+ name: string;
12
+ persona: string | null;
13
+ model: string | null;
14
+ role: MemberRole;
15
+ }
16
+
17
+ interface Props {
18
+ open: boolean;
19
+ /** Editing an existing member, or null when adding a new one. */
20
+ member: GroupMember | null;
21
+ projectName: string;
22
+ providerId?: string;
23
+ onSubmit: (values: MemberFormValues) => Promise<void>;
24
+ onClose: () => void;
25
+ }
26
+
27
+ const inputCls =
28
+ "w-full min-h-[40px] rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-text-subtle focus:outline-none focus:ring-1 focus:ring-primary";
29
+
30
+ export function GroupMemberEditDialog({ open, member, projectName, providerId = "claude", onSubmit, onClose }: Props) {
31
+ const isMobile = useIsMobile();
32
+ const [name, setName] = useState(member?.name ?? "");
33
+ const [persona, setPersona] = useState(member?.persona ?? "");
34
+ const [model, setModel] = useState<string | null>(member?.model ?? null);
35
+ const [isLeader, setIsLeader] = useState(member?.role === "leader");
36
+ const [submitting, setSubmitting] = useState(false);
37
+ const [error, setError] = useState<string | null>(null);
38
+
39
+ const handleSubmit = useCallback(async () => {
40
+ const n = name.trim();
41
+ if (!n) { setError("Name is required"); return; }
42
+ setSubmitting(true);
43
+ setError(null);
44
+ try {
45
+ await onSubmit({ name: n, persona: persona.trim() || null, model, role: isLeader ? "leader" : "member" });
46
+ onClose();
47
+ } catch (e) {
48
+ setError(e instanceof Error ? e.message : "Failed to save member");
49
+ setSubmitting(false);
50
+ }
51
+ }, [name, persona, model, isLeader, onSubmit, onClose]);
52
+
53
+ const alreadyLeader = member?.role === "leader";
54
+
55
+ const form = (
56
+ <div className="flex flex-col gap-3 px-1 py-1">
57
+ <input className={inputCls} value={name} onChange={(e) => setName(e.target.value)} placeholder="Member name" autoFocus />
58
+ <input className={inputCls} value={persona} onChange={(e) => setPersona(e.target.value)} placeholder="Persona (optional)" />
59
+ <ModelSelector value={model} onChange={setModel} projectName={projectName} providerId={providerId} />
60
+ <label className={cnLeader(alreadyLeader)}>
61
+ <input
62
+ type="checkbox"
63
+ className="size-4 accent-[var(--color-primary)]"
64
+ checked={isLeader}
65
+ disabled={alreadyLeader}
66
+ onChange={(e) => setIsLeader(e.target.checked)}
67
+ />
68
+ <span>{alreadyLeader ? "Leader (reassign from another member)" : "Set as leader"}</span>
69
+ </label>
70
+ {error && <p className="text-xs text-destructive">{error}</p>}
71
+ <div className="flex justify-end gap-2 pt-1">
72
+ <Button variant="outline" onClick={onClose} disabled={submitting}>Cancel</Button>
73
+ <Button onClick={handleSubmit} disabled={submitting}>
74
+ {submitting && <Loader2 className="mr-1.5 size-4 animate-spin" />}
75
+ {member ? "Save" : "Add member"}
76
+ </Button>
77
+ </div>
78
+ </div>
79
+ );
80
+
81
+ if (!open) return null;
82
+ const title = member ? "Edit member" : "Add member";
83
+
84
+ if (isMobile) {
85
+ return (
86
+ <BottomSheet open onClose={onClose} className="flex max-h-[90vh] flex-col">
87
+ <div className="flex min-h-0 flex-col px-4 pb-2">
88
+ <h2 className="mb-2 text-base font-semibold text-foreground">{title}</h2>
89
+ {form}
90
+ </div>
91
+ </BottomSheet>
92
+ );
93
+ }
94
+
95
+ return (
96
+ <Dialog open onOpenChange={(o) => { if (!o) onClose(); }}>
97
+ <DialogContent className="flex flex-col sm:max-w-md">
98
+ <DialogHeader><DialogTitle>{title}</DialogTitle></DialogHeader>
99
+ {form}
100
+ </DialogContent>
101
+ </Dialog>
102
+ );
103
+ }
104
+
105
+ /** Label styling for the leader checkbox row (dimmed when already leader). */
106
+ function cnLeader(disabled: boolean): string {
107
+ return `flex items-center gap-2 text-sm text-text-secondary ${disabled ? "opacity-60" : ""}`;
108
+ }
@@ -1,12 +1,19 @@
1
1
  import { memo } from "react";
2
+ import { Pencil, Trash2, UserPlus } from "lucide-react";
2
3
  import { cn } from "@/lib/utils";
3
- import type { MemberStatus } from "../../../types/group-chat";
4
- import type { RosterMember } from "@/hooks/use-group-chat";
4
+ import type { GroupMember, MemberStatus } from "../../../types/group-chat";
5
5
 
6
6
  interface GroupMemberRosterProps {
7
- members: RosterMember[];
7
+ members: GroupMember[];
8
+ /** memberId → live status (working/done/error) from the running burst. */
9
+ liveStatus: Map<string, MemberStatus>;
8
10
  /** Member name → true when composing a turn. */
9
11
  typing: Record<string, boolean>;
12
+ /** Disables actions while a mutation is in flight. */
13
+ busy?: boolean;
14
+ onAdd: () => void;
15
+ onEdit: (member: GroupMember) => void;
16
+ onRemove: (member: GroupMember) => void;
10
17
  }
11
18
 
12
19
  const STATUS_DOT: Record<MemberStatus, string> = {
@@ -23,26 +30,17 @@ const STATUS_LABEL: Record<MemberStatus, string> = {
23
30
  error: "Error",
24
31
  };
25
32
 
26
- /** Compact roster: avatar dot + name + role + live status; shows typing state. */
33
+ /** Editable roster: avatar + name + role/persona + live status; add/edit/remove. */
27
34
  export const GroupMemberRoster = memo(function GroupMemberRoster({
28
- members,
29
- typing,
35
+ members, liveStatus, typing, busy, onAdd, onEdit, onRemove,
30
36
  }: GroupMemberRosterProps) {
31
- if (members.length === 0) {
32
- return (
33
- <div className="p-3 text-xs text-text-subtle">No members yet.</div>
34
- );
35
- }
36
-
37
37
  return (
38
- <ul className="flex flex-col gap-0.5 p-2">
38
+ <div className="flex flex-col gap-0.5 p-2">
39
39
  {members.map((m) => {
40
40
  const isTyping = typing[m.name];
41
+ const status = liveStatus.get(m.id) ?? m.status;
41
42
  return (
42
- <li
43
- key={m.id}
44
- className="flex items-center gap-2 rounded-md px-2 py-1.5"
45
- >
43
+ <div key={m.id} className="group flex items-center gap-2 rounded-md px-2 py-1.5">
46
44
  <span
47
45
  className="flex size-6 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold text-white ring-2 ring-background"
48
46
  style={{ backgroundColor: m.color ?? "var(--accent)" }}
@@ -59,18 +57,48 @@ export const GroupMemberRoster = memo(function GroupMemberRoster({
59
57
  </span>
60
58
  )}
61
59
  </div>
62
- <span className="text-[10px] text-text-subtle">
63
- {isTyping ? "typing…" : STATUS_LABEL[m.status]}
60
+ <span className="block truncate text-[10px] text-text-subtle">
61
+ {isTyping ? "typing…" : (m.persona || STATUS_LABEL[status])}
64
62
  </span>
65
63
  </div>
64
+ {/* Actions — always visible on touch; hover-reveal on pointer devices. */}
65
+ <div className="flex shrink-0 items-center gap-0.5 can-hover:opacity-0 can-hover:group-hover:opacity-100">
66
+ <button
67
+ type="button"
68
+ onClick={() => onEdit(m)}
69
+ disabled={busy}
70
+ aria-label={`Edit ${m.name}`}
71
+ className="flex size-8 items-center justify-center rounded-md text-text-subtle hover:bg-surface-elevated hover:text-foreground active:bg-surface-elevated disabled:opacity-40"
72
+ >
73
+ <Pencil className="size-3.5" />
74
+ </button>
75
+ <button
76
+ type="button"
77
+ onClick={() => onRemove(m)}
78
+ disabled={busy}
79
+ aria-label={`Remove ${m.name}`}
80
+ className="flex size-8 items-center justify-center rounded-md text-text-subtle hover:bg-surface-elevated hover:text-destructive active:bg-surface-elevated disabled:opacity-40"
81
+ >
82
+ <Trash2 className="size-3.5" />
83
+ </button>
84
+ </div>
66
85
  <span
67
- className={cn("size-2 shrink-0 rounded-full", STATUS_DOT[m.status])}
68
- title={STATUS_LABEL[m.status]}
86
+ className={cn("size-2 shrink-0 rounded-full", STATUS_DOT[status])}
87
+ title={STATUS_LABEL[status]}
69
88
  aria-hidden
70
89
  />
71
- </li>
90
+ </div>
72
91
  );
73
92
  })}
74
- </ul>
93
+
94
+ <button
95
+ type="button"
96
+ onClick={onAdd}
97
+ disabled={busy}
98
+ className="mt-1 flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-primary hover:bg-surface-elevated active:bg-surface-elevated disabled:opacity-40"
99
+ >
100
+ <UserPlus className="size-4" /> Add member
101
+ </button>
102
+ </div>
75
103
  );
76
104
  });
@@ -1,5 +1,12 @@
1
1
  import { memo, type ReactNode } from "react";
2
+ import { ScrollText } from "lucide-react";
2
3
  import { cn } from "@/lib/utils";
4
+ import {
5
+ ContextMenu,
6
+ ContextMenuTrigger,
7
+ ContextMenuContent,
8
+ ContextMenuItem,
9
+ } from "@/components/ui/adaptive-context-menu";
3
10
  import type { GroupMessage } from "../../../types/group-chat";
4
11
 
5
12
  interface GroupMessageItemProps {
@@ -21,7 +28,10 @@ function initials(name: string): string {
21
28
 
22
29
  function formatTime(ts: number): string {
23
30
  try {
24
- return new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
31
+ // The bus stores created_at in SECONDS (SQLite unixepoch()); Date expects ms.
32
+ // Normalize second-scale values so timestamps don't all collapse to one minute.
33
+ const ms = ts < 1e12 ? ts * 1000 : ts;
34
+ return new Date(ms).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
25
35
  } catch {
26
36
  return "";
27
37
  }
@@ -30,7 +40,7 @@ function formatTime(ts: number): string {
30
40
  /** Render body text with @mentions tinted in the mentioned member's color
31
41
  * (falls back to the primary accent) so it's obvious who is being addressed. */
32
42
  function withMentions(text: string, colorFor: (n: string) => string | null): ReactNode[] {
33
- return text.split(/(@\w+)/g).map((part, i) => {
43
+ return text.split(/(@[\p{L}\p{N}_]+)/gu).map((part, i) => {
34
44
  if (part.startsWith("@") && part.length > 1) {
35
45
  const c = colorFor(part.slice(1));
36
46
  return (
@@ -44,7 +54,7 @@ function withMentions(text: string, colorFor: (n: string) => string | null): Rea
44
54
  }
45
55
 
46
56
  /** Slack-style feed row: colored avatar + name accent per speaker, left color
47
- * bar, "You" for the user, leader badge, highlighted @mentions, final card. */
57
+ * bar, "You" for the user, leader badge, highlighted @mentions. */
48
58
  export const GroupMessageItem = memo(function GroupMessageItem({
49
59
  message,
50
60
  colorFor,
@@ -55,18 +65,30 @@ export const GroupMessageItem = memo(function GroupMessageItem({
55
65
  const displayName = isUser ? "You" : message.fromMember;
56
66
  const accent = isUser ? "var(--color-primary)" : (colorFor(message.fromMember) ?? "var(--accent)");
57
67
  const leader = !isUser && isLeader(message.fromMember);
58
- const isFinal = message.kind === "final";
59
68
  const summary = message.summary ?? "";
60
69
  const target = message.toMember && message.toMember !== "all" ? message.toMember : null;
61
70
 
62
- return (
71
+ const row = (
63
72
  <div
64
73
  className={cn(
65
- "flex gap-2.5 px-3 py-2 transition-colors hover:bg-surface-elevated/50",
74
+ "group relative flex gap-2.5 px-3 py-2 transition-colors hover:bg-surface-elevated/50",
66
75
  isUser && "bg-primary/5",
67
76
  )}
68
77
  style={{ boxShadow: `inset 3px 0 0 0 ${accent}` }}
69
78
  >
79
+ {/* Transcript (AI raw thinking / debug) — top-right icon, POINTER DEVICES ONLY,
80
+ revealed on hover. On touch it's hidden; use long-press → context menu instead. */}
81
+ {message.fullSessionRef && (
82
+ <button
83
+ type="button"
84
+ onClick={() => onViewFull(message)}
85
+ title="View full transcript (AI's raw thinking / debug)"
86
+ aria-label="View full transcript"
87
+ className="absolute right-1.5 top-1.5 hidden items-center rounded p-1 text-text-subtle/60 hover:bg-surface-elevated hover:text-text-secondary can-hover:group-hover:inline-flex"
88
+ >
89
+ <ScrollText className="size-3.5" />
90
+ </button>
91
+ )}
70
92
  <div
71
93
  className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full text-[11px] font-semibold text-white ring-2 ring-background"
72
94
  style={{ backgroundColor: accent }}
@@ -75,7 +97,7 @@ export const GroupMessageItem = memo(function GroupMessageItem({
75
97
  {initials(displayName)}
76
98
  </div>
77
99
 
78
- <div className="min-w-0 flex-1">
100
+ <div className="min-w-0 flex-1 can-hover:pr-6">
79
101
  <div className="flex flex-wrap items-center gap-x-2 gap-y-0.5">
80
102
  <span
81
103
  className="text-sm font-semibold"
@@ -91,31 +113,28 @@ export const GroupMessageItem = memo(function GroupMessageItem({
91
113
  {target && (
92
114
  <span className="text-[11px] text-text-subtle">→ {target}</span>
93
115
  )}
94
- {isFinal && (
95
- <span className="rounded-full bg-accent-wash px-1.5 py-px text-[10px] font-medium text-primary">
96
- final
97
- </span>
98
- )}
99
116
  <span className="text-[11px] text-text-subtle">{formatTime(message.createdAt)}</span>
100
117
  </div>
101
118
 
102
- <div className={cn(
103
- "mt-0.5 whitespace-pre-wrap break-words text-sm leading-relaxed text-text-secondary",
104
- isFinal && "mt-1.5 rounded-md border border-accent-wash bg-accent-wash/40 px-3 py-2 text-foreground",
105
- )}>
119
+ <div className="mt-0.5 whitespace-pre-wrap break-words text-sm leading-relaxed text-text-secondary">
106
120
  {withMentions(summary, colorFor)}
107
121
  </div>
108
-
109
- {message.fullSessionRef && (
110
- <button
111
- type="button"
112
- onClick={() => onViewFull(message)}
113
- className="mt-1 inline-flex min-h-[44px] items-center text-xs font-medium text-primary hover:underline md:min-h-[32px]"
114
- >
115
- View full transcript
116
- </button>
117
- )}
118
122
  </div>
119
123
  </div>
120
124
  );
125
+
126
+ // No transcript → plain row. Otherwise wrap so long-press (mobile) / right-click
127
+ // (desktop) opens a menu with the transcript action; the hover icon covers pointer.
128
+ if (!message.fullSessionRef) return row;
129
+
130
+ return (
131
+ <ContextMenu>
132
+ <ContextMenuTrigger asChild>{row}</ContextMenuTrigger>
133
+ <ContextMenuContent>
134
+ <ContextMenuItem onClick={() => onViewFull(message)}>
135
+ <ScrollText className="size-4" /> View full transcript
136
+ </ContextMenuItem>
137
+ </ContextMenuContent>
138
+ </ContextMenu>
139
+ );
121
140
  });
@@ -0,0 +1,126 @@
1
+ import { useState } from "react";
2
+ import { ChevronRight, Brain, Settings2 } from "lucide-react";
3
+ import { MarkdownRenderer } from "@/components/shared/markdown-renderer";
4
+ import { ToolCard } from "@/components/chat/tool-cards";
5
+ import { cn } from "@/lib/utils";
6
+ import type { ChatMessage, ChatEvent } from "../../../types/chat";
7
+ import type { TranscriptConfig } from "@/lib/api-group-chat";
8
+
9
+ interface Props {
10
+ messages: ChatMessage[];
11
+ config: TranscriptConfig | null;
12
+ projectName?: string;
13
+ }
14
+
15
+ /** Read-only, chat-style render of an archived member transcript: text (markdown),
16
+ * collapsible thinking, tool calls with inputs + outputs, and the session input config.
17
+ * Deliberately minimal — no approvals / fork / version affordances. */
18
+ export function GroupTranscriptMessages({ messages, config, projectName }: Props) {
19
+ return (
20
+ <div className="flex flex-col gap-3">
21
+ {config && <ConfigBlock config={config} />}
22
+ {messages.map((m) => (
23
+ <div key={m.id} className="flex flex-col gap-1.5">
24
+ <span className="text-[10px] font-semibold uppercase tracking-wide text-text-subtle">
25
+ {m.role === "user" ? "User" : m.role === "assistant" ? "Assistant" : m.role}
26
+ </span>
27
+ <MessageBody message={m} projectName={projectName} />
28
+ </div>
29
+ ))}
30
+ {messages.length === 0 && (
31
+ <p className="py-6 text-center text-sm text-text-subtle">Transcript is empty.</p>
32
+ )}
33
+ </div>
34
+ );
35
+ }
36
+
37
+ function MessageBody({ message, projectName }: { message: ChatMessage; projectName?: string }) {
38
+ const events = message.events ?? [];
39
+ if (events.length === 0) {
40
+ return message.content.trim()
41
+ ? <MarkdownRenderer content={message.content} />
42
+ : null;
43
+ }
44
+ // Match tool_result events to their tool_use by id (rendered inside the ToolCard).
45
+ const resultById = new Map<string, ChatEvent>();
46
+ for (const ev of events) {
47
+ if (ev.type === "tool_result" && ev.toolUseId) resultById.set(ev.toolUseId, ev);
48
+ }
49
+ return (
50
+ <div className="flex flex-col gap-2">
51
+ {events.map((ev, i) => {
52
+ if (ev.type === "text") {
53
+ return ev.content.trim() ? <MarkdownRenderer key={i} content={ev.content} /> : null;
54
+ }
55
+ if (ev.type === "thinking") {
56
+ return <ThinkingBlock key={i} content={ev.content} />;
57
+ }
58
+ if (ev.type === "tool_use") {
59
+ const result = ev.toolUseId ? resultById.get(ev.toolUseId) : undefined;
60
+ return <ToolCard key={i} tool={ev} result={result} completed={!!result} projectName={projectName} />;
61
+ }
62
+ return null; // tool_result rendered via its tool_use
63
+ })}
64
+ </div>
65
+ );
66
+ }
67
+
68
+ /** Collapsible reasoning block (collapsed by default). */
69
+ function ThinkingBlock({ content }: { content: string }) {
70
+ const [open, setOpen] = useState(false);
71
+ return (
72
+ <div className="rounded-md border border-border bg-surface-elevated/40">
73
+ <button
74
+ type="button"
75
+ onClick={() => setOpen((v) => !v)}
76
+ className="flex w-full items-center gap-1.5 px-2.5 py-1.5 text-xs text-text-subtle hover:text-text-secondary"
77
+ >
78
+ <ChevronRight className={cn("size-3.5 transition-transform", open && "rotate-90")} />
79
+ <Brain className="size-3.5" />
80
+ <span>Thinking</span>
81
+ </button>
82
+ {open && (
83
+ <div className="border-t border-border px-3 py-2 text-xs leading-relaxed text-text-secondary">
84
+ <MarkdownRenderer content={content} />
85
+ </div>
86
+ )}
87
+ </div>
88
+ );
89
+ }
90
+
91
+ /** Collapsible input-config summary (model / cwd / branch / version / permission mode). */
92
+ function ConfigBlock({ config }: { config: TranscriptConfig }) {
93
+ const [open, setOpen] = useState(false);
94
+ const rows: Array<[string, string | undefined]> = [
95
+ ["Model", config.model],
96
+ ["Permission", config.permissionMode],
97
+ ["CWD", config.cwd],
98
+ ["Git branch", config.gitBranch],
99
+ ["CLI version", config.version],
100
+ ];
101
+ const shown = rows.filter(([, v]) => v);
102
+ if (shown.length === 0) return null;
103
+ return (
104
+ <div className="rounded-md border border-border bg-surface-elevated/40">
105
+ <button
106
+ type="button"
107
+ onClick={() => setOpen((v) => !v)}
108
+ className="flex w-full items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-text-secondary hover:text-foreground"
109
+ >
110
+ <ChevronRight className={cn("size-3.5 transition-transform", open && "rotate-90")} />
111
+ <Settings2 className="size-3.5" />
112
+ <span>Input config</span>
113
+ </button>
114
+ {open && (
115
+ <dl className="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 border-t border-border px-3 py-2 text-xs">
116
+ {shown.map(([k, v]) => (
117
+ <div key={k} className="contents">
118
+ <dt className="text-text-subtle">{k}</dt>
119
+ <dd className="break-all font-mono text-text-secondary">{v}</dd>
120
+ </div>
121
+ ))}
122
+ </dl>
123
+ )}
124
+ </div>
125
+ );
126
+ }
@@ -22,9 +22,11 @@ interface TunnelStatus {
22
22
 
23
23
  interface Props {
24
24
  onClose: () => void;
25
+ /** "popover" = self-contained card (desktop rail); "sheet" = fills a bottom sheet on mobile. */
26
+ variant?: "popover" | "sheet";
25
27
  }
26
28
 
27
- export function CloudSharePopover({ onClose }: Props) {
29
+ export function CloudSharePopover({ onClose, variant = "popover" }: Props) {
28
30
  const [cloud, setCloud] = useState<CloudStatus | null>(null);
29
31
  const [tunnel, setTunnel] = useState<TunnelStatus | null>(null);
30
32
  const [loading, setLoading] = useState(true);
@@ -184,7 +186,13 @@ export function CloudSharePopover({ onClose }: Props) {
184
186
  const shareUrl = tunnel?.url || cloud?.tunnel_url;
185
187
 
186
188
  return (
187
- <div className="w-72 bg-background border border-border rounded-lg shadow-lg p-3 space-y-3">
189
+ <div
190
+ className={
191
+ variant === "sheet"
192
+ ? "w-full p-3 space-y-3"
193
+ : "w-72 bg-background border border-border rounded-lg shadow-lg p-3 space-y-3"
194
+ }
195
+ >
188
196
  {/* Header */}
189
197
  <div className="flex items-center justify-between">
190
198
  <div className="flex items-center gap-1.5">
@@ -134,6 +134,11 @@ export function MobileDrawerTabBar({ tabs, activeId, onSelect, onReorder }: Prop
134
134
  >
135
135
  <Icon className="size-4" />
136
136
  <span>{tab.shortLabel ?? tab.label}</span>
137
+ {tab.beta && (
138
+ <span className="absolute top-1 right-2 rounded-full bg-accent-wash px-1 text-[7px] font-bold uppercase leading-[1.4] tracking-wide text-primary">
139
+ beta
140
+ </span>
141
+ )}
137
142
  </button>
138
143
  );
139
144
  })}
@@ -168,6 +173,11 @@ export function MobileDrawerTabBar({ tabs, activeId, onSelect, onReorder }: Prop
168
173
  >
169
174
  <Icon className="size-4 shrink-0" />
170
175
  <span>{tab.label}</span>
176
+ {tab.beta && (
177
+ <span className="rounded-full bg-accent-wash px-1.5 py-px text-[9px] font-semibold uppercase tracking-wide text-primary">
178
+ beta
179
+ </span>
180
+ )}
171
181
  </button>
172
182
  );
173
183
  })}