@hotmeshio/long-tail 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/build/api/roles.js +4 -0
  2. package/build/api/scan-codes/choice.js +6 -3
  3. package/build/api/scan-codes/context.d.ts +7 -1
  4. package/build/api/scan-codes/context.js +24 -0
  5. package/build/api/scan-codes/execute.js +4 -2
  6. package/build/api/scan-codes/present.d.ts +3 -1
  7. package/build/api/scan-codes/present.js +25 -12
  8. package/build/routes/oauth.js +9 -6
  9. package/build/services/oauth/providers/github.js +2 -1
  10. package/build/services/oauth/providers/google.js +3 -3
  11. package/build/services/oauth/providers/microsoft.js +4 -1
  12. package/build/services/oauth/providers/mock.js +1 -1
  13. package/build/services/role/scan-done.d.ts +7 -0
  14. package/build/services/role/scan-done.js +36 -0
  15. package/build/services/role/seed.js +4 -0
  16. package/build/services/role/types.d.ts +11 -0
  17. package/build/services/role/types.js +4 -0
  18. package/build/services/scan-code/validate.js +50 -0
  19. package/build/tsconfig.tsbuildinfo +1 -1
  20. package/build/types/index.d.ts +2 -2
  21. package/build/types/index.js +3 -1
  22. package/build/types/oauth.d.ts +1 -0
  23. package/build/types/scan-choice.d.ts +8 -0
  24. package/build/types/scan-code/constants.d.ts +3 -0
  25. package/build/types/scan-code/constants.js +4 -1
  26. package/build/types/scan-code/response.d.ts +14 -0
  27. package/build/types/scan-code/rule.d.ts +11 -0
  28. package/dashboard/dist/assets/{AdminDashboard-DRE0hSDS.js → AdminDashboard-Bjf_7-S6.js} +2 -2
  29. package/dashboard/dist/assets/{AdminDashboard-DRE0hSDS.js.map → AdminDashboard-Bjf_7-S6.js.map} +1 -1
  30. package/dashboard/dist/assets/{AgentConfigPage-BuflQGgy.js → AgentConfigPage-CEGk5Gbv.js} +6 -6
  31. package/dashboard/dist/assets/{AgentConfigPage-BuflQGgy.js.map → AgentConfigPage-CEGk5Gbv.js.map} +1 -1
  32. package/dashboard/dist/assets/{AgentDetailPage-BiL9FB7i.js → AgentDetailPage-C52Oi1_f.js} +3 -3
  33. package/dashboard/dist/assets/{AgentDetailPage-BiL9FB7i.js.map → AgentDetailPage-C52Oi1_f.js.map} +1 -1
  34. package/dashboard/dist/assets/{AgentsPage-C4ZxCNxt.js → AgentsPage-CohqxaWS.js} +2 -2
  35. package/dashboard/dist/assets/{AgentsPage-C4ZxCNxt.js.map → AgentsPage-CohqxaWS.js.map} +1 -1
  36. package/dashboard/dist/assets/{AvailableEscalationsPage-B5p8QJvI.js → AvailableEscalationsPage-DXpRnOVd.js} +2 -2
  37. package/dashboard/dist/assets/{AvailableEscalationsPage-B5p8QJvI.js.map → AvailableEscalationsPage-DXpRnOVd.js.map} +1 -1
  38. package/dashboard/dist/assets/{BotPicker-B7V77PnY.js → BotPicker-DPglulL6.js} +2 -2
  39. package/dashboard/dist/assets/{BotPicker-B7V77PnY.js.map → BotPicker-DPglulL6.js.map} +1 -1
  40. package/dashboard/dist/assets/{BulkAssignModal-DcGVMQqm.js → BulkAssignModal-DWNR3FJJ.js} +2 -2
  41. package/dashboard/dist/assets/{BulkAssignModal-DcGVMQqm.js.map → BulkAssignModal-DWNR3FJJ.js.map} +1 -1
  42. package/dashboard/dist/assets/{CapabilitiesPage-DmbC1pEs.js → CapabilitiesPage-ChBBD0IX.js} +2 -2
  43. package/dashboard/dist/assets/{CapabilitiesPage-DmbC1pEs.js.map → CapabilitiesPage-ChBBD0IX.js.map} +1 -1
  44. package/dashboard/dist/assets/{CollapsibleSection-C81S1qic.js → CollapsibleSection-QAXKTYc6.js} +2 -2
  45. package/dashboard/dist/assets/{CollapsibleSection-C81S1qic.js.map → CollapsibleSection-QAXKTYc6.js.map} +1 -1
  46. package/dashboard/dist/assets/{ConfirmDeleteModal-3RFyWN9Q.js → ConfirmDeleteModal-J9xc_gVZ.js} +2 -2
  47. package/dashboard/dist/assets/{ConfirmDeleteModal-3RFyWN9Q.js.map → ConfirmDeleteModal-J9xc_gVZ.js.map} +1 -1
  48. package/dashboard/dist/assets/{ConnectedAppsPage-B0D2OvTD.js → ConnectedAppsPage-BKhsc_jJ.js} +2 -2
  49. package/dashboard/dist/assets/{ConnectedAppsPage-B0D2OvTD.js.map → ConnectedAppsPage-BKhsc_jJ.js.map} +1 -1
  50. package/dashboard/dist/assets/{CountdownTimer-iAG28fzG.js → CountdownTimer-C4hP64lF.js} +2 -2
  51. package/dashboard/dist/assets/{CountdownTimer-iAG28fzG.js.map → CountdownTimer-C4hP64lF.js.map} +1 -1
  52. package/dashboard/dist/assets/{CredentialsPage-DoFwNvFv.js → CredentialsPage-DUfgsEbI.js} +2 -2
  53. package/dashboard/dist/assets/{CredentialsPage-DoFwNvFv.js.map → CredentialsPage-DUfgsEbI.js.map} +1 -1
  54. package/dashboard/dist/assets/{CronLabel-C1Bb2wo4.js → CronLabel-CBc3Tvau.js} +2 -2
  55. package/dashboard/dist/assets/{CronLabel-C1Bb2wo4.js.map → CronLabel-CBc3Tvau.js.map} +1 -1
  56. package/dashboard/dist/assets/{DropZone-Cl_Flb16.js → DropZone-DefYTYQy.js} +2 -2
  57. package/dashboard/dist/assets/{DropZone-Cl_Flb16.js.map → DropZone-DefYTYQy.js.map} +1 -1
  58. package/dashboard/dist/assets/{ElapsedCell-DZs1I1JW.js → ElapsedCell-V27Y2Ksb.js} +2 -2
  59. package/dashboard/dist/assets/{ElapsedCell-DZs1I1JW.js.map → ElapsedCell-V27Y2Ksb.js.map} +1 -1
  60. package/dashboard/dist/assets/{EntityTimelinePanel-Du1O6Oly.js → EntityTimelinePanel-BA4MWXkB.js} +2 -2
  61. package/dashboard/dist/assets/{EntityTimelinePanel-Du1O6Oly.js.map → EntityTimelinePanel-BA4MWXkB.js.map} +1 -1
  62. package/dashboard/dist/assets/{EscalationListSchemaPage-CrpBhC0e.js → EscalationListSchemaPage-B20HUAlO.js} +2 -2
  63. package/dashboard/dist/assets/{EscalationListSchemaPage-CrpBhC0e.js.map → EscalationListSchemaPage-B20HUAlO.js.map} +1 -1
  64. package/dashboard/dist/assets/{EscalationSchemaPage-Co59lcuD.js → EscalationSchemaPage-Cen9HGYG.js} +2 -2
  65. package/dashboard/dist/assets/{EscalationSchemaPage-Co59lcuD.js.map → EscalationSchemaPage-Cen9HGYG.js.map} +1 -1
  66. package/dashboard/dist/assets/{EscalationTimeline-B_fzNsX5.js → EscalationTimeline-DGNgcMm0.js} +2 -2
  67. package/dashboard/dist/assets/{EscalationTimeline-B_fzNsX5.js.map → EscalationTimeline-DGNgcMm0.js.map} +1 -1
  68. package/dashboard/dist/assets/{EscalationTitleSelect-C2Goebjo.js → EscalationTitleSelect-BhsflGiC.js} +2 -2
  69. package/dashboard/dist/assets/{EscalationTitleSelect-C2Goebjo.js.map → EscalationTitleSelect-BhsflGiC.js.map} +1 -1
  70. package/dashboard/dist/assets/{EscalationsOverview-Cgmrl8Zc.js → EscalationsOverview-C2nc-Pgv.js} +2 -2
  71. package/dashboard/dist/assets/{EscalationsOverview-Cgmrl8Zc.js.map → EscalationsOverview-C2nc-Pgv.js.map} +1 -1
  72. package/dashboard/dist/assets/{EventTable-BdEiu3Fv.js → EventTable-BvNxHKy1.js} +2 -2
  73. package/dashboard/dist/assets/{EventTable-BdEiu3Fv.js.map → EventTable-BvNxHKy1.js.map} +1 -1
  74. package/dashboard/dist/assets/{FilterBar-CzKYBOMC.js → FilterBar-22FDO0R_.js} +2 -2
  75. package/dashboard/dist/assets/{FilterBar-CzKYBOMC.js.map → FilterBar-22FDO0R_.js.map} +1 -1
  76. package/dashboard/dist/assets/{GraphInvokePage-CcDFhY53.js → GraphInvokePage-BAyfJ-PY.js} +2 -2
  77. package/dashboard/dist/assets/{GraphInvokePage-CcDFhY53.js.map → GraphInvokePage-BAyfJ-PY.js.map} +1 -1
  78. package/dashboard/dist/assets/{HomePage-Xahqcdu9.js → HomePage-CtjG2kGn.js} +2 -2
  79. package/dashboard/dist/assets/{HomePage-Xahqcdu9.js.map → HomePage-CtjG2kGn.js.map} +1 -1
  80. package/dashboard/dist/assets/{LinePage-DKwhGunp.js → LinePage-DPe-vP3-.js} +3 -3
  81. package/dashboard/dist/assets/{LinePage-DKwhGunp.js.map → LinePage-DPe-vP3-.js.map} +1 -1
  82. package/dashboard/dist/assets/{LinesPage-BXZVO4MC.js → LinesPage-BCSfYkuL.js} +2 -2
  83. package/dashboard/dist/assets/{LinesPage-BXZVO4MC.js.map → LinesPage-BCSfYkuL.js.map} +1 -1
  84. package/dashboard/dist/assets/{ListToolbar-orQsOdl_.js → ListToolbar-6siR0Hao.js} +2 -2
  85. package/dashboard/dist/assets/{ListToolbar-orQsOdl_.js.map → ListToolbar-6siR0Hao.js.map} +1 -1
  86. package/dashboard/dist/assets/{McpOverview-pSnadtSM.js → McpOverview-Cbu2CXlQ.js} +2 -2
  87. package/dashboard/dist/assets/{McpOverview-pSnadtSM.js.map → McpOverview-Cbu2CXlQ.js.map} +1 -1
  88. package/dashboard/dist/assets/{McpQueryDetailPage-BCAJ3rKO.js → McpQueryDetailPage--1FsnGuM.js} +2 -2
  89. package/dashboard/dist/assets/{McpQueryDetailPage-BCAJ3rKO.js.map → McpQueryDetailPage--1FsnGuM.js.map} +1 -1
  90. package/dashboard/dist/assets/{McpQueryPage-CRyXeRp5.js → McpQueryPage-CPUUMIiY.js} +2 -2
  91. package/dashboard/dist/assets/{McpQueryPage-CRyXeRp5.js.map → McpQueryPage-CPUUMIiY.js.map} +1 -1
  92. package/dashboard/dist/assets/{McpRunDetailPage-BHppCztI.js → McpRunDetailPage-BDCv-c1o.js} +2 -2
  93. package/dashboard/dist/assets/{McpRunDetailPage-BHppCztI.js.map → McpRunDetailPage-BDCv-c1o.js.map} +1 -1
  94. package/dashboard/dist/assets/{McpRunsPage-Cd9yCT-_.js → McpRunsPage-Df4yOclO.js} +2 -2
  95. package/dashboard/dist/assets/{McpRunsPage-Cd9yCT-_.js.map → McpRunsPage-Df4yOclO.js.map} +1 -1
  96. package/dashboard/dist/assets/{NamespacePill-OTZD2hzt.js → NamespacePill-CeSfHH-j.js} +2 -2
  97. package/dashboard/dist/assets/{NamespacePill-OTZD2hzt.js.map → NamespacePill-CeSfHH-j.js.map} +1 -1
  98. package/dashboard/dist/assets/{OperationsPage-BtnthZgj.js → OperationsPage-BYUGFgPp.js} +2 -2
  99. package/dashboard/dist/assets/{OperationsPage-BtnthZgj.js.map → OperationsPage-BYUGFgPp.js.map} +1 -1
  100. package/dashboard/dist/assets/{OperatorDashboard-B4_OBhYh.js → OperatorDashboard-Dd1EhTZe.js} +2 -2
  101. package/dashboard/dist/assets/{OperatorDashboard-B4_OBhYh.js.map → OperatorDashboard-Dd1EhTZe.js.map} +1 -1
  102. package/dashboard/dist/assets/{PageHeader-Hx8APPwE.js → PageHeader-DiGWAQlR.js} +2 -2
  103. package/dashboard/dist/assets/{PageHeader-Hx8APPwE.js.map → PageHeader-DiGWAQlR.js.map} +1 -1
  104. package/dashboard/dist/assets/{PageHeaderWithStats-BEQYYBJv.js → PageHeaderWithStats-DwnKQ06j.js} +2 -2
  105. package/dashboard/dist/assets/{PageHeaderWithStats-BEQYYBJv.js.map → PageHeaderWithStats-DwnKQ06j.js.map} +1 -1
  106. package/dashboard/dist/assets/{PersonaDetailPage-BAYjM9qf.js → PersonaDetailPage-BCx3Ey2_.js} +2 -2
  107. package/dashboard/dist/assets/{PersonaDetailPage-BAYjM9qf.js.map → PersonaDetailPage-BCx3Ey2_.js.map} +1 -1
  108. package/dashboard/dist/assets/{PersonasPage-6HsOp-1y.js → PersonasPage--Ez0YeHh.js} +2 -2
  109. package/dashboard/dist/assets/{PersonasPage-6HsOp-1y.js.map → PersonasPage--Ez0YeHh.js.map} +1 -1
  110. package/dashboard/dist/assets/{PortalPage-6OMr7KtJ.js → PortalPage-BmBmheBp.js} +2 -2
  111. package/dashboard/dist/assets/{PortalPage-6OMr7KtJ.js.map → PortalPage-BmBmheBp.js.map} +1 -1
  112. package/dashboard/dist/assets/{ProcessDetailPage-AidH_h7z.js → ProcessDetailPage-DBj4VEnP.js} +2 -2
  113. package/dashboard/dist/assets/{ProcessDetailPage-AidH_h7z.js.map → ProcessDetailPage-DBj4VEnP.js.map} +1 -1
  114. package/dashboard/dist/assets/{ProcessesListPage-BWKoKbXk.js → ProcessesListPage-CD5NRIBK.js} +2 -2
  115. package/dashboard/dist/assets/{ProcessesListPage-BWKoKbXk.js.map → ProcessesListPage-CD5NRIBK.js.map} +1 -1
  116. package/dashboard/dist/assets/{ResolverForm-BaSvhLoT.js → ResolverForm-Baxwv_IG.js} +2 -2
  117. package/dashboard/dist/assets/{ResolverForm-BaSvhLoT.js.map → ResolverForm-Baxwv_IG.js.map} +1 -1
  118. package/dashboard/dist/assets/RoleDetailPage-6ukNyycs.js +8 -0
  119. package/dashboard/dist/assets/RoleDetailPage-6ukNyycs.js.map +1 -0
  120. package/dashboard/dist/assets/{RolePill-R5_ctGFy.js → RolePill-D3hkAdKf.js} +2 -2
  121. package/dashboard/dist/assets/{RolePill-R5_ctGFy.js.map → RolePill-D3hkAdKf.js.map} +1 -1
  122. package/dashboard/dist/assets/{RolesPage-T2hH_MV5.js → RolesPage-DRs2XeSd.js} +2 -2
  123. package/dashboard/dist/assets/{RolesPage-T2hH_MV5.js.map → RolesPage-DRs2XeSd.js.map} +1 -1
  124. package/dashboard/dist/assets/{RosterWidget-DG6Rcx4P.js → RosterWidget-BPBPSa1k.js} +2 -2
  125. package/dashboard/dist/assets/{RosterWidget-DG6Rcx4P.js.map → RosterWidget-BPBPSa1k.js.map} +1 -1
  126. package/dashboard/dist/assets/{RunAsSelector-M2h9U6PP.js → RunAsSelector-Br9FiMwP.js} +2 -2
  127. package/dashboard/dist/assets/{RunAsSelector-M2h9U6PP.js.map → RunAsSelector-Br9FiMwP.js.map} +1 -1
  128. package/dashboard/dist/assets/{ScanCodesPage-lB_WxoZw.js → ScanCodesPage-BXENWoZb.js} +2 -2
  129. package/dashboard/dist/assets/{ScanCodesPage-lB_WxoZw.js.map → ScanCodesPage-BXENWoZb.js.map} +1 -1
  130. package/dashboard/dist/assets/{ScanSchemeDetailPage-C3VLg61H.js → ScanSchemeDetailPage-CaM4rUBV.js} +2 -2
  131. package/dashboard/dist/assets/{ScanSchemeDetailPage-C3VLg61H.js.map → ScanSchemeDetailPage-CaM4rUBV.js.map} +1 -1
  132. package/dashboard/dist/assets/ScanStationPage-CmJKgWy_.js +2 -0
  133. package/dashboard/dist/assets/ScanStationPage-CmJKgWy_.js.map +1 -0
  134. package/dashboard/dist/assets/{ScopeBadge-BXZ084nD.js → ScopeBadge-DGz79rmG.js} +2 -2
  135. package/dashboard/dist/assets/{ScopeBadge-BXZ084nD.js.map → ScopeBadge-DGz79rmG.js.map} +1 -1
  136. package/dashboard/dist/assets/{StickyPagination-BdjseWXr.js → StickyPagination-DX5CPgrX.js} +2 -2
  137. package/dashboard/dist/assets/{StickyPagination-BdjseWXr.js.map → StickyPagination-DX5CPgrX.js.map} +1 -1
  138. package/dashboard/dist/assets/{StreamMessageDetail-DJCBxETh.js → StreamMessageDetail-3mWw3_M5.js} +2 -2
  139. package/dashboard/dist/assets/{StreamMessageDetail-DJCBxETh.js.map → StreamMessageDetail-3mWw3_M5.js.map} +1 -1
  140. package/dashboard/dist/assets/{SwimlaneTimeline-DiXm9jIk.js → SwimlaneTimeline-C_pIcWBJ.js} +2 -2
  141. package/dashboard/dist/assets/{SwimlaneTimeline-DiXm9jIk.js.map → SwimlaneTimeline-C_pIcWBJ.js.map} +1 -1
  142. package/dashboard/dist/assets/{TagInput-DjPUDp2M.js → TagInput-DaIdhv3h.js} +2 -2
  143. package/dashboard/dist/assets/{TagInput-DjPUDp2M.js.map → TagInput-DaIdhv3h.js.map} +1 -1
  144. package/dashboard/dist/assets/{TaskDetailPage-m8CQFN4w.js → TaskDetailPage-DthMVBZO.js} +2 -2
  145. package/dashboard/dist/assets/{TaskDetailPage-m8CQFN4w.js.map → TaskDetailPage-DthMVBZO.js.map} +1 -1
  146. package/dashboard/dist/assets/{TaskQueuePill-D-4Ynf3K.js → TaskQueuePill-sUA1nZe-.js} +2 -2
  147. package/dashboard/dist/assets/{TaskQueuePill-D-4Ynf3K.js.map → TaskQueuePill-sUA1nZe-.js.map} +1 -1
  148. package/dashboard/dist/assets/{TasksListPage-DHBSUhZC.js → TasksListPage-MtawUpuU.js} +2 -2
  149. package/dashboard/dist/assets/{TasksListPage-DHBSUhZC.js.map → TasksListPage-MtawUpuU.js.map} +1 -1
  150. package/dashboard/dist/assets/{TimeAgo-Cq3bKUd-.js → TimeAgo-DIziYk-v.js} +2 -2
  151. package/dashboard/dist/assets/{TimeAgo-Cq3bKUd-.js.map → TimeAgo-DIziYk-v.js.map} +1 -1
  152. package/dashboard/dist/assets/{TimestampCell-e5gRR_FY.js → TimestampCell-Dn5M-Eey.js} +2 -2
  153. package/dashboard/dist/assets/{TimestampCell-e5gRR_FY.js.map → TimestampCell-Dn5M-Eey.js.map} +1 -1
  154. package/dashboard/dist/assets/{ToolPill-GsKQ80CO.js → ToolPill-CpBAFdEX.js} +2 -2
  155. package/dashboard/dist/assets/{ToolPill-GsKQ80CO.js.map → ToolPill-CpBAFdEX.js.map} +1 -1
  156. package/dashboard/dist/assets/{ToolTestPanel-Bg0ss9oN.js → ToolTestPanel-DaBrgPML.js} +2 -2
  157. package/dashboard/dist/assets/{ToolTestPanel-Bg0ss9oN.js.map → ToolTestPanel-DaBrgPML.js.map} +1 -1
  158. package/dashboard/dist/assets/{TopicDetailPage-DhPiCfOO.js → TopicDetailPage-zNE3EigP.js} +2 -2
  159. package/dashboard/dist/assets/{TopicDetailPage-DhPiCfOO.js.map → TopicDetailPage-zNE3EigP.js.map} +1 -1
  160. package/dashboard/dist/assets/{TopicsPage-BqZaVv3d.js → TopicsPage-Cj0ugdie.js} +2 -2
  161. package/dashboard/dist/assets/{TopicsPage-BqZaVv3d.js.map → TopicsPage-Cj0ugdie.js.map} +1 -1
  162. package/dashboard/dist/assets/{UserName-C6ZNHHKN.js → UserName-t3PbLYfd.js} +2 -2
  163. package/dashboard/dist/assets/{UserName-C6ZNHHKN.js.map → UserName-t3PbLYfd.js.map} +1 -1
  164. package/dashboard/dist/assets/{WorkflowExecutionPage-BUqIhtcr.js → WorkflowExecutionPage-CZ2c5QLL.js} +2 -2
  165. package/dashboard/dist/assets/{WorkflowExecutionPage-BUqIhtcr.js.map → WorkflowExecutionPage-CZ2c5QLL.js.map} +1 -1
  166. package/dashboard/dist/assets/{WorkflowPill-D7244fKp.js → WorkflowPill-CKHip3hH.js} +2 -2
  167. package/dashboard/dist/assets/{WorkflowPill-D7244fKp.js.map → WorkflowPill-CKHip3hH.js.map} +1 -1
  168. package/dashboard/dist/assets/{WorkflowsDashboard-BKxhC_hT.js → WorkflowsDashboard-DLb71Sa2.js} +2 -2
  169. package/dashboard/dist/assets/{WorkflowsDashboard-BKxhC_hT.js.map → WorkflowsDashboard-DLb71Sa2.js.map} +1 -1
  170. package/dashboard/dist/assets/{WorkflowsOverview-018s2q_p.js → WorkflowsOverview-Wz6RzxHJ.js} +2 -2
  171. package/dashboard/dist/assets/{WorkflowsOverview-018s2q_p.js.map → WorkflowsOverview-Wz6RzxHJ.js.map} +1 -1
  172. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C2zcXDr1.js → YamlWorkflowDetailPage-CcRAN_ey.js} +2 -2
  173. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C2zcXDr1.js.map → YamlWorkflowDetailPage-CcRAN_ey.js.map} +1 -1
  174. package/dashboard/dist/assets/{YamlWorkflowsPage-aVcNZNu6.js → YamlWorkflowsPage-B4C9fiYU.js} +2 -2
  175. package/dashboard/dist/assets/{YamlWorkflowsPage-aVcNZNu6.js.map → YamlWorkflowsPage-B4C9fiYU.js.map} +1 -1
  176. package/dashboard/dist/assets/{agents-DRaaJUue.js → agents-BvRjwrof.js} +2 -2
  177. package/dashboard/dist/assets/{agents-DRaaJUue.js.map → agents-BvRjwrof.js.map} +1 -1
  178. package/dashboard/dist/assets/{bots-C4N90NCj.js → bots-qx7qPwFo.js} +2 -2
  179. package/dashboard/dist/assets/{bots-C4N90NCj.js.map → bots-qx7qPwFo.js.map} +1 -1
  180. package/dashboard/dist/assets/{capabilities-BoRWifSC.js → capabilities-DJrUEeew.js} +2 -2
  181. package/dashboard/dist/assets/{capabilities-BoRWifSC.js.map → capabilities-DJrUEeew.js.map} +1 -1
  182. package/dashboard/dist/assets/{controlplane-DGZAxi7J.js → controlplane-D82a5cfq.js} +2 -2
  183. package/dashboard/dist/assets/{controlplane-DGZAxi7J.js.map → controlplane-D82a5cfq.js.map} +1 -1
  184. package/dashboard/dist/assets/{escalation-columns-DJbfsH_m.js → escalation-columns-Dmm8LY_f.js} +2 -2
  185. package/dashboard/dist/assets/{escalation-columns-DJbfsH_m.js.map → escalation-columns-Dmm8LY_f.js.map} +1 -1
  186. package/dashboard/dist/assets/{escalation-items-C8iJZEA8.js → escalation-items-C3ko1DCb.js} +2 -2
  187. package/dashboard/dist/assets/{escalation-items-C8iJZEA8.js.map → escalation-items-C3ko1DCb.js.map} +1 -1
  188. package/dashboard/dist/assets/{index-BuSUevzO.js → index-BAxEeqfF.js} +2 -2
  189. package/dashboard/dist/assets/{index-BuSUevzO.js.map → index-BAxEeqfF.js.map} +1 -1
  190. package/dashboard/dist/assets/{index-DhKGp4QK.js → index-BCSeHOZH.js} +2 -2
  191. package/dashboard/dist/assets/{index-DhKGp4QK.js.map → index-BCSeHOZH.js.map} +1 -1
  192. package/dashboard/dist/assets/{index-DeyA88jq.js → index-BJrsQM-E.js} +2 -2
  193. package/dashboard/dist/assets/{index-DeyA88jq.js.map → index-BJrsQM-E.js.map} +1 -1
  194. package/dashboard/dist/assets/{index-CXXc9sUr.js → index-BVxqddYr.js} +2 -2
  195. package/dashboard/dist/assets/{index-CXXc9sUr.js.map → index-BVxqddYr.js.map} +1 -1
  196. package/dashboard/dist/assets/{index-DIU89TX3.js → index-C59ZyWOo.js} +2 -2
  197. package/dashboard/dist/assets/{index-DIU89TX3.js.map → index-C59ZyWOo.js.map} +1 -1
  198. package/dashboard/dist/assets/{index-CyL-6CAa.js → index-CNDnGdvT.js} +2 -2
  199. package/dashboard/dist/assets/{index-CyL-6CAa.js.map → index-CNDnGdvT.js.map} +1 -1
  200. package/dashboard/dist/assets/{index-pzbGpihI.js → index-CSr5q355.js} +25 -25
  201. package/dashboard/dist/assets/index-CSr5q355.js.map +1 -0
  202. package/dashboard/dist/assets/{index-DMKLnxt8.js → index-CXnmU0TS.js} +2 -2
  203. package/dashboard/dist/assets/{index-DMKLnxt8.js.map → index-CXnmU0TS.js.map} +1 -1
  204. package/dashboard/dist/assets/{index-CjjRxpVe.js → index-C_-FoMo9.js} +2 -2
  205. package/dashboard/dist/assets/{index-CjjRxpVe.js.map → index-C_-FoMo9.js.map} +1 -1
  206. package/dashboard/dist/assets/index-C_dp4WgY.css +1 -0
  207. package/dashboard/dist/assets/{index-3HaFP00M.js → index-D-vNL8Hm.js} +2 -2
  208. package/dashboard/dist/assets/{index-3HaFP00M.js.map → index-D-vNL8Hm.js.map} +1 -1
  209. package/dashboard/dist/assets/{index-BFxHIfQ_.js → index-DOkHnsLK.js} +2 -2
  210. package/dashboard/dist/assets/{index-BFxHIfQ_.js.map → index-DOkHnsLK.js.map} +1 -1
  211. package/dashboard/dist/assets/{index-BhS9XSy8.js → index-U5gC9Xgq.js} +2 -2
  212. package/dashboard/dist/assets/{index-BhS9XSy8.js.map → index-U5gC9Xgq.js.map} +1 -1
  213. package/dashboard/dist/assets/{index-CeeSFnl-.js → index-f4-pKYcm.js} +2 -2
  214. package/dashboard/dist/assets/{index-CeeSFnl-.js.map → index-f4-pKYcm.js.map} +1 -1
  215. package/dashboard/dist/assets/{knowledge-BWo3OCJc.js → knowledge-i7_nXSbf.js} +2 -2
  216. package/dashboard/dist/assets/{knowledge-BWo3OCJc.js.map → knowledge-i7_nXSbf.js.map} +1 -1
  217. package/dashboard/dist/assets/{machines-LEYY_yar.js → machines-DfSNshLg.js} +2 -2
  218. package/dashboard/dist/assets/{machines-LEYY_yar.js.map → machines-DfSNshLg.js.map} +1 -1
  219. package/dashboard/dist/assets/{mcp-_0kFRcyT.js → mcp-dCLNwcC8.js} +2 -2
  220. package/dashboard/dist/assets/{mcp-_0kFRcyT.js.map → mcp-dCLNwcC8.js.map} +1 -1
  221. package/dashboard/dist/assets/{mcp-query-BzmN0lc5.js → mcp-query-wmbaGRYi.js} +2 -2
  222. package/dashboard/dist/assets/{mcp-query-BzmN0lc5.js.map → mcp-query-wmbaGRYi.js.map} +1 -1
  223. package/dashboard/dist/assets/{personas-kE4PMrgo.js → personas-B_cJA5UG.js} +2 -2
  224. package/dashboard/dist/assets/{personas-kE4PMrgo.js.map → personas-B_cJA5UG.js.map} +1 -1
  225. package/dashboard/dist/assets/{pipelines-DYDNaypF.js → pipelines-ClUmuwmY.js} +2 -2
  226. package/dashboard/dist/assets/{pipelines-DYDNaypF.js.map → pipelines-ClUmuwmY.js.map} +1 -1
  227. package/dashboard/dist/assets/{tasks-ClJ-mbj9.js → tasks-BE97GrLr.js} +2 -2
  228. package/dashboard/dist/assets/{tasks-ClJ-mbj9.js.map → tasks-BE97GrLr.js.map} +1 -1
  229. package/dashboard/dist/assets/{topics-oHX4vbqe.js → topics-Dk0Y3kZP.js} +2 -2
  230. package/dashboard/dist/assets/{topics-oHX4vbqe.js.map → topics-Dk0Y3kZP.js.map} +1 -1
  231. package/dashboard/dist/assets/{useDebouncedValue-C97KADrj.js → useDebouncedValue-BLGuHd_v.js} +2 -2
  232. package/dashboard/dist/assets/{useDebouncedValue-C97KADrj.js.map → useDebouncedValue-BLGuHd_v.js.map} +1 -1
  233. package/dashboard/dist/assets/{useNamespace-Kje0Rn7j.js → useNamespace-Cj7t8eQd.js} +2 -2
  234. package/dashboard/dist/assets/{useNamespace-Kje0Rn7j.js.map → useNamespace-Cj7t8eQd.js.map} +1 -1
  235. package/dashboard/dist/assets/{useYamlActivityEvents-DMz-HKFv.js → useYamlActivityEvents-C7eurSkD.js} +2 -2
  236. package/dashboard/dist/assets/{useYamlActivityEvents-DMz-HKFv.js.map → useYamlActivityEvents-C7eurSkD.js.map} +1 -1
  237. package/dashboard/dist/assets/{validate-hUqjWN63.js → validate-BypZfZ8R.js} +2 -2
  238. package/dashboard/dist/assets/{validate-hUqjWN63.js.map → validate-BypZfZ8R.js.map} +1 -1
  239. package/dashboard/dist/assets/{vendor-icons-fxBvvHBi.js → vendor-icons-en0_uSRD.js} +191 -186
  240. package/dashboard/dist/assets/vendor-icons-en0_uSRD.js.map +1 -0
  241. package/dashboard/dist/assets/{yaml-workflows-64vfmKJx.js → yaml-workflows-CnMKmznF.js} +2 -2
  242. package/dashboard/dist/assets/{yaml-workflows-64vfmKJx.js.map → yaml-workflows-CnMKmznF.js.map} +1 -1
  243. package/dashboard/dist/index.html +3 -3
  244. package/docs/api/http/roles.md +1 -1
  245. package/docs/dashboard.md +2 -2
  246. package/docs/oauth-and-delegation.md +5 -1
  247. package/docs/scan-codes.md +56 -0
  248. package/package.json +1 -1
  249. package/dashboard/dist/assets/RoleDetailPage-D_30TDVh.js +0 -8
  250. package/dashboard/dist/assets/RoleDetailPage-D_30TDVh.js.map +0 -1
  251. package/dashboard/dist/assets/ScanStationPage-CVET1_4r.js +0 -2
  252. package/dashboard/dist/assets/ScanStationPage-CVET1_4r.js.map +0 -1
  253. package/dashboard/dist/assets/index-B9uv-euR.css +0 -1
  254. package/dashboard/dist/assets/index-pzbGpihI.js.map +0 -1
  255. package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LinePage-DKwhGunp.js","sources":["../../src/hooks/useWireTape.ts","../../src/pages/lines/line-view-prefs.ts","../../src/pages/lines/wire-display.ts","../../src/pages/lines/CommandForm.tsx","../../src/pages/lines/InspectForm.tsx","../../src/pages/lines/MachinePanel.tsx","../../src/pages/lines/MachineRows.tsx","../../src/pages/lines/MachineStrip.tsx","../../src/pages/lines/MachineViews.tsx","../../src/pages/lines/WireRow.tsx","../../src/pages/lines/WireTape.tsx","../../src/pages/lines/TapeSection.tsx","../../src/pages/lines/WireDetailPanel.tsx","../../src/pages/lines/LinePage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useReducer } from 'react';\nimport { useEventSubscription } from './useEventContext';\nimport {\n machineWirePattern,\n WIRE_EVENT_TYPE,\n WIRE_KINDS,\n type WireDirection,\n type WireEvent,\n type WireKind,\n} from '../api/machines';\n\n/** The tape keeps this many events, newest first; older ones fall off the end. */\nexport const WIRE_TAPE_CAPACITY = 2000;\n\nexport interface WireTapeFilters {\n machine: string | null;\n channel: string | null;\n direction: WireDirection | null;\n kind: WireKind | null;\n violationsOnly: boolean;\n}\n\nexport interface WireTapeState {\n /** Newest first. */\n events: WireEvent[];\n /** Events that arrived while paused, newest first; they join the tape on resume. */\n held: WireEvent[];\n paused: boolean;\n filters: WireTapeFilters;\n}\n\nexport type WireTapeAction =\n | { type: 'ingest'; event: WireEvent }\n | { type: 'pause' }\n | { type: 'resume' }\n | { type: 'clear' }\n | { type: 'filter'; patch: Partial<WireTapeFilters> };\n\nexport const EMPTY_FILTERS: WireTapeFilters = {\n machine: null,\n channel: null,\n direction: null,\n kind: null,\n violationsOnly: false,\n};\n\nexport function initialTapeState(): WireTapeState {\n return { events: [], held: [], paused: false, filters: EMPTY_FILTERS };\n}\n\nfunction cap(events: WireEvent[]): WireEvent[] {\n return events.length > WIRE_TAPE_CAPACITY ? events.slice(0, WIRE_TAPE_CAPACITY) : events;\n}\n\nexport function wireTapeReducer(state: WireTapeState, action: WireTapeAction): WireTapeState {\n switch (action.type) {\n case 'ingest':\n return state.paused\n ? { ...state, held: cap([action.event, ...state.held]) }\n : { ...state, events: cap([action.event, ...state.events]) };\n case 'pause':\n return state.paused ? state : { ...state, paused: true };\n case 'resume':\n return { ...state, paused: false, held: [], events: cap([...state.held, ...state.events]) };\n case 'clear':\n return { ...state, events: [], held: [] };\n case 'filter':\n return { ...state, filters: { ...state.filters, ...action.patch } };\n }\n}\n\nexport function matchesFilters(event: WireEvent, filters: WireTapeFilters): boolean {\n if (filters.machine && event.machineId !== filters.machine) return false;\n if (filters.channel && event.channel !== filters.channel) return false;\n if (filters.direction && event.direction !== filters.direction) return false;\n if (filters.kind && event.kind !== filters.kind) return false;\n if (filters.violationsOnly && event.violations.length === 0) return false;\n return true;\n}\n\nexport function applyFilters(events: WireEvent[], filters: WireTapeFilters): WireEvent[] {\n return events.filter((event) => matchesFilters(event, filters));\n}\n\nconst KINDS = new Set<string>(WIRE_KINDS);\n\n/**\n * The transport hands over the published event envelope: its routing type\n * carries the site, line, machine and direction tokens after `machine.wire`,\n * and the wire event itself rides in `data`. A bare wire event is read as is.\n */\nexport function toWireEvent(raw: unknown): WireEvent | null {\n if (!raw || typeof raw !== 'object') return null;\n const envelope = raw as Record<string, unknown>;\n const type = envelope.type;\n if (typeof type !== 'string' || (type !== WIRE_EVENT_TYPE && !type.startsWith(`${WIRE_EVENT_TYPE}.`))) {\n return null;\n }\n const e = envelope.data && typeof envelope.data === 'object' ? (envelope.data as Record<string, unknown>) : envelope;\n if (typeof e.siteId !== 'string' || typeof e.lineId !== 'string') return null;\n if (e.direction !== 'in' && e.direction !== 'out') return null;\n const kind = typeof e.kind === 'string' && KINDS.has(e.kind) ? (e.kind as WireKind) : 'unknown';\n const at = [e.at, envelope.timestamp].find((v): v is string => typeof v === 'string') ?? new Date().toISOString();\n return {\n type: WIRE_EVENT_TYPE,\n siteId: e.siteId,\n lineId: e.lineId,\n machineId: typeof e.machineId === 'string' ? e.machineId : null,\n address: typeof e.address === 'string' ? e.address : null,\n direction: e.direction,\n channel: typeof e.channel === 'string' ? e.channel : '',\n topic: typeof e.topic === 'string' ? e.topic : '',\n id: typeof e.id === 'string' ? e.id : null,\n at,\n retained: e.retained === true,\n kind,\n event: typeof e.event === 'string' ? e.event : null,\n summary: typeof e.summary === 'string' ? e.summary : '',\n violations: Array.isArray(e.violations) ? e.violations.filter((v): v is string => typeof v === 'string') : [],\n actions: Array.isArray(e.actions) ? (e.actions as WireEvent['actions']) : [],\n ...('payload' in e ? { payload: e.payload } : {}),\n };\n}\n\nfunction distinct(values: (string | null)[]): string[] {\n return [...new Set(values.filter((v): v is string => !!v))].sort();\n}\n\n/**\n * The live tape of one line's wire events: a bounded ring buffer fed by the\n * event transport, with filters and a pause that holds new arrivals aside.\n */\nexport function useWireTape(siteId: string, lineId: string) {\n const [state, dispatch] = useReducer(wireTapeReducer, undefined, initialTapeState);\n\n useEffect(() => {\n dispatch({ type: 'clear' });\n }, [siteId, lineId]);\n\n useEventSubscription(machineWirePattern(siteId, lineId), (raw) => {\n const event = toWireEvent(raw);\n if (event) dispatch({ type: 'ingest', event });\n });\n\n const visible = useMemo(() => applyFilters(state.events, state.filters), [state.events, state.filters]);\n const machines = useMemo(() => distinct(state.events.map((e) => e.machineId)), [state.events]);\n const channels = useMemo(() => distinct(state.events.map((e) => e.channel)), [state.events]);\n\n const setFilter = useCallback((patch: Partial<WireTapeFilters>) => dispatch({ type: 'filter', patch }), []);\n const togglePause = useCallback(() => dispatch({ type: state.paused ? 'resume' : 'pause' }), [state.paused]);\n const clear = useCallback(() => dispatch({ type: 'clear' }), []);\n\n return {\n events: visible,\n total: state.events.length,\n heldCount: state.held.length,\n paused: state.paused,\n filters: state.filters,\n machines,\n channels,\n setFilter,\n togglePause,\n clear,\n };\n}\n","import type { MachineView } from '../../api/machines';\n\n/** How the machines region lists its machines. */\nexport const MACHINE_VIEWS = ['tiles', 'rows'] as const;\nexport type MachineViewMode = (typeof MACHINE_VIEWS)[number];\nexport const MACHINE_VIEW_LABEL: Record<MachineViewMode, string> = { tiles: 'Tiles', rows: 'Rows' };\n\n/** Tiles read well to a dozen machines; beyond that, rows. */\nexport const TILES_MAX = 12;\n\nexport function machineViewStorageKey(siteId: string, lineId: string): string {\n return `lt:lines:${siteId}/${lineId}:machines-view`;\n}\n\nexport function autoMachineView(count: number): MachineViewMode {\n return count <= TILES_MAX ? 'tiles' : 'rows';\n}\n\nexport function readStored<T extends string>(key: string, allowed: readonly T[]): T | null {\n try {\n const value = localStorage.getItem(key);\n return value && (allowed as readonly string[]).includes(value) ? (value as T) : null;\n } catch {\n return null;\n }\n}\n\nexport function writeStored(key: string, value: string | null): void {\n try {\n if (value === null) localStorage.removeItem(key);\n else localStorage.setItem(key, value);\n } catch {\n // storage may be unavailable; the choice then lasts the session\n }\n}\n\n/** A machine that needs a person: offline, quiet, an active alarm, or an open row. */\nexport function needsAttention(view: MachineView | undefined): boolean {\n if (!view) return false;\n if (view.online === false) return true;\n if (view.rows.offlineRowId || view.rows.quietRowId) return true;\n if (view.alarms.length > 0) return true;\n return view.rows.handoff + view.rows.command + view.rows.alarm > 0;\n}\n","import type { MachineView, WireAction, WireVerb } from '../../api/machines';\nimport { getDisplayTimeZone } from '../../lib/display-zone';\n\n/** Past-tense wording for each action the gateway took on a message. */\nexport const WIRE_VERB_LABEL: Record<WireVerb, string> = {\n claim: 'claimed',\n accumulate: 'accumulated',\n resolve: 'resolved',\n 'create-row': 'row created',\n refuse: 'refused',\n hold: 'held',\n unmatched: 'unmatched',\n unreadable: 'unreadable',\n ack: 'acknowledged',\n none: '',\n};\n\n/** Text-safe status tone per verb. */\nexport const WIRE_VERB_TONE: Record<WireVerb, string> = {\n claim: 'text-text-secondary',\n accumulate: 'text-text-secondary',\n resolve: 'text-status-success',\n 'create-row': 'text-text-secondary',\n refuse: 'text-status-error',\n hold: 'text-status-warning',\n unmatched: 'text-status-warning',\n unreadable: 'text-status-error',\n ack: 'text-text-secondary',\n none: 'text-text-quaternary',\n};\n\n/** \"accumulated arrived:U1\": the verb plus the item it touched. */\nexport function describeAction(action: WireAction): string {\n const label = WIRE_VERB_LABEL[action.verb] ?? action.verb;\n return action.itemKey ? `${label} ${action.itemKey}` : label;\n}\n\n/** Actions worth a word; `none` stays silent. */\nexport function visibleActions(actions: WireAction[]): WireAction[] {\n return actions.filter((a) => a.verb !== 'none');\n}\n\n/** The escalation detail route for a row the gateway named. */\nexport function rowPath(rowId: string): string {\n return `/escalations/detail/${encodeURIComponent(rowId)}`;\n}\n\n/** \"13:02:07\" in the display zone, for the tape's time column. */\nexport function formatClock(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n const zone = getDisplayTimeZone();\n return new Intl.DateTimeFormat('en-GB', {\n ...(zone ? { timeZone: zone } : {}),\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n }).format(date);\n}\n\nexport type Presence = 'online' | 'quiet' | 'offline' | 'unknown';\n\n/** Ring color per presence, through the graphic status tokens. */\nexport const PRESENCE_DOT: Record<Presence, string> = {\n online: 'bg-status-success-graphic',\n quiet: 'bg-status-pending-graphic',\n offline: 'bg-status-error',\n unknown: 'bg-text-quaternary',\n};\n\nexport const PRESENCE_LABEL: Record<Presence, string> = {\n online: 'online',\n quiet: 'quiet',\n offline: 'offline',\n unknown: 'unknown',\n};\n\n/** Quiet is online with an open quiet row; unknown is a machine the leader has yet to hear. */\nexport function presenceOf(view: MachineView | undefined): Presence {\n if (!view || view.online === null) return 'unknown';\n if (!view.online) return 'offline';\n return view.rows.quietRowId ? 'quiet' : 'online';\n}\n\n/** Pretty JSON for panels; strings stay as they are. */\nexport function formatJson(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n","import { useState, type FormEvent } from 'react';\nimport { Link } from 'react-router-dom';\nimport { commandOpsFor, sendCommand, SNAPSHOT_OP, type LineSummaryMachine } from '../../api/machines';\nimport { rowPath } from './wire-display';\n\nexport type CommandOutcome =\n | { request: string; ok: true; rowId: string }\n | { request: string; ok: false; message: string };\n\n/** The scan idiom: the request in mono, the verdict in its tone. */\nexport function CommandOutcomeBody({ outcome }: { outcome: CommandOutcome }) {\n return (\n <div className=\"min-w-0\" data-testid=\"command-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n {outcome.ok ? (\n <div className=\"text-xs font-medium text-status-success\">\n Row created{' '}\n <Link to={rowPath(outcome.rowId)} className=\"font-mono text-accent hover:underline\">{outcome.rowId}</Link>\n </div>\n ) : (\n <div className=\"text-xs font-medium text-status-error\">{outcome.message}</div>\n )}\n </div>\n );\n}\n\nconst ARG_HELPERS = ['jobId', 'recipe'] as const;\n\nfunction mergeArgKey(text: string, key: string): string {\n let current: Record<string, unknown> = {};\n try {\n const parsed = text.trim() ? JSON.parse(text) : {};\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) current = parsed;\n } catch {\n current = {};\n }\n if (!(key in current)) current[key] = '';\n return JSON.stringify(current, null, 2);\n}\n\nfunction parseArgs(text: string): Record<string, unknown> {\n if (!text.trim()) return {};\n const parsed = JSON.parse(text);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('Args must be a JSON object.');\n }\n return parsed;\n}\n\n/**\n * Send one command to a machine: an op from the line's vocabulary and a\n * small JSON args object. The server creates the row; the role decides.\n */\nexport function CommandForm({\n siteId,\n lineId,\n machine,\n}: {\n siteId: string;\n lineId: string;\n machine: LineSummaryMachine;\n}) {\n const [op, setOp] = useState('');\n const [args, setArgs] = useState('');\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<CommandOutcome | null>(null);\n const ops = commandOpsFor(machine);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n if (!op) return;\n const request = `${op} ${args.trim() || '{}'}`;\n setBusy(true);\n try {\n const parsed = parseArgs(args);\n const receipt = await sendCommand(siteId, lineId, machine.machineId, { op, args: parsed });\n setOutcome({ request, ok: true, rowId: receipt.rowId });\n } catch (err) {\n setOutcome({ request, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <form onSubmit={submit} className=\"space-y-3\" aria-label=\"Send command\">\n <div>\n <label htmlFor=\"command-op\" className=\"block text-2xs font-medium text-text-secondary\">\n Op <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Pick the operation the machine runs.</p>\n <select\n id=\"command-op\"\n className=\"select text-xs font-mono\"\n value={op}\n required\n onChange={(e) => setOp(e.target.value)}\n >\n <option value=\"\" disabled>Choose…</option>\n {ops.map((o) => <option key={o} value={o}>{o}</option>)}\n </select>\n </div>\n <div>\n <label htmlFor=\"command-args\" className=\"block text-2xs font-medium text-text-secondary\">Args</label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Write a JSON object, or add a key from the helpers.</p>\n <textarea\n id=\"command-args\"\n className=\"textarea text-2xs font-mono min-h-[4.5rem]\"\n value={args}\n placeholder=\"{}\"\n onChange={(e) => setArgs(e.target.value)}\n />\n <div className=\"flex items-center gap-2 mt-1\">\n {ARG_HELPERS.map((key) => (\n <button\n key={key}\n type=\"button\"\n onClick={() => setArgs((t) => mergeArgKey(t, key))}\n className=\"text-2xs font-mono icon-link\"\n >\n + {key}\n </button>\n ))}\n </div>\n </div>\n <button type=\"submit\" disabled={busy || !op} className=\"btn-primary text-xs py-1.5 px-4\">\n Send\n </button>\n {outcome && <CommandOutcomeBody outcome={outcome} />}\n </form>\n );\n}\n\n/** One click asks the machine for a fresh snapshot, as a command row. */\nexport function SnapshotButton({\n siteId,\n lineId,\n machineId,\n}: {\n siteId: string;\n lineId: string;\n machineId: string;\n}) {\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<CommandOutcome | null>(null);\n\n const ask = async () => {\n setBusy(true);\n try {\n const receipt = await sendCommand(siteId, lineId, machineId, { op: SNAPSHOT_OP, args: {} });\n setOutcome({ request: `${SNAPSHOT_OP} {}`, ok: true, rowId: receipt.rowId });\n } catch (err) {\n setOutcome({ request: `${SNAPSHOT_OP} {}`, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"space-y-2\">\n <button type=\"button\" onClick={ask} disabled={busy} className=\"btn-secondary text-xs py-1.5 px-4\">\n Ask for a snapshot\n </button>\n {outcome && <CommandOutcomeBody outcome={outcome} />}\n </div>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport { Link } from 'react-router-dom';\nimport { inspectMessage, type InspectResult } from '../../api/machines';\nimport { describeAction, formatJson, rowPath, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\nconst RETAINED_CHOICES = [\n { value: 'live', label: 'Live', retained: false },\n { value: 'retained', label: 'Retained', retained: true },\n] as const;\n\ntype Retained = (typeof RETAINED_CHOICES)[number]['value'];\n\n/** A payload that parses as JSON goes as JSON; anything else goes as the text typed. */\nexport function parsePayload(text: string): unknown {\n const trimmed = text.trim();\n if (!trimmed) return '';\n try {\n return JSON.parse(trimmed);\n } catch {\n return text;\n }\n}\n\ntype InspectOutcome =\n | { request: string; ok: true; result: InspectResult }\n | { request: string; ok: false; message: string };\n\n/** The dry-run verdict: summary, violations in the warning tone, planned actions with row links. */\nexport function InspectOutcomeBody({ outcome }: { outcome: InspectOutcome }) {\n return (\n <div className=\"min-w-0 space-y-2\" data-testid=\"inspect-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n {!outcome.ok ? (\n <div className=\"text-xs font-medium text-status-error\">{outcome.message}</div>\n ) : (\n <>\n <div className={`text-xs font-medium ${outcome.result.violations.length ? 'text-status-warning' : 'text-status-success'}`}>\n {outcome.result.kind ?? 'message'}\n {outcome.result.event ? ` · ${outcome.result.event}` : ''}\n {outcome.result.violations.length\n ? ` · ${outcome.result.violations.length} violation${outcome.result.violations.length === 1 ? '' : 's'}`\n : ' · matches the contract'}\n </div>\n {outcome.result.summary && <div className=\"text-2xs text-text-secondary\">{outcome.result.summary}</div>}\n {outcome.result.violations.length > 0 && (\n <ul className=\"space-y-0.5\" aria-label=\"Violations\">\n {outcome.result.violations.map((v, i) => (\n <li key={i} className=\"text-2xs text-status-warning\">{v}</li>\n ))}\n </ul>\n )}\n <div>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1\">Planned actions</p>\n {visibleActions(outcome.result.actions).length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The gateway would take no action.</p>\n ) : (\n <ul className=\"space-y-0.5\" aria-label=\"Planned actions\">\n {visibleActions(outcome.result.actions).map((a, i) => (\n <li key={`${a.verb}-${i}`} className=\"text-2xs\">\n <span className={WIRE_VERB_TONE[a.verb]}>{describeAction(a)}</span>\n {a.rowId && (\n <>\n {' '}\n <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">{a.rowId}</Link>\n </>\n )}\n {a.detail && <span className=\"text-text-tertiary\"> · {a.detail}</span>}\n </li>\n ))}\n </ul>\n )}\n </div>\n {outcome.result.inspections !== undefined && (\n <pre className=\"text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(outcome.result.inspections)}\n </pre>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Inspect a message as a dry run: the leader decodes it and plans what it\n * would do, without applying anything.\n */\nexport function InspectForm({ siteId, lineId }: { siteId: string; lineId: string }) {\n const [topic, setTopic] = useState('');\n const [payload, setPayload] = useState('');\n const [retained, setRetained] = useState<Retained | ''>('');\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<InspectOutcome | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n const choice = RETAINED_CHOICES.find((c) => c.value === retained);\n if (!topic.trim() || !choice) return;\n const request = `${topic.trim()} ${payload.trim() || '\"\"'}`;\n setBusy(true);\n try {\n const result = await inspectMessage(siteId, lineId, {\n topic: topic.trim(),\n payload: parsePayload(payload),\n retained: choice.retained,\n });\n setOutcome({ request, ok: true, result: { ...result, violations: result.violations ?? [], actions: result.actions ?? [] } });\n } catch (err) {\n setOutcome({ request, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <form onSubmit={submit} className=\"space-y-3\" aria-label=\"Inspect a message\">\n <div>\n <label htmlFor=\"inspect-topic\" className=\"block text-2xs font-medium text-text-secondary\">\n Topic <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Enter the topic the message arrives on.</p>\n <input\n id=\"inspect-topic\"\n className=\"input text-2xs font-mono\"\n value={topic}\n required\n onChange={(e) => setTopic(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor=\"inspect-payload\" className=\"block text-2xs font-medium text-text-secondary\">Payload</label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Paste the body; JSON is sent as JSON, anything else as text.</p>\n <textarea\n id=\"inspect-payload\"\n className=\"textarea text-2xs font-mono min-h-[5rem]\"\n value={payload}\n onChange={(e) => setPayload(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor=\"inspect-retained\" className=\"block text-2xs font-medium text-text-secondary\">\n Delivery <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Say whether the broker would hand this over as a retained message.</p>\n <select\n id=\"inspect-retained\"\n className=\"select text-xs\"\n value={retained}\n required\n onChange={(e) => setRetained(e.target.value as Retained)}\n >\n <option value=\"\" disabled>Choose…</option>\n {RETAINED_CHOICES.map((c) => <option key={c.value} value={c.value}>{c.label}</option>)}\n </select>\n </div>\n <button type=\"submit\" disabled={busy || !topic.trim() || !retained} className=\"btn-primary text-xs py-1.5 px-4\">\n Inspect\n </button>\n {outcome && <InspectOutcomeBody outcome={outcome} />}\n </form>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { X, ChevronRight } from 'lucide-react';\nimport { MACHINE_FACETS, type LineSummaryMachine, type MachineView } from '../../api/machines';\nimport { PanelField } from '../../components/common/layout/SlidePanel';\nimport { EntityTimelinePanel } from '../../components/escalation/EntityTimelinePanel';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport { formatDateTime } from '../../lib/format';\nimport { CommandForm, SnapshotButton } from './CommandForm';\nimport { InspectForm } from './InspectForm';\nimport { formatJson, PRESENCE_DOT, PRESENCE_LABEL, presenceOf, rowPath } from './wire-display';\n\nexport const MACHINE_PANEL_KEY = 'machine';\nexport const MACHINE_PANEL_WIDTH = 440;\nconst TIMELINE_PANEL_KEY = 'entity-timeline';\n\nfunction Section({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">{title}</p>\n {children}\n </section>\n );\n}\n\nfunction RowLink({ rowId, label }: { rowId: string; label: string }) {\n return (\n <li className=\"text-2xs\">\n <span className=\"text-text-secondary\">{label}</span>{' '}\n <Link to={rowPath(rowId)} className=\"font-mono text-accent hover:underline\">{rowId}</Link>\n </li>\n );\n}\n\n/**\n * One machine in the shell's right panel: the last snapshot in brief, its\n * open rows, a way into its timeline, and the tools for those who may act.\n */\nexport function MachinePanel({\n siteId,\n lineId,\n summary,\n view,\n canAct,\n onClose,\n}: {\n siteId: string;\n lineId: string;\n summary: LineSummaryMachine;\n view: MachineView | undefined;\n canAct: boolean;\n onClose: () => void;\n}) {\n const presence = presenceOf(view);\n const shell = useShellPanelOptional();\n const [jobsOpen, setJobsOpen] = useState(false);\n\n // The timeline takes the shell slot; the strip tile reopens this panel.\n const openTimeline = useCallback(\n (facetKey: string) => {\n shell?.setPanel(\n <EntityTimelinePanel facetKey={facetKey} value={summary.machineId} role={summary.role} />,\n { key: TIMELINE_PANEL_KEY, width: 420 },\n );\n },\n [shell, summary.machineId, summary.role],\n );\n\n const alarms = view?.alarms ?? [];\n const held = view?.heldUnits ?? [];\n const jobs = view?.jobs ?? [];\n\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${PRESENCE_DOT[presence]}`} title={PRESENCE_LABEL[presence]} />\n <span className=\"text-sm font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs text-text-quaternary\">{PRESENCE_LABEL[presence]}</span>\n </div>\n <p className=\"text-2xs font-mono text-text-tertiary mt-0.5\">\n {summary.process} · {summary.role}\n </p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4 space-y-5\">\n <Section title=\"Snapshot\">\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <PanelField label=\"Address\">\n <span className=\"font-mono\">{view?.address ?? summary.address ?? '—'}</span>\n <span className=\"text-text-quaternary\"> · {summary.addressing}</span>\n </PanelField>\n <PanelField label=\"Software\"><span className=\"font-mono\">{view?.software ?? '—'}</span></PanelField>\n <PanelField label=\"Since\">{view?.since ? formatDateTime(view.since) : '—'}</PanelField>\n <PanelField label=\"Last seen\">{view?.lastSeen ? formatDateTime(view.lastSeen) : '—'}</PanelField>\n <PanelField label=\"Boot\"><span className=\"font-mono break-all\">{view?.bootId ?? '—'}</span></PanelField>\n <PanelField label=\"Session\"><span className=\"font-mono break-all\">{view?.sessionId ?? '—'}</span></PanelField>\n </dl>\n </Section>\n\n <Section title={`Jobs · ${jobs.length}`}>\n {jobs.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The last snapshot carried no jobs.</p>\n ) : (\n <>\n <button type=\"button\" onClick={() => setJobsOpen((v) => !v)} className=\"inline-flex items-center gap-1 text-2xs icon-link\">\n <ChevronRight className={`w-3 h-3 transition-transform ${jobsOpen ? 'rotate-90' : ''}`} />\n {jobsOpen ? 'Hide' : 'Show'} the jobs as reported\n </button>\n {jobsOpen && (\n <pre className=\"mt-1.5 text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(jobs)}\n </pre>\n )}\n </>\n )}\n </Section>\n\n <Section title={`Alarms · ${alarms.length}`}>\n {alarms.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The machine reports no active alarm.</p>\n ) : (\n <ul className=\"space-y-1\">\n {alarms.map((a) => (\n <li key={a.alarmId} className=\"text-2xs flex items-baseline gap-2\">\n <span className=\"font-mono text-status-warning\">{a.alarmId}</span>\n <span className=\"text-text-tertiary\">{a.level}</span>\n <span className=\"text-text-quaternary ml-auto\">{formatDateTime(a.raisedAt)}</span>\n {a.rowId && <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">row</Link>}\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section title={`Held units · ${held.length}`}>\n {held.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The machine holds no unit.</p>\n ) : (\n <ul className=\"space-y-1\">\n {held.map((u) => (\n <RowLink key={u.unitId} rowId={u.rowId} label={u.carrierId ? `${u.unitId} on ${u.carrierId}` : u.unitId} />\n ))}\n </ul>\n )}\n </Section>\n\n <Section title=\"Open rows\">\n <p className=\"text-2xs font-mono text-text-secondary tabular-nums\">\n handoff {view?.rows.handoff ?? 0} · command {view?.rows.command ?? 0} · alarm {view?.rows.alarm ?? 0}\n </p>\n {(view?.rows.offlineRowId || view?.rows.quietRowId) && (\n <ul className=\"space-y-1 mt-1\">\n {view.rows.offlineRowId && <RowLink rowId={view.rows.offlineRowId} label=\"offline\" />}\n {view.rows.quietRowId && <RowLink rowId={view.rows.quietRowId} label=\"quiet\" />}\n </ul>\n )}\n </Section>\n\n <Section title=\"Over a window\">\n <p className=\"text-2xs text-text-tertiary mb-1.5\">Open the rows that moved work to or from this machine.</p>\n <div className=\"flex items-center gap-3\">\n <button type=\"button\" onClick={() => openTimeline(MACHINE_FACETS.TO)} className=\"text-2xs icon-link font-mono\">\n {MACHINE_FACETS.TO}\n </button>\n <button type=\"button\" onClick={() => openTimeline(MACHINE_FACETS.FROM)} className=\"text-2xs icon-link font-mono\">\n {MACHINE_FACETS.FROM}\n </button>\n </div>\n </Section>\n\n {canAct && (\n <>\n <Section title=\"Ask for a snapshot\">\n <SnapshotButton siteId={siteId} lineId={lineId} machineId={summary.machineId} />\n </Section>\n <Section title=\"Send command\">\n <CommandForm siteId={siteId} lineId={lineId} machine={summary} />\n </Section>\n <Section title=\"Inspect a message\">\n <InspectForm siteId={siteId} lineId={lineId} />\n </Section>\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useMemo, useState } from 'react';\nimport type { StripMachine } from './MachineStrip';\nimport { PRESENCE_DOT, PRESENCE_LABEL, presenceOf } from './wire-display';\n\nconst ROWS_BOX_CLASS = 'flex-1 min-h-0 overflow-y-auto border-t border-surface-border';\n\nfunction matches(machine: StripMachine, needle: string): boolean {\n if (!needle) return true;\n const { summary, view } = machine;\n const hay = [summary.machineId, summary.process, summary.role, view?.address ?? summary.address ?? ''].join(' ').toLowerCase();\n return hay.includes(needle);\n}\n\n/**\n * One dense line per machine in line order, in a list that scrolls within\n * the region. The search narrows the declared list by id, process, role or address.\n */\nexport function MachineRows({\n machines,\n selectedId,\n onSelect,\n}: {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n}) {\n const [query, setQuery] = useState('');\n const needle = query.trim().toLowerCase();\n const shown = useMemo(() => machines.filter((m) => matches(m, needle)), [machines, needle]);\n return (\n <div className=\"flex flex-col h-full min-h-0\">\n <div className=\"flex items-center gap-3 pb-2 shrink-0\">\n <label className=\"sr-only\" htmlFor=\"machine-search\">Find a machine</label>\n <input\n id=\"machine-search\"\n type=\"search\"\n className=\"input text-2xs font-mono py-1 w-full max-w-[16rem]\"\n placeholder=\"id, process, role, address\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <span className=\"text-2xs text-text-quaternary tabular-nums\">{shown.length} of {machines.length}</span>\n </div>\n <ul className={ROWS_BOX_CLASS} aria-label=\"Machines\">\n {shown.map(({ summary, view }) => {\n const presence = presenceOf(view);\n const selected = summary.machineId === selectedId;\n const address = view?.address ?? summary.address;\n const alarms = view?.alarms.length ?? 0;\n return (\n <li key={summary.machineId}>\n <button\n type=\"button\"\n onClick={() => onSelect(summary.machineId)}\n aria-pressed={selected}\n data-presence={presence}\n className={`w-full text-left grid grid-cols-[auto_minmax(6rem,1fr)_minmax(0,2fr)_auto_auto_auto] items-baseline gap-x-3 px-2 py-1 border-l-2 border-b border-surface-border/60 hover:bg-surface-hover transition-colors ${\n selected ? 'border-l-accent' : 'border-l-transparent'\n }`}\n >\n <span className={`w-2 h-2 rounded-full dot-ring self-center ${PRESENCE_DOT[presence]}`} title={PRESENCE_LABEL[presence]} />\n <span className=\"text-2xs font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs font-mono text-text-tertiary truncate\" title={address ?? undefined}>\n {summary.process}\n {address ? <span className=\"text-text-quaternary\"> · {address}</span> : null}\n </span>\n <span className=\"text-2xs text-text-tertiary truncate max-w-[6rem]\" title=\"Software\">{view?.software ?? '—'}</span>\n <span className=\"text-2xs text-text-secondary tabular-nums whitespace-nowrap\" title=\"Units held\">held {view?.heldUnits.length ?? 0}</span>\n <span className=\"text-2xs font-mono text-text-tertiary tabular-nums whitespace-nowrap\">\n h {view?.rows.handoff ?? 0} c {view?.rows.command ?? 0} a {view?.rows.alarm ?? 0}\n {alarms > 0 && <span className=\"text-status-warning ml-2\" title=\"Active alarms\">{alarms} alarm{alarms === 1 ? '' : 's'}</span>}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n {shown.length === 0 && <p className=\"text-2xs text-text-tertiary py-2\">No machine matches.</p>}\n </div>\n );\n}\n","import type { LineSummaryMachine, MachineView } from '../../api/machines';\nimport { PRESENCE_DOT, PRESENCE_LABEL, presenceOf } from './wire-display';\n\nexport interface StripMachine {\n summary: LineSummaryMachine;\n /** Absent while the replica stands by or before the leader has heard the machine. */\n view: MachineView | undefined;\n}\n\n/**\n * One tile per machine in line order: presence ring, identity in mono, the\n * software it runs, what it holds, and its open rows by kind. Click selects.\n * Tiles fill the width in as many columns as fit.\n */\nexport function MachineStrip({\n machines,\n selectedId,\n onSelect,\n}: {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n}) {\n if (machines.length === 0) {\n return <p className=\"text-2xs text-text-tertiary\">The line declares no machines.</p>;\n }\n return (\n <div className=\"grid grid-cols-[repeat(auto-fill,minmax(11rem,1fr))] gap-y-3\" role=\"list\" aria-label=\"Machines\">\n {machines.map(({ summary, view }) => {\n const presence = presenceOf(view);\n const selected = summary.machineId === selectedId;\n const address = view?.address ?? summary.address;\n const alarms = view?.alarms.length ?? 0;\n return (\n <button\n key={summary.machineId}\n type=\"button\"\n role=\"listitem\"\n onClick={() => onSelect(summary.machineId)}\n aria-pressed={selected}\n data-presence={presence}\n className={`text-left min-w-0 pl-3 pr-4 py-1.5 border-l-2 transition-colors hover:bg-surface-hover ${\n selected ? 'border-accent' : 'border-surface-border'\n }`}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <span\n className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${PRESENCE_DOT[presence]}`}\n title={PRESENCE_LABEL[presence]}\n />\n <span className=\"text-xs font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs text-text-quaternary ml-auto shrink-0\">{PRESENCE_LABEL[presence]}</span>\n </div>\n <div className=\"text-2xs font-mono text-text-tertiary truncate mt-0.5\" title={address ?? undefined}>\n {summary.process}\n {address ? <span className=\"text-text-quaternary\"> · {address}</span> : null}\n </div>\n <div className=\"flex items-center gap-3 text-2xs mt-1 tabular-nums\">\n <span className=\"text-text-tertiary truncate\" title=\"Software\">{view?.software ?? '—'}</span>\n <span className=\"text-text-secondary shrink-0\" title=\"Units held\">\n held {view?.heldUnits.length ?? 0}\n </span>\n </div>\n <div className=\"flex items-center gap-3 text-2xs font-mono mt-0.5 tabular-nums\">\n <span className=\"text-text-tertiary\" title=\"Open handoff rows\">h {view?.rows.handoff ?? 0}</span>\n <span className=\"text-text-tertiary\" title=\"Open command rows\">c {view?.rows.command ?? 0}</span>\n <span className=\"text-text-tertiary\" title=\"Open alarm rows\">a {view?.rows.alarm ?? 0}</span>\n {alarms > 0 && (\n <span className=\"text-status-warning ml-auto\" title=\"Active alarms\">\n {alarms} alarm{alarms === 1 ? '' : 's'}\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { LayoutGrid, List } from 'lucide-react';\nimport { MACHINE_VIEWS, MACHINE_VIEW_LABEL, needsAttention, type MachineViewMode } from './line-view-prefs';\nimport { MachineRows } from './MachineRows';\nimport { MachineStrip, type StripMachine } from './MachineStrip';\n\nconst VIEW_ICON: Record<MachineViewMode, typeof LayoutGrid> = { tiles: LayoutGrid, rows: List };\nconst RADIO_CLASS = 'p-1 transition-colors';\nconst RADIO_ON = 'text-text-primary bg-surface-sunken';\nconst RADIO_OFF = 'text-text-tertiary hover:text-text-primary';\n\nexport interface MachineViewsProps {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n view: MachineViewMode;\n onView: (view: MachineViewMode) => void;\n attentionOnly: boolean;\n onAttentionOnly: (on: boolean) => void;\n}\n\n/**\n * The machines region: the count, a needs-attention filter and the view\n * radios on the right (tiles or rows), with the chosen view filling the\n * region beneath. The region is bounded, so the wire below never moves.\n */\nexport function MachineViews(props: MachineViewsProps) {\n const { machines, selectedId, onSelect, view, onView, attentionOnly, onAttentionOnly } = props;\n const shown = useMemo(\n () => (attentionOnly ? machines.filter((m) => needsAttention(m.view)) : machines),\n [machines, attentionOnly],\n );\n const attention = useMemo(() => machines.filter((m) => needsAttention(m.view)).length, [machines]);\n if (machines.length === 0) {\n return <p className=\"text-2xs text-text-tertiary\">The line declares no machines.</p>;\n }\n const View = view === 'rows' ? MachineRows : MachineStrip;\n return (\n <section aria-label=\"Machines region\" data-view={view} className=\"flex flex-col h-full min-h-0\">\n <div className=\"flex items-center gap-3 pb-2 shrink-0\">\n <span className=\"text-2xs text-text-quaternary tabular-nums\">\n {machines.length} machine{machines.length === 1 ? '' : 's'}\n {attention > 0 && <span className=\"text-status-warning\"> · {attention} need{attention === 1 ? 's' : ''} attention</span>}\n </span>\n <span className=\"ml-auto flex items-center gap-3\">\n <button\n type=\"button\"\n aria-pressed={attentionOnly}\n onClick={() => onAttentionOnly(!attentionOnly)}\n className={`px-2 py-0.5 text-2xs rounded border transition-colors ${\n attentionOnly ? 'border-status-warning text-status-warning' : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Needs attention\n </button>\n <span className=\"inline-flex rounded border border-surface-border overflow-hidden\" role=\"radiogroup\" aria-label=\"Machines view\">\n {MACHINE_VIEWS.map((mode) => {\n const Icon = VIEW_ICON[mode];\n return (\n <button\n key={mode}\n type=\"button\"\n role=\"radio\"\n aria-checked={view === mode}\n aria-label={MACHINE_VIEW_LABEL[mode]}\n title={MACHINE_VIEW_LABEL[mode]}\n onClick={() => onView(mode)}\n className={`${RADIO_CLASS} ${view === mode ? RADIO_ON : RADIO_OFF}`}\n >\n <Icon className=\"w-3.5 h-3.5\" />\n </button>\n );\n })}\n </span>\n </span>\n </div>\n {shown.length === 0 ? (\n <p className=\"text-2xs text-text-tertiary py-1\">Every machine is quiet.</p>\n ) : (\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <View machines={shown} selectedId={selectedId} onSelect={onSelect} />\n </div>\n )}\n </section>\n );\n}\n","import { ArrowDownLeft, ArrowUpRight } from 'lucide-react';\nimport type { WireEvent } from '../../api/machines';\nimport { describeAction, formatClock, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\n/**\n * One line of the tape. At table width it is one row of columns: time,\n * direction, machine, channel and topic in mono, the summary, then the\n * violations and the actions the gateway took. Below it the row is a\n * dictionary: identity on the first line, the summary and the actions on\n * the second, the topic on the third.\n */\nexport function WireRow({ event, onOpen }: { event: WireEvent; onOpen: (event: WireEvent) => void }) {\n const actions = visibleActions(event.actions);\n const Direction = event.direction === 'in' ? ArrowDownLeft : ArrowUpRight;\n return (\n <li>\n <button\n type=\"button\"\n onClick={() => onOpen(event)}\n data-direction={event.direction}\n data-kind={event.kind}\n className=\"w-full text-left grid items-baseline gap-x-3 gap-y-0.5 px-2 py-1.5 border-b border-surface-border/60 hover:bg-surface-hover transition-colors\n grid-cols-[auto_auto_minmax(0,1fr)_auto]\n @table/tape:grid-cols-[auto_auto_6rem_11rem_minmax(0,1fr)_auto]\"\n >\n <span className=\"text-2xs font-mono tabular-nums text-text-quaternary\">{formatClock(event.at)}</span>\n <Direction\n className=\"w-3 h-3 self-center text-accent/65\"\n aria-label={event.direction === 'in' ? 'in' : 'out'}\n />\n <span\n className=\"text-2xs font-mono text-text-primary min-w-0 truncate col-span-2 @table/tape:col-span-1\"\n title={event.machineId ?? event.address ?? undefined}\n >\n {event.machineId ?? event.address ?? '—'}\n </span>\n <span\n className=\"text-2xs font-mono text-text-tertiary min-w-0 truncate col-start-3 col-span-2 @table/tape:col-start-4 @table/tape:col-span-1\"\n title={`${event.channel} ${event.topic}`}\n >\n {event.channel}\n <span className=\"text-text-quaternary\"> · </span>\n {event.topic}\n </span>\n <span\n className=\"text-xs text-text-secondary min-w-0 truncate col-start-3 @table/tape:col-start-5\"\n title={event.summary}\n >\n {event.summary || `${event.kind}${event.event ? ` · ${event.event}` : ''}`}\n </span>\n <span className=\"min-w-0 max-w-[12rem] @table/tape:max-w-[22rem] truncate text-2xs col-start-4 @table/tape:col-start-6\">\n {event.violations.length > 0 && (\n <span className=\"text-status-warning tabular-nums mr-2\" title={event.violations.join('\\n')}>\n {event.violations.length} violation{event.violations.length === 1 ? '' : 's'}\n </span>\n )}\n {actions.map((a, i) => (\n <span\n key={`${a.verb}-${a.rowId ?? ''}-${i}`}\n className={`${WIRE_VERB_TONE[a.verb] ?? 'text-text-secondary'} ${i < actions.length - 1 ? 'mr-2' : ''}`}\n >\n {describeAction(a)}\n </span>\n ))}\n </span>\n </button>\n </li>\n );\n}\n","import { Pause, Play, Eraser, X } from 'lucide-react';\nimport type { ReactNode, RefObject } from 'react';\nimport { WIRE_KINDS, type WireDirection, type WireEvent, type WireKind } from '../../api/machines';\nimport type { WireTapeFilters } from '../../hooks/useWireTape';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { WireRow } from './WireRow';\n\nexport interface WireTapeProps {\n events: WireEvent[];\n total: number;\n paused: boolean;\n heldCount: number;\n filters: WireTapeFilters;\n machines: string[];\n channels: string[];\n setFilter: (patch: Partial<WireTapeFilters>) => void;\n togglePause: () => void;\n clear: () => void;\n onOpen: (event: WireEvent) => void;\n /** Extra header controls after Clear: full screen, watch. */\n controls?: ReactNode;\n /** Sizes the scrolling list; the section decides how much room it has. */\n listClassName?: string;\n listRef?: RefObject<HTMLUListElement | null>;\n}\n\nconst DEFAULT_LIST_CLASS = 'flex-1 min-h-0';\n\nconst DIRECTIONS: { value: WireDirection; label: string }[] = [\n { value: 'in', label: 'in' },\n { value: 'out', label: 'out' },\n];\n\nfunction activeFilterCount(filters: WireTapeFilters): number {\n return [filters.machine, filters.channel, filters.direction, filters.kind].filter(Boolean).length\n + (filters.violationsOnly ? 1 : 0);\n}\n\n/**\n * The live list of wire events, newest first, with its filter band and the\n * pause that holds new arrivals aside while you read. The band folds its\n * controls behind one Filters button when the container is narrow; the rows\n * fold from columns into console cards below the table threshold.\n */\nexport function WireTape(props: WireTapeProps) {\n const { events, total, paused, heldCount, filters, machines, channels, setFilter, togglePause, clear, onOpen, controls, listClassName, listRef } = props;\n return (\n <div className=\"flex flex-col min-h-0 flex-1 @container/tape\">\n <FilterBar\n embedded\n activeFilterCount={activeFilterCount(filters)}\n actions={\n <>\n <span className=\"text-2xs text-text-quaternary tabular-nums whitespace-nowrap\">\n {events.length} shown · {total} on tape\n </span>\n <button\n type=\"button\"\n onClick={togglePause}\n aria-pressed={paused}\n className=\"inline-flex items-center gap-1 text-2xs icon-link whitespace-nowrap\"\n title={paused ? 'Resume the tape' : 'Pause the tape'}\n >\n {paused ? <Play className=\"w-3 h-3\" /> : <Pause className=\"w-3 h-3\" />}\n {paused ? `Resume${heldCount ? ` · ${heldCount} held` : ''}` : 'Pause'}\n </button>\n <button type=\"button\" onClick={clear} className=\"inline-flex items-center gap-1 text-2xs icon-link\" title=\"Clear the tape\">\n <Eraser className=\"w-3 h-3\" />\n Clear\n </button>\n {controls}\n </>\n }\n >\n <FilterSelect\n label=\"Machine\"\n value={filters.machine ?? ''}\n onChange={(v) => setFilter({ machine: v || null })}\n options={machines.map((m) => ({ value: m, label: m }))}\n placeholder=\"every machine\"\n />\n <FilterSelect\n label=\"Channel\"\n value={filters.channel ?? ''}\n onChange={(v) => setFilter({ channel: v || null })}\n options={channels.map((c) => ({ value: c, label: c }))}\n placeholder=\"every channel\"\n />\n <FilterSelect\n label=\"Direction\"\n value={filters.direction ?? ''}\n onChange={(v) => setFilter({ direction: (v || null) as WireDirection | null })}\n options={DIRECTIONS}\n placeholder=\"both\"\n />\n <FilterSelect\n label=\"Kind\"\n value={filters.kind ?? ''}\n onChange={(v) => setFilter({ kind: (v || null) as WireKind | null })}\n options={WIRE_KINDS.map((k) => ({ value: k, label: k }))}\n placeholder=\"every kind\"\n />\n <button\n type=\"button\"\n aria-pressed={filters.violationsOnly}\n onClick={() => setFilter({ violationsOnly: !filters.violationsOnly })}\n className={`self-start px-2 py-1 text-2xs rounded border transition-colors whitespace-nowrap ${\n filters.violationsOnly\n ? 'border-status-warning text-status-warning'\n : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Violations only\n </button>\n </FilterBar>\n {filters.machine && (\n <div className=\"flex items-center gap-2 px-3 py-1.5 text-2xs shrink-0\">\n <span className=\"text-text-quaternary\">Following</span>\n <button\n type=\"button\"\n onClick={() => setFilter({ machine: null })}\n className=\"inline-flex items-center gap-1 rounded-full border border-surface-border px-2 py-0.5 font-mono text-text-primary hover:text-accent transition-colors\"\n title=\"Show every machine\"\n >\n {filters.machine}\n <X className=\"w-3 h-3\" />\n <span className=\"font-sans text-text-tertiary\">release</span>\n </button>\n </div>\n )}\n {events.length === 0 ? (\n <p className=\"text-2xs text-text-tertiary px-3 py-3\">\n {total === 0 ? 'Waiting for traffic on the wire.' : 'Every event on the tape is filtered out.'}\n </p>\n ) : (\n <ul ref={listRef} className={`${listClassName ?? DEFAULT_LIST_CLASS} overflow-y-auto`} aria-label=\"Wire tape\">\n {events.map((event) => (\n <WireRow key={`${event.at}-${event.id ?? ''}-${event.topic}-${event.direction}`} event={event} onOpen={onOpen} />\n ))}\n </ul>\n )}\n </div>\n );\n}\n","import { useRef } from 'react';\nimport { Maximize2, Minimize2, Radio } from 'lucide-react';\nimport { FullscreenOverlay } from '../../components/common/layout/FullscreenOverlay';\nimport { WireTape, type WireTapeProps } from './WireTape';\n\n/** The embed: a bordered box of its own, the band inside, the list scrolling within. */\nexport const TAPE_BOX_CLASS = 'flex flex-col h-full min-h-0 overflow-hidden rounded-[var(--lt-radius-section)] border border-surface-border bg-surface-sunken';\n\nexport interface TapeSectionProps extends Omit<WireTapeProps, 'controls' | 'listClassName' | 'listRef'> {\n fullscreen: boolean;\n onFullscreen: (open: boolean) => void;\n /** Whether the shell's event stream already carries this line's wire. */\n watching: boolean;\n onWatch: () => void;\n}\n\n/**\n * The wire as an embed beneath the machines: boxed in, its filters and\n * controls in its own band, a full-screen view in the shell's overlay, and\n * a way to keep watching the line from the event stream anywhere in the app.\n */\nexport function TapeSection(props: TapeSectionProps) {\n const { fullscreen, onFullscreen, watching, onWatch, ...tape } = props;\n const listRef = useRef<HTMLUListElement | null>(null);\n const controls = (\n <>\n <button type=\"button\" onClick={() => onFullscreen(true)} className=\"inline-flex items-center gap-1 text-2xs icon-link\" title=\"Full screen\">\n <Maximize2 className=\"w-3 h-3\" />\n Full screen\n </button>\n <button\n type=\"button\"\n onClick={onWatch}\n disabled={watching}\n className=\"inline-flex items-center gap-1 text-2xs icon-link disabled:opacity-60\"\n title={watching ? 'The event stream carries this line' : 'Add this line to the event stream'}\n >\n <Radio className=\"w-3 h-3\" />\n {watching ? 'Watching' : 'Watch on the event stream'}\n </button>\n </>\n );\n return (\n <section aria-label=\"Wire tape\" className={TAPE_BOX_CLASS}>\n <WireTape {...tape} controls={controls} listRef={listRef} />\n <FullscreenOverlay open={fullscreen} onClose={() => onFullscreen(false)} sourceRef={listRef}>\n <div className=\"sticky top-0 float-right z-10\">\n <button\n type=\"button\"\n onClick={() => onFullscreen(false)}\n className=\"p-2 rounded text-text-tertiary hover:text-text-primary hover:bg-surface-raised transition-colors duration-150 bg-surface-sunken/80 backdrop-blur-sm\"\n title=\"Close (Esc)\"\n >\n <Minimize2 className=\"w-5 h-5\" />\n </button>\n </div>\n {fullscreen && <WireTape {...tape} listClassName=\"min-h-[60vh]\" />}\n </FullscreenOverlay>\n </section>\n );\n}\n","import { Link } from 'react-router-dom';\nimport { X } from 'lucide-react';\nimport type { WireEvent } from '../../api/machines';\nimport { PanelField } from '../../components/common/layout/SlidePanel';\nimport { formatDateTime } from '../../lib/format';\nimport { describeAction, formatJson, rowPath, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\nexport const WIRE_PANEL_KEY = 'wire';\n\n/**\n * One wire event in full: the envelope, the payload when the server sends it,\n * the violations, and each action with a link to its row.\n */\nexport function WireDetailPanel({ event, onClose }: { event: WireEvent; onClose: () => void }) {\n const actions = visibleActions(event.actions);\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">\n {event.kind}{event.event ? <span className=\"normal-case font-mono\"> · {event.event}</span> : null}\n </p>\n <p className=\"text-sm text-text-primary mt-0.5\">{event.summary || event.topic}</p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4 space-y-5\">\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <PanelField label=\"At\">{formatDateTime(event.at)}</PanelField>\n <PanelField label=\"Direction\">{event.direction}</PanelField>\n <PanelField label=\"Machine\"><span className=\"font-mono\">{event.machineId ?? '—'}</span></PanelField>\n <PanelField label=\"Address\"><span className=\"font-mono\">{event.address ?? '—'}</span></PanelField>\n <PanelField label=\"Channel\"><span className=\"font-mono\">{event.channel}</span></PanelField>\n <PanelField label=\"Retained\">{event.retained ? 'yes' : 'no'}</PanelField>\n <div className=\"col-span-2\">\n <PanelField label=\"Topic\"><span className=\"font-mono break-all\">{event.topic}</span></PanelField>\n </div>\n {event.id && (\n <div className=\"col-span-2\">\n <PanelField label=\"Message id\"><span className=\"font-mono break-all\">{event.id}</span></PanelField>\n </div>\n )}\n </dl>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">\n Violations{event.violations.length ? ` · ${event.violations.length}` : ''}\n </p>\n {event.violations.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The message matched the contract.</p>\n ) : (\n <ul className=\"space-y-1\">\n {event.violations.map((v, i) => (\n <li key={i} className=\"text-xs text-status-warning\">{v}</li>\n ))}\n </ul>\n )}\n </section>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">Actions</p>\n {actions.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The gateway took no action.</p>\n ) : (\n <ul className=\"space-y-1.5\">\n {actions.map((a, i) => (\n <li key={`${a.verb}-${i}`} className=\"text-xs\">\n <span className={WIRE_VERB_TONE[a.verb]}>{describeAction(a)}</span>\n {a.rowId && (\n <>\n {' '}\n <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">{a.rowId}</Link>\n </>\n )}\n {a.detail && <span className=\"block text-2xs text-text-tertiary\">{a.detail}</span>}\n </li>\n ))}\n </ul>\n )}\n </section>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">Payload</p>\n {event.payload === undefined ? (\n <p className=\"text-2xs text-text-quaternary\">Builders see the payload here.</p>\n ) : (\n <pre className=\"text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(event.payload)}\n </pre>\n )}\n </section>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n machineLineQueryKey,\n machineWirePattern,\n useLine,\n type LineSummaryMachine,\n type WireEvent,\n} from '../../api/machines';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useEventSubscriptions } from '../../hooks/useEventContext';\nimport { useThrottledInvalidation } from '../../hooks/useEventHooks';\nimport { useEventFeedPatterns } from '../../hooks/useEventFeedPatterns';\nimport { useShellPanel } from '../../hooks/useShellPanel';\nimport { useWireTape } from '../../hooks/useWireTape';\nimport { escalationPattern } from '../../lib/events/subjects';\nimport { formatDateTime } from '../../lib/format';\nimport {\n MACHINE_VIEWS,\n autoMachineView,\n machineViewStorageKey,\n readStored,\n writeStored,\n type MachineViewMode,\n} from './line-view-prefs';\nimport { MachinePanel, MACHINE_PANEL_KEY, MACHINE_PANEL_WIDTH } from './MachinePanel';\nimport type { StripMachine } from './MachineStrip';\nimport { MachineViews } from './MachineViews';\nimport { TapeSection } from './TapeSection';\nimport { WireDetailPanel, WIRE_PANEL_KEY } from './WireDetailPanel';\n\nconst WIRE_PANEL_WIDTH = 420;\n/** The machines take three quarters of the page below the header, the wire the last quarter. */\nconst MACHINES_REGION_CLASS = 'flex-[3] min-h-0 flex flex-col mb-4';\nconst TAPE_REGION_CLASS = 'flex-[1] min-h-[14rem] flex flex-col';\n\n/** The tape's size, remembered per device. */\n/** The machines view: the count picks it, an override remembered per line wins. */\nfunction useMachineView(siteId: string, lineId: string, count: number): [MachineViewMode, (view: MachineViewMode) => void] {\n const key = machineViewStorageKey(siteId, lineId);\n const [override, setOverride] = useState<MachineViewMode | null>(() => readStored(key, MACHINE_VIEWS));\n useEffect(() => {\n setOverride(readStored(key, MACHINE_VIEWS));\n }, [key]);\n const choose = useCallback((view: MachineViewMode) => {\n setOverride(view);\n writeStored(key, view);\n }, [key]);\n return [override ?? autoMachineView(count), choose];\n}\n\n/**\n * Line state refreshes through the LIST tier on the line's own wire events\n * and on escalation events in the roles its machines own.\n */\nfunction useLineRefresh(siteId: string, lineId: string, roles: string[]) {\n const invalidate = useThrottledInvalidation('LIST');\n const patterns = useMemo(\n () => [machineWirePattern(siteId, lineId), ...roles.map((role) => escalationPattern({ role }))],\n [siteId, lineId, roles],\n );\n useEventSubscriptions(patterns, () => {\n invalidate([machineLineQueryKey(siteId, lineId)]);\n });\n}\n\n/** One line: the machines region, the tape section, the machine and wire panels. */\nexport function LinePage() {\n const { siteId = '', lineId = '' } = useParams<{ siteId: string; lineId: string }>();\n const { isOps, isBuilder } = useAccess();\n const canAct = isOps || isBuilder;\n const { data: line, isLoading, error } = useLine(siteId, lineId);\n const { setPanel, closePanel, ownerKey } = useShellPanel();\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [fullscreen, setFullscreen] = useState(false);\n const [attentionOnly, setAttentionOnly] = useState(false);\n const { userPatterns, addPattern } = useEventFeedPatterns();\n\n const summary = line?.summary ?? null;\n // The summary is line order; the view, when leading, enriches each tile.\n const machines = useMemo<StripMachine[]>(() => {\n const views = new Map((line?.machines ?? []).map((m) => [m.machineId, m]));\n const declared: LineSummaryMachine[] = summary?.machines\n ?? (line?.machines ?? []).map((m) => ({\n machineId: m.machineId, process: m.process, role: m.role, address: m.address, addressing: 'declared' as const,\n }));\n return declared.map((s) => ({ summary: s, view: views.get(s.machineId) }));\n }, [summary, line]);\n const roles = useMemo(() => [...new Set(machines.map((m) => m.summary.role))].sort(), [machines]);\n\n useLineRefresh(siteId, lineId, roles);\n const tape = useWireTape(siteId, lineId);\n const [machineView, setMachineView] = useMachineView(siteId, lineId, machines.length);\n const wirePattern = machineWirePattern(siteId, lineId);\n const watching = userPatterns.includes(wirePattern);\n\n const selected = machines.find((m) => m.summary.machineId === selectedId) ?? null;\n // One focus: the chosen machine opens its panel and the tape follows it.\n const selectMachine = useCallback((machineId: string) => {\n setSelectedId(machineId);\n tape.setFilter({ machine: machineId });\n }, [tape.setFilter]);\n const closeMachine = useCallback(() => {\n setSelectedId(null);\n closePanel(MACHINE_PANEL_KEY);\n }, [closePanel]);\n\n // The panel re-renders with every refresh of the line while it stays selected.\n useEffect(() => {\n if (!selected) return;\n setPanel(\n <MachinePanel\n siteId={siteId}\n lineId={lineId}\n summary={selected.summary}\n view={selected.view}\n canAct={canAct}\n onClose={closeMachine}\n />,\n { key: MACHINE_PANEL_KEY, width: MACHINE_PANEL_WIDTH },\n );\n }, [selected, siteId, lineId, canAct, closeMachine, setPanel]);\n\n // Another claimant taking the slot (a wire row, a timeline) clears the\n // selection. Ownership is tracked, since the slot changes hands one render\n // after the selection is made.\n const ownedRef = useRef(false);\n useEffect(() => {\n if (ownerKey === MACHINE_PANEL_KEY) {\n ownedRef.current = true;\n return;\n }\n if (ownedRef.current) {\n ownedRef.current = false;\n setSelectedId(null);\n }\n }, [ownerKey]);\n\n const openWire = useCallback((event: WireEvent) => {\n setPanel(\n <WireDetailPanel event={event} onClose={() => closePanel(WIRE_PANEL_KEY)} />,\n { key: WIRE_PANEL_KEY, width: WIRE_PANEL_WIDTH },\n );\n }, [setPanel, closePanel]);\n\n const standingBy = !!line && !line.leading;\n\n return (\n <div className=\"flex flex-col flex-1 min-h-0\">\n <PageHeader\n title={<span className=\"font-mono\">{siteId} · {lineId}</span>}\n actions={\n line?.leading && line.takenAt ? (\n <span className=\"text-2xs text-text-quaternary\">leading since {formatDateTime(line.takenAt)}</span>\n ) : null\n }\n />\n\n {isLoading && <p className=\"text-2xs text-text-tertiary italic mb-4\">Loading the line…</p>}\n {error && <p className=\"text-2xs text-status-error mb-4\">{(error as Error).message}</p>}\n {standingBy && (\n <p className=\"text-xs text-text-secondary mb-4\" data-testid=\"standing-by\">\n Standing by. Another replica leads this line; the tape stays live from the leader.\n </p>\n )}\n {line && line.contested.length > 0 && (\n <p className=\"text-2xs text-status-warning mb-4\">\n Contested: {line.contested.map((c) => `${c.address} at ${c.station}`).join(', ')}\n </p>\n )}\n\n <div className={MACHINES_REGION_CLASS}>\n <MachineViews\n machines={machines}\n selectedId={selectedId}\n onSelect={selectMachine}\n view={machineView}\n onView={setMachineView}\n attentionOnly={attentionOnly}\n onAttentionOnly={setAttentionOnly}\n />\n </div>\n\n <div className={TAPE_REGION_CLASS}>\n <TapeSection\n events={tape.events}\n total={tape.total}\n paused={tape.paused}\n heldCount={tape.heldCount}\n filters={tape.filters}\n machines={tape.machines}\n channels={tape.channels}\n setFilter={tape.setFilter}\n togglePause={tape.togglePause}\n clear={tape.clear}\n onOpen={openWire}\n fullscreen={fullscreen}\n onFullscreen={setFullscreen}\n watching={watching}\n onWatch={() => addPattern(wirePattern)}\n />\n </div>\n </div>\n );\n}\n"],"names":["WIRE_TAPE_CAPACITY","EMPTY_FILTERS","initialTapeState","cap","events","wireTapeReducer","state","action","matchesFilters","event","filters","applyFilters","KINDS","WIRE_KINDS","toWireEvent","raw","envelope","type","WIRE_EVENT_TYPE","e","kind","at","v","distinct","values","useWireTape","siteId","lineId","dispatch","useReducer","useEffect","useEventSubscription","machineWirePattern","visible","useMemo","machines","channels","setFilter","useCallback","patch","togglePause","clear","MACHINE_VIEWS","MACHINE_VIEW_LABEL","TILES_MAX","machineViewStorageKey","autoMachineView","count","readStored","key","allowed","value","writeStored","needsAttention","view","WIRE_VERB_LABEL","WIRE_VERB_TONE","describeAction","label","visibleActions","actions","a","rowPath","rowId","formatClock","iso","date","zone","getDisplayTimeZone","PRESENCE_DOT","PRESENCE_LABEL","presenceOf","formatJson","CommandOutcomeBody","outcome","jsxs","jsx","Link","ARG_HELPERS","mergeArgKey","text","current","parsed","parseArgs","CommandForm","machine","op","setOp","useState","args","setArgs","busy","setBusy","setOutcome","ops","commandOpsFor","submit","request","receipt","sendCommand","err","o","t","SnapshotButton","machineId","ask","SNAPSHOT_OP","RETAINED_CHOICES","parsePayload","trimmed","InspectOutcomeBody","Fragment","i","InspectForm","topic","setTopic","payload","setPayload","retained","setRetained","choice","c","result","inspectMessage","MACHINE_PANEL_KEY","MACHINE_PANEL_WIDTH","TIMELINE_PANEL_KEY","Section","title","children","RowLink","MachinePanel","summary","canAct","onClose","presence","shell","useShellPanelOptional","jobsOpen","setJobsOpen","openTimeline","facetKey","EntityTimelinePanel","alarms","held","jobs","X","PanelField","formatDateTime","ChevronRight","u","MACHINE_FACETS","ROWS_BOX_CLASS","matches","needle","MachineRows","selectedId","onSelect","query","setQuery","shown","m","selected","address","MachineStrip","VIEW_ICON","LayoutGrid","List","RADIO_CLASS","RADIO_ON","RADIO_OFF","MachineViews","props","onView","attentionOnly","onAttentionOnly","attention","View","mode","Icon","WireRow","onOpen","Direction","ArrowDownLeft","ArrowUpRight","DEFAULT_LIST_CLASS","DIRECTIONS","activeFilterCount","WireTape","total","paused","heldCount","controls","listClassName","listRef","FilterBar","Play","Pause","Eraser","FilterSelect","k","TAPE_BOX_CLASS","TapeSection","fullscreen","onFullscreen","watching","onWatch","tape","useRef","Maximize2","Radio","FullscreenOverlay","Minimize2","WIRE_PANEL_KEY","WireDetailPanel","WIRE_PANEL_WIDTH","MACHINES_REGION_CLASS","TAPE_REGION_CLASS","useMachineView","override","setOverride","choose","useLineRefresh","roles","invalidate","useThrottledInvalidation","patterns","role","escalationPattern","useEventSubscriptions","machineLineQueryKey","LinePage","useParams","isOps","isBuilder","useAccess","line","isLoading","error","useLine","setPanel","closePanel","ownerKey","useShellPanel","setSelectedId","setFullscreen","setAttentionOnly","userPatterns","addPattern","useEventFeedPatterns","views","s","machineView","setMachineView","wirePattern","selectMachine","closeMachine","ownedRef","openWire","standingBy","PageHeader"],"mappings":"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"}
1
+ {"version":3,"file":"LinePage-DPe-vP3-.js","sources":["../../src/hooks/useWireTape.ts","../../src/pages/lines/line-view-prefs.ts","../../src/pages/lines/wire-display.ts","../../src/pages/lines/CommandForm.tsx","../../src/pages/lines/InspectForm.tsx","../../src/pages/lines/MachinePanel.tsx","../../src/pages/lines/MachineRows.tsx","../../src/pages/lines/MachineStrip.tsx","../../src/pages/lines/MachineViews.tsx","../../src/pages/lines/WireRow.tsx","../../src/pages/lines/WireTape.tsx","../../src/pages/lines/TapeSection.tsx","../../src/pages/lines/WireDetailPanel.tsx","../../src/pages/lines/LinePage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useReducer } from 'react';\nimport { useEventSubscription } from './useEventContext';\nimport {\n machineWirePattern,\n WIRE_EVENT_TYPE,\n WIRE_KINDS,\n type WireDirection,\n type WireEvent,\n type WireKind,\n} from '../api/machines';\n\n/** The tape keeps this many events, newest first; older ones fall off the end. */\nexport const WIRE_TAPE_CAPACITY = 2000;\n\nexport interface WireTapeFilters {\n machine: string | null;\n channel: string | null;\n direction: WireDirection | null;\n kind: WireKind | null;\n violationsOnly: boolean;\n}\n\nexport interface WireTapeState {\n /** Newest first. */\n events: WireEvent[];\n /** Events that arrived while paused, newest first; they join the tape on resume. */\n held: WireEvent[];\n paused: boolean;\n filters: WireTapeFilters;\n}\n\nexport type WireTapeAction =\n | { type: 'ingest'; event: WireEvent }\n | { type: 'pause' }\n | { type: 'resume' }\n | { type: 'clear' }\n | { type: 'filter'; patch: Partial<WireTapeFilters> };\n\nexport const EMPTY_FILTERS: WireTapeFilters = {\n machine: null,\n channel: null,\n direction: null,\n kind: null,\n violationsOnly: false,\n};\n\nexport function initialTapeState(): WireTapeState {\n return { events: [], held: [], paused: false, filters: EMPTY_FILTERS };\n}\n\nfunction cap(events: WireEvent[]): WireEvent[] {\n return events.length > WIRE_TAPE_CAPACITY ? events.slice(0, WIRE_TAPE_CAPACITY) : events;\n}\n\nexport function wireTapeReducer(state: WireTapeState, action: WireTapeAction): WireTapeState {\n switch (action.type) {\n case 'ingest':\n return state.paused\n ? { ...state, held: cap([action.event, ...state.held]) }\n : { ...state, events: cap([action.event, ...state.events]) };\n case 'pause':\n return state.paused ? state : { ...state, paused: true };\n case 'resume':\n return { ...state, paused: false, held: [], events: cap([...state.held, ...state.events]) };\n case 'clear':\n return { ...state, events: [], held: [] };\n case 'filter':\n return { ...state, filters: { ...state.filters, ...action.patch } };\n }\n}\n\nexport function matchesFilters(event: WireEvent, filters: WireTapeFilters): boolean {\n if (filters.machine && event.machineId !== filters.machine) return false;\n if (filters.channel && event.channel !== filters.channel) return false;\n if (filters.direction && event.direction !== filters.direction) return false;\n if (filters.kind && event.kind !== filters.kind) return false;\n if (filters.violationsOnly && event.violations.length === 0) return false;\n return true;\n}\n\nexport function applyFilters(events: WireEvent[], filters: WireTapeFilters): WireEvent[] {\n return events.filter((event) => matchesFilters(event, filters));\n}\n\nconst KINDS = new Set<string>(WIRE_KINDS);\n\n/**\n * The transport hands over the published event envelope: its routing type\n * carries the site, line, machine and direction tokens after `machine.wire`,\n * and the wire event itself rides in `data`. A bare wire event is read as is.\n */\nexport function toWireEvent(raw: unknown): WireEvent | null {\n if (!raw || typeof raw !== 'object') return null;\n const envelope = raw as Record<string, unknown>;\n const type = envelope.type;\n if (typeof type !== 'string' || (type !== WIRE_EVENT_TYPE && !type.startsWith(`${WIRE_EVENT_TYPE}.`))) {\n return null;\n }\n const e = envelope.data && typeof envelope.data === 'object' ? (envelope.data as Record<string, unknown>) : envelope;\n if (typeof e.siteId !== 'string' || typeof e.lineId !== 'string') return null;\n if (e.direction !== 'in' && e.direction !== 'out') return null;\n const kind = typeof e.kind === 'string' && KINDS.has(e.kind) ? (e.kind as WireKind) : 'unknown';\n const at = [e.at, envelope.timestamp].find((v): v is string => typeof v === 'string') ?? new Date().toISOString();\n return {\n type: WIRE_EVENT_TYPE,\n siteId: e.siteId,\n lineId: e.lineId,\n machineId: typeof e.machineId === 'string' ? e.machineId : null,\n address: typeof e.address === 'string' ? e.address : null,\n direction: e.direction,\n channel: typeof e.channel === 'string' ? e.channel : '',\n topic: typeof e.topic === 'string' ? e.topic : '',\n id: typeof e.id === 'string' ? e.id : null,\n at,\n retained: e.retained === true,\n kind,\n event: typeof e.event === 'string' ? e.event : null,\n summary: typeof e.summary === 'string' ? e.summary : '',\n violations: Array.isArray(e.violations) ? e.violations.filter((v): v is string => typeof v === 'string') : [],\n actions: Array.isArray(e.actions) ? (e.actions as WireEvent['actions']) : [],\n ...('payload' in e ? { payload: e.payload } : {}),\n };\n}\n\nfunction distinct(values: (string | null)[]): string[] {\n return [...new Set(values.filter((v): v is string => !!v))].sort();\n}\n\n/**\n * The live tape of one line's wire events: a bounded ring buffer fed by the\n * event transport, with filters and a pause that holds new arrivals aside.\n */\nexport function useWireTape(siteId: string, lineId: string) {\n const [state, dispatch] = useReducer(wireTapeReducer, undefined, initialTapeState);\n\n useEffect(() => {\n dispatch({ type: 'clear' });\n }, [siteId, lineId]);\n\n useEventSubscription(machineWirePattern(siteId, lineId), (raw) => {\n const event = toWireEvent(raw);\n if (event) dispatch({ type: 'ingest', event });\n });\n\n const visible = useMemo(() => applyFilters(state.events, state.filters), [state.events, state.filters]);\n const machines = useMemo(() => distinct(state.events.map((e) => e.machineId)), [state.events]);\n const channels = useMemo(() => distinct(state.events.map((e) => e.channel)), [state.events]);\n\n const setFilter = useCallback((patch: Partial<WireTapeFilters>) => dispatch({ type: 'filter', patch }), []);\n const togglePause = useCallback(() => dispatch({ type: state.paused ? 'resume' : 'pause' }), [state.paused]);\n const clear = useCallback(() => dispatch({ type: 'clear' }), []);\n\n return {\n events: visible,\n total: state.events.length,\n heldCount: state.held.length,\n paused: state.paused,\n filters: state.filters,\n machines,\n channels,\n setFilter,\n togglePause,\n clear,\n };\n}\n","import type { MachineView } from '../../api/machines';\n\n/** How the machines region lists its machines. */\nexport const MACHINE_VIEWS = ['tiles', 'rows'] as const;\nexport type MachineViewMode = (typeof MACHINE_VIEWS)[number];\nexport const MACHINE_VIEW_LABEL: Record<MachineViewMode, string> = { tiles: 'Tiles', rows: 'Rows' };\n\n/** Tiles read well to a dozen machines; beyond that, rows. */\nexport const TILES_MAX = 12;\n\nexport function machineViewStorageKey(siteId: string, lineId: string): string {\n return `lt:lines:${siteId}/${lineId}:machines-view`;\n}\n\nexport function autoMachineView(count: number): MachineViewMode {\n return count <= TILES_MAX ? 'tiles' : 'rows';\n}\n\nexport function readStored<T extends string>(key: string, allowed: readonly T[]): T | null {\n try {\n const value = localStorage.getItem(key);\n return value && (allowed as readonly string[]).includes(value) ? (value as T) : null;\n } catch {\n return null;\n }\n}\n\nexport function writeStored(key: string, value: string | null): void {\n try {\n if (value === null) localStorage.removeItem(key);\n else localStorage.setItem(key, value);\n } catch {\n // storage may be unavailable; the choice then lasts the session\n }\n}\n\n/** A machine that needs a person: offline, quiet, an active alarm, or an open row. */\nexport function needsAttention(view: MachineView | undefined): boolean {\n if (!view) return false;\n if (view.online === false) return true;\n if (view.rows.offlineRowId || view.rows.quietRowId) return true;\n if (view.alarms.length > 0) return true;\n return view.rows.handoff + view.rows.command + view.rows.alarm > 0;\n}\n","import type { MachineView, WireAction, WireVerb } from '../../api/machines';\nimport { getDisplayTimeZone } from '../../lib/display-zone';\n\n/** Past-tense wording for each action the gateway took on a message. */\nexport const WIRE_VERB_LABEL: Record<WireVerb, string> = {\n claim: 'claimed',\n accumulate: 'accumulated',\n resolve: 'resolved',\n 'create-row': 'row created',\n refuse: 'refused',\n hold: 'held',\n unmatched: 'unmatched',\n unreadable: 'unreadable',\n ack: 'acknowledged',\n none: '',\n};\n\n/** Text-safe status tone per verb. */\nexport const WIRE_VERB_TONE: Record<WireVerb, string> = {\n claim: 'text-text-secondary',\n accumulate: 'text-text-secondary',\n resolve: 'text-status-success',\n 'create-row': 'text-text-secondary',\n refuse: 'text-status-error',\n hold: 'text-status-warning',\n unmatched: 'text-status-warning',\n unreadable: 'text-status-error',\n ack: 'text-text-secondary',\n none: 'text-text-quaternary',\n};\n\n/** \"accumulated arrived:U1\": the verb plus the item it touched. */\nexport function describeAction(action: WireAction): string {\n const label = WIRE_VERB_LABEL[action.verb] ?? action.verb;\n return action.itemKey ? `${label} ${action.itemKey}` : label;\n}\n\n/** Actions worth a word; `none` stays silent. */\nexport function visibleActions(actions: WireAction[]): WireAction[] {\n return actions.filter((a) => a.verb !== 'none');\n}\n\n/** The escalation detail route for a row the gateway named. */\nexport function rowPath(rowId: string): string {\n return `/escalations/detail/${encodeURIComponent(rowId)}`;\n}\n\n/** \"13:02:07\" in the display zone, for the tape's time column. */\nexport function formatClock(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n const zone = getDisplayTimeZone();\n return new Intl.DateTimeFormat('en-GB', {\n ...(zone ? { timeZone: zone } : {}),\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n }).format(date);\n}\n\nexport type Presence = 'online' | 'quiet' | 'offline' | 'unknown';\n\n/** Ring color per presence, through the graphic status tokens. */\nexport const PRESENCE_DOT: Record<Presence, string> = {\n online: 'bg-status-success-graphic',\n quiet: 'bg-status-pending-graphic',\n offline: 'bg-status-error',\n unknown: 'bg-text-quaternary',\n};\n\nexport const PRESENCE_LABEL: Record<Presence, string> = {\n online: 'online',\n quiet: 'quiet',\n offline: 'offline',\n unknown: 'unknown',\n};\n\n/** Quiet is online with an open quiet row; unknown is a machine the leader has yet to hear. */\nexport function presenceOf(view: MachineView | undefined): Presence {\n if (!view || view.online === null) return 'unknown';\n if (!view.online) return 'offline';\n return view.rows.quietRowId ? 'quiet' : 'online';\n}\n\n/** Pretty JSON for panels; strings stay as they are. */\nexport function formatJson(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n","import { useState, type FormEvent } from 'react';\nimport { Link } from 'react-router-dom';\nimport { commandOpsFor, sendCommand, SNAPSHOT_OP, type LineSummaryMachine } from '../../api/machines';\nimport { rowPath } from './wire-display';\n\nexport type CommandOutcome =\n | { request: string; ok: true; rowId: string }\n | { request: string; ok: false; message: string };\n\n/** The scan idiom: the request in mono, the verdict in its tone. */\nexport function CommandOutcomeBody({ outcome }: { outcome: CommandOutcome }) {\n return (\n <div className=\"min-w-0\" data-testid=\"command-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n {outcome.ok ? (\n <div className=\"text-xs font-medium text-status-success\">\n Row created{' '}\n <Link to={rowPath(outcome.rowId)} className=\"font-mono text-accent hover:underline\">{outcome.rowId}</Link>\n </div>\n ) : (\n <div className=\"text-xs font-medium text-status-error\">{outcome.message}</div>\n )}\n </div>\n );\n}\n\nconst ARG_HELPERS = ['jobId', 'recipe'] as const;\n\nfunction mergeArgKey(text: string, key: string): string {\n let current: Record<string, unknown> = {};\n try {\n const parsed = text.trim() ? JSON.parse(text) : {};\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) current = parsed;\n } catch {\n current = {};\n }\n if (!(key in current)) current[key] = '';\n return JSON.stringify(current, null, 2);\n}\n\nfunction parseArgs(text: string): Record<string, unknown> {\n if (!text.trim()) return {};\n const parsed = JSON.parse(text);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('Args must be a JSON object.');\n }\n return parsed;\n}\n\n/**\n * Send one command to a machine: an op from the line's vocabulary and a\n * small JSON args object. The server creates the row; the role decides.\n */\nexport function CommandForm({\n siteId,\n lineId,\n machine,\n}: {\n siteId: string;\n lineId: string;\n machine: LineSummaryMachine;\n}) {\n const [op, setOp] = useState('');\n const [args, setArgs] = useState('');\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<CommandOutcome | null>(null);\n const ops = commandOpsFor(machine);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n if (!op) return;\n const request = `${op} ${args.trim() || '{}'}`;\n setBusy(true);\n try {\n const parsed = parseArgs(args);\n const receipt = await sendCommand(siteId, lineId, machine.machineId, { op, args: parsed });\n setOutcome({ request, ok: true, rowId: receipt.rowId });\n } catch (err) {\n setOutcome({ request, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <form onSubmit={submit} className=\"space-y-3\" aria-label=\"Send command\">\n <div>\n <label htmlFor=\"command-op\" className=\"block text-2xs font-medium text-text-secondary\">\n Op <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Pick the operation the machine runs.</p>\n <select\n id=\"command-op\"\n className=\"select text-xs font-mono\"\n value={op}\n required\n onChange={(e) => setOp(e.target.value)}\n >\n <option value=\"\" disabled>Choose…</option>\n {ops.map((o) => <option key={o} value={o}>{o}</option>)}\n </select>\n </div>\n <div>\n <label htmlFor=\"command-args\" className=\"block text-2xs font-medium text-text-secondary\">Args</label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Write a JSON object, or add a key from the helpers.</p>\n <textarea\n id=\"command-args\"\n className=\"textarea text-2xs font-mono min-h-[4.5rem]\"\n value={args}\n placeholder=\"{}\"\n onChange={(e) => setArgs(e.target.value)}\n />\n <div className=\"flex items-center gap-2 mt-1\">\n {ARG_HELPERS.map((key) => (\n <button\n key={key}\n type=\"button\"\n onClick={() => setArgs((t) => mergeArgKey(t, key))}\n className=\"text-2xs font-mono icon-link\"\n >\n + {key}\n </button>\n ))}\n </div>\n </div>\n <button type=\"submit\" disabled={busy || !op} className=\"btn-primary text-xs py-1.5 px-4\">\n Send\n </button>\n {outcome && <CommandOutcomeBody outcome={outcome} />}\n </form>\n );\n}\n\n/** One click asks the machine for a fresh snapshot, as a command row. */\nexport function SnapshotButton({\n siteId,\n lineId,\n machineId,\n}: {\n siteId: string;\n lineId: string;\n machineId: string;\n}) {\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<CommandOutcome | null>(null);\n\n const ask = async () => {\n setBusy(true);\n try {\n const receipt = await sendCommand(siteId, lineId, machineId, { op: SNAPSHOT_OP, args: {} });\n setOutcome({ request: `${SNAPSHOT_OP} {}`, ok: true, rowId: receipt.rowId });\n } catch (err) {\n setOutcome({ request: `${SNAPSHOT_OP} {}`, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"space-y-2\">\n <button type=\"button\" onClick={ask} disabled={busy} className=\"btn-secondary text-xs py-1.5 px-4\">\n Ask for a snapshot\n </button>\n {outcome && <CommandOutcomeBody outcome={outcome} />}\n </div>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport { Link } from 'react-router-dom';\nimport { inspectMessage, type InspectResult } from '../../api/machines';\nimport { describeAction, formatJson, rowPath, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\nconst RETAINED_CHOICES = [\n { value: 'live', label: 'Live', retained: false },\n { value: 'retained', label: 'Retained', retained: true },\n] as const;\n\ntype Retained = (typeof RETAINED_CHOICES)[number]['value'];\n\n/** A payload that parses as JSON goes as JSON; anything else goes as the text typed. */\nexport function parsePayload(text: string): unknown {\n const trimmed = text.trim();\n if (!trimmed) return '';\n try {\n return JSON.parse(trimmed);\n } catch {\n return text;\n }\n}\n\ntype InspectOutcome =\n | { request: string; ok: true; result: InspectResult }\n | { request: string; ok: false; message: string };\n\n/** The dry-run verdict: summary, violations in the warning tone, planned actions with row links. */\nexport function InspectOutcomeBody({ outcome }: { outcome: InspectOutcome }) {\n return (\n <div className=\"min-w-0 space-y-2\" data-testid=\"inspect-outcome\">\n <div className=\"text-xs font-mono text-text-secondary truncate\" title={outcome.request}>{outcome.request}</div>\n {!outcome.ok ? (\n <div className=\"text-xs font-medium text-status-error\">{outcome.message}</div>\n ) : (\n <>\n <div className={`text-xs font-medium ${outcome.result.violations.length ? 'text-status-warning' : 'text-status-success'}`}>\n {outcome.result.kind ?? 'message'}\n {outcome.result.event ? ` · ${outcome.result.event}` : ''}\n {outcome.result.violations.length\n ? ` · ${outcome.result.violations.length} violation${outcome.result.violations.length === 1 ? '' : 's'}`\n : ' · matches the contract'}\n </div>\n {outcome.result.summary && <div className=\"text-2xs text-text-secondary\">{outcome.result.summary}</div>}\n {outcome.result.violations.length > 0 && (\n <ul className=\"space-y-0.5\" aria-label=\"Violations\">\n {outcome.result.violations.map((v, i) => (\n <li key={i} className=\"text-2xs text-status-warning\">{v}</li>\n ))}\n </ul>\n )}\n <div>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1\">Planned actions</p>\n {visibleActions(outcome.result.actions).length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The gateway would take no action.</p>\n ) : (\n <ul className=\"space-y-0.5\" aria-label=\"Planned actions\">\n {visibleActions(outcome.result.actions).map((a, i) => (\n <li key={`${a.verb}-${i}`} className=\"text-2xs\">\n <span className={WIRE_VERB_TONE[a.verb]}>{describeAction(a)}</span>\n {a.rowId && (\n <>\n {' '}\n <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">{a.rowId}</Link>\n </>\n )}\n {a.detail && <span className=\"text-text-tertiary\"> · {a.detail}</span>}\n </li>\n ))}\n </ul>\n )}\n </div>\n {outcome.result.inspections !== undefined && (\n <pre className=\"text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(outcome.result.inspections)}\n </pre>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * Inspect a message as a dry run: the leader decodes it and plans what it\n * would do, without applying anything.\n */\nexport function InspectForm({ siteId, lineId }: { siteId: string; lineId: string }) {\n const [topic, setTopic] = useState('');\n const [payload, setPayload] = useState('');\n const [retained, setRetained] = useState<Retained | ''>('');\n const [busy, setBusy] = useState(false);\n const [outcome, setOutcome] = useState<InspectOutcome | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n const choice = RETAINED_CHOICES.find((c) => c.value === retained);\n if (!topic.trim() || !choice) return;\n const request = `${topic.trim()} ${payload.trim() || '\"\"'}`;\n setBusy(true);\n try {\n const result = await inspectMessage(siteId, lineId, {\n topic: topic.trim(),\n payload: parsePayload(payload),\n retained: choice.retained,\n });\n setOutcome({ request, ok: true, result: { ...result, violations: result.violations ?? [], actions: result.actions ?? [] } });\n } catch (err) {\n setOutcome({ request, ok: false, message: (err as Error).message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <form onSubmit={submit} className=\"space-y-3\" aria-label=\"Inspect a message\">\n <div>\n <label htmlFor=\"inspect-topic\" className=\"block text-2xs font-medium text-text-secondary\">\n Topic <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Enter the topic the message arrives on.</p>\n <input\n id=\"inspect-topic\"\n className=\"input text-2xs font-mono\"\n value={topic}\n required\n onChange={(e) => setTopic(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor=\"inspect-payload\" className=\"block text-2xs font-medium text-text-secondary\">Payload</label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Paste the body; JSON is sent as JSON, anything else as text.</p>\n <textarea\n id=\"inspect-payload\"\n className=\"textarea text-2xs font-mono min-h-[5rem]\"\n value={payload}\n onChange={(e) => setPayload(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor=\"inspect-retained\" className=\"block text-2xs font-medium text-text-secondary\">\n Delivery <span className=\"text-status-error\">*</span>\n </label>\n <p className=\"text-2xs text-text-tertiary mb-1\">Say whether the broker would hand this over as a retained message.</p>\n <select\n id=\"inspect-retained\"\n className=\"select text-xs\"\n value={retained}\n required\n onChange={(e) => setRetained(e.target.value as Retained)}\n >\n <option value=\"\" disabled>Choose…</option>\n {RETAINED_CHOICES.map((c) => <option key={c.value} value={c.value}>{c.label}</option>)}\n </select>\n </div>\n <button type=\"submit\" disabled={busy || !topic.trim() || !retained} className=\"btn-primary text-xs py-1.5 px-4\">\n Inspect\n </button>\n {outcome && <InspectOutcomeBody outcome={outcome} />}\n </form>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { X, ChevronRight } from 'lucide-react';\nimport { MACHINE_FACETS, type LineSummaryMachine, type MachineView } from '../../api/machines';\nimport { PanelField } from '../../components/common/layout/SlidePanel';\nimport { EntityTimelinePanel } from '../../components/escalation/EntityTimelinePanel';\nimport { useShellPanelOptional } from '../../hooks/useShellPanel';\nimport { formatDateTime } from '../../lib/format';\nimport { CommandForm, SnapshotButton } from './CommandForm';\nimport { InspectForm } from './InspectForm';\nimport { formatJson, PRESENCE_DOT, PRESENCE_LABEL, presenceOf, rowPath } from './wire-display';\n\nexport const MACHINE_PANEL_KEY = 'machine';\nexport const MACHINE_PANEL_WIDTH = 440;\nconst TIMELINE_PANEL_KEY = 'entity-timeline';\n\nfunction Section({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">{title}</p>\n {children}\n </section>\n );\n}\n\nfunction RowLink({ rowId, label }: { rowId: string; label: string }) {\n return (\n <li className=\"text-2xs\">\n <span className=\"text-text-secondary\">{label}</span>{' '}\n <Link to={rowPath(rowId)} className=\"font-mono text-accent hover:underline\">{rowId}</Link>\n </li>\n );\n}\n\n/**\n * One machine in the shell's right panel: the last snapshot in brief, its\n * open rows, a way into its timeline, and the tools for those who may act.\n */\nexport function MachinePanel({\n siteId,\n lineId,\n summary,\n view,\n canAct,\n onClose,\n}: {\n siteId: string;\n lineId: string;\n summary: LineSummaryMachine;\n view: MachineView | undefined;\n canAct: boolean;\n onClose: () => void;\n}) {\n const presence = presenceOf(view);\n const shell = useShellPanelOptional();\n const [jobsOpen, setJobsOpen] = useState(false);\n\n // The timeline takes the shell slot; the strip tile reopens this panel.\n const openTimeline = useCallback(\n (facetKey: string) => {\n shell?.setPanel(\n <EntityTimelinePanel facetKey={facetKey} value={summary.machineId} role={summary.role} />,\n { key: TIMELINE_PANEL_KEY, width: 420 },\n );\n },\n [shell, summary.machineId, summary.role],\n );\n\n const alarms = view?.alarms ?? [];\n const held = view?.heldUnits ?? [];\n const jobs = view?.jobs ?? [];\n\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${PRESENCE_DOT[presence]}`} title={PRESENCE_LABEL[presence]} />\n <span className=\"text-sm font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs text-text-quaternary\">{PRESENCE_LABEL[presence]}</span>\n </div>\n <p className=\"text-2xs font-mono text-text-tertiary mt-0.5\">\n {summary.process} · {summary.role}\n </p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4 space-y-5\">\n <Section title=\"Snapshot\">\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <PanelField label=\"Address\">\n <span className=\"font-mono\">{view?.address ?? summary.address ?? '—'}</span>\n <span className=\"text-text-quaternary\"> · {summary.addressing}</span>\n </PanelField>\n <PanelField label=\"Software\"><span className=\"font-mono\">{view?.software ?? '—'}</span></PanelField>\n <PanelField label=\"Since\">{view?.since ? formatDateTime(view.since) : '—'}</PanelField>\n <PanelField label=\"Last seen\">{view?.lastSeen ? formatDateTime(view.lastSeen) : '—'}</PanelField>\n <PanelField label=\"Boot\"><span className=\"font-mono break-all\">{view?.bootId ?? '—'}</span></PanelField>\n <PanelField label=\"Session\"><span className=\"font-mono break-all\">{view?.sessionId ?? '—'}</span></PanelField>\n </dl>\n </Section>\n\n <Section title={`Jobs · ${jobs.length}`}>\n {jobs.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The last snapshot carried no jobs.</p>\n ) : (\n <>\n <button type=\"button\" onClick={() => setJobsOpen((v) => !v)} className=\"inline-flex items-center gap-1 text-2xs icon-link\">\n <ChevronRight className={`w-3 h-3 transition-transform ${jobsOpen ? 'rotate-90' : ''}`} />\n {jobsOpen ? 'Hide' : 'Show'} the jobs as reported\n </button>\n {jobsOpen && (\n <pre className=\"mt-1.5 text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(jobs)}\n </pre>\n )}\n </>\n )}\n </Section>\n\n <Section title={`Alarms · ${alarms.length}`}>\n {alarms.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The machine reports no active alarm.</p>\n ) : (\n <ul className=\"space-y-1\">\n {alarms.map((a) => (\n <li key={a.alarmId} className=\"text-2xs flex items-baseline gap-2\">\n <span className=\"font-mono text-status-warning\">{a.alarmId}</span>\n <span className=\"text-text-tertiary\">{a.level}</span>\n <span className=\"text-text-quaternary ml-auto\">{formatDateTime(a.raisedAt)}</span>\n {a.rowId && <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">row</Link>}\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section title={`Held units · ${held.length}`}>\n {held.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The machine holds no unit.</p>\n ) : (\n <ul className=\"space-y-1\">\n {held.map((u) => (\n <RowLink key={u.unitId} rowId={u.rowId} label={u.carrierId ? `${u.unitId} on ${u.carrierId}` : u.unitId} />\n ))}\n </ul>\n )}\n </Section>\n\n <Section title=\"Open rows\">\n <p className=\"text-2xs font-mono text-text-secondary tabular-nums\">\n handoff {view?.rows.handoff ?? 0} · command {view?.rows.command ?? 0} · alarm {view?.rows.alarm ?? 0}\n </p>\n {(view?.rows.offlineRowId || view?.rows.quietRowId) && (\n <ul className=\"space-y-1 mt-1\">\n {view.rows.offlineRowId && <RowLink rowId={view.rows.offlineRowId} label=\"offline\" />}\n {view.rows.quietRowId && <RowLink rowId={view.rows.quietRowId} label=\"quiet\" />}\n </ul>\n )}\n </Section>\n\n <Section title=\"Over a window\">\n <p className=\"text-2xs text-text-tertiary mb-1.5\">Open the rows that moved work to or from this machine.</p>\n <div className=\"flex items-center gap-3\">\n <button type=\"button\" onClick={() => openTimeline(MACHINE_FACETS.TO)} className=\"text-2xs icon-link font-mono\">\n {MACHINE_FACETS.TO}\n </button>\n <button type=\"button\" onClick={() => openTimeline(MACHINE_FACETS.FROM)} className=\"text-2xs icon-link font-mono\">\n {MACHINE_FACETS.FROM}\n </button>\n </div>\n </Section>\n\n {canAct && (\n <>\n <Section title=\"Ask for a snapshot\">\n <SnapshotButton siteId={siteId} lineId={lineId} machineId={summary.machineId} />\n </Section>\n <Section title=\"Send command\">\n <CommandForm siteId={siteId} lineId={lineId} machine={summary} />\n </Section>\n <Section title=\"Inspect a message\">\n <InspectForm siteId={siteId} lineId={lineId} />\n </Section>\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useMemo, useState } from 'react';\nimport type { StripMachine } from './MachineStrip';\nimport { PRESENCE_DOT, PRESENCE_LABEL, presenceOf } from './wire-display';\n\nconst ROWS_BOX_CLASS = 'flex-1 min-h-0 overflow-y-auto border-t border-surface-border';\n\nfunction matches(machine: StripMachine, needle: string): boolean {\n if (!needle) return true;\n const { summary, view } = machine;\n const hay = [summary.machineId, summary.process, summary.role, view?.address ?? summary.address ?? ''].join(' ').toLowerCase();\n return hay.includes(needle);\n}\n\n/**\n * One dense line per machine in line order, in a list that scrolls within\n * the region. The search narrows the declared list by id, process, role or address.\n */\nexport function MachineRows({\n machines,\n selectedId,\n onSelect,\n}: {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n}) {\n const [query, setQuery] = useState('');\n const needle = query.trim().toLowerCase();\n const shown = useMemo(() => machines.filter((m) => matches(m, needle)), [machines, needle]);\n return (\n <div className=\"flex flex-col h-full min-h-0\">\n <div className=\"flex items-center gap-3 pb-2 shrink-0\">\n <label className=\"sr-only\" htmlFor=\"machine-search\">Find a machine</label>\n <input\n id=\"machine-search\"\n type=\"search\"\n className=\"input text-2xs font-mono py-1 w-full max-w-[16rem]\"\n placeholder=\"id, process, role, address\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <span className=\"text-2xs text-text-quaternary tabular-nums\">{shown.length} of {machines.length}</span>\n </div>\n <ul className={ROWS_BOX_CLASS} aria-label=\"Machines\">\n {shown.map(({ summary, view }) => {\n const presence = presenceOf(view);\n const selected = summary.machineId === selectedId;\n const address = view?.address ?? summary.address;\n const alarms = view?.alarms.length ?? 0;\n return (\n <li key={summary.machineId}>\n <button\n type=\"button\"\n onClick={() => onSelect(summary.machineId)}\n aria-pressed={selected}\n data-presence={presence}\n className={`w-full text-left grid grid-cols-[auto_minmax(6rem,1fr)_minmax(0,2fr)_auto_auto_auto] items-baseline gap-x-3 px-2 py-1 border-l-2 border-b border-surface-border/60 hover:bg-surface-hover transition-colors ${\n selected ? 'border-l-accent' : 'border-l-transparent'\n }`}\n >\n <span className={`w-2 h-2 rounded-full dot-ring self-center ${PRESENCE_DOT[presence]}`} title={PRESENCE_LABEL[presence]} />\n <span className=\"text-2xs font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs font-mono text-text-tertiary truncate\" title={address ?? undefined}>\n {summary.process}\n {address ? <span className=\"text-text-quaternary\"> · {address}</span> : null}\n </span>\n <span className=\"text-2xs text-text-tertiary truncate max-w-[6rem]\" title=\"Software\">{view?.software ?? '—'}</span>\n <span className=\"text-2xs text-text-secondary tabular-nums whitespace-nowrap\" title=\"Units held\">held {view?.heldUnits.length ?? 0}</span>\n <span className=\"text-2xs font-mono text-text-tertiary tabular-nums whitespace-nowrap\">\n h {view?.rows.handoff ?? 0} c {view?.rows.command ?? 0} a {view?.rows.alarm ?? 0}\n {alarms > 0 && <span className=\"text-status-warning ml-2\" title=\"Active alarms\">{alarms} alarm{alarms === 1 ? '' : 's'}</span>}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n {shown.length === 0 && <p className=\"text-2xs text-text-tertiary py-2\">No machine matches.</p>}\n </div>\n );\n}\n","import type { LineSummaryMachine, MachineView } from '../../api/machines';\nimport { PRESENCE_DOT, PRESENCE_LABEL, presenceOf } from './wire-display';\n\nexport interface StripMachine {\n summary: LineSummaryMachine;\n /** Absent while the replica stands by or before the leader has heard the machine. */\n view: MachineView | undefined;\n}\n\n/**\n * One tile per machine in line order: presence ring, identity in mono, the\n * software it runs, what it holds, and its open rows by kind. Click selects.\n * Tiles fill the width in as many columns as fit.\n */\nexport function MachineStrip({\n machines,\n selectedId,\n onSelect,\n}: {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n}) {\n if (machines.length === 0) {\n return <p className=\"text-2xs text-text-tertiary\">The line declares no machines.</p>;\n }\n return (\n <div className=\"grid grid-cols-[repeat(auto-fill,minmax(11rem,1fr))] gap-y-3\" role=\"list\" aria-label=\"Machines\">\n {machines.map(({ summary, view }) => {\n const presence = presenceOf(view);\n const selected = summary.machineId === selectedId;\n const address = view?.address ?? summary.address;\n const alarms = view?.alarms.length ?? 0;\n return (\n <button\n key={summary.machineId}\n type=\"button\"\n role=\"listitem\"\n onClick={() => onSelect(summary.machineId)}\n aria-pressed={selected}\n data-presence={presence}\n className={`text-left min-w-0 pl-3 pr-4 py-1.5 border-l-2 transition-colors hover:bg-surface-hover ${\n selected ? 'border-accent' : 'border-surface-border'\n }`}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <span\n className={`w-2.5 h-2.5 rounded-full dot-ring shrink-0 ${PRESENCE_DOT[presence]}`}\n title={PRESENCE_LABEL[presence]}\n />\n <span className=\"text-xs font-mono text-text-primary truncate\">{summary.machineId}</span>\n <span className=\"text-2xs text-text-quaternary ml-auto shrink-0\">{PRESENCE_LABEL[presence]}</span>\n </div>\n <div className=\"text-2xs font-mono text-text-tertiary truncate mt-0.5\" title={address ?? undefined}>\n {summary.process}\n {address ? <span className=\"text-text-quaternary\"> · {address}</span> : null}\n </div>\n <div className=\"flex items-center gap-3 text-2xs mt-1 tabular-nums\">\n <span className=\"text-text-tertiary truncate\" title=\"Software\">{view?.software ?? '—'}</span>\n <span className=\"text-text-secondary shrink-0\" title=\"Units held\">\n held {view?.heldUnits.length ?? 0}\n </span>\n </div>\n <div className=\"flex items-center gap-3 text-2xs font-mono mt-0.5 tabular-nums\">\n <span className=\"text-text-tertiary\" title=\"Open handoff rows\">h {view?.rows.handoff ?? 0}</span>\n <span className=\"text-text-tertiary\" title=\"Open command rows\">c {view?.rows.command ?? 0}</span>\n <span className=\"text-text-tertiary\" title=\"Open alarm rows\">a {view?.rows.alarm ?? 0}</span>\n {alarms > 0 && (\n <span className=\"text-status-warning ml-auto\" title=\"Active alarms\">\n {alarms} alarm{alarms === 1 ? '' : 's'}\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { LayoutGrid, List } from 'lucide-react';\nimport { MACHINE_VIEWS, MACHINE_VIEW_LABEL, needsAttention, type MachineViewMode } from './line-view-prefs';\nimport { MachineRows } from './MachineRows';\nimport { MachineStrip, type StripMachine } from './MachineStrip';\n\nconst VIEW_ICON: Record<MachineViewMode, typeof LayoutGrid> = { tiles: LayoutGrid, rows: List };\nconst RADIO_CLASS = 'p-1 transition-colors';\nconst RADIO_ON = 'text-text-primary bg-surface-sunken';\nconst RADIO_OFF = 'text-text-tertiary hover:text-text-primary';\n\nexport interface MachineViewsProps {\n machines: StripMachine[];\n selectedId: string | null;\n onSelect: (machineId: string) => void;\n view: MachineViewMode;\n onView: (view: MachineViewMode) => void;\n attentionOnly: boolean;\n onAttentionOnly: (on: boolean) => void;\n}\n\n/**\n * The machines region: the count, a needs-attention filter and the view\n * radios on the right (tiles or rows), with the chosen view filling the\n * region beneath. The region is bounded, so the wire below never moves.\n */\nexport function MachineViews(props: MachineViewsProps) {\n const { machines, selectedId, onSelect, view, onView, attentionOnly, onAttentionOnly } = props;\n const shown = useMemo(\n () => (attentionOnly ? machines.filter((m) => needsAttention(m.view)) : machines),\n [machines, attentionOnly],\n );\n const attention = useMemo(() => machines.filter((m) => needsAttention(m.view)).length, [machines]);\n if (machines.length === 0) {\n return <p className=\"text-2xs text-text-tertiary\">The line declares no machines.</p>;\n }\n const View = view === 'rows' ? MachineRows : MachineStrip;\n return (\n <section aria-label=\"Machines region\" data-view={view} className=\"flex flex-col h-full min-h-0\">\n <div className=\"flex items-center gap-3 pb-2 shrink-0\">\n <span className=\"text-2xs text-text-quaternary tabular-nums\">\n {machines.length} machine{machines.length === 1 ? '' : 's'}\n {attention > 0 && <span className=\"text-status-warning\"> · {attention} need{attention === 1 ? 's' : ''} attention</span>}\n </span>\n <span className=\"ml-auto flex items-center gap-3\">\n <button\n type=\"button\"\n aria-pressed={attentionOnly}\n onClick={() => onAttentionOnly(!attentionOnly)}\n className={`px-2 py-0.5 text-2xs rounded border transition-colors ${\n attentionOnly ? 'border-status-warning text-status-warning' : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Needs attention\n </button>\n <span className=\"inline-flex rounded border border-surface-border overflow-hidden\" role=\"radiogroup\" aria-label=\"Machines view\">\n {MACHINE_VIEWS.map((mode) => {\n const Icon = VIEW_ICON[mode];\n return (\n <button\n key={mode}\n type=\"button\"\n role=\"radio\"\n aria-checked={view === mode}\n aria-label={MACHINE_VIEW_LABEL[mode]}\n title={MACHINE_VIEW_LABEL[mode]}\n onClick={() => onView(mode)}\n className={`${RADIO_CLASS} ${view === mode ? RADIO_ON : RADIO_OFF}`}\n >\n <Icon className=\"w-3.5 h-3.5\" />\n </button>\n );\n })}\n </span>\n </span>\n </div>\n {shown.length === 0 ? (\n <p className=\"text-2xs text-text-tertiary py-1\">Every machine is quiet.</p>\n ) : (\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <View machines={shown} selectedId={selectedId} onSelect={onSelect} />\n </div>\n )}\n </section>\n );\n}\n","import { ArrowDownLeft, ArrowUpRight } from 'lucide-react';\nimport type { WireEvent } from '../../api/machines';\nimport { describeAction, formatClock, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\n/**\n * One line of the tape. At table width it is one row of columns: time,\n * direction, machine, channel and topic in mono, the summary, then the\n * violations and the actions the gateway took. Below it the row is a\n * dictionary: identity on the first line, the summary and the actions on\n * the second, the topic on the third.\n */\nexport function WireRow({ event, onOpen }: { event: WireEvent; onOpen: (event: WireEvent) => void }) {\n const actions = visibleActions(event.actions);\n const Direction = event.direction === 'in' ? ArrowDownLeft : ArrowUpRight;\n return (\n <li>\n <button\n type=\"button\"\n onClick={() => onOpen(event)}\n data-direction={event.direction}\n data-kind={event.kind}\n className=\"w-full text-left grid items-baseline gap-x-3 gap-y-0.5 px-2 py-1.5 border-b border-surface-border/60 hover:bg-surface-hover transition-colors\n grid-cols-[auto_auto_minmax(0,1fr)_auto]\n @table/tape:grid-cols-[auto_auto_6rem_11rem_minmax(0,1fr)_auto]\"\n >\n <span className=\"text-2xs font-mono tabular-nums text-text-quaternary\">{formatClock(event.at)}</span>\n <Direction\n className=\"w-3 h-3 self-center text-accent/65\"\n aria-label={event.direction === 'in' ? 'in' : 'out'}\n />\n <span\n className=\"text-2xs font-mono text-text-primary min-w-0 truncate col-span-2 @table/tape:col-span-1\"\n title={event.machineId ?? event.address ?? undefined}\n >\n {event.machineId ?? event.address ?? '—'}\n </span>\n <span\n className=\"text-2xs font-mono text-text-tertiary min-w-0 truncate col-start-3 col-span-2 @table/tape:col-start-4 @table/tape:col-span-1\"\n title={`${event.channel} ${event.topic}`}\n >\n {event.channel}\n <span className=\"text-text-quaternary\"> · </span>\n {event.topic}\n </span>\n <span\n className=\"text-xs text-text-secondary min-w-0 truncate col-start-3 @table/tape:col-start-5\"\n title={event.summary}\n >\n {event.summary || `${event.kind}${event.event ? ` · ${event.event}` : ''}`}\n </span>\n <span className=\"min-w-0 max-w-[12rem] @table/tape:max-w-[22rem] truncate text-2xs col-start-4 @table/tape:col-start-6\">\n {event.violations.length > 0 && (\n <span className=\"text-status-warning tabular-nums mr-2\" title={event.violations.join('\\n')}>\n {event.violations.length} violation{event.violations.length === 1 ? '' : 's'}\n </span>\n )}\n {actions.map((a, i) => (\n <span\n key={`${a.verb}-${a.rowId ?? ''}-${i}`}\n className={`${WIRE_VERB_TONE[a.verb] ?? 'text-text-secondary'} ${i < actions.length - 1 ? 'mr-2' : ''}`}\n >\n {describeAction(a)}\n </span>\n ))}\n </span>\n </button>\n </li>\n );\n}\n","import { Pause, Play, Eraser, X } from 'lucide-react';\nimport type { ReactNode, RefObject } from 'react';\nimport { WIRE_KINDS, type WireDirection, type WireEvent, type WireKind } from '../../api/machines';\nimport type { WireTapeFilters } from '../../hooks/useWireTape';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { WireRow } from './WireRow';\n\nexport interface WireTapeProps {\n events: WireEvent[];\n total: number;\n paused: boolean;\n heldCount: number;\n filters: WireTapeFilters;\n machines: string[];\n channels: string[];\n setFilter: (patch: Partial<WireTapeFilters>) => void;\n togglePause: () => void;\n clear: () => void;\n onOpen: (event: WireEvent) => void;\n /** Extra header controls after Clear: full screen, watch. */\n controls?: ReactNode;\n /** Sizes the scrolling list; the section decides how much room it has. */\n listClassName?: string;\n listRef?: RefObject<HTMLUListElement | null>;\n}\n\nconst DEFAULT_LIST_CLASS = 'flex-1 min-h-0';\n\nconst DIRECTIONS: { value: WireDirection; label: string }[] = [\n { value: 'in', label: 'in' },\n { value: 'out', label: 'out' },\n];\n\nfunction activeFilterCount(filters: WireTapeFilters): number {\n return [filters.machine, filters.channel, filters.direction, filters.kind].filter(Boolean).length\n + (filters.violationsOnly ? 1 : 0);\n}\n\n/**\n * The live list of wire events, newest first, with its filter band and the\n * pause that holds new arrivals aside while you read. The band folds its\n * controls behind one Filters button when the container is narrow; the rows\n * fold from columns into console cards below the table threshold.\n */\nexport function WireTape(props: WireTapeProps) {\n const { events, total, paused, heldCount, filters, machines, channels, setFilter, togglePause, clear, onOpen, controls, listClassName, listRef } = props;\n return (\n <div className=\"flex flex-col min-h-0 flex-1 @container/tape\">\n <FilterBar\n embedded\n activeFilterCount={activeFilterCount(filters)}\n actions={\n <>\n <span className=\"text-2xs text-text-quaternary tabular-nums whitespace-nowrap\">\n {events.length} shown · {total} on tape\n </span>\n <button\n type=\"button\"\n onClick={togglePause}\n aria-pressed={paused}\n className=\"inline-flex items-center gap-1 text-2xs icon-link whitespace-nowrap\"\n title={paused ? 'Resume the tape' : 'Pause the tape'}\n >\n {paused ? <Play className=\"w-3 h-3\" /> : <Pause className=\"w-3 h-3\" />}\n {paused ? `Resume${heldCount ? ` · ${heldCount} held` : ''}` : 'Pause'}\n </button>\n <button type=\"button\" onClick={clear} className=\"inline-flex items-center gap-1 text-2xs icon-link\" title=\"Clear the tape\">\n <Eraser className=\"w-3 h-3\" />\n Clear\n </button>\n {controls}\n </>\n }\n >\n <FilterSelect\n label=\"Machine\"\n value={filters.machine ?? ''}\n onChange={(v) => setFilter({ machine: v || null })}\n options={machines.map((m) => ({ value: m, label: m }))}\n placeholder=\"every machine\"\n />\n <FilterSelect\n label=\"Channel\"\n value={filters.channel ?? ''}\n onChange={(v) => setFilter({ channel: v || null })}\n options={channels.map((c) => ({ value: c, label: c }))}\n placeholder=\"every channel\"\n />\n <FilterSelect\n label=\"Direction\"\n value={filters.direction ?? ''}\n onChange={(v) => setFilter({ direction: (v || null) as WireDirection | null })}\n options={DIRECTIONS}\n placeholder=\"both\"\n />\n <FilterSelect\n label=\"Kind\"\n value={filters.kind ?? ''}\n onChange={(v) => setFilter({ kind: (v || null) as WireKind | null })}\n options={WIRE_KINDS.map((k) => ({ value: k, label: k }))}\n placeholder=\"every kind\"\n />\n <button\n type=\"button\"\n aria-pressed={filters.violationsOnly}\n onClick={() => setFilter({ violationsOnly: !filters.violationsOnly })}\n className={`self-start px-2 py-1 text-2xs rounded border transition-colors whitespace-nowrap ${\n filters.violationsOnly\n ? 'border-status-warning text-status-warning'\n : 'border-surface-border text-text-secondary hover:text-text-primary'\n }`}\n >\n Violations only\n </button>\n </FilterBar>\n {filters.machine && (\n <div className=\"flex items-center gap-2 px-3 py-1.5 text-2xs shrink-0\">\n <span className=\"text-text-quaternary\">Following</span>\n <button\n type=\"button\"\n onClick={() => setFilter({ machine: null })}\n className=\"inline-flex items-center gap-1 rounded-full border border-surface-border px-2 py-0.5 font-mono text-text-primary hover:text-accent transition-colors\"\n title=\"Show every machine\"\n >\n {filters.machine}\n <X className=\"w-3 h-3\" />\n <span className=\"font-sans text-text-tertiary\">release</span>\n </button>\n </div>\n )}\n {events.length === 0 ? (\n <p className=\"text-2xs text-text-tertiary px-3 py-3\">\n {total === 0 ? 'Waiting for traffic on the wire.' : 'Every event on the tape is filtered out.'}\n </p>\n ) : (\n <ul ref={listRef} className={`${listClassName ?? DEFAULT_LIST_CLASS} overflow-y-auto`} aria-label=\"Wire tape\">\n {events.map((event) => (\n <WireRow key={`${event.at}-${event.id ?? ''}-${event.topic}-${event.direction}`} event={event} onOpen={onOpen} />\n ))}\n </ul>\n )}\n </div>\n );\n}\n","import { useRef } from 'react';\nimport { Maximize2, Minimize2, Radio } from 'lucide-react';\nimport { FullscreenOverlay } from '../../components/common/layout/FullscreenOverlay';\nimport { WireTape, type WireTapeProps } from './WireTape';\n\n/** The embed: a bordered box of its own, the band inside, the list scrolling within. */\nexport const TAPE_BOX_CLASS = 'flex flex-col h-full min-h-0 overflow-hidden rounded-[var(--lt-radius-section)] border border-surface-border bg-surface-sunken';\n\nexport interface TapeSectionProps extends Omit<WireTapeProps, 'controls' | 'listClassName' | 'listRef'> {\n fullscreen: boolean;\n onFullscreen: (open: boolean) => void;\n /** Whether the shell's event stream already carries this line's wire. */\n watching: boolean;\n onWatch: () => void;\n}\n\n/**\n * The wire as an embed beneath the machines: boxed in, its filters and\n * controls in its own band, a full-screen view in the shell's overlay, and\n * a way to keep watching the line from the event stream anywhere in the app.\n */\nexport function TapeSection(props: TapeSectionProps) {\n const { fullscreen, onFullscreen, watching, onWatch, ...tape } = props;\n const listRef = useRef<HTMLUListElement | null>(null);\n const controls = (\n <>\n <button type=\"button\" onClick={() => onFullscreen(true)} className=\"inline-flex items-center gap-1 text-2xs icon-link\" title=\"Full screen\">\n <Maximize2 className=\"w-3 h-3\" />\n Full screen\n </button>\n <button\n type=\"button\"\n onClick={onWatch}\n disabled={watching}\n className=\"inline-flex items-center gap-1 text-2xs icon-link disabled:opacity-60\"\n title={watching ? 'The event stream carries this line' : 'Add this line to the event stream'}\n >\n <Radio className=\"w-3 h-3\" />\n {watching ? 'Watching' : 'Watch on the event stream'}\n </button>\n </>\n );\n return (\n <section aria-label=\"Wire tape\" className={TAPE_BOX_CLASS}>\n <WireTape {...tape} controls={controls} listRef={listRef} />\n <FullscreenOverlay open={fullscreen} onClose={() => onFullscreen(false)} sourceRef={listRef}>\n <div className=\"sticky top-0 float-right z-10\">\n <button\n type=\"button\"\n onClick={() => onFullscreen(false)}\n className=\"p-2 rounded text-text-tertiary hover:text-text-primary hover:bg-surface-raised transition-colors duration-150 bg-surface-sunken/80 backdrop-blur-sm\"\n title=\"Close (Esc)\"\n >\n <Minimize2 className=\"w-5 h-5\" />\n </button>\n </div>\n {fullscreen && <WireTape {...tape} listClassName=\"min-h-[60vh]\" />}\n </FullscreenOverlay>\n </section>\n );\n}\n","import { Link } from 'react-router-dom';\nimport { X } from 'lucide-react';\nimport type { WireEvent } from '../../api/machines';\nimport { PanelField } from '../../components/common/layout/SlidePanel';\nimport { formatDateTime } from '../../lib/format';\nimport { describeAction, formatJson, rowPath, visibleActions, WIRE_VERB_TONE } from './wire-display';\n\nexport const WIRE_PANEL_KEY = 'wire';\n\n/**\n * One wire event in full: the envelope, the payload when the server sends it,\n * the violations, and each action with a link to its row.\n */\nexport function WireDetailPanel({ event, onClose }: { event: WireEvent; onClose: () => void }) {\n const actions = visibleActions(event.actions);\n return (\n <div className=\"h-full flex flex-col\">\n <div className=\"flex items-start justify-between px-5 pt-5 pb-3 border-b border-surface-border/40\">\n <div className=\"min-w-0\">\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">\n {event.kind}{event.event ? <span className=\"normal-case font-mono\"> · {event.event}</span> : null}\n </p>\n <p className=\"text-sm text-text-primary mt-0.5\">{event.summary || event.topic}</p>\n </div>\n <button onClick={onClose} className=\"icon-link shrink-0 ml-2\" title=\"Close\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4 space-y-5\">\n <dl className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <PanelField label=\"At\">{formatDateTime(event.at)}</PanelField>\n <PanelField label=\"Direction\">{event.direction}</PanelField>\n <PanelField label=\"Machine\"><span className=\"font-mono\">{event.machineId ?? '—'}</span></PanelField>\n <PanelField label=\"Address\"><span className=\"font-mono\">{event.address ?? '—'}</span></PanelField>\n <PanelField label=\"Channel\"><span className=\"font-mono\">{event.channel}</span></PanelField>\n <PanelField label=\"Retained\">{event.retained ? 'yes' : 'no'}</PanelField>\n <div className=\"col-span-2\">\n <PanelField label=\"Topic\"><span className=\"font-mono break-all\">{event.topic}</span></PanelField>\n </div>\n {event.id && (\n <div className=\"col-span-2\">\n <PanelField label=\"Message id\"><span className=\"font-mono break-all\">{event.id}</span></PanelField>\n </div>\n )}\n </dl>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">\n Violations{event.violations.length ? ` · ${event.violations.length}` : ''}\n </p>\n {event.violations.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The message matched the contract.</p>\n ) : (\n <ul className=\"space-y-1\">\n {event.violations.map((v, i) => (\n <li key={i} className=\"text-xs text-status-warning\">{v}</li>\n ))}\n </ul>\n )}\n </section>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">Actions</p>\n {actions.length === 0 ? (\n <p className=\"text-2xs text-text-quaternary\">The gateway took no action.</p>\n ) : (\n <ul className=\"space-y-1.5\">\n {actions.map((a, i) => (\n <li key={`${a.verb}-${i}`} className=\"text-xs\">\n <span className={WIRE_VERB_TONE[a.verb]}>{describeAction(a)}</span>\n {a.rowId && (\n <>\n {' '}\n <Link to={rowPath(a.rowId)} className=\"font-mono text-accent hover:underline\">{a.rowId}</Link>\n </>\n )}\n {a.detail && <span className=\"block text-2xs text-text-tertiary\">{a.detail}</span>}\n </li>\n ))}\n </ul>\n )}\n </section>\n\n <section>\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-1.5\">Payload</p>\n {event.payload === undefined ? (\n <p className=\"text-2xs text-text-quaternary\">Builders see the payload here.</p>\n ) : (\n <pre className=\"text-2xs font-mono text-text-secondary whitespace-pre-wrap break-all bg-surface-sunken rounded px-2 py-1.5\">\n {formatJson(event.payload)}\n </pre>\n )}\n </section>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n machineLineQueryKey,\n machineWirePattern,\n useLine,\n type LineSummaryMachine,\n type WireEvent,\n} from '../../api/machines';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { useAccess } from '../../hooks/useAccess';\nimport { useEventSubscriptions } from '../../hooks/useEventContext';\nimport { useThrottledInvalidation } from '../../hooks/useEventHooks';\nimport { useEventFeedPatterns } from '../../hooks/useEventFeedPatterns';\nimport { useShellPanel } from '../../hooks/useShellPanel';\nimport { useWireTape } from '../../hooks/useWireTape';\nimport { escalationPattern } from '../../lib/events/subjects';\nimport { formatDateTime } from '../../lib/format';\nimport {\n MACHINE_VIEWS,\n autoMachineView,\n machineViewStorageKey,\n readStored,\n writeStored,\n type MachineViewMode,\n} from './line-view-prefs';\nimport { MachinePanel, MACHINE_PANEL_KEY, MACHINE_PANEL_WIDTH } from './MachinePanel';\nimport type { StripMachine } from './MachineStrip';\nimport { MachineViews } from './MachineViews';\nimport { TapeSection } from './TapeSection';\nimport { WireDetailPanel, WIRE_PANEL_KEY } from './WireDetailPanel';\n\nconst WIRE_PANEL_WIDTH = 420;\n/** The machines take three quarters of the page below the header, the wire the last quarter. */\nconst MACHINES_REGION_CLASS = 'flex-[3] min-h-0 flex flex-col mb-4';\nconst TAPE_REGION_CLASS = 'flex-[1] min-h-[14rem] flex flex-col';\n\n/** The tape's size, remembered per device. */\n/** The machines view: the count picks it, an override remembered per line wins. */\nfunction useMachineView(siteId: string, lineId: string, count: number): [MachineViewMode, (view: MachineViewMode) => void] {\n const key = machineViewStorageKey(siteId, lineId);\n const [override, setOverride] = useState<MachineViewMode | null>(() => readStored(key, MACHINE_VIEWS));\n useEffect(() => {\n setOverride(readStored(key, MACHINE_VIEWS));\n }, [key]);\n const choose = useCallback((view: MachineViewMode) => {\n setOverride(view);\n writeStored(key, view);\n }, [key]);\n return [override ?? autoMachineView(count), choose];\n}\n\n/**\n * Line state refreshes through the LIST tier on the line's own wire events\n * and on escalation events in the roles its machines own.\n */\nfunction useLineRefresh(siteId: string, lineId: string, roles: string[]) {\n const invalidate = useThrottledInvalidation('LIST');\n const patterns = useMemo(\n () => [machineWirePattern(siteId, lineId), ...roles.map((role) => escalationPattern({ role }))],\n [siteId, lineId, roles],\n );\n useEventSubscriptions(patterns, () => {\n invalidate([machineLineQueryKey(siteId, lineId)]);\n });\n}\n\n/** One line: the machines region, the tape section, the machine and wire panels. */\nexport function LinePage() {\n const { siteId = '', lineId = '' } = useParams<{ siteId: string; lineId: string }>();\n const { isOps, isBuilder } = useAccess();\n const canAct = isOps || isBuilder;\n const { data: line, isLoading, error } = useLine(siteId, lineId);\n const { setPanel, closePanel, ownerKey } = useShellPanel();\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [fullscreen, setFullscreen] = useState(false);\n const [attentionOnly, setAttentionOnly] = useState(false);\n const { userPatterns, addPattern } = useEventFeedPatterns();\n\n const summary = line?.summary ?? null;\n // The summary is line order; the view, when leading, enriches each tile.\n const machines = useMemo<StripMachine[]>(() => {\n const views = new Map((line?.machines ?? []).map((m) => [m.machineId, m]));\n const declared: LineSummaryMachine[] = summary?.machines\n ?? (line?.machines ?? []).map((m) => ({\n machineId: m.machineId, process: m.process, role: m.role, address: m.address, addressing: 'declared' as const,\n }));\n return declared.map((s) => ({ summary: s, view: views.get(s.machineId) }));\n }, [summary, line]);\n const roles = useMemo(() => [...new Set(machines.map((m) => m.summary.role))].sort(), [machines]);\n\n useLineRefresh(siteId, lineId, roles);\n const tape = useWireTape(siteId, lineId);\n const [machineView, setMachineView] = useMachineView(siteId, lineId, machines.length);\n const wirePattern = machineWirePattern(siteId, lineId);\n const watching = userPatterns.includes(wirePattern);\n\n const selected = machines.find((m) => m.summary.machineId === selectedId) ?? null;\n // One focus: the chosen machine opens its panel and the tape follows it.\n const selectMachine = useCallback((machineId: string) => {\n setSelectedId(machineId);\n tape.setFilter({ machine: machineId });\n }, [tape.setFilter]);\n const closeMachine = useCallback(() => {\n setSelectedId(null);\n closePanel(MACHINE_PANEL_KEY);\n }, [closePanel]);\n\n // The panel re-renders with every refresh of the line while it stays selected.\n useEffect(() => {\n if (!selected) return;\n setPanel(\n <MachinePanel\n siteId={siteId}\n lineId={lineId}\n summary={selected.summary}\n view={selected.view}\n canAct={canAct}\n onClose={closeMachine}\n />,\n { key: MACHINE_PANEL_KEY, width: MACHINE_PANEL_WIDTH },\n );\n }, [selected, siteId, lineId, canAct, closeMachine, setPanel]);\n\n // Another claimant taking the slot (a wire row, a timeline) clears the\n // selection. Ownership is tracked, since the slot changes hands one render\n // after the selection is made.\n const ownedRef = useRef(false);\n useEffect(() => {\n if (ownerKey === MACHINE_PANEL_KEY) {\n ownedRef.current = true;\n return;\n }\n if (ownedRef.current) {\n ownedRef.current = false;\n setSelectedId(null);\n }\n }, [ownerKey]);\n\n const openWire = useCallback((event: WireEvent) => {\n setPanel(\n <WireDetailPanel event={event} onClose={() => closePanel(WIRE_PANEL_KEY)} />,\n { key: WIRE_PANEL_KEY, width: WIRE_PANEL_WIDTH },\n );\n }, [setPanel, closePanel]);\n\n const standingBy = !!line && !line.leading;\n\n return (\n <div className=\"flex flex-col flex-1 min-h-0\">\n <PageHeader\n title={<span className=\"font-mono\">{siteId} · {lineId}</span>}\n actions={\n line?.leading && line.takenAt ? (\n <span className=\"text-2xs text-text-quaternary\">leading since {formatDateTime(line.takenAt)}</span>\n ) : null\n }\n />\n\n {isLoading && <p className=\"text-2xs text-text-tertiary italic mb-4\">Loading the line…</p>}\n {error && <p className=\"text-2xs text-status-error mb-4\">{(error as Error).message}</p>}\n {standingBy && (\n <p className=\"text-xs text-text-secondary mb-4\" data-testid=\"standing-by\">\n Standing by. Another replica leads this line; the tape stays live from the leader.\n </p>\n )}\n {line && line.contested.length > 0 && (\n <p className=\"text-2xs text-status-warning mb-4\">\n Contested: {line.contested.map((c) => `${c.address} at ${c.station}`).join(', ')}\n </p>\n )}\n\n <div className={MACHINES_REGION_CLASS}>\n <MachineViews\n machines={machines}\n selectedId={selectedId}\n onSelect={selectMachine}\n view={machineView}\n onView={setMachineView}\n attentionOnly={attentionOnly}\n onAttentionOnly={setAttentionOnly}\n />\n </div>\n\n <div className={TAPE_REGION_CLASS}>\n <TapeSection\n events={tape.events}\n total={tape.total}\n paused={tape.paused}\n heldCount={tape.heldCount}\n filters={tape.filters}\n machines={tape.machines}\n channels={tape.channels}\n setFilter={tape.setFilter}\n togglePause={tape.togglePause}\n clear={tape.clear}\n onOpen={openWire}\n fullscreen={fullscreen}\n onFullscreen={setFullscreen}\n watching={watching}\n onWatch={() => addPattern(wirePattern)}\n />\n </div>\n </div>\n );\n}\n"],"names":["WIRE_TAPE_CAPACITY","EMPTY_FILTERS","initialTapeState","cap","events","wireTapeReducer","state","action","matchesFilters","event","filters","applyFilters","KINDS","WIRE_KINDS","toWireEvent","raw","envelope","type","WIRE_EVENT_TYPE","e","kind","at","v","distinct","values","useWireTape","siteId","lineId","dispatch","useReducer","useEffect","useEventSubscription","machineWirePattern","visible","useMemo","machines","channels","setFilter","useCallback","patch","togglePause","clear","MACHINE_VIEWS","MACHINE_VIEW_LABEL","TILES_MAX","machineViewStorageKey","autoMachineView","count","readStored","key","allowed","value","writeStored","needsAttention","view","WIRE_VERB_LABEL","WIRE_VERB_TONE","describeAction","label","visibleActions","actions","a","rowPath","rowId","formatClock","iso","date","zone","getDisplayTimeZone","PRESENCE_DOT","PRESENCE_LABEL","presenceOf","formatJson","CommandOutcomeBody","outcome","jsxs","jsx","Link","ARG_HELPERS","mergeArgKey","text","current","parsed","parseArgs","CommandForm","machine","op","setOp","useState","args","setArgs","busy","setBusy","setOutcome","ops","commandOpsFor","submit","request","receipt","sendCommand","err","o","t","SnapshotButton","machineId","ask","SNAPSHOT_OP","RETAINED_CHOICES","parsePayload","trimmed","InspectOutcomeBody","Fragment","i","InspectForm","topic","setTopic","payload","setPayload","retained","setRetained","choice","c","result","inspectMessage","MACHINE_PANEL_KEY","MACHINE_PANEL_WIDTH","TIMELINE_PANEL_KEY","Section","title","children","RowLink","MachinePanel","summary","canAct","onClose","presence","shell","useShellPanelOptional","jobsOpen","setJobsOpen","openTimeline","facetKey","EntityTimelinePanel","alarms","held","jobs","X","PanelField","formatDateTime","ChevronRight","u","MACHINE_FACETS","ROWS_BOX_CLASS","matches","needle","MachineRows","selectedId","onSelect","query","setQuery","shown","m","selected","address","MachineStrip","VIEW_ICON","LayoutGrid","List","RADIO_CLASS","RADIO_ON","RADIO_OFF","MachineViews","props","onView","attentionOnly","onAttentionOnly","attention","View","mode","Icon","WireRow","onOpen","Direction","ArrowDownLeft","ArrowUpRight","DEFAULT_LIST_CLASS","DIRECTIONS","activeFilterCount","WireTape","total","paused","heldCount","controls","listClassName","listRef","FilterBar","Play","Pause","Eraser","FilterSelect","k","TAPE_BOX_CLASS","TapeSection","fullscreen","onFullscreen","watching","onWatch","tape","useRef","Maximize2","Radio","FullscreenOverlay","Minimize2","WIRE_PANEL_KEY","WireDetailPanel","WIRE_PANEL_WIDTH","MACHINES_REGION_CLASS","TAPE_REGION_CLASS","useMachineView","override","setOverride","choose","useLineRefresh","roles","invalidate","useThrottledInvalidation","patterns","role","escalationPattern","useEventSubscriptions","machineLineQueryKey","LinePage","useParams","isOps","isBuilder","useAccess","line","isLoading","error","useLine","setPanel","closePanel","ownerKey","useShellPanel","setSelectedId","setFullscreen","setAttentionOnly","userPatterns","addPattern","useEventFeedPatterns","views","s","machineView","setMachineView","wirePattern","selectMachine","closeMachine","ownedRef","openWire","standingBy","PageHeader"],"mappings":"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"}