@ashlr/hub 3.11.2 → 3.11.3

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 (262) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/build-identity.json +2 -2
  3. package/dist/core/web/public/next/assets/{ActionMenu-_DhtX2gO.js → ActionMenu-FxXeRbPx.js} +2 -2
  4. package/dist/core/web/public/next/assets/{ActionMenu-_DhtX2gO.js.map → ActionMenu-FxXeRbPx.js.map} +1 -1
  5. package/dist/core/web/public/next/assets/{Advanced-CAAfaBke.js → Advanced-D_eS4472.js} +2 -2
  6. package/dist/core/web/public/next/assets/{Advanced-CAAfaBke.js.map → Advanced-D_eS4472.js.map} +1 -1
  7. package/dist/core/web/public/next/assets/{App-BAywyjE8.js → App-Cj4zKbG3.js} +2 -2
  8. package/dist/core/web/public/next/assets/{App-BAywyjE8.js.map → App-Cj4zKbG3.js.map} +1 -1
  9. package/dist/core/web/public/next/assets/{AppsSection-CUypKeog.js → AppsSection-Ddu_RCQE.js} +2 -2
  10. package/dist/core/web/public/next/assets/{AppsSection-CUypKeog.js.map → AppsSection-Ddu_RCQE.js.map} +1 -1
  11. package/dist/core/web/public/next/assets/{AreaTrend-CblDqC8Q.js → AreaTrend-CDxrQU4b.js} +2 -2
  12. package/dist/core/web/public/next/assets/{AreaTrend-CblDqC8Q.js.map → AreaTrend-CDxrQU4b.js.map} +1 -1
  13. package/dist/core/web/public/next/assets/AutonomySection-DuQkHGD_.js +2 -0
  14. package/dist/core/web/public/next/assets/{AutonomySection-D3d8lYO3.js.map → AutonomySection-DuQkHGD_.js.map} +1 -1
  15. package/dist/core/web/public/next/assets/{BranchBar-DU0jAV1E.js → BranchBar-CLsvOcyK.js} +2 -2
  16. package/dist/core/web/public/next/assets/{BranchBar-DU0jAV1E.js.map → BranchBar-CLsvOcyK.js.map} +1 -1
  17. package/dist/core/web/public/next/assets/{BudgetControl-Mm1ZL4u6.js → BudgetControl-TL3FeZ1D.js} +2 -2
  18. package/dist/core/web/public/next/assets/{BudgetControl-Mm1ZL4u6.js.map → BudgetControl-TL3FeZ1D.js.map} +1 -1
  19. package/dist/core/web/public/next/assets/{BurnDown-C1fgcFqo.js → BurnDown-sFXkUGdB.js} +2 -2
  20. package/dist/core/web/public/next/assets/{BurnDown-C1fgcFqo.js.map → BurnDown-sFXkUGdB.js.map} +1 -1
  21. package/dist/core/web/public/next/assets/{Button-DqgLUZvd.js → Button-HHXgoXGr.js} +2 -2
  22. package/dist/core/web/public/next/assets/{Button-DqgLUZvd.js.map → Button-HHXgoXGr.js.map} +1 -1
  23. package/dist/core/web/public/next/assets/{CapacityStrip-nWFHvqFB.js → CapacityStrip-qReu0RaF.js} +2 -2
  24. package/dist/core/web/public/next/assets/{CapacityStrip-nWFHvqFB.js.map → CapacityStrip-qReu0RaF.js.map} +1 -1
  25. package/dist/core/web/public/next/assets/{ChatSection-DUZNpiVr.js → ChatSection-DZuZfTaC.js} +3 -3
  26. package/dist/core/web/public/next/assets/{ChatSection-DUZNpiVr.js.map → ChatSection-DZuZfTaC.js.map} +1 -1
  27. package/dist/core/web/public/next/assets/{CloudBudgetForm-2OW38o_C.js → CloudBudgetForm-DJbiT1wi.js} +2 -2
  28. package/dist/core/web/public/next/assets/{CloudBudgetForm-2OW38o_C.js.map → CloudBudgetForm-DJbiT1wi.js.map} +1 -1
  29. package/dist/core/web/public/next/assets/{CommandPalette-C5w2o1-r.js → CommandPalette-zYLFZRnj.js} +2 -2
  30. package/dist/core/web/public/next/assets/{CommandPalette-C5w2o1-r.js.map → CommandPalette-zYLFZRnj.js.map} +1 -1
  31. package/dist/core/web/public/next/assets/{CommandSection-Bx2knNqY.js → CommandSection-rIeMK5Ch.js} +2 -2
  32. package/dist/core/web/public/next/assets/{CommandSection-Bx2knNqY.js.map → CommandSection-rIeMK5Ch.js.map} +1 -1
  33. package/dist/core/web/public/next/assets/{ConfirmDialog-B7ZwCQOX.js → ConfirmDialog-DLrLKM0c.js} +2 -2
  34. package/dist/core/web/public/next/assets/{ConfirmDialog-B7ZwCQOX.js.map → ConfirmDialog-DLrLKM0c.js.map} +1 -1
  35. package/dist/core/web/public/next/assets/{Dialog-BpgcEW6b.js → Dialog-BS9Dxi3G.js} +2 -2
  36. package/dist/core/web/public/next/assets/{Dialog-BpgcEW6b.js.map → Dialog-BS9Dxi3G.js.map} +1 -1
  37. package/dist/core/web/public/next/assets/{DiffPane-DpqRUtCx.js → DiffPane-TOmUf3b2.js} +2 -2
  38. package/dist/core/web/public/next/assets/{DiffPane-DpqRUtCx.js.map → DiffPane-TOmUf3b2.js.map} +1 -1
  39. package/dist/core/web/public/next/assets/{DiffViewer-CoV5-nUf.js → DiffViewer-BpH56302.js} +2 -2
  40. package/dist/core/web/public/next/assets/{DiffViewer-CoV5-nUf.js.map → DiffViewer-BpH56302.js.map} +1 -1
  41. package/dist/core/web/public/next/assets/{DockHost-C0Pq7Jak.js → DockHost-DzkzR-HD.js} +2 -2
  42. package/dist/core/web/public/next/assets/{DockHost-C0Pq7Jak.js.map → DockHost-DzkzR-HD.js.map} +1 -1
  43. package/dist/core/web/public/next/assets/{EmptyState-DYW29ncw.js → EmptyState-BqR5YAmf.js} +2 -2
  44. package/dist/core/web/public/next/assets/{EmptyState-DYW29ncw.js.map → EmptyState-BqR5YAmf.js.map} +1 -1
  45. package/dist/core/web/public/next/assets/{Epistemic-DVx6oHzp.js → Epistemic-dhvDTwAZ.js} +2 -2
  46. package/dist/core/web/public/next/assets/{Epistemic-DVx6oHzp.js.map → Epistemic-dhvDTwAZ.js.map} +1 -1
  47. package/dist/core/web/public/next/assets/{FleetSection-DSETviPK.js → FleetSection-ViAb549H.js} +3 -3
  48. package/dist/core/web/public/next/assets/{FleetSection-DSETviPK.js.map → FleetSection-ViAb549H.js.map} +1 -1
  49. package/dist/core/web/public/next/assets/{Funnel-DxiGqJrt.js → Funnel-D2u7Wlzc.js} +2 -2
  50. package/dist/core/web/public/next/assets/{Funnel-DxiGqJrt.js.map → Funnel-D2u7Wlzc.js.map} +1 -1
  51. package/dist/core/web/public/next/assets/{GearTray-C3I89sIt.js → GearTray-Cb2npoxM.js} +2 -2
  52. package/dist/core/web/public/next/assets/{GearTray-C3I89sIt.js.map → GearTray-Cb2npoxM.js.map} +1 -1
  53. package/dist/core/web/public/next/assets/{GrowthSection-C3m2bPEz.js → GrowthSection-C5aDPs8B.js} +2 -2
  54. package/dist/core/web/public/next/assets/{GrowthSection-C3m2bPEz.js.map → GrowthSection-C5aDPs8B.js.map} +1 -1
  55. package/dist/core/web/public/next/assets/{HandoffDialog-Bjb96a0N.js → HandoffDialog-BF3AYg-X.js} +2 -2
  56. package/dist/core/web/public/next/assets/{HandoffDialog-Bjb96a0N.js.map → HandoffDialog-BF3AYg-X.js.map} +1 -1
  57. package/dist/core/web/public/next/assets/{Input-ekTehVaH.js → Input-B5dmGLZx.js} +2 -2
  58. package/dist/core/web/public/next/assets/{Input-ekTehVaH.js.map → Input-B5dmGLZx.js.map} +1 -1
  59. package/dist/core/web/public/next/assets/{LeaderCard-85VBbbaZ.js → LeaderCard-DZrmjDbI.js} +2 -2
  60. package/dist/core/web/public/next/assets/{LeaderCard-85VBbbaZ.js.map → LeaderCard-DZrmjDbI.js.map} +1 -1
  61. package/dist/core/web/public/next/assets/{MatrixHeatmap-Bo8j0QPC.js → MatrixHeatmap-BgEUs2Eu.js} +2 -2
  62. package/dist/core/web/public/next/assets/{MatrixHeatmap-Bo8j0QPC.js.map → MatrixHeatmap-BgEUs2Eu.js.map} +1 -1
  63. package/dist/core/web/public/next/assets/McpSection-DZkiOuoq.js +2 -0
  64. package/dist/core/web/public/next/assets/{McpSection-DvHFaVyp.js.map → McpSection-DZkiOuoq.js.map} +1 -1
  65. package/dist/core/web/public/next/assets/{MessageMarkdown-fsY_ltVa.js → MessageMarkdown-BauY8ZTY.js} +3 -3
  66. package/dist/core/web/public/next/assets/{MessageMarkdown-fsY_ltVa.js.map → MessageMarkdown-BauY8ZTY.js.map} +1 -1
  67. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DDdtu82l.js → MessageMarkdownRenderer-DLBNLfsn.js} +2 -2
  68. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DDdtu82l.js.map → MessageMarkdownRenderer-DLBNLfsn.js.map} +1 -1
  69. package/dist/core/web/public/next/assets/{Meter-CeGDXdDM.js → Meter-DNeocJnD.js} +2 -2
  70. package/dist/core/web/public/next/assets/{Meter-CeGDXdDM.js.map → Meter-DNeocJnD.js.map} +1 -1
  71. package/dist/core/web/public/next/assets/{MindSection-CDVhHvXl.js → MindSection-BvJXFjyX.js} +2 -2
  72. package/dist/core/web/public/next/assets/{MindSection-CDVhHvXl.js.map → MindSection-BvJXFjyX.js.map} +1 -1
  73. package/dist/core/web/public/next/assets/{MutationTokenDialog-DTQzEOHR.js → MutationTokenDialog-mxrw0Yvy.js} +2 -2
  74. package/dist/core/web/public/next/assets/{MutationTokenDialog-DTQzEOHR.js.map → MutationTokenDialog-mxrw0Yvy.js.map} +1 -1
  75. package/dist/core/web/public/next/assets/{NeedsYouDrawer-6AuN0BF3.js → NeedsYouDrawer-CO-Balfp.js} +2 -2
  76. package/dist/core/web/public/next/assets/{NeedsYouDrawer-6AuN0BF3.js.map → NeedsYouDrawer-CO-Balfp.js.map} +1 -1
  77. package/dist/core/web/public/next/assets/{NeedsYouList-ChnRmbSk.js → NeedsYouList-CzDZbzRD.js} +2 -2
  78. package/dist/core/web/public/next/assets/{NeedsYouList-ChnRmbSk.js.map → NeedsYouList-CzDZbzRD.js.map} +1 -1
  79. package/dist/core/web/public/next/assets/{NewChatDialog-B06E7sqg.js → NewChatDialog-B8eJjlFf.js} +2 -2
  80. package/dist/core/web/public/next/assets/{NewChatDialog-B06E7sqg.js.map → NewChatDialog-B8eJjlFf.js.map} +1 -1
  81. package/dist/core/web/public/next/assets/{OnboardingFlow-C2M3zov9.js → OnboardingFlow-Cij6KWat.js} +2 -2
  82. package/dist/core/web/public/next/assets/{OnboardingFlow-C2M3zov9.js.map → OnboardingFlow-Cij6KWat.js.map} +1 -1
  83. package/dist/core/web/public/next/assets/{PreviewPane-Bd6HsX1k.js → PreviewPane-BS-CleCd.js} +2 -2
  84. package/dist/core/web/public/next/assets/{PreviewPane-Bd6HsX1k.js.map → PreviewPane-BS-CleCd.js.map} +1 -1
  85. package/dist/core/web/public/next/assets/{ProviderLogo-Bz7KR5j3.js → ProviderLogo-C5mBg8i0.js} +2 -2
  86. package/dist/core/web/public/next/assets/{ProviderLogo-Bz7KR5j3.js.map → ProviderLogo-C5mBg8i0.js.map} +1 -1
  87. package/dist/core/web/public/next/assets/{RailStatus-CctCuuLy.js → RailStatus-cPRyOmrk.js} +2 -2
  88. package/dist/core/web/public/next/assets/{RailStatus-CctCuuLy.js.map → RailStatus-cPRyOmrk.js.map} +1 -1
  89. package/dist/core/web/public/next/assets/{RefreshIndicator-CKY5BGdD.js → RefreshIndicator-CMwSCiz5.js} +2 -2
  90. package/dist/core/web/public/next/assets/{RefreshIndicator-CKY5BGdD.js.map → RefreshIndicator-CMwSCiz5.js.map} +1 -1
  91. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-CspIsW_G.js → ResourcePoolConsoleApp-BFi1opsC.js} +2 -2
  92. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-CspIsW_G.js.map → ResourcePoolConsoleApp-BFi1opsC.js.map} +1 -1
  93. package/dist/core/web/public/next/assets/{ResourcesChrome-B7fHZ6zX.js → ResourcesChrome-BJCauW_t.js} +3 -3
  94. package/dist/core/web/public/next/assets/{ResourcesChrome-B7fHZ6zX.js.map → ResourcesChrome-BJCauW_t.js.map} +1 -1
  95. package/dist/core/web/public/next/assets/{ResourcesDrawer-B7-N9n7-.js → ResourcesDrawer-BDecg6nO.js} +2 -2
  96. package/dist/core/web/public/next/assets/{ResourcesDrawer-B7-N9n7-.js.map → ResourcesDrawer-BDecg6nO.js.map} +1 -1
  97. package/dist/core/web/public/next/assets/{RouteErrorBoundary-C_B11J0s.js → RouteErrorBoundary-DYtwc2ja.js} +2 -2
  98. package/dist/core/web/public/next/assets/{RouteErrorBoundary-C_B11J0s.js.map → RouteErrorBoundary-DYtwc2ja.js.map} +1 -1
  99. package/dist/core/web/public/next/assets/{RunInCloudAction-_juw4EXd.js → RunInCloudAction-BEGEEM8O.js} +2 -2
  100. package/dist/core/web/public/next/assets/{RunInCloudAction-_juw4EXd.js.map → RunInCloudAction-BEGEEM8O.js.map} +1 -1
  101. package/dist/core/web/public/next/assets/{SeatSelector-D_YXvkPy.js → SeatSelector-CYHRR7Wp.js} +2 -2
  102. package/dist/core/web/public/next/assets/{SeatSelector-D_YXvkPy.js.map → SeatSelector-CYHRR7Wp.js.map} +1 -1
  103. package/dist/core/web/public/next/assets/{Segmented-DnKP6rr7.js → Segmented-BE53BenI.js} +2 -2
  104. package/dist/core/web/public/next/assets/{Segmented-DnKP6rr7.js.map → Segmented-BE53BenI.js.map} +1 -1
  105. package/dist/core/web/public/next/assets/{Select-DlbUupTX.js → Select-BwSGkHCS.js} +2 -2
  106. package/dist/core/web/public/next/assets/{Select-DlbUupTX.js.map → Select-BwSGkHCS.js.map} +1 -1
  107. package/dist/core/web/public/next/assets/{SessionGate-DnuTZACL.js → SessionGate-e0dFJm9d.js} +2 -2
  108. package/dist/core/web/public/next/assets/{SessionGate-DnuTZACL.js.map → SessionGate-e0dFJm9d.js.map} +1 -1
  109. package/dist/core/web/public/next/assets/{SessionInsightChip-C33-k-Q5.js → SessionInsightChip-CxlSyueJ.js} +2 -2
  110. package/dist/core/web/public/next/assets/{SessionInsightChip-C33-k-Q5.js.map → SessionInsightChip-CxlSyueJ.js.map} +1 -1
  111. package/dist/core/web/public/next/assets/{SessionSearch-DhhR9Csg.js → SessionSearch-_yp7S2TP.js} +2 -2
  112. package/dist/core/web/public/next/assets/{SessionSearch-DhhR9Csg.js.map → SessionSearch-_yp7S2TP.js.map} +1 -1
  113. package/dist/core/web/public/next/assets/{SettingsSection-C0xQvCz3.js → SettingsSection-wGnpWeGW.js} +2 -2
  114. package/dist/core/web/public/next/assets/{SettingsSection-C0xQvCz3.js.map → SettingsSection-wGnpWeGW.js.map} +1 -1
  115. package/dist/core/web/public/next/assets/{Sheet-BvNYOYv5.js → Sheet-DVP2Mgy6.js} +2 -2
  116. package/dist/core/web/public/next/assets/{Sheet-BvNYOYv5.js.map → Sheet-DVP2Mgy6.js.map} +1 -1
  117. package/dist/core/web/public/next/assets/{ShortcutsOverlay-1nUBVO-Z.js → ShortcutsOverlay-BcIcoClX.js} +2 -2
  118. package/dist/core/web/public/next/assets/{ShortcutsOverlay-1nUBVO-Z.js.map → ShortcutsOverlay-BcIcoClX.js.map} +1 -1
  119. package/dist/core/web/public/next/assets/{Sidebar-YrVvvBNM.js → Sidebar-DjQOqPbm.js} +3 -3
  120. package/dist/core/web/public/next/assets/{Sidebar-YrVvvBNM.js.map → Sidebar-DjQOqPbm.js.map} +1 -1
  121. package/dist/core/web/public/next/assets/{Slider-B2c-dbQb.js → Slider-BypUWjpH.js} +2 -2
  122. package/dist/core/web/public/next/assets/{Slider-B2c-dbQb.js.map → Slider-BypUWjpH.js.map} +1 -1
  123. package/dist/core/web/public/next/assets/{StatusBadge-Q9YYkijx.js → StatusBadge-HCZp416_.js} +2 -2
  124. package/dist/core/web/public/next/assets/{StatusBadge-Q9YYkijx.js.map → StatusBadge-HCZp416_.js.map} +1 -1
  125. package/dist/core/web/public/next/assets/{StepBand-Ci-C0GUG.js → StepBand-Duz1PUes.js} +2 -2
  126. package/dist/core/web/public/next/assets/{StepBand-Ci-C0GUG.js.map → StepBand-Duz1PUes.js.map} +1 -1
  127. package/dist/core/web/public/next/assets/{Surface-DBovMq4P.js → Surface-B75lVfzm.js} +2 -2
  128. package/dist/core/web/public/next/assets/{Surface-DBovMq4P.js.map → Surface-B75lVfzm.js.map} +1 -1
  129. package/dist/core/web/public/next/assets/{Swimlane-Cdc4TqDe.js → Swimlane-DGcIcnNA.js} +2 -2
  130. package/dist/core/web/public/next/assets/{Swimlane-Cdc4TqDe.js.map → Swimlane-DGcIcnNA.js.map} +1 -1
  131. package/dist/core/web/public/next/assets/{Switch-CUrvzO2k.js → Switch-iveI-8NY.js} +2 -2
  132. package/dist/core/web/public/next/assets/{Switch-CUrvzO2k.js.map → Switch-iveI-8NY.js.map} +1 -1
  133. package/dist/core/web/public/next/assets/{Tag-Bv8u6APt.js → Tag-DH15CUJp.js} +2 -2
  134. package/dist/core/web/public/next/assets/{Tag-Bv8u6APt.js.map → Tag-DH15CUJp.js.map} +1 -1
  135. package/dist/core/web/public/next/assets/{TerminalPane-BE4Xlqi5.js → TerminalPane-MQT-veKZ.js} +2 -2
  136. package/dist/core/web/public/next/assets/{TerminalPane-BE4Xlqi5.js.map → TerminalPane-MQT-veKZ.js.map} +1 -1
  137. package/dist/core/web/public/next/assets/{UniverseConsoleApp-BGwejf0m.js → UniverseConsoleApp-C8yQ0AaR.js} +2 -2
  138. package/dist/core/web/public/next/assets/{UniverseConsoleApp-BGwejf0m.js.map → UniverseConsoleApp-C8yQ0AaR.js.map} +1 -1
  139. package/dist/core/web/public/next/assets/{UniverseView-CgKa-WXC.js → UniverseView-_nPURPqe.js} +2 -2
  140. package/dist/core/web/public/next/assets/{UniverseView-CgKa-WXC.js.map → UniverseView-_nPURPqe.js.map} +1 -1
  141. package/dist/core/web/public/next/assets/{UsageSection-CazsHm1f.js → UsageSection-CqxRGJ40.js} +2 -2
  142. package/dist/core/web/public/next/assets/{UsageSection-CazsHm1f.js.map → UsageSection-CqxRGJ40.js.map} +1 -1
  143. package/dist/core/web/public/next/assets/{VerseConsoleApp-CTF3Shs0.js → VerseConsoleApp-DTjDpGCd.js} +3 -3
  144. package/dist/core/web/public/next/assets/{VerseConsoleApp-CTF3Shs0.js.map → VerseConsoleApp-DTjDpGCd.js.map} +1 -1
  145. package/dist/core/web/public/next/assets/{Workspace-CgdyXiEV.js → Workspace-DfcFGzME.js} +5 -5
  146. package/dist/core/web/public/next/assets/{Workspace-CgdyXiEV.js.map → Workspace-DfcFGzME.js.map} +1 -1
  147. package/dist/core/web/public/next/assets/{actions-MtxBGS5B.js → actions-tWevL9HV.js} +2 -2
  148. package/dist/core/web/public/next/assets/{actions-MtxBGS5B.js.map → actions-tWevL9HV.js.map} +1 -1
  149. package/dist/core/web/public/next/assets/{budget-queries-CP7hgR-p.js → budget-queries-V3wcJVK_.js} +2 -2
  150. package/dist/core/web/public/next/assets/{budget-queries-CP7hgR-p.js.map → budget-queries-V3wcJVK_.js.map} +1 -1
  151. package/dist/core/web/public/next/assets/{capacity-strip-model-fHfu5cph.js → capacity-strip-model-BDbmQ3e3.js} +2 -2
  152. package/dist/core/web/public/next/assets/{capacity-strip-model-fHfu5cph.js.map → capacity-strip-model-BDbmQ3e3.js.map} +1 -1
  153. package/dist/core/web/public/next/assets/{charts-Bis9WSiS.js → charts-CfAjuKMv.js} +2 -2
  154. package/dist/core/web/public/next/assets/{charts-Bis9WSiS.js.map → charts-CfAjuKMv.js.map} +1 -1
  155. package/dist/core/web/public/next/assets/{cloud-queries-BsOepFz6.js → cloud-queries-Br_r0UAz.js} +2 -2
  156. package/dist/core/web/public/next/assets/{cloud-queries-BsOepFz6.js.map → cloud-queries-Br_r0UAz.js.map} +1 -1
  157. package/dist/core/web/public/next/assets/{cloud.module-DoFnr8ZH.js → cloud.module-ascz58c3.js} +2 -2
  158. package/dist/core/web/public/next/assets/{cloud.module-DoFnr8ZH.js.map → cloud.module-ascz58c3.js.map} +1 -1
  159. package/dist/core/web/public/next/assets/{command-bus-CMvbYP5K.js → command-bus-xYZoK9nQ.js} +2 -2
  160. package/dist/core/web/public/next/assets/{command-bus-CMvbYP5K.js.map → command-bus-xYZoK9nQ.js.map} +1 -1
  161. package/dist/core/web/public/next/assets/{context-model-Ci3Ch9t5.js → context-model-BC-HOmPo.js} +2 -2
  162. package/dist/core/web/public/next/assets/{context-model-Ci3Ch9t5.js.map → context-model-BC-HOmPo.js.map} +1 -1
  163. package/dist/core/web/public/next/assets/{context-model-CjiJTnf1.js → context-model-CIBmSugV.js} +2 -2
  164. package/dist/core/web/public/next/assets/{context-model-CjiJTnf1.js.map → context-model-CIBmSugV.js.map} +1 -1
  165. package/dist/core/web/public/next/assets/{context-queries-BDXT6LQ3.js → context-queries-CrPcHWTz.js} +2 -2
  166. package/dist/core/web/public/next/assets/{context-queries-BDXT6LQ3.js.map → context-queries-CrPcHWTz.js.map} +1 -1
  167. package/dist/core/web/public/next/assets/{control-queries-Dv-h1Clu.js → control-queries-CmgBgKV7.js} +2 -2
  168. package/dist/core/web/public/next/assets/{control-queries-Dv-h1Clu.js.map → control-queries-CmgBgKV7.js.map} +1 -1
  169. package/dist/core/web/public/next/assets/{dock-icons-t--Eugrd.js → dock-icons-CUh8dOxJ.js} +2 -2
  170. package/dist/core/web/public/next/assets/{dock-icons-t--Eugrd.js.map → dock-icons-CUh8dOxJ.js.map} +1 -1
  171. package/dist/core/web/public/next/assets/{dock-store-qIu7kSQE.js → dock-store-B2vlxqPu.js} +2 -2
  172. package/dist/core/web/public/next/assets/{dock-store-qIu7kSQE.js.map → dock-store-B2vlxqPu.js.map} +1 -1
  173. package/dist/core/web/public/next/assets/{fleet-model-IRbwfhkR.js → fleet-model-7i-FbzKI.js} +2 -2
  174. package/dist/core/web/public/next/assets/{fleet-model-IRbwfhkR.js.map → fleet-model-7i-FbzKI.js.map} +1 -1
  175. package/dist/core/web/public/next/assets/{fleet-queries-7FVNByX1.js → fleet-queries-DzGoqq8X.js} +2 -2
  176. package/dist/core/web/public/next/assets/{fleet-queries-7FVNByX1.js.map → fleet-queries-DzGoqq8X.js.map} +1 -1
  177. package/dist/core/web/public/next/assets/{focus-trap-QqQxQdvH.js → focus-trap-HtcoXeEq.js} +2 -2
  178. package/dist/core/web/public/next/assets/{focus-trap-QqQxQdvH.js.map → focus-trap-HtcoXeEq.js.map} +1 -1
  179. package/dist/core/web/public/next/assets/{format-CaMmVQCn.js → format-BkWdOQDL.js} +2 -2
  180. package/dist/core/web/public/next/assets/{format-CaMmVQCn.js.map → format-BkWdOQDL.js.map} +1 -1
  181. package/dist/core/web/public/next/assets/{git-model-B4S_GUNA.js → git-model-bk_RXh3y.js} +2 -2
  182. package/dist/core/web/public/next/assets/{git-model-B4S_GUNA.js.map → git-model-bk_RXh3y.js.map} +1 -1
  183. package/dist/core/web/public/next/assets/{global-BkNl4e6E.js → global-oEl9Qj8u.js} +2 -2
  184. package/dist/core/web/public/next/assets/{global-BkNl4e6E.js.map → global-oEl9Qj8u.js.map} +1 -1
  185. package/dist/core/web/public/next/assets/{guarded-action-DHiL8tY5.js → guarded-action-OzqcPjmh.js} +3 -3
  186. package/dist/core/web/public/next/assets/{guarded-action-DHiL8tY5.js.map → guarded-action-OzqcPjmh.js.map} +1 -1
  187. package/dist/core/web/public/next/assets/{guarded-runners-DmGEkM2P.js → guarded-runners-LHLXmXIk.js} +2 -2
  188. package/dist/core/web/public/next/assets/{guarded-runners-DmGEkM2P.js.map → guarded-runners-LHLXmXIk.js.map} +1 -1
  189. package/dist/core/web/public/next/assets/{icon-base-NtFmP2yB.js → icon-base-DvM1eI5V.js} +2 -2
  190. package/dist/core/web/public/next/assets/{icon-base-NtFmP2yB.js.map → icon-base-DvM1eI5V.js.map} +1 -1
  191. package/dist/core/web/public/next/assets/{icons-C5EFt_Ts.js → icons-DEQa2rTx.js} +2 -2
  192. package/dist/core/web/public/next/assets/{icons-C5EFt_Ts.js.map → icons-DEQa2rTx.js.map} +1 -1
  193. package/dist/core/web/public/next/assets/{index-DbDw9UAs.js → index-BVxOlseC.js} +3 -3
  194. package/dist/core/web/public/next/assets/{index-DbDw9UAs.js.map → index-BVxOlseC.js.map} +1 -1
  195. package/dist/core/web/public/next/assets/{live-model-DEwrl7_A.js → live-model-bmsJgnYD.js} +2 -2
  196. package/dist/core/web/public/next/assets/{live-model-DEwrl7_A.js.map → live-model-bmsJgnYD.js.map} +1 -1
  197. package/dist/core/web/public/next/assets/{mind.module-CLhqMQak.js → mind.module-gTGAuJt1.js} +2 -2
  198. package/dist/core/web/public/next/assets/{mind.module-CLhqMQak.js.map → mind.module-gTGAuJt1.js.map} +1 -1
  199. package/dist/core/web/public/next/assets/{mutations-Kvzsg-iK.js → mutations-C5S7okTW.js} +2 -2
  200. package/dist/core/web/public/next/assets/{mutations-Kvzsg-iK.js.map → mutations-C5S7okTW.js.map} +1 -1
  201. package/dist/core/web/public/next/assets/{nav-C0IunEYF.js → nav-NVtnuG7A.js} +2 -2
  202. package/dist/core/web/public/next/assets/{nav-C0IunEYF.js.map → nav-NVtnuG7A.js.map} +1 -1
  203. package/dist/core/web/public/next/assets/{overnight-queries-C_AfcL7q.js → overnight-queries-DGm3qL1b.js} +2 -2
  204. package/dist/core/web/public/next/assets/{overnight-queries-C_AfcL7q.js.map → overnight-queries-DGm3qL1b.js.map} +1 -1
  205. package/dist/core/web/public/next/assets/{preloaded-CctOitLu.js → preloaded-Cwf9rsnZ.js} +2 -2
  206. package/dist/core/web/public/next/assets/{preloaded-CctOitLu.js.map → preloaded-Cwf9rsnZ.js.map} +1 -1
  207. package/dist/core/web/public/next/assets/primitives-DyCKYSBG.js +1 -0
  208. package/dist/core/web/public/next/assets/{queries-THD05gHP.js → queries-CYisSAAB.js} +2 -2
  209. package/dist/core/web/public/next/assets/{queries-THD05gHP.js.map → queries-CYisSAAB.js.map} +1 -1
  210. package/dist/core/web/public/next/assets/{reasoning-pref-BVPu0SME.js → reasoning-pref-BUcFF_5G.js} +2 -2
  211. package/dist/core/web/public/next/assets/{reasoning-pref-BVPu0SME.js.map → reasoning-pref-BUcFF_5G.js.map} +1 -1
  212. package/dist/core/web/public/next/assets/{reveal-anchor-wCT5b4m3.js → reveal-anchor-D-tV8xau.js} +2 -2
  213. package/dist/core/web/public/next/assets/{reveal-anchor-wCT5b4m3.js.map → reveal-anchor-D-tV8xau.js.map} +1 -1
  214. package/dist/core/web/public/next/assets/{seat-subscription-CR_VylsK.js → seat-subscription-B-f9ViU2.js} +2 -2
  215. package/dist/core/web/public/next/assets/{seat-subscription-CR_VylsK.js.map → seat-subscription-B-f9ViU2.js.map} +1 -1
  216. package/dist/core/web/public/next/assets/{section-visibility-B0xXUQJ0.js → section-visibility-Yctxu-if.js} +2 -2
  217. package/dist/core/web/public/next/assets/{section-visibility-B0xXUQJ0.js.map → section-visibility-Yctxu-if.js.map} +1 -1
  218. package/dist/core/web/public/next/assets/{sidebar-model-C5wVXGpb.js → sidebar-model-DQ-FyBHW.js} +2 -2
  219. package/dist/core/web/public/next/assets/{sidebar-model-C5wVXGpb.js.map → sidebar-model-DQ-FyBHW.js.map} +1 -1
  220. package/dist/core/web/public/next/assets/{slots-DDd8cEoh.js → slots-BhP8b8tf.js} +3 -3
  221. package/dist/core/web/public/next/assets/{slots-DDd8cEoh.js.map → slots-BhP8b8tf.js.map} +1 -1
  222. package/dist/core/web/public/next/assets/{surface-data-BFxAlefI.js → surface-data-DTI7LjvH.js} +2 -2
  223. package/dist/core/web/public/next/assets/{surface-data-BFxAlefI.js.map → surface-data-DTI7LjvH.js.map} +1 -1
  224. package/dist/core/web/public/next/assets/surface-prefetch-CdUEBFrl.js +2 -0
  225. package/dist/core/web/public/next/assets/{surface-prefetch-CHusyO9q.js.map → surface-prefetch-CdUEBFrl.js.map} +1 -1
  226. package/dist/core/web/public/next/assets/{tasks-model-DvkWveXs.js → tasks-model-BKDNqmmt.js} +2 -2
  227. package/dist/core/web/public/next/assets/{tasks-model-DvkWveXs.js.map → tasks-model-BKDNqmmt.js.map} +1 -1
  228. package/dist/core/web/public/next/assets/{terminal-icons-Dp6pJgV2.js → terminal-icons-D2xe-aM1.js} +2 -2
  229. package/dist/core/web/public/next/assets/{terminal-icons-Dp6pJgV2.js.map → terminal-icons-D2xe-aM1.js.map} +1 -1
  230. package/dist/core/web/public/next/assets/{usage-queries-CUTmnegA.js → usage-queries-BZuAANlI.js} +2 -2
  231. package/dist/core/web/public/next/assets/{usage-queries-CUTmnegA.js.map → usage-queries-BZuAANlI.js.map} +1 -1
  232. package/dist/core/web/public/next/assets/{use-guarded-action-UCX2u1t1.js → use-guarded-action-Cf4MeNBa.js} +2 -2
  233. package/dist/core/web/public/next/assets/{use-guarded-action-UCX2u1t1.js.map → use-guarded-action-Cf4MeNBa.js.map} +1 -1
  234. package/dist/core/web/public/next/assets/{use-ticker-OXAjob3y.js → use-ticker-D9yi49my.js} +2 -2
  235. package/dist/core/web/public/next/assets/{use-ticker-OXAjob3y.js.map → use-ticker-D9yi49my.js.map} +1 -1
  236. package/dist/core/web/public/next/assets/{use-token-gate-CDDRAoKH.js → use-token-gate-DqrSXdX6.js} +2 -2
  237. package/dist/core/web/public/next/assets/{use-token-gate-CDDRAoKH.js.map → use-token-gate-DqrSXdX6.js.map} +1 -1
  238. package/dist/core/web/public/next/assets/{useChartWidth-D9M7kUw7.js → useChartWidth-owwodNVz.js} +2 -2
  239. package/dist/core/web/public/next/assets/{useChartWidth-D9M7kUw7.js.map → useChartWidth-owwodNVz.js.map} +1 -1
  240. package/dist/core/web/public/next/assets/{useSeatsRefresh-B2dCVcj9.js → useSeatsRefresh-DgFy-Ph4.js} +2 -2
  241. package/dist/core/web/public/next/assets/{useSeatsRefresh-B2dCVcj9.js.map → useSeatsRefresh-DgFy-Ph4.js.map} +1 -1
  242. package/dist/core/web/public/next/assets/{useVerseTranscript-BL3CljSI.js → useVerseTranscript-CDYrrWOO.js} +2 -2
  243. package/dist/core/web/public/next/assets/{useVerseTranscript-BL3CljSI.js.map → useVerseTranscript-CDYrrWOO.js.map} +1 -1
  244. package/dist/core/web/public/next/assets/{verse-icons-DASWdYuE.js → verse-icons-F9VwX07_.js} +2 -2
  245. package/dist/core/web/public/next/assets/{verse-icons-DASWdYuE.js.map → verse-icons-F9VwX07_.js.map} +1 -1
  246. package/dist/core/web/public/next/assets/{verse-model-BQ0Y2CSr.js → verse-model-DyCwZF-M.js} +2 -2
  247. package/dist/core/web/public/next/assets/{verse-model-BQ0Y2CSr.js.map → verse-model-DyCwZF-M.js.map} +1 -1
  248. package/dist/core/web/public/next/assets/{verse-ui-store-D7YXi63q.js → verse-ui-store-62DxpVHS.js} +3 -3
  249. package/dist/core/web/public/next/assets/{verse-ui-store-D7YXi63q.js.map → verse-ui-store-62DxpVHS.js.map} +1 -1
  250. package/dist/core/web/public/next/assets/{viewport-BYGH5EgA.js → viewport-nTubFCwf.js} +2 -2
  251. package/dist/core/web/public/next/assets/{viewport-BYGH5EgA.js.map → viewport-nTubFCwf.js.map} +1 -1
  252. package/dist/core/web/public/next/assets/{warmup-AsqwWCUi.js → warmup-HG5vYbsN.js} +3 -3
  253. package/dist/core/web/public/next/assets/{warmup-AsqwWCUi.js.map → warmup-HG5vYbsN.js.map} +1 -1
  254. package/dist/core/web/public/next/assets/{workspace-model-CXorJr0G.js → workspace-model-CbhdPhei.js} +2 -2
  255. package/dist/core/web/public/next/assets/{workspace-model-CXorJr0G.js.map → workspace-model-CbhdPhei.js.map} +1 -1
  256. package/dist/core/web/public/next/index.html +1 -1
  257. package/dist/release-dependency-inventory.json +1 -1
  258. package/package.json +1 -1
  259. package/dist/core/web/public/next/assets/AutonomySection-D3d8lYO3.js +0 -2
  260. package/dist/core/web/public/next/assets/McpSection-DvHFaVyp.js +0 -2
  261. package/dist/core/web/public/next/assets/primitives-CbAGCNKt.js +0 -1
  262. package/dist/core/web/public/next/assets/surface-prefetch-CHusyO9q.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"OnboardingFlow-C2M3zov9.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/onboarding/onboarding-model.ts","../../../../../../src/web-ui/routes/verse/onboarding/onboarding.module.css","../../../../../../src/web-ui/routes/verse/onboarding/OnboardingFlow.tsx"],"sourcesContent":["/**\n * routes/verse/onboarding/onboarding-model.ts — the first-run tour's facts,\n * derived from the same reads the Usage section uses, with the same honesty\n * rules (docs/VERSE-TELEMETRY-V2.md).\n *\n * Pure: no React, no I/O. Everything the tour asserts about the machine is\n * computed here so it can be tested without a DOM, and so the one rule that\n * matters is enforced in one place:\n *\n * AN ABSENT READ IS \"UNKNOWN\", NEVER \"FINE\" AND NEVER \"BROKEN\".\n *\n * A first-run screen is exactly where a confident lie does the most damage —\n * it is the operator's first and only calibration of how much this app's\n * claims can be trusted. So a route that 404s, a payload that does not\n * narrow, and a probe that could not reach a runtime each produce their own\n * sentence, and none of them produces a green check.\n *\n * The tour NEVER renders a command it invented: the seats step shows only\n * A2's own fix argv (through C6's capacity rows).\n */\nimport type { LocalModelsSnapshot } from '../usage/usage-contract.js';\n\n// ---------------------------------------------------------------------------\n// Steps\n// ---------------------------------------------------------------------------\n\nexport type OnboardingStepId = 'welcome' | 'accounts' | 'local' | 'stops' | 'finish';\n\nexport interface OnboardingStepMeta {\n id: OnboardingStepId;\n /** Shown as the card's heading. */\n title: string;\n /** One line under the heading. */\n subtitle: string;\n}\n\nexport const ONBOARDING_STEPS: readonly OnboardingStepMeta[] = [\n {\n id: 'welcome',\n title: 'Welcome to Verse',\n subtitle: 'Five sections, one rail. Two minutes and you will know what each one does.',\n },\n {\n id: 'accounts',\n title: 'Your seats',\n subtitle: 'Which provider accounts this machine can actually dispatch to right now.',\n },\n {\n id: 'local',\n title: 'Local runtime',\n subtitle: 'Whether there is a model on this machine, and what that changes.',\n },\n {\n id: 'stops',\n title: 'Three ways to stop',\n subtitle: 'They do not have the same blast radius. This is the one screen that says so.',\n },\n {\n id: 'finish',\n title: 'Make it yours',\n subtitle: 'Theme, accent, density and font live in Settings. Then start a chat.',\n },\n];\n\nexport function clampStep(step: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(ONBOARDING_STEPS.length - 1, Math.max(0, Math.trunc(step)));\n}\n\n// ---------------------------------------------------------------------------\n// Tone\n// ---------------------------------------------------------------------------\n\n/**\n * Step 2 (seats) is C6's shared LiveCapacityStrip since 3.10 — the tour no\n * longer narrows the accounts route itself, so the seats can never read\n * differently here than in Apps & Accounts. The tone below serves the local\n * runtime and the stops.\n */\nexport type FindingTone = 'ok' | 'attention' | 'unknown';\n\n// ---------------------------------------------------------------------------\n// Local runtime\n// ---------------------------------------------------------------------------\n\nexport interface LocalFinding {\n tone: FindingTone;\n state: string;\n summary: string;\n /** What having (or not having) a local runtime means for the operator. */\n meaning: string;\n /** Present only when there is something to do about it. */\n fix: string | null;\n modelCount: number;\n toolCapableCount: number;\n /** True when this reading was retained from an earlier probe. */\n stale: boolean;\n}\n\nexport interface LocalInput {\n snapshot: LocalModelsSnapshot | null;\n loading: boolean;\n unavailableReason: string | null;\n}\n\nconst LOCAL_MEANING_AVAILABLE =\n 'Local seats cost nothing and consume no provider quota, so the autonomous loop can keep working after a cloud window is used up.';\nconst LOCAL_MEANING_ABSENT =\n 'Without one, every turn and every autonomous tick spends a provider account, and a used-up window stops the work.';\n\nexport function buildLocalFinding(input: LocalInput): LocalFinding {\n if (input.loading) {\n return {\n tone: 'unknown',\n state: 'checking',\n summary: 'Probing the local runtimes on this machine…',\n meaning: LOCAL_MEANING_AVAILABLE,\n fix: null,\n modelCount: 0,\n toolCapableCount: 0,\n stale: false,\n };\n }\n\n if (!input.snapshot) {\n return {\n tone: 'unknown',\n state: 'not reported',\n summary: 'This server does not report local runtimes, so Verse cannot say whether one is available here.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: input.unavailableReason,\n modelCount: 0,\n toolCapableCount: 0,\n stale: false,\n };\n }\n\n const models = input.snapshot.models;\n const toolCapable = models.filter((m) => m.supportsTools === true).length;\n const stale = input.snapshot.runtimes.some((r) => r.stale);\n\n if (!input.snapshot.reachable) {\n return {\n tone: 'attention',\n state: 'unreachable',\n // \"Not reachable\" and \"not installed\" are different facts and the probe\n // cannot tell them apart — so this does not claim either one.\n summary:\n 'No local runtime answered. Verse cannot tell whether one is not running or not installed — the probe only knows it got no answer.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: 'Start Ollama (or LM Studio) and press Refresh in Usage. If neither is installed, everything still works — it all runs on the cloud seats.',\n modelCount: 0,\n toolCapableCount: 0,\n stale,\n };\n }\n\n if (models.length === 0) {\n return {\n tone: 'attention',\n state: 'no models',\n summary: 'A local runtime answered, but it has no models installed.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: 'Pull a model into the runtime, then press Refresh in Usage.',\n modelCount: 0,\n toolCapableCount: 0,\n stale,\n };\n }\n\n return {\n tone: 'ok',\n state: stale ? 'available (retained reading)' : 'available',\n summary:\n `${models.length} local ${models.length === 1 ? 'model' : 'models'} available` +\n (toolCapable > 0 ? `, ${toolCapable} of them tool-capable.` : ', none of them tool-capable.') +\n (stale ? ' This is a retained reading, not a fresh probe.' : ''),\n meaning: toolCapable > 0\n ? LOCAL_MEANING_AVAILABLE\n : `${LOCAL_MEANING_AVAILABLE} A model that cannot call tools can answer, but cannot run an agentic turn.`,\n fix: null,\n modelCount: models.length,\n toolCapableCount: toolCapable,\n stale,\n };\n}\n\n// ---------------------------------------------------------------------------\n// The three stops\n// ---------------------------------------------------------------------------\n\nexport interface StopControl {\n name: string;\n /** What it halts. */\n scope: string;\n /** What it does NOT halt — the half people get wrong. */\n limit: string;\n reversible: string;\n tone: FindingTone;\n}\n\n/**\n * Verbatim against docs/VERSE-CONTRACT-V2.md's two footguns and the V2.1\n * amendment. The kill switch is never called a pause, and \"Stop loop\" is\n * stated as engaging the same global sentinel as the emergency control,\n * because it does (`stopDaemon()` is `setKill(true)`).\n */\nexport const STOP_CONTROLS: readonly StopControl[] = [\n {\n name: 'Pause',\n scope: 'Halts autonomous dispatch only. A running loop parks instead of exiting.',\n limit: 'Your own chats and the agent’s write tools keep working.',\n reversible: 'Reversible in one click, with no restart and no confirmation.',\n tone: 'ok',\n },\n {\n name: 'Stop loop',\n scope: 'Stops the daemon — and engages the GLOBAL kill switch while doing it.',\n limit: 'That means it also refuses the agent’s own write tools, exactly like the emergency control.',\n reversible: 'Reversible, but confirm-guarded. For an ordinary halt, use Pause.',\n tone: 'attention',\n },\n {\n name: 'Emergency stop',\n scope: 'Engages the global kill switch (~/.ashlr/KILL) directly.',\n limit: 'Every mutating path refuses: the loop, dispatch, and the agent’s own write tools.',\n reversible: 'Reversible, confirm-guarded, and deliberately separated from the other two.',\n tone: 'attention',\n },\n];\n","/* First-run tour — a docked card, not a dialog. No backdrop: the app behind\n it stays visible and clickable, which is the whole design constraint.\n Hairlines and one elevation (DESIGN-V2 §1/§2); the only colour is the\n status tone on a glyph, never on body text. */\n\n/* Docked bottom-LEFT of the content area, not bottom-right of the viewport.\n The composer is centred on --measure-read inside the workspace and its\n control row — seat pill, mic, Send/Stop — sits at the bottom of that column,\n right-aligned. A 420px card pinned to the viewport's bottom-right lands on\n top of exactly those controls at ordinary window widths, which breaks this\n file's own rule 1: everything behind the card stays clickable. Clearing the\n rail and hugging the left edge keeps it out of the composer's way in both\n the wide and the 900px layouts. */\n.card {\n position: fixed;\n z-index: var(--z-dialog);\n left: calc(var(--rail-width) + var(--space-5));\n right: auto;\n bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));\n width: min(420px, calc(100vw - var(--rail-width) - var(--space-5) * 2));\n max-height: min(640px, calc(100vh - var(--space-8)));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--bg-surface-raised);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-dialog);\n}\n\n/* One declaration, correct in all four motion states. `--duration-base`\n already collapses to 1ms under BOTH triggers the app honours — the OS\n preference (unless Settings asked for full motion) and Settings' own\n `data-motion=\"reduce\"` — so a bare `prefers-reduced-motion` media query was\n wrong in two of them: it ignored an operator who chose Reduce in Settings,\n and it removed the animation from one who chose Full against an OS reduce\n preference. This is a one-shot animation, so unlike the persistent\n `.dictationPulse`/`.caret` cases it needs no by-name rules. */\n.card {\n animation: onboarding-in var(--duration-base) var(--ease-decelerate);\n}\n\n@keyframes onboarding-in {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n\n/* ------------------------------------------------------------------ head */\n\n.head {\n display: flex;\n align-items: flex-start;\n gap: var(--space-2);\n padding: var(--space-4) var(--space-4) var(--space-3);\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.headText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.eyebrow {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.title {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display);\n color: var(--text-primary);\n}\n\n.subtitle {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n/* ------------------------------------------------------------------ body */\n\n.body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-4);\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n align-items: flex-start;\n}\n\n.lead {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n color: var(--text-primary);\n}\n\n.aside,\n.caveat {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-tertiary);\n}\n\n.caveat {\n border-left: 2px solid var(--border-strong);\n padding-left: var(--space-3);\n}\n\n.kbd {\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n padding: 1px 5px;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-xs);\n background: var(--bg-surface);\n color: var(--text-secondary);\n white-space: nowrap;\n}\n\n/* --------------------------------------------------------- rail overview */\n\n.sections,\n.findings {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.sectionRow {\n display: flex;\n align-items: flex-start;\n gap: var(--space-3);\n padding: var(--space-2) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.sectionRow:first-child {\n border-top: none;\n}\n\n.sectionIcon,\n.localIcon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Derived from the density scale rather than a literal, so compact density\n actually reaches it (design/control-density.test.ts). */\n width: var(--control-h-xs);\n height: var(--control-h-xs);\n color: var(--text-tertiary);\n}\n\n.sectionText {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.sectionName {\n font-family: var(--font-display);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.sectionBlurb {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n/* ----------------------------------------------------------- findings */\n\n.finding {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.finding:first-child {\n border-top: none;\n}\n\n.findingHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-2);\n flex-wrap: wrap;\n}\n\n.stopName {\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.findingDetail {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.findingNote {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-tertiary);\n}\n\n.findingFix {\n display: flex;\n align-items: baseline;\n gap: var(--space-2);\n flex-wrap: wrap;\n margin-top: 2px;\n}\n\n.fixLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n flex: none;\n}\n\n.fixText {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.code {\n font-family: var(--font-mono);\n /* A command an operator is meant to READ and retype, not a micro-label:\n tokens.css reserves --text-2xs for uppercase labels and keyboard hints\n and sets the body floor at 12px. */\n font-size: var(--text-xs-size);\n padding: 2px 6px;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n background: var(--bg-code, var(--bg-surface));\n color: var(--text-primary);\n overflow-wrap: anywhere;\n}\n\n/* --------------------------------------------------------------- tone */\n\n.tone {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n flex: none;\n}\n\n.toneLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-secondary);\n}\n\n.tone[data-tone='ok'] {\n color: var(--status-success-fg, var(--text-secondary));\n}\n\n.tone[data-tone='attention'] {\n color: var(--status-warning-fg, var(--text-secondary));\n}\n\n.tone[data-tone='unknown'] {\n color: var(--text-tertiary);\n}\n\n/* ------------------------------------------------------------------ foot */\n\n.foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-3);\n padding: var(--space-3) var(--space-4);\n border-top: 1px solid var(--border-subtle);\n background: var(--bg-surface);\n}\n\n.pips {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n gap: 5px;\n}\n\n.pip {\n width: 14px;\n height: 2px;\n border-radius: 1px;\n background: var(--border-default);\n}\n\n.pip[data-state='current'] {\n background: var(--accent-500);\n}\n\n.pip[data-state='done'] {\n background: var(--border-strong);\n}\n\n.actions {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n/* Narrow layouts keep the SAME left anchor and the same cap. Stretching the\n card to `right: var(--space-3)` put it back over the composer's right end —\n which is exactly where Send and Stop sit — so the wide layout's fix stopped\n holding at the width where the window is tightest and the overlap matters\n most. Only the gutter tightens; the card still ends well left of Send. */\n@media (max-width: 900px) {\n .card {\n left: calc(var(--rail-width) + var(--space-3));\n right: auto;\n width: min(420px, calc(100vw - var(--rail-width) - var(--space-3) * 2));\n }\n}\n","/**\n * routes/verse/onboarding/OnboardingFlow.tsx — the first-run tour.\n *\n * A first-time operator opens Verse to five unlabelled rail icons and no\n * guidance. This is five short steps that answer the questions that actually\n * block someone on day one: which of my accounts can this thing use, is\n * there anything local, what do the three stop buttons really do, where do I\n * change how it looks, and how do I start.\n *\n * THREE RULES IT IS BUILT AROUND:\n *\n * 1. It never blocks the app. This is NOT a modal — no backdrop, no focus\n * trap, no `aria-modal`. It is a docked card over the section area; every\n * rail button, shortcut and section behind it stays clickable while it is\n * open. Escape closes it, so does Skip, so does the close button, and any\n * of those three silences it for good.\n *\n * 2. It never asserts more than it read. Step 2 is C6's shared capacity\n * strip (no reading is \"no reading\", never zero); step 3 reads the same\n * local-models route Usage reads, through the same narrower — an\n * unanswered probe is \"no answer\", never a green check (logic in\n * ./onboarding-model.ts, tested without a DOM).\n *\n * 3. It costs no extra requests on the common path. Each data step mounts\n * its own query only when the operator reaches it, and those queries are\n * the Usage section's own cache entries — so a first-run user who walks\n * the tour and then opens Usage finds both reads already in cache and\n * within the freshness window (data/hooks.ts DEFAULT_QUERY_FRESH_MS).\n */\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react';\nimport { Button } from '../../../components/primitives/index.js';\nimport {\n IconAlert,\n IconCheckCircle,\n IconChat,\n IconCpu,\n IconInfo,\n IconSliders,\n IconX,\n} from '../../../components/primitives/icons.js';\nimport { useQuery } from '../../../data/hooks.js';\nimport { SECTION_ICON } from '../verse-icons.js';\nimport { RAIL_SECTIONS, requestVerseCommand, setVerseSection } from '../verse-ui-store.js';\nimport { LiveCapacityStrip } from '../usage/CapacityStrip.js';\nimport { tidyProse } from '../autonomy/format.js';\nimport { verseLocalModelsQuery } from '../usage/usage-queries.js';\nimport { projectLocalModels } from '../usage/usage-contract.js';\nimport {\n ONBOARDING_STEPS,\n STOP_CONTROLS,\n buildLocalFinding,\n clampStep,\n type FindingTone,\n} from './onboarding-model.js';\nimport {\n completeOnboarding,\n dismissOnboarding,\n setOnboardingStep,\n} from './onboarding-store.js';\nimport { useOnboarding } from './useOnboarding.js';\nimport styles from './onboarding.module.css';\n\n/**\n * Tone is paired with a glyph everywhere it appears, never carried by colour\n * alone (DESIGN-V2 §6).\n */\nfunction ToneMark({ tone, label }: { tone: FindingTone; label: string }) {\n const Glyph = tone === 'ok' ? IconCheckCircle : tone === 'attention' ? IconAlert : IconInfo;\n return (\n <span className={styles.tone} data-tone={tone}>\n <Glyph size={13} aria-hidden=\"true\" focusable=\"false\" />\n <span className={styles.toneLabel}>{label}</span>\n </span>\n );\n}\n\nfunction StepBody({ children }: { children: ReactNode }) {\n return <div className={styles.body}>{children}</div>;\n}\n\n// ---------------------------------------------------------------------------\n// Step 1 — what the rail is\n// ---------------------------------------------------------------------------\n\nfunction WelcomeStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Verse is the desktop surface over this machine’s agentic fleet. Everything it shows comes from one local\n server — no session, token or artifact leaves this machine.\n </p>\n {/*\n The five rail surfaces, in ⌘1–⌘5 order, with the same one-line blurbs\n the palette uses (VERSE_SECTIONS) — one description per surface, not\n a second copy that drifts. Settings, Apps and Usage live in the gear.\n */}\n <ul className={styles.sections}>\n {RAIL_SECTIONS.map((entry, index) => {\n const Icon = SECTION_ICON[entry.id];\n return (\n <li key={entry.id} className={styles.sectionRow}>\n <span className={styles.sectionIcon} aria-hidden=\"true\">\n <Icon />\n </span>\n <span className={styles.sectionText}>\n <span className={styles.sectionName}>\n {entry.label} <kbd className={styles.kbd}>⌘{index + 1}</kbd>\n </span>\n <span className={styles.sectionBlurb}>{entry.blurb}</span>\n </span>\n </li>\n );\n })}\n </ul>\n <p className={styles.sectionBlurb}>\n <kbd className={styles.kbd}>⌘K</kbd> runs anything by name · <kbd className={styles.kbd}>⌘J</kbd> is everything\n waiting on you · Settings, Apps &amp; Accounts and Usage are under the gear.\n </p>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 2 — seats\n// ---------------------------------------------------------------------------\n\n/**\n * Step 2 mounts C6's shared LiveCapacityStrip — the SAME projection Apps &\n * Accounts, Usage, the new-chat dialog and the rail's capacity ring read — so\n * the tour can never describe a seat differently from the rest of the app\n * (3.9 had its own accounts narrower here, which drifted from Usage). A seat\n * that is signed out or out of usage shows the exact command that fixes it,\n * straight from A2's health report; nothing is run from the tour.\n */\nfunction AccountsStep() {\n return (\n <StepBody>\n <LiveCapacityStrip\n density=\"compact\"\n headline\n local=\"collapse\"\n // The step's own heading (\"Your seats\") names the strip: a second,\n // hidden heading with the same words is noise to a screen reader.\n labelledBy=\"verse-onboarding-title\"\n emptyText=\"No seats reported yet. Connect an account in Apps & Accounts, or start Ollama for local models.\"\n renderActions={(row) =>\n row.connection?.fixCommand ? (\n <p className={styles.findingFix}>\n <span className={styles.fixLabel}>Fix</span>\n <code className={styles.code}>{row.connection.fixCommand.join(' ')}</code>\n </p>\n ) : null\n }\n />\n <p className={styles.aside}>\n Every window, reset and reserve lives in Apps &amp; Accounts, under the gear.\n </p>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 3 — local runtime\n// ---------------------------------------------------------------------------\n\nfunction LocalStep() {\n const read = useQuery(verseLocalModelsQuery);\n const finding = useMemo(() => {\n // The server's sentence, with any ISO instant in it read as local time.\n const reason = read.data?.reason ?? read.error?.message ?? null;\n return buildLocalFinding({\n snapshot: read.data?.available ? projectLocalModels(read.data.raw) : null,\n loading: read.data === undefined && read.status !== 'error',\n unavailableReason: reason === null ? null : tidyProse(reason),\n });\n }, [read.data, read.status, read.error]);\n\n return (\n <StepBody>\n <div className={styles.findingHead}>\n <span className={styles.localIcon} aria-hidden=\"true\">\n <IconCpu size={15} />\n </span>\n <ToneMark tone={finding.tone} label={finding.state} />\n </div>\n <p className={styles.lead}>{finding.summary}</p>\n <p className={styles.findingDetail}>{finding.meaning}</p>\n {finding.fix ? (\n <p className={styles.findingFix}>\n <span className={styles.fixLabel}>Fix</span>\n <span className={styles.fixText}>{finding.fix}</span>\n </p>\n ) : null}\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 4 — the three stops\n// ---------------------------------------------------------------------------\n\nfunction StopsStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Fleet <kbd className={styles.kbd}>⌘2</kbd> has three stop controls. They are not interchangeable, and the\n difference is the most important thing on this screen.\n </p>\n <ul className={styles.findings}>\n {STOP_CONTROLS.map((control) => (\n <li key={control.name} className={styles.finding}>\n <div className={styles.findingHead}>\n <span className={styles.stopName}>{control.name}</span>\n <ToneMark tone={control.tone} label={control.tone === 'ok' ? 'narrow' : 'global'} />\n </div>\n <p className={styles.findingDetail}>{control.scope}</p>\n <p className={styles.findingDetail}>{control.limit}</p>\n <p className={styles.findingNote}>{control.reversible}</p>\n </li>\n ))}\n </ul>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 5 — appearance, then go\n// ---------------------------------------------------------------------------\n\nfunction FinishStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Settings <kbd className={styles.kbd}>⌘,</kbd> carries theme, accent hue, density, display font, corner radius\n and reduced motion. Every change applies as you make it — there is no save button.\n </p>\n <Button\n variant=\"subtle\"\n icon={<IconSliders size={14} />}\n onClick={() => setVerseSection('settings')}\n >\n Open Settings\n </Button>\n <p className={styles.aside}>\n You can replay this tour any time from Settings → Onboarding.\n </p>\n </StepBody>\n );\n}\n\nconst STEP_COMPONENTS = [WelcomeStep, AccountsStep, LocalStep, StopsStep, FinishStep] as const;\n\n// ---------------------------------------------------------------------------\n// The card\n// ---------------------------------------------------------------------------\n\nexport function OnboardingFlow() {\n const { open, step } = useOnboarding();\n const index = clampStep(step);\n const meta = ONBOARDING_STEPS[index]!;\n const Step = STEP_COMPONENTS[index]!;\n const last = index === ONBOARDING_STEPS.length - 1;\n\n const close = useCallback(() => dismissOnboarding(), []);\n const cardRef = useRef<HTMLElement>(null);\n\n // Escape dismisses the tour — but ONLY when the focus is inside the card.\n //\n // This card is deliberately not a modal (rule 1 above): the operator works\n // behind it, and every Escape they press for something else — closing the\n // command palette, backing out of a seat menu, stopping dictation — used to\n // land here too and permanently dismiss the tour, writing `dismissedAt` with\n // no confirmation and no undo short of Settings → Replay. It also swallowed\n // the default Escape behaviour of whatever they were actually trying to\n // close. Scoped to the card, both problems go away and the shortcut still\n // works where the operator would expect it to.\n useEffect(() => {\n if (!open) return undefined;\n function onKey(event: globalThis.KeyboardEvent) {\n if (event.key !== 'Escape') return;\n const card = cardRef.current;\n if (!card || !(event.target instanceof Node) || !card.contains(event.target)) return;\n event.preventDefault();\n dismissOnboarding();\n }\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [open]);\n\n if (!open) return null;\n\n return (\n <aside ref={cardRef} className={styles.card} aria-labelledby=\"verse-onboarding-title\" role=\"region\">\n <header className={styles.head}>\n <div className={styles.headText}>\n <p className={styles.eyebrow}>\n Getting started · {index + 1} of {ONBOARDING_STEPS.length}\n </p>\n <h2 id=\"verse-onboarding-title\" className={styles.title}>\n {meta.title}\n </h2>\n <p className={styles.subtitle}>{meta.subtitle}</p>\n </div>\n <Button\n iconOnly\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Close getting started\"\n title=\"Close getting started\"\n icon={<IconX size={14} />}\n onClick={close}\n />\n </header>\n\n <Step />\n\n <footer className={styles.foot}>\n <ol className={styles.pips} aria-hidden=\"true\">\n {ONBOARDING_STEPS.map((s, i) => (\n <li key={s.id} className={styles.pip} data-state={i === index ? 'current' : i < index ? 'done' : 'todo'} />\n ))}\n </ol>\n <div className={styles.actions}>\n <Button variant=\"ghost\" size=\"sm\" onClick={close}>\n Skip setup\n </Button>\n {index > 0 ? (\n <Button variant=\"subtle\" size=\"sm\" onClick={() => setOnboardingStep(index - 1)}>\n Back\n </Button>\n ) : null}\n {last ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n icon={<IconChat size={14} />}\n onClick={() => {\n completeOnboarding();\n // Switches to Chat and raises the one-shot ⌘N command the\n // chat section consumes by nonce (verse-ui-store.ts).\n requestVerseCommand('new-chat');\n }}\n >\n Start a first chat\n </Button>\n ) : (\n <Button variant=\"primary\" size=\"sm\" onClick={() => setOnboardingStep(index + 1)}>\n Next\n </Button>\n )}\n </div>\n </footer>\n </aside>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OnboardingFlow-Cij6KWat.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/onboarding/onboarding-model.ts","../../../../../../src/web-ui/routes/verse/onboarding/onboarding.module.css","../../../../../../src/web-ui/routes/verse/onboarding/OnboardingFlow.tsx"],"sourcesContent":["/**\n * routes/verse/onboarding/onboarding-model.ts — the first-run tour's facts,\n * derived from the same reads the Usage section uses, with the same honesty\n * rules (docs/VERSE-TELEMETRY-V2.md).\n *\n * Pure: no React, no I/O. Everything the tour asserts about the machine is\n * computed here so it can be tested without a DOM, and so the one rule that\n * matters is enforced in one place:\n *\n * AN ABSENT READ IS \"UNKNOWN\", NEVER \"FINE\" AND NEVER \"BROKEN\".\n *\n * A first-run screen is exactly where a confident lie does the most damage —\n * it is the operator's first and only calibration of how much this app's\n * claims can be trusted. So a route that 404s, a payload that does not\n * narrow, and a probe that could not reach a runtime each produce their own\n * sentence, and none of them produces a green check.\n *\n * The tour NEVER renders a command it invented: the seats step shows only\n * A2's own fix argv (through C6's capacity rows).\n */\nimport type { LocalModelsSnapshot } from '../usage/usage-contract.js';\n\n// ---------------------------------------------------------------------------\n// Steps\n// ---------------------------------------------------------------------------\n\nexport type OnboardingStepId = 'welcome' | 'accounts' | 'local' | 'stops' | 'finish';\n\nexport interface OnboardingStepMeta {\n id: OnboardingStepId;\n /** Shown as the card's heading. */\n title: string;\n /** One line under the heading. */\n subtitle: string;\n}\n\nexport const ONBOARDING_STEPS: readonly OnboardingStepMeta[] = [\n {\n id: 'welcome',\n title: 'Welcome to Verse',\n subtitle: 'Five sections, one rail. Two minutes and you will know what each one does.',\n },\n {\n id: 'accounts',\n title: 'Your seats',\n subtitle: 'Which provider accounts this machine can actually dispatch to right now.',\n },\n {\n id: 'local',\n title: 'Local runtime',\n subtitle: 'Whether there is a model on this machine, and what that changes.',\n },\n {\n id: 'stops',\n title: 'Three ways to stop',\n subtitle: 'They do not have the same blast radius. This is the one screen that says so.',\n },\n {\n id: 'finish',\n title: 'Make it yours',\n subtitle: 'Theme, accent, density and font live in Settings. Then start a chat.',\n },\n];\n\nexport function clampStep(step: number): number {\n if (!Number.isFinite(step)) return 0;\n return Math.min(ONBOARDING_STEPS.length - 1, Math.max(0, Math.trunc(step)));\n}\n\n// ---------------------------------------------------------------------------\n// Tone\n// ---------------------------------------------------------------------------\n\n/**\n * Step 2 (seats) is C6's shared LiveCapacityStrip since 3.10 — the tour no\n * longer narrows the accounts route itself, so the seats can never read\n * differently here than in Apps & Accounts. The tone below serves the local\n * runtime and the stops.\n */\nexport type FindingTone = 'ok' | 'attention' | 'unknown';\n\n// ---------------------------------------------------------------------------\n// Local runtime\n// ---------------------------------------------------------------------------\n\nexport interface LocalFinding {\n tone: FindingTone;\n state: string;\n summary: string;\n /** What having (or not having) a local runtime means for the operator. */\n meaning: string;\n /** Present only when there is something to do about it. */\n fix: string | null;\n modelCount: number;\n toolCapableCount: number;\n /** True when this reading was retained from an earlier probe. */\n stale: boolean;\n}\n\nexport interface LocalInput {\n snapshot: LocalModelsSnapshot | null;\n loading: boolean;\n unavailableReason: string | null;\n}\n\nconst LOCAL_MEANING_AVAILABLE =\n 'Local seats cost nothing and consume no provider quota, so the autonomous loop can keep working after a cloud window is used up.';\nconst LOCAL_MEANING_ABSENT =\n 'Without one, every turn and every autonomous tick spends a provider account, and a used-up window stops the work.';\n\nexport function buildLocalFinding(input: LocalInput): LocalFinding {\n if (input.loading) {\n return {\n tone: 'unknown',\n state: 'checking',\n summary: 'Probing the local runtimes on this machine…',\n meaning: LOCAL_MEANING_AVAILABLE,\n fix: null,\n modelCount: 0,\n toolCapableCount: 0,\n stale: false,\n };\n }\n\n if (!input.snapshot) {\n return {\n tone: 'unknown',\n state: 'not reported',\n summary: 'This server does not report local runtimes, so Verse cannot say whether one is available here.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: input.unavailableReason,\n modelCount: 0,\n toolCapableCount: 0,\n stale: false,\n };\n }\n\n const models = input.snapshot.models;\n const toolCapable = models.filter((m) => m.supportsTools === true).length;\n const stale = input.snapshot.runtimes.some((r) => r.stale);\n\n if (!input.snapshot.reachable) {\n return {\n tone: 'attention',\n state: 'unreachable',\n // \"Not reachable\" and \"not installed\" are different facts and the probe\n // cannot tell them apart — so this does not claim either one.\n summary:\n 'No local runtime answered. Verse cannot tell whether one is not running or not installed — the probe only knows it got no answer.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: 'Start Ollama (or LM Studio) and press Refresh in Usage. If neither is installed, everything still works — it all runs on the cloud seats.',\n modelCount: 0,\n toolCapableCount: 0,\n stale,\n };\n }\n\n if (models.length === 0) {\n return {\n tone: 'attention',\n state: 'no models',\n summary: 'A local runtime answered, but it has no models installed.',\n meaning: LOCAL_MEANING_ABSENT,\n fix: 'Pull a model into the runtime, then press Refresh in Usage.',\n modelCount: 0,\n toolCapableCount: 0,\n stale,\n };\n }\n\n return {\n tone: 'ok',\n state: stale ? 'available (retained reading)' : 'available',\n summary:\n `${models.length} local ${models.length === 1 ? 'model' : 'models'} available` +\n (toolCapable > 0 ? `, ${toolCapable} of them tool-capable.` : ', none of them tool-capable.') +\n (stale ? ' This is a retained reading, not a fresh probe.' : ''),\n meaning: toolCapable > 0\n ? LOCAL_MEANING_AVAILABLE\n : `${LOCAL_MEANING_AVAILABLE} A model that cannot call tools can answer, but cannot run an agentic turn.`,\n fix: null,\n modelCount: models.length,\n toolCapableCount: toolCapable,\n stale,\n };\n}\n\n// ---------------------------------------------------------------------------\n// The three stops\n// ---------------------------------------------------------------------------\n\nexport interface StopControl {\n name: string;\n /** What it halts. */\n scope: string;\n /** What it does NOT halt — the half people get wrong. */\n limit: string;\n reversible: string;\n tone: FindingTone;\n}\n\n/**\n * Verbatim against docs/VERSE-CONTRACT-V2.md's two footguns and the V2.1\n * amendment. The kill switch is never called a pause, and \"Stop loop\" is\n * stated as engaging the same global sentinel as the emergency control,\n * because it does (`stopDaemon()` is `setKill(true)`).\n */\nexport const STOP_CONTROLS: readonly StopControl[] = [\n {\n name: 'Pause',\n scope: 'Halts autonomous dispatch only. A running loop parks instead of exiting.',\n limit: 'Your own chats and the agent’s write tools keep working.',\n reversible: 'Reversible in one click, with no restart and no confirmation.',\n tone: 'ok',\n },\n {\n name: 'Stop loop',\n scope: 'Stops the daemon — and engages the GLOBAL kill switch while doing it.',\n limit: 'That means it also refuses the agent’s own write tools, exactly like the emergency control.',\n reversible: 'Reversible, but confirm-guarded. For an ordinary halt, use Pause.',\n tone: 'attention',\n },\n {\n name: 'Emergency stop',\n scope: 'Engages the global kill switch (~/.ashlr/KILL) directly.',\n limit: 'Every mutating path refuses: the loop, dispatch, and the agent’s own write tools.',\n reversible: 'Reversible, confirm-guarded, and deliberately separated from the other two.',\n tone: 'attention',\n },\n];\n","/* First-run tour — a docked card, not a dialog. No backdrop: the app behind\n it stays visible and clickable, which is the whole design constraint.\n Hairlines and one elevation (DESIGN-V2 §1/§2); the only colour is the\n status tone on a glyph, never on body text. */\n\n/* Docked bottom-LEFT of the content area, not bottom-right of the viewport.\n The composer is centred on --measure-read inside the workspace and its\n control row — seat pill, mic, Send/Stop — sits at the bottom of that column,\n right-aligned. A 420px card pinned to the viewport's bottom-right lands on\n top of exactly those controls at ordinary window widths, which breaks this\n file's own rule 1: everything behind the card stays clickable. Clearing the\n rail and hugging the left edge keeps it out of the composer's way in both\n the wide and the 900px layouts. */\n.card {\n position: fixed;\n z-index: var(--z-dialog);\n left: calc(var(--rail-width) + var(--space-5));\n right: auto;\n bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));\n width: min(420px, calc(100vw - var(--rail-width) - var(--space-5) * 2));\n max-height: min(640px, calc(100vh - var(--space-8)));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--bg-surface-raised);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-dialog);\n}\n\n/* One declaration, correct in all four motion states. `--duration-base`\n already collapses to 1ms under BOTH triggers the app honours — the OS\n preference (unless Settings asked for full motion) and Settings' own\n `data-motion=\"reduce\"` — so a bare `prefers-reduced-motion` media query was\n wrong in two of them: it ignored an operator who chose Reduce in Settings,\n and it removed the animation from one who chose Full against an OS reduce\n preference. This is a one-shot animation, so unlike the persistent\n `.dictationPulse`/`.caret` cases it needs no by-name rules. */\n.card {\n animation: onboarding-in var(--duration-base) var(--ease-decelerate);\n}\n\n@keyframes onboarding-in {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n\n/* ------------------------------------------------------------------ head */\n\n.head {\n display: flex;\n align-items: flex-start;\n gap: var(--space-2);\n padding: var(--space-4) var(--space-4) var(--space-3);\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.headText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.eyebrow {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.title {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display);\n color: var(--text-primary);\n}\n\n.subtitle {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n/* ------------------------------------------------------------------ body */\n\n.body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-4);\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n align-items: flex-start;\n}\n\n.lead {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line-relaxed);\n color: var(--text-primary);\n}\n\n.aside,\n.caveat {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-tertiary);\n}\n\n.caveat {\n border-left: 2px solid var(--border-strong);\n padding-left: var(--space-3);\n}\n\n.kbd {\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n padding: 1px 5px;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-xs);\n background: var(--bg-surface);\n color: var(--text-secondary);\n white-space: nowrap;\n}\n\n/* --------------------------------------------------------- rail overview */\n\n.sections,\n.findings {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.sectionRow {\n display: flex;\n align-items: flex-start;\n gap: var(--space-3);\n padding: var(--space-2) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.sectionRow:first-child {\n border-top: none;\n}\n\n.sectionIcon,\n.localIcon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Derived from the density scale rather than a literal, so compact density\n actually reaches it (design/control-density.test.ts). */\n width: var(--control-h-xs);\n height: var(--control-h-xs);\n color: var(--text-tertiary);\n}\n\n.sectionText {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.sectionName {\n font-family: var(--font-display);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.sectionBlurb {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n/* ----------------------------------------------------------- findings */\n\n.finding {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n\n.finding:first-child {\n border-top: none;\n}\n\n.findingHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-2);\n flex-wrap: wrap;\n}\n\n.stopName {\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.findingDetail {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.findingNote {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-tertiary);\n}\n\n.findingFix {\n display: flex;\n align-items: baseline;\n gap: var(--space-2);\n flex-wrap: wrap;\n margin-top: 2px;\n}\n\n.fixLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-tertiary);\n flex: none;\n}\n\n.fixText {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n\n.code {\n font-family: var(--font-mono);\n /* A command an operator is meant to READ and retype, not a micro-label:\n tokens.css reserves --text-2xs for uppercase labels and keyboard hints\n and sets the body floor at 12px. */\n font-size: var(--text-xs-size);\n padding: 2px 6px;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n background: var(--bg-code, var(--bg-surface));\n color: var(--text-primary);\n overflow-wrap: anywhere;\n}\n\n/* --------------------------------------------------------------- tone */\n\n.tone {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n flex: none;\n}\n\n.toneLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--text-secondary);\n}\n\n.tone[data-tone='ok'] {\n color: var(--status-success-fg, var(--text-secondary));\n}\n\n.tone[data-tone='attention'] {\n color: var(--status-warning-fg, var(--text-secondary));\n}\n\n.tone[data-tone='unknown'] {\n color: var(--text-tertiary);\n}\n\n/* ------------------------------------------------------------------ foot */\n\n.foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-3);\n padding: var(--space-3) var(--space-4);\n border-top: 1px solid var(--border-subtle);\n background: var(--bg-surface);\n}\n\n.pips {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n gap: 5px;\n}\n\n.pip {\n width: 14px;\n height: 2px;\n border-radius: 1px;\n background: var(--border-default);\n}\n\n.pip[data-state='current'] {\n background: var(--accent-500);\n}\n\n.pip[data-state='done'] {\n background: var(--border-strong);\n}\n\n.actions {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n/* Narrow layouts keep the SAME left anchor and the same cap. Stretching the\n card to `right: var(--space-3)` put it back over the composer's right end —\n which is exactly where Send and Stop sit — so the wide layout's fix stopped\n holding at the width where the window is tightest and the overlap matters\n most. Only the gutter tightens; the card still ends well left of Send. */\n@media (max-width: 900px) {\n .card {\n left: calc(var(--rail-width) + var(--space-3));\n right: auto;\n width: min(420px, calc(100vw - var(--rail-width) - var(--space-3) * 2));\n }\n}\n","/**\n * routes/verse/onboarding/OnboardingFlow.tsx — the first-run tour.\n *\n * A first-time operator opens Verse to five unlabelled rail icons and no\n * guidance. This is five short steps that answer the questions that actually\n * block someone on day one: which of my accounts can this thing use, is\n * there anything local, what do the three stop buttons really do, where do I\n * change how it looks, and how do I start.\n *\n * THREE RULES IT IS BUILT AROUND:\n *\n * 1. It never blocks the app. This is NOT a modal — no backdrop, no focus\n * trap, no `aria-modal`. It is a docked card over the section area; every\n * rail button, shortcut and section behind it stays clickable while it is\n * open. Escape closes it, so does Skip, so does the close button, and any\n * of those three silences it for good.\n *\n * 2. It never asserts more than it read. Step 2 is C6's shared capacity\n * strip (no reading is \"no reading\", never zero); step 3 reads the same\n * local-models route Usage reads, through the same narrower — an\n * unanswered probe is \"no answer\", never a green check (logic in\n * ./onboarding-model.ts, tested without a DOM).\n *\n * 3. It costs no extra requests on the common path. Each data step mounts\n * its own query only when the operator reaches it, and those queries are\n * the Usage section's own cache entries — so a first-run user who walks\n * the tour and then opens Usage finds both reads already in cache and\n * within the freshness window (data/hooks.ts DEFAULT_QUERY_FRESH_MS).\n */\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react';\nimport { Button } from '../../../components/primitives/index.js';\nimport {\n IconAlert,\n IconCheckCircle,\n IconChat,\n IconCpu,\n IconInfo,\n IconSliders,\n IconX,\n} from '../../../components/primitives/icons.js';\nimport { useQuery } from '../../../data/hooks.js';\nimport { SECTION_ICON } from '../verse-icons.js';\nimport { RAIL_SECTIONS, requestVerseCommand, setVerseSection } from '../verse-ui-store.js';\nimport { LiveCapacityStrip } from '../usage/CapacityStrip.js';\nimport { tidyProse } from '../autonomy/format.js';\nimport { verseLocalModelsQuery } from '../usage/usage-queries.js';\nimport { projectLocalModels } from '../usage/usage-contract.js';\nimport {\n ONBOARDING_STEPS,\n STOP_CONTROLS,\n buildLocalFinding,\n clampStep,\n type FindingTone,\n} from './onboarding-model.js';\nimport {\n completeOnboarding,\n dismissOnboarding,\n setOnboardingStep,\n} from './onboarding-store.js';\nimport { useOnboarding } from './useOnboarding.js';\nimport styles from './onboarding.module.css';\n\n/**\n * Tone is paired with a glyph everywhere it appears, never carried by colour\n * alone (DESIGN-V2 §6).\n */\nfunction ToneMark({ tone, label }: { tone: FindingTone; label: string }) {\n const Glyph = tone === 'ok' ? IconCheckCircle : tone === 'attention' ? IconAlert : IconInfo;\n return (\n <span className={styles.tone} data-tone={tone}>\n <Glyph size={13} aria-hidden=\"true\" focusable=\"false\" />\n <span className={styles.toneLabel}>{label}</span>\n </span>\n );\n}\n\nfunction StepBody({ children }: { children: ReactNode }) {\n return <div className={styles.body}>{children}</div>;\n}\n\n// ---------------------------------------------------------------------------\n// Step 1 — what the rail is\n// ---------------------------------------------------------------------------\n\nfunction WelcomeStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Verse is the desktop surface over this machine’s agentic fleet. Everything it shows comes from one local\n server — no session, token or artifact leaves this machine.\n </p>\n {/*\n The five rail surfaces, in ⌘1–⌘5 order, with the same one-line blurbs\n the palette uses (VERSE_SECTIONS) — one description per surface, not\n a second copy that drifts. Settings, Apps and Usage live in the gear.\n */}\n <ul className={styles.sections}>\n {RAIL_SECTIONS.map((entry, index) => {\n const Icon = SECTION_ICON[entry.id];\n return (\n <li key={entry.id} className={styles.sectionRow}>\n <span className={styles.sectionIcon} aria-hidden=\"true\">\n <Icon />\n </span>\n <span className={styles.sectionText}>\n <span className={styles.sectionName}>\n {entry.label} <kbd className={styles.kbd}>⌘{index + 1}</kbd>\n </span>\n <span className={styles.sectionBlurb}>{entry.blurb}</span>\n </span>\n </li>\n );\n })}\n </ul>\n <p className={styles.sectionBlurb}>\n <kbd className={styles.kbd}>⌘K</kbd> runs anything by name · <kbd className={styles.kbd}>⌘J</kbd> is everything\n waiting on you · Settings, Apps &amp; Accounts and Usage are under the gear.\n </p>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 2 — seats\n// ---------------------------------------------------------------------------\n\n/**\n * Step 2 mounts C6's shared LiveCapacityStrip — the SAME projection Apps &\n * Accounts, Usage, the new-chat dialog and the rail's capacity ring read — so\n * the tour can never describe a seat differently from the rest of the app\n * (3.9 had its own accounts narrower here, which drifted from Usage). A seat\n * that is signed out or out of usage shows the exact command that fixes it,\n * straight from A2's health report; nothing is run from the tour.\n */\nfunction AccountsStep() {\n return (\n <StepBody>\n <LiveCapacityStrip\n density=\"compact\"\n headline\n local=\"collapse\"\n // The step's own heading (\"Your seats\") names the strip: a second,\n // hidden heading with the same words is noise to a screen reader.\n labelledBy=\"verse-onboarding-title\"\n emptyText=\"No seats reported yet. Connect an account in Apps & Accounts, or start Ollama for local models.\"\n renderActions={(row) =>\n row.connection?.fixCommand ? (\n <p className={styles.findingFix}>\n <span className={styles.fixLabel}>Fix</span>\n <code className={styles.code}>{row.connection.fixCommand.join(' ')}</code>\n </p>\n ) : null\n }\n />\n <p className={styles.aside}>\n Every window, reset and reserve lives in Apps &amp; Accounts, under the gear.\n </p>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 3 — local runtime\n// ---------------------------------------------------------------------------\n\nfunction LocalStep() {\n const read = useQuery(verseLocalModelsQuery);\n const finding = useMemo(() => {\n // The server's sentence, with any ISO instant in it read as local time.\n const reason = read.data?.reason ?? read.error?.message ?? null;\n return buildLocalFinding({\n snapshot: read.data?.available ? projectLocalModels(read.data.raw) : null,\n loading: read.data === undefined && read.status !== 'error',\n unavailableReason: reason === null ? null : tidyProse(reason),\n });\n }, [read.data, read.status, read.error]);\n\n return (\n <StepBody>\n <div className={styles.findingHead}>\n <span className={styles.localIcon} aria-hidden=\"true\">\n <IconCpu size={15} />\n </span>\n <ToneMark tone={finding.tone} label={finding.state} />\n </div>\n <p className={styles.lead}>{finding.summary}</p>\n <p className={styles.findingDetail}>{finding.meaning}</p>\n {finding.fix ? (\n <p className={styles.findingFix}>\n <span className={styles.fixLabel}>Fix</span>\n <span className={styles.fixText}>{finding.fix}</span>\n </p>\n ) : null}\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 4 — the three stops\n// ---------------------------------------------------------------------------\n\nfunction StopsStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Fleet <kbd className={styles.kbd}>⌘2</kbd> has three stop controls. They are not interchangeable, and the\n difference is the most important thing on this screen.\n </p>\n <ul className={styles.findings}>\n {STOP_CONTROLS.map((control) => (\n <li key={control.name} className={styles.finding}>\n <div className={styles.findingHead}>\n <span className={styles.stopName}>{control.name}</span>\n <ToneMark tone={control.tone} label={control.tone === 'ok' ? 'narrow' : 'global'} />\n </div>\n <p className={styles.findingDetail}>{control.scope}</p>\n <p className={styles.findingDetail}>{control.limit}</p>\n <p className={styles.findingNote}>{control.reversible}</p>\n </li>\n ))}\n </ul>\n </StepBody>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Step 5 — appearance, then go\n// ---------------------------------------------------------------------------\n\nfunction FinishStep() {\n return (\n <StepBody>\n <p className={styles.lead}>\n Settings <kbd className={styles.kbd}>⌘,</kbd> carries theme, accent hue, density, display font, corner radius\n and reduced motion. Every change applies as you make it — there is no save button.\n </p>\n <Button\n variant=\"subtle\"\n icon={<IconSliders size={14} />}\n onClick={() => setVerseSection('settings')}\n >\n Open Settings\n </Button>\n <p className={styles.aside}>\n You can replay this tour any time from Settings → Onboarding.\n </p>\n </StepBody>\n );\n}\n\nconst STEP_COMPONENTS = [WelcomeStep, AccountsStep, LocalStep, StopsStep, FinishStep] as const;\n\n// ---------------------------------------------------------------------------\n// The card\n// ---------------------------------------------------------------------------\n\nexport function OnboardingFlow() {\n const { open, step } = useOnboarding();\n const index = clampStep(step);\n const meta = ONBOARDING_STEPS[index]!;\n const Step = STEP_COMPONENTS[index]!;\n const last = index === ONBOARDING_STEPS.length - 1;\n\n const close = useCallback(() => dismissOnboarding(), []);\n const cardRef = useRef<HTMLElement>(null);\n\n // Escape dismisses the tour — but ONLY when the focus is inside the card.\n //\n // This card is deliberately not a modal (rule 1 above): the operator works\n // behind it, and every Escape they press for something else — closing the\n // command palette, backing out of a seat menu, stopping dictation — used to\n // land here too and permanently dismiss the tour, writing `dismissedAt` with\n // no confirmation and no undo short of Settings → Replay. It also swallowed\n // the default Escape behaviour of whatever they were actually trying to\n // close. Scoped to the card, both problems go away and the shortcut still\n // works where the operator would expect it to.\n useEffect(() => {\n if (!open) return undefined;\n function onKey(event: globalThis.KeyboardEvent) {\n if (event.key !== 'Escape') return;\n const card = cardRef.current;\n if (!card || !(event.target instanceof Node) || !card.contains(event.target)) return;\n event.preventDefault();\n dismissOnboarding();\n }\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [open]);\n\n if (!open) return null;\n\n return (\n <aside ref={cardRef} className={styles.card} aria-labelledby=\"verse-onboarding-title\" role=\"region\">\n <header className={styles.head}>\n <div className={styles.headText}>\n <p className={styles.eyebrow}>\n Getting started · {index + 1} of {ONBOARDING_STEPS.length}\n </p>\n <h2 id=\"verse-onboarding-title\" className={styles.title}>\n {meta.title}\n </h2>\n <p className={styles.subtitle}>{meta.subtitle}</p>\n </div>\n <Button\n iconOnly\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Close getting started\"\n title=\"Close getting started\"\n icon={<IconX size={14} />}\n onClick={close}\n />\n </header>\n\n <Step />\n\n <footer className={styles.foot}>\n <ol className={styles.pips} aria-hidden=\"true\">\n {ONBOARDING_STEPS.map((s, i) => (\n <li key={s.id} className={styles.pip} data-state={i === index ? 'current' : i < index ? 'done' : 'todo'} />\n ))}\n </ol>\n <div className={styles.actions}>\n <Button variant=\"ghost\" size=\"sm\" onClick={close}>\n Skip setup\n </Button>\n {index > 0 ? (\n <Button variant=\"subtle\" size=\"sm\" onClick={() => setOnboardingStep(index - 1)}>\n Back\n </Button>\n ) : null}\n {last ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n icon={<IconChat size={14} />}\n onClick={() => {\n completeOnboarding();\n // Switches to Chat and raises the one-shot ⌘N command the\n // chat section consumes by nonce (verse-ui-store.ts).\n requestVerseCommand('new-chat');\n }}\n >\n Start a first chat\n </Button>\n ) : (\n <Button variant=\"primary\" size=\"sm\" onClick={() => setOnboardingStep(index + 1)}>\n Next\n </Button>\n )}\n </div>\n </footer>\n </aside>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as e,n as t,s as n}from"./index-DbDw9UAs.js";import{M as r,O as i,c as a,i as o,o as s}from"./global-BkNl4e6E.js";import{d as c,f as l,y as u}from"./workbench-types-DzN-5trg.js";import{n as ee}from"./viewport-BYGH5EgA.js";import{i as te,r as ne}from"./section-visibility-B0xXUQJ0.js";import{t as d}from"./MessageMarkdown-fsY_ltVa.js";import{t as re}from"./Segmented-DnKP6rr7.js";import{n as f,t as p}from"./Button-DqgLUZvd.js";import{c as ie,h as ae,x as m}from"./icons-C5EFt_Ts.js";import{t as h}from"./EmptyState-DYW29ncw.js";import{a as oe,c as se,d as ce,i as le,l as ue,n as de,o as fe,s as g,t as pe}from"./terminal-icons-Dp6pJgV2.js";import{t as me}from"./pane-chrome.module-D7o-fVd0.js";var _=n(e(),1),v=`/api/verse/preview/ticket`;function y(e){return new URLSearchParams(e).toString()}var b={targets:(e,t)=>a(`${l}?${y({sessionId:e})}`,t),ticket:(e,t)=>a(`${v}?${y({sessionId:e,path:t})}`),text:async(e,t)=>{let n=`${c}?${y({sessionId:e,path:t})}`,a=await fetch(n,{credentials:`same-origin`,headers:{"x-ashlr-read-client":i()}});if(a.status===401)throw r(),new s(`Read session expired.`,401,n);if(!a.ok)throw new s(`GET ${n} failed (HTTP ${a.status}).`,a.status,n);return a.text()}};function x(e){return e.port||(e.protocol===`https:`?`443`:`80`)}function S(e,t){let n=e.trim();if(n.length===0||n.length>2048||/\s/.test(n))return{kind:`invalid`};let r=n;if(/^:?\d{2,5}$/.test(n))r=`http://localhost:${n.replace(`:`,``)}/`;else if(/^(?:localhost|127\.0\.0\.1)(?::\d{1,5})?(?:[/?#].*)?$/i.test(n))r=`http://${n}`;else if(!/^[a-z][a-z0-9+.-]*:/i.test(n)){if(!/^[\w-]+(?:\.[\w-]+)+(?::\d{1,5})?(?:[/?#].*)?$/.test(n))return{kind:`invalid`};r=`https://${n}`}let i;try{i=new URL(r)}catch{return{kind:`invalid`}}if(i.protocol!==`http:`&&i.protocol!==`https:`)return{kind:`invalid`};if(u(i.href)){let e=null;try{e=new URL(t)}catch{e=null}return e&&(e.hostname===`localhost`||e.hostname===`127.0.0.1`)&&x(e)===x(i)?{kind:`self`,url:i.href}:{kind:`loopback`,url:i.href}}return i.username||i.password?{kind:`invalid`}:{kind:`external`,url:i.href}}function C(e){try{let t=new URL(e),n=t.pathname===`/`?``:t.pathname;return`${t.host}${n}${t.search}`}catch{return e}}function w(e){return!Number.isFinite(e)||e<0?`—`:e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(+(e<10240))} KB`:`${(e/1048576).toFixed(1)} MB`}var T={pane:`_pane_k6hui_8`,strip:`_strip_k6hui_19`,tabs:`_tabs_k6hui_28`,tab:`_tab_k6hui_28`,tabButton:`_tabButton_k6hui_60`,tabClose:`_tabClose_k6hui_78`,noticeClose:`_noticeClose_k6hui_79`,external:`_external_k6hui_80`,tabTitle:`_tabTitle_k6hui_85`,newTab:`_newTab_k6hui_118`,toolbar:`_toolbar_k6hui_126`,nav:`_nav_k6hui_128`,addressForm:`_addressForm_k6hui_134`,address:`_address_k6hui_134`,addressNote:`_addressNote_k6hui_177`,notice:`_notice_k6hui_79`,waiting:`_waiting_k6hui_179`,waitingText:`_waitingText_k6hui_201`,pulse:`_pulse_k6hui_208`,body:`_body_k6hui_234`,loading:`_loading_k6hui_243`,stage:`_stage_k6hui_250`,frame:`_frame_k6hui_262`,frameHint:`_frameHint_k6hui_278`,imageStage:`_imageStage_k6hui_291`,image:`_image_k6hui_291`,markdown:`_markdown_k6hui_308`,launcher:`_launcher_k6hui_316`,section:`_section_k6hui_322`,sectionTitle:`_sectionTitle_k6hui_328`,muted:`_muted_k6hui_339`,rows:`_rows_k6hui_347`,row:`_row_k6hui_347`,dot:`_dot_k6hui_364`,fileIcon:`_fileIcon_k6hui_376`,rowMain:`_rowMain_k6hui_378`,rowTitle:`_rowTitle_k6hui_385`,rowMeta:`_rowMeta_k6hui_395`,rowCommand:`_rowCommand_k6hui_405`},E=t(),he={api:b,origin:()=>window.location.origin,now:()=>Date.now()},ge=12e4,_e=2e3,ve=5e3,D=`ashlr.verse.preview.v1:`,O={"launch-json":`launch.json`,"package-json":`package.json`,listening:`running`},ye={html:`HTML`,md:`Markdown`,svg:`SVG`,image:`Image`,pdf:`PDF`},k=0,A=0,j=()=>`p${++A}`;function M(){k=0,A=0}function N(e){let t=e.toLowerCase().slice(e.lastIndexOf(`.`));return t===`.html`||t===`.htm`?`html`:t===`.md`||t===`.markdown`?`md`:t===`.svg`?`svg`:t===`.pdf`?`pdf`:[`.png`,`.jpg`,`.jpeg`,`.gif`,`.webp`,`.avif`,`.bmp`,`.ico`].includes(t)?`image`:null}function P(e){return e.slice(e.lastIndexOf(`/`)+1)||e}function F(e){return e.kind===`launcher`?`New tab`:e.kind===`url`?C(e.history[e.index]??``):P(e.path)}function be(e){return e?.kind===`url`?e.history[e.index]??null:null}function xe(e,t){try{let n=localStorage.getItem(`${D}${e}`);if(!n)return null;let r=JSON.parse(n),i=[],a=null;return Array.isArray(r.tabs)&&r.tabs.slice(0,12).forEach((e,n)=>{if(!e||typeof e!=`object`)return;let o=e,s=j();if(o.url&&typeof o.url==`string`&&S(o.url,t).kind===`loopback`)i.push({id:s,kind:`url`,history:[o.url],index:0,reloadKey:0});else if(typeof o.path==`string`){let e=N(o.path);if(e)i.push({id:s,kind:`artifact`,path:o.path,artifactKind:e,reloadKey:0});else return}else return;r.active===n&&(a=s)}),{tabs:i,activeId:a??i.at(-1)?.id??null,device:r.device===`phone`?`phone`:`desktop`}}catch{return null}}function Se(e,t,n,r){try{let i=t.filter(e=>e.kind!==`launcher`);localStorage.setItem(`${D}${e}`,JSON.stringify({tabs:i.map(e=>e.kind===`url`?{url:e.history[e.index]}:e.kind===`artifact`?{path:e.path}:{}),active:i.findIndex(e=>e.id===n),device:r}))}catch{}}function I({sessionId:e,roots:t,request:n,onOpenTerminal:r,visible:i,deps:a}){let o=(0,_.useMemo)(()=>({...he,...a}),[a]),c=te(),l=i&&c,u=ee().compact,[d]=(0,_.useState)(()=>xe(e,o.origin())),[h,g]=(0,_.useState)(()=>d?.tabs??[]),[v,y]=(0,_.useState)(()=>d?.activeId??null),[b,x]=(0,_.useState)(()=>d?.device??`desktop`),[w,ge]=(0,_.useState)(e),[D,O]=(0,_.useState)(null),[ye,A]=(0,_.useState)(null),[M,P]=(0,_.useState)(``),[I,L]=(0,_.useState)(null),[R,z]=(0,_.useState)(null),[Ee,B]=(0,_.useState)(null),[V,H]=(0,_.useState)(()=>new Map),[De,Oe]=(0,_.useState)(()=>o.now()),U=(0,_.useRef)(!0),W=(0,_.useRef)(new Map),ke=(0,_.useRef)(null);if(w!==e){let t=xe(e,o.origin());ge(e),g(t?.tabs??[]),y(t?.activeId??null),O(null),z(null),B(null)}let G=h.find(e=>e.id===v)??null,K=be(G),q=!G||G.kind===`launcher`;(0,_.useEffect)(()=>(U.current=!0,()=>{U.current=!1}),[]),(0,_.useEffect)(()=>{w===e&&Se(e,h,v,b)},[w,e,h,v,b]),(0,_.useEffect)(()=>{P(G?.kind===`url`?G.history[G.index]??``:G?.kind===`artifact`?G.path:``),L(null)},[G]);let J=(0,_.useCallback)(async()=>{try{let t=await o.api.targets(e);return U.current?(O(t),A(null),t):null}catch(e){return U.current&&A(e instanceof s&&e.detail?e.detail:`Dev servers and files could not be listed.`),null}},[o.api,e]),Ae=(0,_.useRef)(null);(0,_.useEffect)(()=>{l&&Ae.current!==e&&(Ae.current=e,J())},[l,e,J]),ne(()=>{J()},R?_e:ve,{enabled:i&&(R!==null||q)});let Y=(0,_.useCallback)((e,t={})=>{B(null);let n=h.find(e=>e.id===v);if(!t.newTab&&n?.kind===`launcher`){g(h.map(t=>t.id===n.id?{id:t.id,kind:`url`,history:[e],index:0,reloadKey:0}:t));return}let r=h.find(t=>t.kind===`url`&&t.history[t.index]===e);if(r&&!t.newTab){y(r.id);return}let i=j();g([...h,{id:i,kind:`url`,history:[e],index:0,reloadKey:0}]),y(i)},[h,v]),je=(0,_.useCallback)(e=>{if(!G||G.kind!==`url`){Y(e);return}g(t=>t.map(t=>{if(t.id!==G.id||t.kind!==`url`)return t;let n=[...t.history.slice(0,t.index+1),e].slice(-50);return{...t,history:n,index:n.length-1}}))},[G,Y]),X=(0,_.useCallback)((e,t)=>{B(null);let n=h.find(t=>t.kind===`artifact`&&t.path===e);if(n){y(n.id);return}let r=h.find(e=>e.id===v);if(r?.kind===`launcher`){g(h.map(n=>n.id===r.id?{id:n.id,kind:`artifact`,path:e,artifactKind:t,reloadKey:0}:n));return}let i=j();g([...h,{id:i,kind:`artifact`,path:e,artifactKind:t,reloadKey:0}]),y(i)},[h,v]),Me=()=>{let e=h.find(e=>e.kind===`launcher`);if(e)y(e.id);else{let e=j();g(t=>[...t,{id:e,kind:`launcher`}]),y(e)}J()},Ne=e=>{let t=h.findIndex(t=>t.id===e.id),n=h.filter(t=>t.id!==e.id);g(n),H(t=>{let n=new Map(t);for(let r of t.keys())r.startsWith(`${e.id}:`)&&n.delete(r);return n}),v===e.id&&y((n[t]??n[t-1]??null)?.id??null)},Pe=(e,t)=>{let n=-1;if(e.key===`ArrowRight`?n=(t+1)%h.length:e.key===`ArrowLeft`?n=(t-1+h.length)%h.length:e.key===`Home`?n=0:e.key===`End`&&(n=h.length-1),n<0)return;e.preventDefault();let r=h[n];y(r.id),W.current.get(r.id)?.focus()},Fe=(0,_.useCallback)(e=>{B(null),r({root:e.root,devServerId:e.id}),z({server:e,since:o.now()})},[o,r]),Z=(0,_.useCallback)(e=>{e.running?Y(e.url):Fe(e)},[Y,Fe]);(0,_.useEffect)(()=>{if(R&&D){if(D.devServers.find(e=>e.running&&(e.id===R.server.id||e.port===R.server.port))){z(null),Y(R.server.url);return}o.now()-R.since>12e4&&(z(null),B(`Nothing answered on port ${R.server.port} within 2 minutes. Check the terminal for errors.`))}},[D,R,Y,o,De]),(0,_.useEffect)(()=>{if(!R)return;let e=setInterval(()=>Oe(o.now()),1e3);return()=>clearInterval(e)},[R,o]);let Q=(0,_.useCallback)(async e=>{if(e.url){let t=S(e.url,o.origin());t.kind===`loopback`?Y(t.url):L(t);return}if(e.artifactPath){let t=D?.artifacts.find(t=>t.path===e.artifactPath)?.kind??N(e.artifactPath);t?X(e.artifactPath,t):B(`That file cannot be previewed.`);return}if(e.devServerId){let t=(await J()??D)?.devServers.find(t=>t.id===e.devServerId);t?Z(t):B(`That dev server is no longer listed for this chat.`)}},[o,X,Z,Y,J,D]);(0,_.useEffect)(()=>{!n||n.nonce<=k||(k=n.nonce,Q(n))},[n,Q]);let $=G?.kind===`artifact`?`${G.id}:${G.reloadKey}`:null;(0,_.useEffect)(()=>{if(!l||!G||G.kind!==`artifact`||!$||V.has($))return;let t=G,n=$;H(e=>new Map(e).set(n,{status:`loading`})),(t.artifactKind===`md`?o.api.text(e,t.path).then(e=>({status:`text`,text:e})):o.api.ticket(e,t.path).then(e=>({status:`frame`,src:e.url}))).then(e=>{U.current&&H(t=>new Map(t).set(n,e))},e=>{let t=e instanceof s&&e.status===404?`This file is no longer in the chat's folder.`:e instanceof s&&e.status===413?`This file is larger than 5 MB, too large to preview.`:`This file could not be loaded.`;U.current&&H(e=>new Map(e).set(n,{status:`error`,message:t}))})},[l,G,$,V,o.api,e]);let Ie=e=>{G&&G.kind===`url`&&g(t=>t.map(t=>t.id===G.id&&t.kind===`url`?{...t,index:Math.min(t.history.length-1,Math.max(0,t.index+e))}:t))},Le=()=>{if(G){if(G.kind===`launcher`){J();return}g(e=>e.map(e=>e.id===G.id&&e.kind!==`launcher`?{...e,reloadKey:e.reloadKey+1}:e))}},Re=e=>{e.preventDefault();let t=S(M,o.origin());if(t.kind===`loopback`){L(null),G?.kind===`url`?je(t.url):Y(t.url);return}L(t)},ze=e=>{e.key===`Escape`&&(e.preventDefault(),P(K??(G?.kind===`artifact`?G.path:``)),L(null),e.currentTarget.blur())},Be=G?.kind===`url`&&G.index>0,Ve=G?.kind===`url`&&G.index<G.history.length-1;return(0,E.jsxs)(`div`,{className:T.pane,"data-compact":u||void 0,children:[(0,E.jsxs)(`div`,{className:T.strip,children:[(0,E.jsx)(`div`,{className:T.tabs,role:`tablist`,"aria-label":`Previews`,children:h.map((e,t)=>{let n=e.id===v,r=F(e);return(0,E.jsxs)(`div`,{className:T.tab,"data-selected":n||void 0,role:`presentation`,children:[(0,E.jsxs)(`button`,{ref:t=>{t?W.current.set(e.id,t):W.current.delete(e.id)},type:`button`,role:`tab`,id:`preview-tab-${e.id}`,"aria-selected":n,"aria-controls":`preview-panel`,tabIndex:n?0:-1,className:T.tabButton,title:e.kind===`url`?e.history[e.index]:e.kind===`artifact`?e.path:`Choose what to preview`,onClick:()=>y(e.id),onKeyDown:e=>Pe(e,t),children:[e.kind===`artifact`?(0,E.jsx)(oe,{size:12}):e.kind===`url`?(0,E.jsx)(ce,{size:12}):(0,E.jsx)(se,{size:12}),(0,E.jsx)(`span`,{className:T.tabTitle,children:r})]}),(0,E.jsx)(`button`,{type:`button`,className:T.tabClose,"aria-label":`Close preview ${r}`,title:`Close`,onClick:()=>Ne(e),children:(0,E.jsx)(m,{size:12})})]},e.id)})}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(ae,{}),"aria-label":`New preview tab`,title:`New preview tab`,className:T.newTab,onClick:Me})]}),(0,E.jsxs)(`div`,{className:`${me.header} ${T.toolbar}`,children:[(0,E.jsxs)(`div`,{className:T.nav,children:[(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(pe,{}),"aria-label":`Back`,title:`Back`,disabled:!Be,onClick:()=>Ie(-1)}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(de,{}),"aria-label":`Forward`,title:`Forward`,disabled:!Ve,onClick:()=>Ie(1)}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(ue,{}),"aria-label":q?`Refresh the list`:`Reload`,title:q?`Refresh the list`:`Reload`,disabled:!G&&q&&D===null,onClick:Le})]}),(0,E.jsx)(`form`,{className:T.addressForm,onSubmit:Re,role:`search`,"aria-label":`Preview address`,children:(0,E.jsx)(`input`,{ref:ke,className:T.address,value:M,onChange:e=>P(e.target.value),onKeyDown:ze,onFocus:e=>e.currentTarget.select(),placeholder:`localhost:5173`,"aria-label":`Address`,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,inputMode:`url`,readOnly:G?.kind===`artifact`})}),(0,E.jsxs)(`div`,{className:me.actions,children:[u?null:(0,E.jsx)(re,{"aria-label":`Frame width`,size:`sm`,value:b,onChange:x,options:[{value:`desktop`,label:(0,E.jsx)(le,{size:14}),ariaLabel:`Desktop width`},{value:`phone`,label:(0,E.jsx)(fe,{size:14}),ariaLabel:`375 px width`}]}),K?(0,E.jsx)(`a`,{className:T.external,href:K,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`Open in browser`,title:`Open in browser`,children:(0,E.jsx)(ie,{})}):(0,E.jsx)(`span`,{className:T.external,"data-placeholder":`true`,"aria-hidden":`true`})]})]}),I?(0,E.jsx)(Ce,{note:I,onDismiss:()=>L(null)}):null,R?(0,E.jsxs)(`div`,{className:T.waiting,role:`status`,children:[(0,E.jsx)(`span`,{className:T.pulse,"aria-hidden":`true`}),(0,E.jsxs)(`span`,{className:T.waitingText,children:[`Starting `,(0,E.jsx)(`code`,{children:R.server.command??R.server.label}),` — waiting for `,C(R.server.url),` · `,Math.max(0,Math.round((De-R.since)/1e3)),`s`]}),(0,E.jsx)(p,{size:`sm`,variant:`ghost`,onClick:()=>z(null),children:`Stop waiting`})]}):null,Ee?(0,E.jsxs)(`div`,{className:T.notice,role:`alert`,children:[(0,E.jsx)(`span`,{children:Ee}),(0,E.jsx)(`button`,{type:`button`,className:T.noticeClose,"aria-label":`Dismiss`,title:`Dismiss`,onClick:()=>B(null),children:(0,E.jsx)(m,{size:12})})]}):null,(0,E.jsx)(`div`,{className:T.body,id:`preview-panel`,role:`tabpanel`,"aria-labelledby":G?`preview-tab-${G.id}`:void 0,children:q?(0,E.jsx)(Te,{targets:D,error:ye,roots:t,onOpenServer:Z,onOpenArtifact:e=>X(e.path,e.kind),onRetry:()=>void J(),onOpenTerminal:()=>r(t[0]?{root:t[0]}:{}),waitingId:R?.server.id??null}):G?.kind===`url`?(0,E.jsxs)(`div`,{className:T.stage,"data-device":b,children:[(0,E.jsx)(`iframe`,{className:T.frame,src:G.history[G.index],title:`Preview of ${F(G)}`,sandbox:`allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-downloads`,referrerPolicy:`no-referrer`},`${G.id}:${G.index}:${G.reloadKey}`),(0,E.jsxs)(`p`,{className:T.frameHint,children:[`Blank page? Some servers refuse to be framed.`,` `,(0,E.jsx)(`a`,{href:G.history[G.index],target:`_blank`,rel:`noopener noreferrer`,children:`Open in browser ↗`})]})]}):G?.kind===`artifact`?(0,E.jsx)(we,{tab:G,content:$?V.get($)??{status:`loading`}:{status:`loading`},device:b,onRetry:Le}):null})]})}function Ce({note:e,onDismiss:t}){return(0,E.jsxs)(`div`,{className:T.addressNote,role:`status`,children:[e.kind===`external`?(0,E.jsxs)(`span`,{children:[`Only local dev servers open here.`,` `,(0,E.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noopener noreferrer`,children:`Open in browser ↗`})]}):e.kind===`self`?(0,E.jsx)(`span`,{children:`That address is Verse itself.`}):(0,E.jsxs)(`span`,{children:[`Enter a local address, like `,(0,E.jsx)(`code`,{children:`localhost:5173`}),`.`]}),(0,E.jsx)(`button`,{type:`button`,className:T.noticeClose,"aria-label":`Dismiss`,title:`Dismiss`,onClick:t,children:(0,E.jsx)(m,{size:12})})]})}function we({tab:e,content:t,device:n,onRetry:r}){return t.status===`loading`?(0,E.jsxs)(`div`,{className:T.loading,"aria-busy":`true`,children:[(0,E.jsx)(o,{width:`50%`}),(0,E.jsx)(o,{width:`80%`})]}):t.status===`error`?(0,E.jsx)(h,{compact:!0,tone:`error`,title:`Preview unavailable`,body:t.message,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:r,children:`Try again`})}):t.status===`text`?(0,E.jsx)(`article`,{className:T.markdown,"aria-label":e.path,children:(0,E.jsx)(d,{text:t.text})}):e.artifactKind===`image`?(0,E.jsx)(`div`,{className:T.imageStage,children:(0,E.jsx)(`img`,{className:T.image,src:t.src,alt:P(e.path)})}):(0,E.jsx)(`div`,{className:T.stage,"data-device":e.artifactKind===`pdf`?`desktop`:n,children:(0,E.jsx)(`iframe`,{className:T.frame,src:t.src,title:`Preview of ${e.path}`,...e.artifactKind===`pdf`?{}:{sandbox:`allow-scripts`},referrerPolicy:`no-referrer`},t.src)})}function Te({targets:e,error:t,roots:n,onOpenServer:r,onOpenArtifact:i,onRetry:a,onOpenTerminal:s,waitingId:c}){if(!e)return t?(0,E.jsx)(h,{compact:!0,tone:`error`,title:`Could not list what to preview`,body:t,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:a,children:`Try again`})}):(0,E.jsxs)(`div`,{className:T.loading,"aria-busy":`true`,children:[(0,E.jsx)(o,{width:`35%`}),(0,E.jsx)(o,{width:`70%`}),(0,E.jsx)(o,{width:`60%`})]});let l=n.length>1;return e.devServers.length===0&&e.artifacts.length===0?(0,E.jsx)(h,{compact:!0,icon:(0,E.jsx)(se,{size:20}),title:`Nothing to preview yet`,body:`Start a dev server in the terminal, or ask for an HTML report. Local servers and the files this chat writes show up here.`,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:s,children:`Open a terminal`})}):(0,E.jsxs)(`div`,{className:T.launcher,children:[(0,E.jsxs)(`section`,{className:T.section,"aria-labelledby":`preview-servers-title`,children:[(0,E.jsx)(`h3`,{className:T.sectionTitle,id:`preview-servers-title`,children:`Dev servers`}),e.devServers.length===0?(0,E.jsxs)(`p`,{className:T.muted,children:[`No dev server found in this chat's folders. Add one to `,(0,E.jsx)(`code`,{children:`.claude/launch.json`}),`, or start it in the terminal.`]}):(0,E.jsx)(`ul`,{className:T.rows,children:e.devServers.map(e=>(0,E.jsxs)(`li`,{className:T.row,children:[(0,E.jsx)(`span`,{className:T.dot,"data-running":e.running||void 0,"aria-hidden":`true`}),(0,E.jsxs)(`span`,{className:T.rowMain,children:[(0,E.jsx)(`span`,{className:T.rowTitle,title:e.label,children:e.label}),(0,E.jsxs)(`span`,{className:T.rowMeta,title:`${C(e.url)} · ${e.running?`running`:`stopped`} · ${O[e.source]}${l?` · ${e.root}`:``}`,children:[C(e.url),` · `,e.running?`running`:`stopped`,` · `,O[e.source],l?` · ${P(e.root)}`:``]}),!e.running&&e.command&&e.command!==e.label?(0,E.jsx)(`code`,{className:T.rowCommand,title:e.command,children:e.command}):null]}),e.running?(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:()=>r(e),"aria-label":`Open ${e.label}`,children:`Open`}):(0,E.jsx)(p,{size:`sm`,variant:`subtle`,icon:(0,E.jsx)(g,{size:12}),busy:c===e.id,onClick:()=>r(e),"aria-label":`Start ${e.label}`,title:`Runs ${e.command??e.label} in a terminal tab`,children:`Start`})]},e.id))})]}),(0,E.jsxs)(`section`,{className:T.section,"aria-labelledby":`preview-files-title`,children:[(0,E.jsx)(`h3`,{className:T.sectionTitle,id:`preview-files-title`,children:`This chat's files`}),e.artifacts.length===0?(0,E.jsx)(`p`,{className:T.muted,children:`Ask the chat for a report or a page: HTML, Markdown, SVG, images and PDFs it writes appear here.`}):(0,E.jsx)(`ul`,{className:T.rows,children:e.artifacts.map(e=>{let t=e.bytes>5242880;return(0,E.jsxs)(`li`,{className:T.row,children:[(0,E.jsx)(oe,{size:14,className:T.fileIcon}),(0,E.jsxs)(`span`,{className:T.rowMain,children:[(0,E.jsx)(`span`,{className:T.rowTitle,title:e.path,children:e.path}),(0,E.jsxs)(`span`,{className:T.rowMeta,children:[ye[e.kind],` · `,w(e.bytes)]})]}),(0,E.jsx)(p,{size:`sm`,variant:`subtle`,disabled:t,title:t?`Larger than 5 MB`:void 0,onClick:()=>i(e),"aria-label":`Open ${e.path}`,children:`Open`})]},e.path)})})]})]})}export{ge as PREVIEW_START_TIMEOUT_MS,I as PreviewPane,M as resetPreviewPaneForTest};
2
- //# sourceMappingURL=PreviewPane-Bd6HsX1k.js.map
1
+ import{a as e,n as t,s as n}from"./index-BVxOlseC.js";import{M as r,O as i,c as a,i as o,o as s}from"./global-oEl9Qj8u.js";import{d as c,f as l,y as u}from"./workbench-types-DzN-5trg.js";import{n as ee}from"./viewport-nTubFCwf.js";import{i as te,r as ne}from"./section-visibility-Yctxu-if.js";import{t as d}from"./MessageMarkdown-BauY8ZTY.js";import{t as re}from"./Segmented-BE53BenI.js";import{n as f,t as p}from"./Button-HHXgoXGr.js";import{c as ie,h as ae,x as m}from"./icons-DEQa2rTx.js";import{t as h}from"./EmptyState-BqR5YAmf.js";import{a as oe,c as se,d as ce,i as le,l as ue,n as de,o as fe,s as g,t as pe}from"./terminal-icons-D2xe-aM1.js";import{t as me}from"./pane-chrome.module-D7o-fVd0.js";var _=n(e(),1),v=`/api/verse/preview/ticket`;function y(e){return new URLSearchParams(e).toString()}var b={targets:(e,t)=>a(`${l}?${y({sessionId:e})}`,t),ticket:(e,t)=>a(`${v}?${y({sessionId:e,path:t})}`),text:async(e,t)=>{let n=`${c}?${y({sessionId:e,path:t})}`,a=await fetch(n,{credentials:`same-origin`,headers:{"x-ashlr-read-client":i()}});if(a.status===401)throw r(),new s(`Read session expired.`,401,n);if(!a.ok)throw new s(`GET ${n} failed (HTTP ${a.status}).`,a.status,n);return a.text()}};function x(e){return e.port||(e.protocol===`https:`?`443`:`80`)}function S(e,t){let n=e.trim();if(n.length===0||n.length>2048||/\s/.test(n))return{kind:`invalid`};let r=n;if(/^:?\d{2,5}$/.test(n))r=`http://localhost:${n.replace(`:`,``)}/`;else if(/^(?:localhost|127\.0\.0\.1)(?::\d{1,5})?(?:[/?#].*)?$/i.test(n))r=`http://${n}`;else if(!/^[a-z][a-z0-9+.-]*:/i.test(n)){if(!/^[\w-]+(?:\.[\w-]+)+(?::\d{1,5})?(?:[/?#].*)?$/.test(n))return{kind:`invalid`};r=`https://${n}`}let i;try{i=new URL(r)}catch{return{kind:`invalid`}}if(i.protocol!==`http:`&&i.protocol!==`https:`)return{kind:`invalid`};if(u(i.href)){let e=null;try{e=new URL(t)}catch{e=null}return e&&(e.hostname===`localhost`||e.hostname===`127.0.0.1`)&&x(e)===x(i)?{kind:`self`,url:i.href}:{kind:`loopback`,url:i.href}}return i.username||i.password?{kind:`invalid`}:{kind:`external`,url:i.href}}function C(e){try{let t=new URL(e),n=t.pathname===`/`?``:t.pathname;return`${t.host}${n}${t.search}`}catch{return e}}function w(e){return!Number.isFinite(e)||e<0?`—`:e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(+(e<10240))} KB`:`${(e/1048576).toFixed(1)} MB`}var T={pane:`_pane_k6hui_8`,strip:`_strip_k6hui_19`,tabs:`_tabs_k6hui_28`,tab:`_tab_k6hui_28`,tabButton:`_tabButton_k6hui_60`,tabClose:`_tabClose_k6hui_78`,noticeClose:`_noticeClose_k6hui_79`,external:`_external_k6hui_80`,tabTitle:`_tabTitle_k6hui_85`,newTab:`_newTab_k6hui_118`,toolbar:`_toolbar_k6hui_126`,nav:`_nav_k6hui_128`,addressForm:`_addressForm_k6hui_134`,address:`_address_k6hui_134`,addressNote:`_addressNote_k6hui_177`,notice:`_notice_k6hui_79`,waiting:`_waiting_k6hui_179`,waitingText:`_waitingText_k6hui_201`,pulse:`_pulse_k6hui_208`,body:`_body_k6hui_234`,loading:`_loading_k6hui_243`,stage:`_stage_k6hui_250`,frame:`_frame_k6hui_262`,frameHint:`_frameHint_k6hui_278`,imageStage:`_imageStage_k6hui_291`,image:`_image_k6hui_291`,markdown:`_markdown_k6hui_308`,launcher:`_launcher_k6hui_316`,section:`_section_k6hui_322`,sectionTitle:`_sectionTitle_k6hui_328`,muted:`_muted_k6hui_339`,rows:`_rows_k6hui_347`,row:`_row_k6hui_347`,dot:`_dot_k6hui_364`,fileIcon:`_fileIcon_k6hui_376`,rowMain:`_rowMain_k6hui_378`,rowTitle:`_rowTitle_k6hui_385`,rowMeta:`_rowMeta_k6hui_395`,rowCommand:`_rowCommand_k6hui_405`},E=t(),he={api:b,origin:()=>window.location.origin,now:()=>Date.now()},ge=12e4,_e=2e3,ve=5e3,D=`ashlr.verse.preview.v1:`,O={"launch-json":`launch.json`,"package-json":`package.json`,listening:`running`},ye={html:`HTML`,md:`Markdown`,svg:`SVG`,image:`Image`,pdf:`PDF`},k=0,A=0,j=()=>`p${++A}`;function M(){k=0,A=0}function N(e){let t=e.toLowerCase().slice(e.lastIndexOf(`.`));return t===`.html`||t===`.htm`?`html`:t===`.md`||t===`.markdown`?`md`:t===`.svg`?`svg`:t===`.pdf`?`pdf`:[`.png`,`.jpg`,`.jpeg`,`.gif`,`.webp`,`.avif`,`.bmp`,`.ico`].includes(t)?`image`:null}function P(e){return e.slice(e.lastIndexOf(`/`)+1)||e}function F(e){return e.kind===`launcher`?`New tab`:e.kind===`url`?C(e.history[e.index]??``):P(e.path)}function be(e){return e?.kind===`url`?e.history[e.index]??null:null}function xe(e,t){try{let n=localStorage.getItem(`${D}${e}`);if(!n)return null;let r=JSON.parse(n),i=[],a=null;return Array.isArray(r.tabs)&&r.tabs.slice(0,12).forEach((e,n)=>{if(!e||typeof e!=`object`)return;let o=e,s=j();if(o.url&&typeof o.url==`string`&&S(o.url,t).kind===`loopback`)i.push({id:s,kind:`url`,history:[o.url],index:0,reloadKey:0});else if(typeof o.path==`string`){let e=N(o.path);if(e)i.push({id:s,kind:`artifact`,path:o.path,artifactKind:e,reloadKey:0});else return}else return;r.active===n&&(a=s)}),{tabs:i,activeId:a??i.at(-1)?.id??null,device:r.device===`phone`?`phone`:`desktop`}}catch{return null}}function Se(e,t,n,r){try{let i=t.filter(e=>e.kind!==`launcher`);localStorage.setItem(`${D}${e}`,JSON.stringify({tabs:i.map(e=>e.kind===`url`?{url:e.history[e.index]}:e.kind===`artifact`?{path:e.path}:{}),active:i.findIndex(e=>e.id===n),device:r}))}catch{}}function I({sessionId:e,roots:t,request:n,onOpenTerminal:r,visible:i,deps:a}){let o=(0,_.useMemo)(()=>({...he,...a}),[a]),c=te(),l=i&&c,u=ee().compact,[d]=(0,_.useState)(()=>xe(e,o.origin())),[h,g]=(0,_.useState)(()=>d?.tabs??[]),[v,y]=(0,_.useState)(()=>d?.activeId??null),[b,x]=(0,_.useState)(()=>d?.device??`desktop`),[w,ge]=(0,_.useState)(e),[D,O]=(0,_.useState)(null),[ye,A]=(0,_.useState)(null),[M,P]=(0,_.useState)(``),[I,L]=(0,_.useState)(null),[R,z]=(0,_.useState)(null),[Ee,B]=(0,_.useState)(null),[V,H]=(0,_.useState)(()=>new Map),[De,Oe]=(0,_.useState)(()=>o.now()),U=(0,_.useRef)(!0),W=(0,_.useRef)(new Map),ke=(0,_.useRef)(null);if(w!==e){let t=xe(e,o.origin());ge(e),g(t?.tabs??[]),y(t?.activeId??null),O(null),z(null),B(null)}let G=h.find(e=>e.id===v)??null,K=be(G),q=!G||G.kind===`launcher`;(0,_.useEffect)(()=>(U.current=!0,()=>{U.current=!1}),[]),(0,_.useEffect)(()=>{w===e&&Se(e,h,v,b)},[w,e,h,v,b]),(0,_.useEffect)(()=>{P(G?.kind===`url`?G.history[G.index]??``:G?.kind===`artifact`?G.path:``),L(null)},[G]);let J=(0,_.useCallback)(async()=>{try{let t=await o.api.targets(e);return U.current?(O(t),A(null),t):null}catch(e){return U.current&&A(e instanceof s&&e.detail?e.detail:`Dev servers and files could not be listed.`),null}},[o.api,e]),Ae=(0,_.useRef)(null);(0,_.useEffect)(()=>{l&&Ae.current!==e&&(Ae.current=e,J())},[l,e,J]),ne(()=>{J()},R?_e:ve,{enabled:i&&(R!==null||q)});let Y=(0,_.useCallback)((e,t={})=>{B(null);let n=h.find(e=>e.id===v);if(!t.newTab&&n?.kind===`launcher`){g(h.map(t=>t.id===n.id?{id:t.id,kind:`url`,history:[e],index:0,reloadKey:0}:t));return}let r=h.find(t=>t.kind===`url`&&t.history[t.index]===e);if(r&&!t.newTab){y(r.id);return}let i=j();g([...h,{id:i,kind:`url`,history:[e],index:0,reloadKey:0}]),y(i)},[h,v]),je=(0,_.useCallback)(e=>{if(!G||G.kind!==`url`){Y(e);return}g(t=>t.map(t=>{if(t.id!==G.id||t.kind!==`url`)return t;let n=[...t.history.slice(0,t.index+1),e].slice(-50);return{...t,history:n,index:n.length-1}}))},[G,Y]),X=(0,_.useCallback)((e,t)=>{B(null);let n=h.find(t=>t.kind===`artifact`&&t.path===e);if(n){y(n.id);return}let r=h.find(e=>e.id===v);if(r?.kind===`launcher`){g(h.map(n=>n.id===r.id?{id:n.id,kind:`artifact`,path:e,artifactKind:t,reloadKey:0}:n));return}let i=j();g([...h,{id:i,kind:`artifact`,path:e,artifactKind:t,reloadKey:0}]),y(i)},[h,v]),Me=()=>{let e=h.find(e=>e.kind===`launcher`);if(e)y(e.id);else{let e=j();g(t=>[...t,{id:e,kind:`launcher`}]),y(e)}J()},Ne=e=>{let t=h.findIndex(t=>t.id===e.id),n=h.filter(t=>t.id!==e.id);g(n),H(t=>{let n=new Map(t);for(let r of t.keys())r.startsWith(`${e.id}:`)&&n.delete(r);return n}),v===e.id&&y((n[t]??n[t-1]??null)?.id??null)},Pe=(e,t)=>{let n=-1;if(e.key===`ArrowRight`?n=(t+1)%h.length:e.key===`ArrowLeft`?n=(t-1+h.length)%h.length:e.key===`Home`?n=0:e.key===`End`&&(n=h.length-1),n<0)return;e.preventDefault();let r=h[n];y(r.id),W.current.get(r.id)?.focus()},Fe=(0,_.useCallback)(e=>{B(null),r({root:e.root,devServerId:e.id}),z({server:e,since:o.now()})},[o,r]),Z=(0,_.useCallback)(e=>{e.running?Y(e.url):Fe(e)},[Y,Fe]);(0,_.useEffect)(()=>{if(R&&D){if(D.devServers.find(e=>e.running&&(e.id===R.server.id||e.port===R.server.port))){z(null),Y(R.server.url);return}o.now()-R.since>12e4&&(z(null),B(`Nothing answered on port ${R.server.port} within 2 minutes. Check the terminal for errors.`))}},[D,R,Y,o,De]),(0,_.useEffect)(()=>{if(!R)return;let e=setInterval(()=>Oe(o.now()),1e3);return()=>clearInterval(e)},[R,o]);let Q=(0,_.useCallback)(async e=>{if(e.url){let t=S(e.url,o.origin());t.kind===`loopback`?Y(t.url):L(t);return}if(e.artifactPath){let t=D?.artifacts.find(t=>t.path===e.artifactPath)?.kind??N(e.artifactPath);t?X(e.artifactPath,t):B(`That file cannot be previewed.`);return}if(e.devServerId){let t=(await J()??D)?.devServers.find(t=>t.id===e.devServerId);t?Z(t):B(`That dev server is no longer listed for this chat.`)}},[o,X,Z,Y,J,D]);(0,_.useEffect)(()=>{!n||n.nonce<=k||(k=n.nonce,Q(n))},[n,Q]);let $=G?.kind===`artifact`?`${G.id}:${G.reloadKey}`:null;(0,_.useEffect)(()=>{if(!l||!G||G.kind!==`artifact`||!$||V.has($))return;let t=G,n=$;H(e=>new Map(e).set(n,{status:`loading`})),(t.artifactKind===`md`?o.api.text(e,t.path).then(e=>({status:`text`,text:e})):o.api.ticket(e,t.path).then(e=>({status:`frame`,src:e.url}))).then(e=>{U.current&&H(t=>new Map(t).set(n,e))},e=>{let t=e instanceof s&&e.status===404?`This file is no longer in the chat's folder.`:e instanceof s&&e.status===413?`This file is larger than 5 MB, too large to preview.`:`This file could not be loaded.`;U.current&&H(e=>new Map(e).set(n,{status:`error`,message:t}))})},[l,G,$,V,o.api,e]);let Ie=e=>{G&&G.kind===`url`&&g(t=>t.map(t=>t.id===G.id&&t.kind===`url`?{...t,index:Math.min(t.history.length-1,Math.max(0,t.index+e))}:t))},Le=()=>{if(G){if(G.kind===`launcher`){J();return}g(e=>e.map(e=>e.id===G.id&&e.kind!==`launcher`?{...e,reloadKey:e.reloadKey+1}:e))}},Re=e=>{e.preventDefault();let t=S(M,o.origin());if(t.kind===`loopback`){L(null),G?.kind===`url`?je(t.url):Y(t.url);return}L(t)},ze=e=>{e.key===`Escape`&&(e.preventDefault(),P(K??(G?.kind===`artifact`?G.path:``)),L(null),e.currentTarget.blur())},Be=G?.kind===`url`&&G.index>0,Ve=G?.kind===`url`&&G.index<G.history.length-1;return(0,E.jsxs)(`div`,{className:T.pane,"data-compact":u||void 0,children:[(0,E.jsxs)(`div`,{className:T.strip,children:[(0,E.jsx)(`div`,{className:T.tabs,role:`tablist`,"aria-label":`Previews`,children:h.map((e,t)=>{let n=e.id===v,r=F(e);return(0,E.jsxs)(`div`,{className:T.tab,"data-selected":n||void 0,role:`presentation`,children:[(0,E.jsxs)(`button`,{ref:t=>{t?W.current.set(e.id,t):W.current.delete(e.id)},type:`button`,role:`tab`,id:`preview-tab-${e.id}`,"aria-selected":n,"aria-controls":`preview-panel`,tabIndex:n?0:-1,className:T.tabButton,title:e.kind===`url`?e.history[e.index]:e.kind===`artifact`?e.path:`Choose what to preview`,onClick:()=>y(e.id),onKeyDown:e=>Pe(e,t),children:[e.kind===`artifact`?(0,E.jsx)(oe,{size:12}):e.kind===`url`?(0,E.jsx)(ce,{size:12}):(0,E.jsx)(se,{size:12}),(0,E.jsx)(`span`,{className:T.tabTitle,children:r})]}),(0,E.jsx)(`button`,{type:`button`,className:T.tabClose,"aria-label":`Close preview ${r}`,title:`Close`,onClick:()=>Ne(e),children:(0,E.jsx)(m,{size:12})})]},e.id)})}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(ae,{}),"aria-label":`New preview tab`,title:`New preview tab`,className:T.newTab,onClick:Me})]}),(0,E.jsxs)(`div`,{className:`${me.header} ${T.toolbar}`,children:[(0,E.jsxs)(`div`,{className:T.nav,children:[(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(pe,{}),"aria-label":`Back`,title:`Back`,disabled:!Be,onClick:()=>Ie(-1)}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(de,{}),"aria-label":`Forward`,title:`Forward`,disabled:!Ve,onClick:()=>Ie(1)}),(0,E.jsx)(f,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(ue,{}),"aria-label":q?`Refresh the list`:`Reload`,title:q?`Refresh the list`:`Reload`,disabled:!G&&q&&D===null,onClick:Le})]}),(0,E.jsx)(`form`,{className:T.addressForm,onSubmit:Re,role:`search`,"aria-label":`Preview address`,children:(0,E.jsx)(`input`,{ref:ke,className:T.address,value:M,onChange:e=>P(e.target.value),onKeyDown:ze,onFocus:e=>e.currentTarget.select(),placeholder:`localhost:5173`,"aria-label":`Address`,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,inputMode:`url`,readOnly:G?.kind===`artifact`})}),(0,E.jsxs)(`div`,{className:me.actions,children:[u?null:(0,E.jsx)(re,{"aria-label":`Frame width`,size:`sm`,value:b,onChange:x,options:[{value:`desktop`,label:(0,E.jsx)(le,{size:14}),ariaLabel:`Desktop width`},{value:`phone`,label:(0,E.jsx)(fe,{size:14}),ariaLabel:`375 px width`}]}),K?(0,E.jsx)(`a`,{className:T.external,href:K,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`Open in browser`,title:`Open in browser`,children:(0,E.jsx)(ie,{})}):(0,E.jsx)(`span`,{className:T.external,"data-placeholder":`true`,"aria-hidden":`true`})]})]}),I?(0,E.jsx)(Ce,{note:I,onDismiss:()=>L(null)}):null,R?(0,E.jsxs)(`div`,{className:T.waiting,role:`status`,children:[(0,E.jsx)(`span`,{className:T.pulse,"aria-hidden":`true`}),(0,E.jsxs)(`span`,{className:T.waitingText,children:[`Starting `,(0,E.jsx)(`code`,{children:R.server.command??R.server.label}),` — waiting for `,C(R.server.url),` · `,Math.max(0,Math.round((De-R.since)/1e3)),`s`]}),(0,E.jsx)(p,{size:`sm`,variant:`ghost`,onClick:()=>z(null),children:`Stop waiting`})]}):null,Ee?(0,E.jsxs)(`div`,{className:T.notice,role:`alert`,children:[(0,E.jsx)(`span`,{children:Ee}),(0,E.jsx)(`button`,{type:`button`,className:T.noticeClose,"aria-label":`Dismiss`,title:`Dismiss`,onClick:()=>B(null),children:(0,E.jsx)(m,{size:12})})]}):null,(0,E.jsx)(`div`,{className:T.body,id:`preview-panel`,role:`tabpanel`,"aria-labelledby":G?`preview-tab-${G.id}`:void 0,children:q?(0,E.jsx)(Te,{targets:D,error:ye,roots:t,onOpenServer:Z,onOpenArtifact:e=>X(e.path,e.kind),onRetry:()=>void J(),onOpenTerminal:()=>r(t[0]?{root:t[0]}:{}),waitingId:R?.server.id??null}):G?.kind===`url`?(0,E.jsxs)(`div`,{className:T.stage,"data-device":b,children:[(0,E.jsx)(`iframe`,{className:T.frame,src:G.history[G.index],title:`Preview of ${F(G)}`,sandbox:`allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-downloads`,referrerPolicy:`no-referrer`},`${G.id}:${G.index}:${G.reloadKey}`),(0,E.jsxs)(`p`,{className:T.frameHint,children:[`Blank page? Some servers refuse to be framed.`,` `,(0,E.jsx)(`a`,{href:G.history[G.index],target:`_blank`,rel:`noopener noreferrer`,children:`Open in browser ↗`})]})]}):G?.kind===`artifact`?(0,E.jsx)(we,{tab:G,content:$?V.get($)??{status:`loading`}:{status:`loading`},device:b,onRetry:Le}):null})]})}function Ce({note:e,onDismiss:t}){return(0,E.jsxs)(`div`,{className:T.addressNote,role:`status`,children:[e.kind===`external`?(0,E.jsxs)(`span`,{children:[`Only local dev servers open here.`,` `,(0,E.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noopener noreferrer`,children:`Open in browser ↗`})]}):e.kind===`self`?(0,E.jsx)(`span`,{children:`That address is Verse itself.`}):(0,E.jsxs)(`span`,{children:[`Enter a local address, like `,(0,E.jsx)(`code`,{children:`localhost:5173`}),`.`]}),(0,E.jsx)(`button`,{type:`button`,className:T.noticeClose,"aria-label":`Dismiss`,title:`Dismiss`,onClick:t,children:(0,E.jsx)(m,{size:12})})]})}function we({tab:e,content:t,device:n,onRetry:r}){return t.status===`loading`?(0,E.jsxs)(`div`,{className:T.loading,"aria-busy":`true`,children:[(0,E.jsx)(o,{width:`50%`}),(0,E.jsx)(o,{width:`80%`})]}):t.status===`error`?(0,E.jsx)(h,{compact:!0,tone:`error`,title:`Preview unavailable`,body:t.message,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:r,children:`Try again`})}):t.status===`text`?(0,E.jsx)(`article`,{className:T.markdown,"aria-label":e.path,children:(0,E.jsx)(d,{text:t.text})}):e.artifactKind===`image`?(0,E.jsx)(`div`,{className:T.imageStage,children:(0,E.jsx)(`img`,{className:T.image,src:t.src,alt:P(e.path)})}):(0,E.jsx)(`div`,{className:T.stage,"data-device":e.artifactKind===`pdf`?`desktop`:n,children:(0,E.jsx)(`iframe`,{className:T.frame,src:t.src,title:`Preview of ${e.path}`,...e.artifactKind===`pdf`?{}:{sandbox:`allow-scripts`},referrerPolicy:`no-referrer`},t.src)})}function Te({targets:e,error:t,roots:n,onOpenServer:r,onOpenArtifact:i,onRetry:a,onOpenTerminal:s,waitingId:c}){if(!e)return t?(0,E.jsx)(h,{compact:!0,tone:`error`,title:`Could not list what to preview`,body:t,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:a,children:`Try again`})}):(0,E.jsxs)(`div`,{className:T.loading,"aria-busy":`true`,children:[(0,E.jsx)(o,{width:`35%`}),(0,E.jsx)(o,{width:`70%`}),(0,E.jsx)(o,{width:`60%`})]});let l=n.length>1;return e.devServers.length===0&&e.artifacts.length===0?(0,E.jsx)(h,{compact:!0,icon:(0,E.jsx)(se,{size:20}),title:`Nothing to preview yet`,body:`Start a dev server in the terminal, or ask for an HTML report. Local servers and the files this chat writes show up here.`,action:(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:s,children:`Open a terminal`})}):(0,E.jsxs)(`div`,{className:T.launcher,children:[(0,E.jsxs)(`section`,{className:T.section,"aria-labelledby":`preview-servers-title`,children:[(0,E.jsx)(`h3`,{className:T.sectionTitle,id:`preview-servers-title`,children:`Dev servers`}),e.devServers.length===0?(0,E.jsxs)(`p`,{className:T.muted,children:[`No dev server found in this chat's folders. Add one to `,(0,E.jsx)(`code`,{children:`.claude/launch.json`}),`, or start it in the terminal.`]}):(0,E.jsx)(`ul`,{className:T.rows,children:e.devServers.map(e=>(0,E.jsxs)(`li`,{className:T.row,children:[(0,E.jsx)(`span`,{className:T.dot,"data-running":e.running||void 0,"aria-hidden":`true`}),(0,E.jsxs)(`span`,{className:T.rowMain,children:[(0,E.jsx)(`span`,{className:T.rowTitle,title:e.label,children:e.label}),(0,E.jsxs)(`span`,{className:T.rowMeta,title:`${C(e.url)} · ${e.running?`running`:`stopped`} · ${O[e.source]}${l?` · ${e.root}`:``}`,children:[C(e.url),` · `,e.running?`running`:`stopped`,` · `,O[e.source],l?` · ${P(e.root)}`:``]}),!e.running&&e.command&&e.command!==e.label?(0,E.jsx)(`code`,{className:T.rowCommand,title:e.command,children:e.command}):null]}),e.running?(0,E.jsx)(p,{size:`sm`,variant:`subtle`,onClick:()=>r(e),"aria-label":`Open ${e.label}`,children:`Open`}):(0,E.jsx)(p,{size:`sm`,variant:`subtle`,icon:(0,E.jsx)(g,{size:12}),busy:c===e.id,onClick:()=>r(e),"aria-label":`Start ${e.label}`,title:`Runs ${e.command??e.label} in a terminal tab`,children:`Start`})]},e.id))})]}),(0,E.jsxs)(`section`,{className:T.section,"aria-labelledby":`preview-files-title`,children:[(0,E.jsx)(`h3`,{className:T.sectionTitle,id:`preview-files-title`,children:`This chat's files`}),e.artifacts.length===0?(0,E.jsx)(`p`,{className:T.muted,children:`Ask the chat for a report or a page: HTML, Markdown, SVG, images and PDFs it writes appear here.`}):(0,E.jsx)(`ul`,{className:T.rows,children:e.artifacts.map(e=>{let t=e.bytes>5242880;return(0,E.jsxs)(`li`,{className:T.row,children:[(0,E.jsx)(oe,{size:14,className:T.fileIcon}),(0,E.jsxs)(`span`,{className:T.rowMain,children:[(0,E.jsx)(`span`,{className:T.rowTitle,title:e.path,children:e.path}),(0,E.jsxs)(`span`,{className:T.rowMeta,children:[ye[e.kind],` · `,w(e.bytes)]})]}),(0,E.jsx)(p,{size:`sm`,variant:`subtle`,disabled:t,title:t?`Larger than 5 MB`:void 0,onClick:()=>i(e),"aria-label":`Open ${e.path}`,children:`Open`})]},e.path)})})]})]})}export{ge as PREVIEW_START_TIMEOUT_MS,I as PreviewPane,M as resetPreviewPaneForTest};
2
+ //# sourceMappingURL=PreviewPane-BS-CleCd.js.map