@openscout/scout 0.2.75 → 0.2.78
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.
- package/README.md +41 -2
- package/bin/openscout-runtime.mjs +48 -30
- package/bin/scout.mjs +2 -2
- package/bin/scoutd +0 -0
- package/dist/build-manifest.json +3 -3
- package/dist/client/assets/ActivityScreen-Cu_1V4bq.js +1 -0
- package/dist/client/assets/AddProjectForm-DMnobKch.js +1 -0
- package/dist/client/assets/AgentAvatar-D90c1Rzk.js +1 -0
- package/dist/client/assets/AgentConfigurationScreen-BqfOz90D.js +1 -0
- package/dist/client/assets/AgentDefinitionsWorkspace-CUpUrY57.js +1 -0
- package/dist/client/assets/AgentDetailCard-BcRBRp88.js +1 -0
- package/dist/client/assets/AgentDetailCard-C4WVeJvJ.css +1 -0
- package/dist/client/assets/AgentFloorView-8LoAEBwS.js +1 -0
- package/dist/client/assets/AgentInfoScreen-DZs2_ibL.js +1 -0
- package/dist/client/assets/AgentLaneCard-RrNnDZu8.js +1 -0
- package/dist/client/assets/AgentLaneChrome-D9ZwUKrl.js +1 -0
- package/dist/client/assets/AgentLaneDetailSheet-BXbPls9N.js +5 -0
- package/dist/client/assets/AgentLaneSummaryResize-BhFmGNzT.js +1 -0
- package/dist/client/assets/AgentLanesEmbedScreen-W3qs022h.js +1 -0
- package/dist/client/assets/AgentLanesPreflight-eSAoDsPi.js +1 -0
- package/dist/client/assets/AgentLanesView-B9vuEEmZ.js +2 -0
- package/dist/client/assets/AgentLiveActions-CGS-Bxb7.css +1 -0
- package/dist/client/assets/AgentLiveActions-DBtnD0qE.js +1 -0
- package/dist/client/assets/AgentSessions-DyqOf4nG.js +6 -0
- package/dist/client/assets/AgentsConsole-BgiYP2wR.js +1 -0
- package/dist/client/assets/AgentsConsole-BjSTs-TV.css +1 -0
- package/dist/client/assets/AgentsScreen-DBi8x4MB.js +1 -0
- package/dist/client/assets/AgentsSubnav-DIEO4NPx.js +1 -0
- package/dist/client/assets/AtopView-BCkae3e1.js +1 -0
- package/dist/client/assets/BackToPicker-BRvfostO.js +1 -0
- package/dist/client/assets/BackToPicker-CdgVu-to.css +1 -0
- package/dist/client/assets/BriefingDetailScreen-BwFyysT8.js +6 -0
- package/dist/client/assets/BriefingsScreen-BQEevztH.js +1 -0
- package/dist/client/assets/BrokerMetadataPanel-7UjcuNjd.js +1 -0
- package/dist/client/assets/BrokerScreen-7ekklu88.js +5 -0
- package/dist/client/assets/ChatCollapsedStrip-CQSYSd8s.js +1 -0
- package/dist/client/assets/CodeDiffPane-DDPt6KPh.js +1 -0
- package/dist/client/assets/CodeProjectPicker-DqKFCpLU.js +2 -0
- package/dist/client/assets/CodeScreen-BxCrpRHd.js +1 -0
- package/dist/client/assets/ContextMenu-bARZqTzD.js +1 -0
- package/dist/client/assets/ConversationComposer-Bla3DDvM.js +1 -0
- package/dist/client/assets/ConversationFeedRows-B_gPxcqA.js +1 -0
- package/dist/client/assets/ConversationHeader-DE3FC0m-.js +1 -0
- package/dist/client/assets/ConversationPanels-DLek4H6A.js +2 -0
- package/dist/client/assets/ConversationScreen-BDRhx-RU.js +1 -0
- package/dist/client/assets/ConversationScreen-C9yMAMYF.css +1 -0
- package/dist/client/assets/ConversationStatus-BwVLiiO4.js +1 -0
- package/dist/client/assets/DataTable-E8s_MmoA.js +1 -0
- package/dist/client/assets/DispatchAftermath-Dpe88DFX.js +1 -0
- package/dist/client/assets/DocumentFocusViewer-BeVwwl26.js +1 -0
- package/dist/client/assets/EmbeddableSurfacesLab-BQqFQVnI.js +1 -0
- package/dist/client/assets/EmptyState-4F9XDFQm.js +1 -0
- package/dist/client/assets/FileViewerPane-CLgUhSm4.js +3 -0
- package/dist/client/assets/FleetSearch-Dz5euQJe.js +1 -0
- package/dist/client/assets/FleetSearch-EXOe8ulE.css +1 -0
- package/dist/client/assets/FlightObserveScreen-6RpZYwVz.js +1 -0
- package/dist/client/assets/FollowScreen-DZ4qfYOY.js +1 -0
- package/dist/client/assets/HarnessMark-Cbv3Ib0c.js +1 -0
- package/dist/client/assets/HarnessesScreen-CznAImej.js +1 -0
- package/dist/client/assets/HomeHero-B3uYd-pP.js +1 -0
- package/dist/client/assets/HomeHero-DEl-WBsT.css +1 -0
- package/dist/client/assets/KnowledgeSearchInspector-Dgdkfvvz.js +1 -0
- package/dist/client/assets/KnowledgeSearchScreen-DJDGGaqC.js +1 -0
- package/dist/client/assets/LaneToolHoverCard-Bla0gBdm.js +1 -0
- package/dist/client/assets/LaneTraceDetailSheet-D1CspRbl.js +1 -0
- package/dist/client/assets/LaneTraceEventFocus-BF9ERP5O.js +1 -0
- package/dist/client/assets/MeshCanvas-DFEPkpqY.js +3 -0
- package/dist/client/assets/MeshCanvasMinimap-CyVFYixr.js +1 -0
- package/dist/client/assets/MeshCanvasMinimap-Dv7nMbl5.css +1 -0
- package/dist/client/assets/MeshScreen-DFgevn8N.js +1 -0
- package/dist/client/assets/MeshTopologyView-CalkZghg.js +2 -0
- package/dist/client/assets/MessageComposerSuggestions-DpxN9WiB.js +1 -0
- package/dist/client/assets/MessagesScreen-C8YKW10Y.js +1 -0
- package/dist/client/assets/MissionControlView-lUeAiSVg.js +1 -0
- package/dist/client/assets/MissionFocusOverlay-wlCmWDCT.js +1 -0
- package/dist/client/assets/MissionLeftAgentRow-BpZWntfl.js +1 -0
- package/dist/client/assets/MissionLogPane-__MVtEl9.js +1 -0
- package/dist/client/assets/NewAgentModal-Bg-eWHpY.js +1 -0
- package/dist/client/assets/NewAgentModal-ru8u5YdJ.css +1 -0
- package/dist/client/assets/NewChatComposer-Cs6OsxK6.js +19 -0
- package/dist/client/assets/NewChatComposer-W-t-L4oV.css +1 -0
- package/dist/client/assets/NewChatOrigin-Bk2OyVjI.js +1 -0
- package/dist/client/assets/ObserveEmbedScreen-y2EpuqRZ.js +2 -0
- package/dist/client/assets/ObserveTextFlow-rsFj_rVo.js +2 -0
- package/dist/client/assets/ObservedTopologyPanel-BsBsvVPL.css +1 -0
- package/dist/client/assets/ObservedTopologyPanel-DyUeV98H.js +2 -0
- package/dist/client/assets/OpenScoutAppShell-Bh6FnEJO.css +1 -0
- package/dist/client/assets/OpenScoutAppShell-C_URc8sV.js +87 -0
- package/dist/client/assets/OpsAgentsView-UN7iOscs.js +1 -0
- package/dist/client/assets/OpsScreen-Buf3LKjb.js +1 -0
- package/dist/client/assets/OpsSubnav-DsuXzHah.js +1 -0
- package/dist/client/assets/PlanView-C1CjH3PG.js +1 -0
- package/dist/client/assets/ProjectAgentProfile-DJusrAV-.js +1 -0
- package/dist/client/assets/ProjectAgentProfileBar-CtTpj6fU.js +1 -0
- package/dist/client/assets/ProjectAgentProfileHero-BFwNJo_N.js +1 -0
- package/dist/client/assets/ProjectsInbox-GhVMxOhw.js +2 -0
- package/dist/client/assets/ProjectsRail-BgiuV4LR.js +1 -0
- package/dist/client/assets/ProjectsScreen-eNUBy4YU.js +1 -0
- package/dist/client/assets/ProjectsThreadAside-CoBgnHmr.js +1 -0
- package/dist/client/assets/Provider-C7UKGHQy.js +1 -0
- package/dist/client/assets/Provider-CCzjtkda.css +1 -0
- package/dist/client/assets/RailRow-BoGxAHNF.js +1 -0
- package/dist/client/assets/RailRow-Cf9LOiEj.css +1 -0
- package/dist/client/assets/RawSessionsTable-DL8y_eEy.js +1 -0
- package/dist/client/assets/RealtimeVoiceScreen-ffS-39zy.js +1 -0
- package/dist/client/assets/RepoDiffEmbedScreen-C0rumUME.js +1 -0
- package/dist/client/assets/RepoDiffPageScreen-DMv6DioL.js +1 -0
- package/dist/client/assets/RepoDiffViewer-D_exm6xK.js +7 -0
- package/dist/client/assets/RepoDiffViewerLazy-BPgF92Bg.js +2 -0
- package/dist/client/assets/ReposScreen-CB_YBWYf.js +6 -0
- package/dist/client/assets/ScoutDeckSurface-CxIYFyWx.js +1 -0
- package/dist/client/assets/ScoutDeckSurface-uhmuZRzC.css +1 -0
- package/dist/client/assets/ScoutSurface-CYz_TcWC.js +1 -0
- package/dist/client/assets/ScoutbotBroadcastChip-CxtYZWPZ.css +1 -0
- package/dist/client/assets/ScoutbotBroadcastChip-L_R9atj0.js +2 -0
- package/dist/client/assets/ScoutbotFxLab-CgiZMDMW.js +4 -0
- package/dist/client/assets/ScoutbotRealtimeVoiceCall-FMQOr1Np.js +1 -0
- package/dist/client/assets/SecondaryNav-B3-nh5dM.js +1 -0
- package/dist/client/assets/SessionEmbedScreen-BVC7yvWF.js +1 -0
- package/dist/client/assets/SessionObserve-BpggNO_M.css +1 -0
- package/dist/client/assets/SessionObserve-yfXFafp8.js +12 -0
- package/dist/client/assets/SessionRefScreen-DRgJu7Jo.js +1 -0
- package/dist/client/assets/SessionsScreen-D6XUsZfA.js +1 -0
- package/dist/client/assets/SettingsDrawer-CmJt72ww.css +1 -0
- package/dist/client/assets/SettingsDrawer-XfdAa_nD.js +3 -0
- package/dist/client/assets/SettingsScreen-Cy8z-EuR.js +1 -0
- package/dist/client/assets/ShikiPane-Ap1iPxYb.js +15 -0
- package/dist/client/assets/SlidePanel-Bg5dVaIa.css +1 -0
- package/dist/client/assets/SlidePanel-COwtoJqR.js +1 -0
- package/dist/client/assets/SpriteAvatar-DyaGuhik.js +1 -0
- package/dist/client/assets/StatusPill-DhBL__p8.js +1 -0
- package/dist/client/assets/TailView-DGj_5HA9.js +2 -0
- package/dist/client/assets/TailView-Mj3AU2u0.css +1 -0
- package/dist/client/assets/Terminal-CqvGbjXU.js +1 -0
- package/dist/client/assets/TerminalEmbedScreen-DuZZFFzW.js +1 -0
- package/dist/client/assets/TextDocumentSurface-BpAw4eQS.js +4 -0
- package/dist/client/assets/TmuxPeek-m1osv33Q.js +1 -0
- package/dist/client/assets/VoicePermissionsPanel-DsK53ar4.js +1 -0
- package/dist/client/assets/VoicePermissionsPanel-RijAZ1gP.css +1 -0
- package/dist/client/assets/WorkDetailScreen-Bx0JimPC.js +5 -0
- package/dist/client/assets/WorkFilesViewer-Btl6C2Q1.js +1 -0
- package/dist/client/assets/activity-CA8qS6PI.js +1 -0
- package/dist/client/assets/{addon-fit-3IrvLm2n.js → addon-fit-BZ-kXjeN.js} +1 -1
- package/dist/client/assets/{addon-webgl-BgxIDUI-.js → addon-webgl-D9-EQVEK.js} +1 -1
- package/dist/client/assets/agent-chat-Bfjd9y6c.js +1 -0
- package/dist/client/assets/agent-definitions-CymTYqvo.css +1 -0
- package/dist/client/assets/agent-directory-studio-injection-Bc8590z5.css +1 -0
- package/dist/client/assets/agent-essentials-BSY1o46q.js +1 -0
- package/dist/client/assets/agent-floor-CuJr1iK1.css +1 -0
- package/dist/client/assets/agent-lane-card-Dm7YWoew.css +1 -0
- package/dist/client/assets/agent-lane-card-model-r2frk57c.js +1 -0
- package/dist/client/assets/agent-lane-detail-Djm3YJEa.js +1 -0
- package/dist/client/assets/agent-lane-preview-CmHVe3dU.js +4 -0
- package/dist/client/assets/agent-lanes-BDNktFBZ.css +1 -0
- package/dist/client/assets/agent-lanes-model-B4YTt4OF.js +2 -0
- package/dist/client/assets/agents-detail-redesign-h34ROjOW.css +1 -0
- package/dist/client/assets/agents-project-COzHxZAF.css +1 -0
- package/dist/client/assets/agents-project-model-UYiamtrU.js +1 -0
- package/dist/client/assets/agents-screen-BMu6PpRY.css +1 -0
- package/dist/client/assets/api-BkjHJfgJ.js +1 -0
- package/dist/client/assets/api-h5zurxmi.js +1 -0
- package/dist/client/assets/{arc.es-Bh8P_xre.js → arc.es-CQBb-dVu.js} +1 -1
- package/dist/client/assets/arrow-down-BPLe0am9.js +1 -0
- package/dist/client/assets/arrow-left-DEZzHiPS.js +1 -0
- package/dist/client/assets/arrow-up-right-ClxBnsi7.js +1 -0
- package/dist/client/assets/bash-format-BRV5C6Gv.js +1 -0
- package/dist/client/assets/bot-eu8pBNvI.js +1 -0
- package/dist/client/assets/briefings-BwuAFQK6.css +1 -0
- package/dist/client/assets/broker-display-pp33bLsu.js +2 -0
- package/dist/client/assets/cache-Dr0why2k.js +2 -0
- package/dist/client/assets/check-DjgFiBxb.js +1 -0
- package/dist/client/assets/chevron-down-BGk5qoEw.js +1 -0
- package/dist/client/assets/chevron-right-XiIHsk4m.js +1 -0
- package/dist/client/assets/chunk-T65CQEWV-CrzwSeEt.js +1 -0
- package/dist/client/assets/chunk-YOZR3KYS-Bet8khjg.js +47 -0
- package/dist/client/assets/clipboard-e3fSpeo7.js +1 -0
- package/dist/client/assets/code-screen-DrKinCyh.css +1 -0
- package/dist/client/assets/code-xml-B6jOCM4V.js +1 -0
- package/dist/client/assets/collapsed-strip-Dz-of2SM.css +1 -0
- package/dist/client/assets/colors-BtO5_zlx.js +1 -0
- package/dist/client/assets/console-B1IBqLI_.css +1 -0
- package/dist/client/assets/content-BDt9VBPk.js +1 -0
- package/dist/client/assets/content-BIXf4cKR.js +1 -0
- package/dist/client/assets/content-BLm0NBJM.js +1 -0
- package/dist/client/assets/content-C2EwTb2y.js +1 -0
- package/dist/client/assets/content-C5UbLsDF.js +1 -0
- package/dist/client/assets/content-CHU0wwA3.css +1 -0
- package/dist/client/assets/content-CR3vdrYY.js +1 -0
- package/dist/client/assets/content-CSPVmo2s.js +1 -0
- package/dist/client/assets/content-C_FGqx1X.js +1 -0
- package/dist/client/assets/content-CvlVUOG8.js +1 -0
- package/dist/client/assets/content-D5kJmfgl.js +1 -0
- package/dist/client/assets/content-DTpQsomG.js +1 -0
- package/dist/client/assets/content-DikVsqLf.js +1 -0
- package/dist/client/assets/content-DlUe5Ono.js +1 -0
- package/dist/client/assets/content-GIBv_55n.js +1 -0
- package/dist/client/assets/content-Q2oclDzi.js +1 -0
- package/dist/client/assets/context-budget-CbB4BDcO.js +1 -0
- package/dist/client/assets/conversation-icons-IIG5ha6D.js +1 -0
- package/dist/client/assets/conversation-model-B47vYmWN.js +1 -0
- package/dist/client/assets/conversation-motion-features-BdAONVls.js +1 -0
- package/dist/client/assets/conversation-prefs-DNre-Lcx.js +1 -0
- package/dist/client/assets/copy-CQGYbxdu.js +1 -0
- package/dist/client/assets/createLucideIcon-OpA4Amw5.js +1 -0
- package/dist/client/assets/ctx-panel-B4s49N9e.css +1 -0
- package/dist/client/assets/discover-C1YwpBDE.js +2 -0
- package/dist/client/assets/document-focus-viewer-BSC_JwVE.css +1 -0
- package/dist/client/assets/embed-entry-BAcGL3g9.js +2 -0
- package/dist/client/assets/external-link-CXBytO9o.js +1 -0
- package/dist/client/assets/eye-0PvebX_a.js +1 -0
- package/dist/client/assets/file-text-BODxCjcz.js +1 -0
- package/dist/client/assets/flight-observe-GFg9L8ft.css +1 -0
- package/dist/client/assets/follow-route-BvcGtBIL.js +1 -0
- package/dist/client/assets/fx-z37u1o2z.js +1 -0
- package/dist/client/assets/gestures-CcwOTu8C.js +1 -0
- package/dist/client/assets/harnesses-screen-DBZoTZz8.css +1 -0
- package/dist/client/assets/home-live-action-B22u89j7.js +1 -0
- package/dist/client/assets/home-moving-signal-CAa0V91u.css +1 -0
- package/dist/client/assets/home-moving-signal-CK147hxn.js +1 -0
- package/dist/client/assets/home-now-card-BgvNWuea.js +1 -0
- package/dist/client/assets/home-now-card-nano-BcjnOU9H.js +1 -0
- package/dist/client/assets/hooks-B6y_O2FB.js +2 -0
- package/dist/client/assets/hooks-D6NI15f6.css +1 -0
- package/dist/client/assets/inbox-thread-redesign-Bz4FjWzr.css +1 -0
- package/dist/client/assets/index-BWHgHrtv.js +1 -0
- package/dist/client/assets/index-BcuhqXLe.js +1 -0
- package/dist/client/assets/index-CJXzfjo9.js +1 -0
- package/dist/client/assets/index-CvF09yvf.css +1 -0
- package/dist/client/assets/index-DMiGbrBt.js +10 -0
- package/dist/client/assets/index-DQPvraRS.js +1 -0
- package/dist/client/assets/index-DxGoC5l5.css +1 -0
- package/dist/client/assets/inspector-panel-DPoCWxKs.js +2 -0
- package/dist/client/assets/keyboard-nav-2kv_tGUS.js +1 -0
- package/dist/client/assets/knowledge-search-CVxQwxPn.js +1 -0
- package/dist/client/assets/knowledge-search-DjrQdiiW.css +1 -0
- package/dist/client/assets/lane-ask-display-B6iCAVcd.js +18 -0
- package/dist/client/assets/lane-edit-display-C_Aujldz.js +9 -0
- package/dist/client/assets/lane-observe-D0rfKDnU.js +7 -0
- package/dist/client/assets/lane-roster-store-D8x1jac2.js +1 -0
- package/dist/client/assets/lane-tool-detail-0WhMf4Vj.js +9 -0
- package/dist/client/assets/left-Bk3XnxPD.css +1 -0
- package/dist/client/assets/left-C--GiIh8.js +2 -0
- package/dist/client/assets/left-CAaRBK9S.css +1 -0
- package/dist/client/assets/left-CCoobxPS.css +1 -0
- package/dist/client/assets/left-Cj7Rt89X.js +1 -0
- package/dist/client/assets/left-CpNEtFEg.js +1 -0
- package/dist/client/assets/left-CzXAuK_t.js +2 -0
- package/dist/client/assets/left-agents-Bo9sO1by.js +1 -0
- package/dist/client/assets/left-bN4PCAXa.js +1 -0
- package/dist/client/assets/left-default-DV9GdvYi.js +1 -0
- package/dist/client/assets/left-jYYGAOYD.js +1 -0
- package/dist/client/assets/left-lanes-D0l_Co7V.js +1 -0
- package/dist/client/assets/left-mission-Ci7zREkQ.js +1 -0
- package/dist/client/assets/left-mission-DSenPIyb.css +1 -0
- package/dist/client/assets/left-plan-D4U1uflW.js +2 -0
- package/dist/client/assets/library-D-RxGiCw.js +1 -0
- package/dist/client/assets/loader-circle-CbHjZsz1.js +1 -0
- package/dist/client/assets/local-agents--00gLMqr.js +1 -0
- package/dist/client/assets/mentions-jSuTGeet.js +1 -0
- package/dist/client/assets/mesh-buckets-CfAukILK.js +1 -0
- package/dist/client/assets/mesh-screen-BSDUjrnV.css +1 -0
- package/dist/client/assets/mesh-view-store-CWidRbTE.js +1 -0
- package/dist/client/assets/message-circle-CG-96zts.js +1 -0
- package/dist/client/assets/message-markup-3J9pi3nx.js +15 -0
- package/dist/client/assets/message-square-DSaGpjFU.js +1 -0
- package/dist/client/assets/message-visibility-kJM8XcSG.js +1 -0
- package/dist/client/assets/mission-control-D3ikEPND.css +1 -0
- package/dist/client/assets/mission-control-model-C0fByIjm.js +1 -0
- package/dist/client/assets/mission-control-store-BlnEhiCq.js +1 -0
- package/dist/client/assets/model-Co0zkMIc.js +1 -0
- package/dist/client/assets/model-CpAxGuis.js +1 -0
- package/dist/client/assets/observe-CuLGD9Zp.js +1 -0
- package/dist/client/assets/openAgent-Bjt57GdM.js +1 -0
- package/dist/client/assets/openContent-C6XO6kr5.js +1 -0
- package/dist/client/assets/operator-attention-BwSPeheT.js +1 -0
- package/dist/client/assets/ops-agents-BOYxzPTm.css +1 -0
- package/dist/client/assets/ops-atop-BB4B4JdE.css +1 -0
- package/dist/client/assets/ops-screen-giu3If_N.css +1 -0
- package/dist/client/assets/page-status-DpkedE1F.js +1 -0
- package/dist/client/assets/page-status-bar-ByUD7VPM.css +1 -0
- package/dist/client/assets/plan-view-D56fneVF.css +1 -0
- package/dist/client/assets/plus--b1raV_O.js +1 -0
- package/dist/client/assets/profile-CVRziEDA.js +1 -0
- package/dist/client/assets/project-overview-helpers-BQTc_Ous.js +1 -0
- package/dist/client/assets/projects-inbox-CHyUFQ6w.js +1 -0
- package/dist/client/assets/projects-inbox-COZ23dLR.css +1 -0
- package/dist/client/assets/radio-Bz8ZePxj.js +1 -0
- package/dist/client/assets/refresh-cw-BBmAnCB7.js +1 -0
- package/dist/client/assets/repo-diff-C9Qs-bEn.css +1 -0
- package/dist/client/assets/resizable-columns-C7ygvLt8.css +1 -0
- package/dist/client/assets/resolve-panes-r9B3mpW7.js +1 -0
- package/dist/client/assets/resolve-sidebar-context-DcG8xGaB.js +1 -0
- package/dist/client/assets/right-BHeiIaty.js +1 -0
- package/dist/client/assets/right-BkgKo9VT.js +1 -0
- package/dist/client/assets/right-BpEU5jWE.js +1 -0
- package/dist/client/assets/right-CRZXoy-X.js +1 -0
- package/dist/client/assets/right-ChF_pbPy.js +1 -0
- package/dist/client/assets/right-DMoUT3KN.js +1 -0
- package/dist/client/assets/right-DjRXbnRP.js +2 -0
- package/dist/client/assets/right-T4Ue6EqM.js +1 -0
- package/dist/client/assets/right-wzrLXKur.js +1 -0
- package/dist/client/assets/rocket-BSNS_rLs.js +1 -0
- package/dist/client/assets/router-Bq5dwf78.js +1 -0
- package/dist/client/assets/runtime-picker-Bcl5iIX5.js +1 -0
- package/dist/client/assets/runtime-picker-vhm0gtLs.css +1 -0
- package/dist/client/assets/scope-views-4khCg2_z.css +1 -0
- package/dist/client/assets/scope-views-U-ucT9m0.js +1 -0
- package/dist/client/assets/scout-voice-CU5c0LGi.js +1 -0
- package/dist/client/assets/scoutbot-BTIErYHo.js +3 -0
- package/dist/client/assets/scroll-text-D6Pdnar7.js +1 -0
- package/dist/client/assets/search-CWfZtOt2.js +1 -0
- package/dist/client/assets/secondaryNavConfig-DqUIp0Es.js +1 -0
- package/dist/client/assets/secondaryNavConfig-xssF_ubT.css +1 -0
- package/dist/client/assets/selection-bridge-16pk1qyG.js +1 -0
- package/dist/client/assets/send-horizontal-Bg5-QggH.js +1 -0
- package/dist/client/assets/server-CPp4ZJhZ.js +1 -0
- package/dist/client/assets/session-catalog-BmoyVTJ_.js +1 -0
- package/dist/client/assets/session-table-DZcrKoIH.js +1 -0
- package/dist/client/assets/sessionRead-CvFz2RHv.js +1 -0
- package/dist/client/assets/sliders-horizontal-1oW76Xc9.js +1 -0
- package/dist/client/assets/sparkles-ClfRJQ6w.js +1 -0
- package/dist/client/assets/sse-CjIkKo46.js +1 -0
- package/dist/client/assets/status-tone-BM_zuRy1.js +1 -0
- package/dist/client/assets/surface-activity-B1rgWB1i.js +1 -0
- package/dist/client/assets/system-surfaces-redesign-CD26LFc0.css +1 -0
- package/dist/client/assets/tail-display-BdyoLvzY.js +2 -0
- package/dist/client/assets/tail-events-D19uAGe3.js +1 -0
- package/dist/client/assets/terminal-B9AOZQKR.js +1 -0
- package/dist/client/assets/terminal-relay-CWbJ1RCW.js +1 -0
- package/dist/client/assets/terminal-screen-19jAI0Cw.css +1 -0
- package/dist/client/assets/terminal-sessions-D5CIR2OL.js +1 -0
- package/dist/client/assets/terminal-takeover-B8UeD9OX.js +1 -0
- package/dist/client/assets/text-DsBWV_4k.js +1 -0
- package/dist/client/assets/time-DltNTpLl.js +1 -0
- package/dist/client/assets/types-B0PlfpKc.js +1 -0
- package/dist/client/assets/ui-LM8pS8qE.js +1 -0
- package/dist/client/assets/use-conversation-list-Byab41G6.js +1 -0
- package/dist/client/assets/use-fleet-active-asks-BIbQx5AS.js +1 -0
- package/dist/client/assets/use-reduced-motion-RRBkmVkk.js +1 -0
- package/dist/client/assets/useAgentHoverCard-DMrbBif0.js +1 -0
- package/dist/client/assets/useContentSecondaryNav-DMl1WNm7.js +1 -0
- package/dist/client/assets/usePierreRuntime-wC-yMtBb.js +50 -0
- package/dist/client/assets/voice-levels-Dcr3jglk.js +1 -0
- package/dist/client/assets/wrench-Bkc_0lKF.js +1 -0
- package/dist/client/assets/x-D3GElQbe.js +1 -0
- package/dist/client/assets/{xterm-CoGJTxj9.js → xterm-BKR8oAkR.js} +1 -1
- package/dist/client/index.html +6 -3
- package/dist/drizzle/0003_harsh_meltdown.sql +45 -0
- package/dist/drizzle/0004_medical_aaron_stack.sql +40 -0
- package/dist/drizzle/0005_wet_shriek.sql +57 -0
- package/dist/drizzle/0006_woozy_dark_beast.sql +1 -0
- package/dist/drizzle/README.md +7 -0
- package/dist/drizzle/meta/0003_snapshot.json +4952 -0
- package/dist/drizzle/meta/0004_snapshot.json +5235 -0
- package/dist/drizzle/meta/0005_snapshot.json +5599 -0
- package/dist/drizzle/meta/0006_snapshot.json +5606 -0
- package/dist/drizzle/meta/_journal.json +28 -0
- package/dist/main.mjs +24964 -12946
- package/dist/node/main.mjs +10212 -195
- package/dist/openscout-terminal-relay.mjs +507 -64
- package/dist/pairing-runtime-controller.mjs +10909 -5177
- package/dist/runtime/base-daemon.mjs +627 -159
- package/dist/runtime/broker-daemon.mjs +65060 -30990
- package/dist/runtime/broker-process-manager.mjs +247 -54
- package/dist/runtime/mesh-discover.mjs +246 -54
- package/dist/scout-control-plane-web.mjs +54699 -45309
- package/dist/scout-web-server.mjs +54699 -45309
- package/package.json +3 -3
- package/dist/client/assets/RepoDiffViewer-CTXJvjIL.js +0 -56
- package/dist/client/assets/embed-entry-wAEtYUEM.js +0 -1
- package/dist/client/assets/index-BK3mRYyN.js +0 -272
- package/dist/client/assets/index-Dm1ZQS9G.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/runtime/src/base-daemon.ts
|
|
3
|
-
import { spawn as spawn3
|
|
3
|
+
import { spawn as spawn3 } from "child_process";
|
|
4
4
|
import { existsSync as existsSync6, mkdirSync as mkdirSync2, openSync, writeFileSync as writeFileSync2 } from "fs";
|
|
5
5
|
import { homedir as homedir6 } from "os";
|
|
6
6
|
import { dirname as dirname4, join as join6, resolve as resolve3 } from "path";
|
|
@@ -81,33 +81,49 @@ function requestBrokerOverUnixSocket(socketPath, baseUrl, path, options) {
|
|
|
81
81
|
if (body !== undefined) {
|
|
82
82
|
headers["content-length"] = Buffer.byteLength(body).toString();
|
|
83
83
|
}
|
|
84
|
+
let settled = false;
|
|
85
|
+
const cleanupAbortListener = () => {
|
|
86
|
+
options.signal?.removeEventListener("abort", handleAbort);
|
|
87
|
+
};
|
|
88
|
+
const rejectOnce = (error) => {
|
|
89
|
+
if (settled)
|
|
90
|
+
return;
|
|
91
|
+
settled = true;
|
|
92
|
+
cleanupAbortListener();
|
|
93
|
+
reject(error);
|
|
94
|
+
};
|
|
84
95
|
const request = httpRequest({
|
|
85
96
|
socketPath,
|
|
86
97
|
path: `${url.pathname}${url.search}`,
|
|
87
98
|
method: options.method ?? (body === undefined ? "GET" : "POST"),
|
|
88
99
|
headers
|
|
89
100
|
}, (response) => {
|
|
90
|
-
|
|
91
|
-
response.setEncoding("utf8");
|
|
101
|
+
const chunks = [];
|
|
92
102
|
response.on("data", (chunk) => {
|
|
93
|
-
|
|
103
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
104
|
+
});
|
|
105
|
+
response.on("aborted", () => {
|
|
106
|
+
rejectOnce(new Error("Scout broker response aborted"));
|
|
94
107
|
});
|
|
108
|
+
response.on("error", rejectOnce);
|
|
95
109
|
response.on("end", () => {
|
|
96
|
-
|
|
110
|
+
if (settled)
|
|
111
|
+
return;
|
|
112
|
+
settled = true;
|
|
113
|
+
cleanupAbortListener();
|
|
97
114
|
resolve({
|
|
98
115
|
ok: Boolean(response.statusCode && response.statusCode >= 200 && response.statusCode < 300),
|
|
99
116
|
status: response.statusCode ?? 0,
|
|
100
|
-
text
|
|
117
|
+
text: Buffer.concat(chunks).toString("utf8")
|
|
101
118
|
});
|
|
102
119
|
});
|
|
103
120
|
});
|
|
104
121
|
const handleAbort = () => {
|
|
105
|
-
|
|
122
|
+
const error = options.signal?.reason instanceof Error ? options.signal.reason : new Error("Scout broker request aborted");
|
|
123
|
+
rejectOnce(error);
|
|
124
|
+
request.destroy(error);
|
|
106
125
|
};
|
|
107
|
-
request.on("error",
|
|
108
|
-
options.signal?.removeEventListener("abort", handleAbort);
|
|
109
|
-
reject(error);
|
|
110
|
-
});
|
|
126
|
+
request.on("error", rejectOnce);
|
|
111
127
|
if (options.signal) {
|
|
112
128
|
if (options.signal.aborted) {
|
|
113
129
|
handleAbort();
|
|
@@ -184,6 +200,175 @@ async function requestScoutBrokerJsonWithTrace(baseUrl, path, options = {}) {
|
|
|
184
200
|
return { value: undefined, trace };
|
|
185
201
|
}
|
|
186
202
|
|
|
203
|
+
// packages/runtime/src/schema-version.ts
|
|
204
|
+
var CONTROL_PLANE_SCHEMA_VERSION = 17;
|
|
205
|
+
|
|
206
|
+
// packages/runtime/src/sqlite-adapter.ts
|
|
207
|
+
import { createRequire } from "module";
|
|
208
|
+
|
|
209
|
+
// packages/runtime/src/runtime-adapters.ts
|
|
210
|
+
function detectRuntimeHost(globalScope = globalThis) {
|
|
211
|
+
return typeof globalScope.Bun === "undefined" ? "node" : "bun";
|
|
212
|
+
}
|
|
213
|
+
function normalizeRuntimeHost(value) {
|
|
214
|
+
const normalized = value?.trim().toLowerCase();
|
|
215
|
+
if (normalized === "bun")
|
|
216
|
+
return "bun";
|
|
217
|
+
if (normalized === "node")
|
|
218
|
+
return "node";
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function normalizeRuntimeServiceAdapter(value) {
|
|
222
|
+
const normalized = value?.trim().toLowerCase().replaceAll("_", "-");
|
|
223
|
+
if (normalized === "macos-scoutd" || normalized === "macos-launchd")
|
|
224
|
+
return "macos-scoutd";
|
|
225
|
+
if (normalized === "linux-systemd-user" || normalized === "systemd-user")
|
|
226
|
+
return "linux-systemd-user";
|
|
227
|
+
if (normalized === "headless-foreground" || normalized === "foreground" || normalized === "headless") {
|
|
228
|
+
return "headless-foreground";
|
|
229
|
+
}
|
|
230
|
+
if (normalized === "windows-service")
|
|
231
|
+
return "windows-service";
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function defaultServiceAdapterForPlatform(platform = process.platform, env = process.env) {
|
|
235
|
+
const explicit = normalizeRuntimeServiceAdapter(env.OPENSCOUT_SERVICE_ADAPTER);
|
|
236
|
+
if (explicit)
|
|
237
|
+
return explicit;
|
|
238
|
+
if (normalizeRuntimeHost(env.OPENSCOUT_RUNTIME_HOST) === "node") {
|
|
239
|
+
return "headless-foreground";
|
|
240
|
+
}
|
|
241
|
+
if (platform === "darwin")
|
|
242
|
+
return "macos-scoutd";
|
|
243
|
+
if (platform === "linux")
|
|
244
|
+
return "headless-foreground";
|
|
245
|
+
if (platform === "win32")
|
|
246
|
+
return "windows-service";
|
|
247
|
+
return "headless-foreground";
|
|
248
|
+
}
|
|
249
|
+
function planRuntimeAdapters(options = {}) {
|
|
250
|
+
const env = options.env ?? process.env;
|
|
251
|
+
const host = options.host ?? normalizeRuntimeHost(env.OPENSCOUT_RUNTIME_HOST) ?? detectRuntimeHost();
|
|
252
|
+
return {
|
|
253
|
+
host,
|
|
254
|
+
database: host === "bun" ? "bun-sqlite" : "node-sqlite",
|
|
255
|
+
httpServer: host === "bun" ? "bun-serve" : "node-http-ws",
|
|
256
|
+
files: host === "bun" ? "bun-file" : "node-fs",
|
|
257
|
+
process: host === "bun" ? "bun-spawn" : "node-child-process",
|
|
258
|
+
service: defaultServiceAdapterForPlatform(options.platform, env)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// packages/runtime/src/sqlite-adapter.ts
|
|
263
|
+
var require2 = createRequire(import.meta.url);
|
|
264
|
+
function controlPlaneSqliteAdapterKind() {
|
|
265
|
+
return planRuntimeAdapters().database;
|
|
266
|
+
}
|
|
267
|
+
function openControlPlaneSqliteDatabase(path, options) {
|
|
268
|
+
return openRuntimeSqliteDatabase(path, options);
|
|
269
|
+
}
|
|
270
|
+
function openRuntimeSqliteDatabase(path, options) {
|
|
271
|
+
const adapter = controlPlaneSqliteAdapterKind();
|
|
272
|
+
if (adapter === "bun-sqlite") {
|
|
273
|
+
const { Database } = require2("bun:sqlite");
|
|
274
|
+
return new Database(path, options);
|
|
275
|
+
}
|
|
276
|
+
const { DatabaseSync } = require2("node:sqlite");
|
|
277
|
+
return new NodeSqliteDatabaseAdapter(new DatabaseSync(path, {
|
|
278
|
+
open: true,
|
|
279
|
+
readOnly: options?.readonly === true
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
function prepareNodeSqliteSql(sql) {
|
|
283
|
+
const numberedParamIndexes = [];
|
|
284
|
+
const normalizedSql = sql.replace(/\?(\d+)/g, (_match, rawIndex) => {
|
|
285
|
+
numberedParamIndexes.push(Number.parseInt(rawIndex, 10) - 1);
|
|
286
|
+
return "?";
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
sql: normalizedSql,
|
|
290
|
+
numberedParamIndexes: numberedParamIndexes.length > 0 ? numberedParamIndexes : null
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function bindNodeSqliteParams(numberedParamIndexes, params) {
|
|
294
|
+
if (!numberedParamIndexes) {
|
|
295
|
+
return params;
|
|
296
|
+
}
|
|
297
|
+
return numberedParamIndexes.map((index) => params[index]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
class NodeSqliteStatementAdapter {
|
|
301
|
+
statement;
|
|
302
|
+
numberedParamIndexes;
|
|
303
|
+
constructor(statement, numberedParamIndexes) {
|
|
304
|
+
this.statement = statement;
|
|
305
|
+
this.numberedParamIndexes = numberedParamIndexes;
|
|
306
|
+
}
|
|
307
|
+
all(...params) {
|
|
308
|
+
return this.statement.all(...bindNodeSqliteParams(this.numberedParamIndexes, params));
|
|
309
|
+
}
|
|
310
|
+
get(...params) {
|
|
311
|
+
return this.statement.get(...bindNodeSqliteParams(this.numberedParamIndexes, params)) ?? null;
|
|
312
|
+
}
|
|
313
|
+
run(...params) {
|
|
314
|
+
return this.statement.run(...bindNodeSqliteParams(this.numberedParamIndexes, params));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
class NodeSqliteDatabaseAdapter {
|
|
319
|
+
database;
|
|
320
|
+
transactionDepth = 0;
|
|
321
|
+
savepointId = 0;
|
|
322
|
+
constructor(database) {
|
|
323
|
+
this.database = database;
|
|
324
|
+
}
|
|
325
|
+
exec(sql) {
|
|
326
|
+
return this.database.exec(sql);
|
|
327
|
+
}
|
|
328
|
+
query(sql) {
|
|
329
|
+
const prepared = prepareNodeSqliteSql(sql);
|
|
330
|
+
return new NodeSqliteStatementAdapter(this.database.prepare(prepared.sql), prepared.numberedParamIndexes);
|
|
331
|
+
}
|
|
332
|
+
close() {
|
|
333
|
+
this.database.close();
|
|
334
|
+
}
|
|
335
|
+
transaction(callback) {
|
|
336
|
+
return (...args) => {
|
|
337
|
+
if (this.transactionDepth > 0) {
|
|
338
|
+
return this.runSavepoint(callback, args);
|
|
339
|
+
}
|
|
340
|
+
this.database.exec("BEGIN IMMEDIATE;");
|
|
341
|
+
this.transactionDepth += 1;
|
|
342
|
+
try {
|
|
343
|
+
const result = callback(...args);
|
|
344
|
+
this.database.exec("COMMIT;");
|
|
345
|
+
return result;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
this.database.exec("ROLLBACK;");
|
|
348
|
+
throw error;
|
|
349
|
+
} finally {
|
|
350
|
+
this.transactionDepth -= 1;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
runSavepoint(callback, args) {
|
|
355
|
+
const savepointName = `openscout_nested_${this.savepointId++}`;
|
|
356
|
+
this.database.exec(`SAVEPOINT ${savepointName};`);
|
|
357
|
+
this.transactionDepth += 1;
|
|
358
|
+
try {
|
|
359
|
+
const result = callback(...args);
|
|
360
|
+
this.database.exec(`RELEASE SAVEPOINT ${savepointName};`);
|
|
361
|
+
return result;
|
|
362
|
+
} catch (error) {
|
|
363
|
+
this.database.exec(`ROLLBACK TO SAVEPOINT ${savepointName};`);
|
|
364
|
+
this.database.exec(`RELEASE SAVEPOINT ${savepointName};`);
|
|
365
|
+
throw error;
|
|
366
|
+
} finally {
|
|
367
|
+
this.transactionDepth -= 1;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
187
372
|
// packages/runtime/src/support-paths.ts
|
|
188
373
|
import { homedir } from "os";
|
|
189
374
|
import { join } from "path";
|
|
@@ -811,7 +996,7 @@ var SCOUT_HOST_PROBE_SCHEMA_VERSIONS = {
|
|
|
811
996
|
"git.mergeBase": 1,
|
|
812
997
|
"git.logLastCommitUnix": 1,
|
|
813
998
|
"git.worktreeListPorcelain": 1,
|
|
814
|
-
"tmux.sessions":
|
|
999
|
+
"tmux.sessions": 2,
|
|
815
1000
|
"tmux.panes": 1,
|
|
816
1001
|
"zellij.sessions": 1,
|
|
817
1002
|
"ps.runtime": 1,
|
|
@@ -1570,6 +1755,8 @@ var tailscaleStatusProbe = defineProbe({
|
|
|
1570
1755
|
|
|
1571
1756
|
// packages/runtime/src/tailscale.ts
|
|
1572
1757
|
var DEFAULT_TAILSCALE_STATUS_TIMEOUT_MS2 = 1500;
|
|
1758
|
+
var SYNC_TAILSCALE_STATUS_CACHE_MS = 30000;
|
|
1759
|
+
var syncStatusCache = null;
|
|
1573
1760
|
function readStatusJsonFromFileSync(filePath) {
|
|
1574
1761
|
const raw = readFileSync2(filePath, "utf8");
|
|
1575
1762
|
return parseTailscaleStatusJson(raw);
|
|
@@ -1594,6 +1781,15 @@ function readStatusJsonSync(env = process.env) {
|
|
|
1594
1781
|
if (!tailscaleBin) {
|
|
1595
1782
|
return null;
|
|
1596
1783
|
}
|
|
1784
|
+
const cacheKey = [
|
|
1785
|
+
tailscaleBin,
|
|
1786
|
+
env.OPENSCOUT_TAILSCALE_AUTO_HOSTS ?? "",
|
|
1787
|
+
env.OPENSCOUT_TAILSCALE_STATUS_TIMEOUT_MS ?? ""
|
|
1788
|
+
].join("\x00");
|
|
1789
|
+
const cached = syncStatusCache;
|
|
1790
|
+
if (env === process.env && cached?.key === cacheKey && Date.now() - cached.at < SYNC_TAILSCALE_STATUS_CACHE_MS) {
|
|
1791
|
+
return cached.value;
|
|
1792
|
+
}
|
|
1597
1793
|
try {
|
|
1598
1794
|
const stdout = execFileSync(tailscaleBin, ["status", "--json"], {
|
|
1599
1795
|
encoding: "utf8",
|
|
@@ -1601,8 +1797,13 @@ function readStatusJsonSync(env = process.env) {
|
|
|
1601
1797
|
timeout: statusTimeoutMs2(env),
|
|
1602
1798
|
windowsHide: true
|
|
1603
1799
|
});
|
|
1604
|
-
|
|
1800
|
+
const value = parseTailscaleStatusJson(stdout);
|
|
1801
|
+
if (env === process.env)
|
|
1802
|
+
syncStatusCache = { key: cacheKey, at: Date.now(), value };
|
|
1803
|
+
return value;
|
|
1605
1804
|
} catch {
|
|
1805
|
+
if (env === process.env)
|
|
1806
|
+
syncStatusCache = { key: cacheKey, at: Date.now(), value: null };
|
|
1606
1807
|
return null;
|
|
1607
1808
|
}
|
|
1608
1809
|
}
|
|
@@ -1853,44 +2054,6 @@ function findExecutableOnSearchPath(name, env) {
|
|
|
1853
2054
|
return null;
|
|
1854
2055
|
}
|
|
1855
2056
|
|
|
1856
|
-
// packages/runtime/src/runtime-adapters.ts
|
|
1857
|
-
function normalizeRuntimeHost(value) {
|
|
1858
|
-
const normalized = value?.trim().toLowerCase();
|
|
1859
|
-
if (normalized === "bun")
|
|
1860
|
-
return "bun";
|
|
1861
|
-
if (normalized === "node")
|
|
1862
|
-
return "node";
|
|
1863
|
-
return null;
|
|
1864
|
-
}
|
|
1865
|
-
function normalizeRuntimeServiceAdapter(value) {
|
|
1866
|
-
const normalized = value?.trim().toLowerCase().replaceAll("_", "-");
|
|
1867
|
-
if (normalized === "macos-scoutd" || normalized === "macos-launchd")
|
|
1868
|
-
return "macos-scoutd";
|
|
1869
|
-
if (normalized === "linux-systemd-user" || normalized === "systemd-user")
|
|
1870
|
-
return "linux-systemd-user";
|
|
1871
|
-
if (normalized === "headless-foreground" || normalized === "foreground" || normalized === "headless") {
|
|
1872
|
-
return "headless-foreground";
|
|
1873
|
-
}
|
|
1874
|
-
if (normalized === "windows-service")
|
|
1875
|
-
return "windows-service";
|
|
1876
|
-
return null;
|
|
1877
|
-
}
|
|
1878
|
-
function defaultServiceAdapterForPlatform(platform = process.platform, env = process.env) {
|
|
1879
|
-
const explicit = normalizeRuntimeServiceAdapter(env.OPENSCOUT_SERVICE_ADAPTER);
|
|
1880
|
-
if (explicit)
|
|
1881
|
-
return explicit;
|
|
1882
|
-
if (normalizeRuntimeHost(env.OPENSCOUT_RUNTIME_HOST) === "node") {
|
|
1883
|
-
return "headless-foreground";
|
|
1884
|
-
}
|
|
1885
|
-
if (platform === "darwin")
|
|
1886
|
-
return "macos-scoutd";
|
|
1887
|
-
if (platform === "linux")
|
|
1888
|
-
return "headless-foreground";
|
|
1889
|
-
if (platform === "win32")
|
|
1890
|
-
return "windows-service";
|
|
1891
|
-
return "headless-foreground";
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
2057
|
// packages/runtime/src/broker-process-manager.ts
|
|
1895
2058
|
function isTmpPath(p) {
|
|
1896
2059
|
return /^\/(?:private\/)?tmp\//.test(p);
|
|
@@ -2066,12 +2229,12 @@ function resolveBrokerServiceLabel(mode) {
|
|
|
2066
2229
|
}
|
|
2067
2230
|
switch (mode) {
|
|
2068
2231
|
case "prod":
|
|
2069
|
-
return "
|
|
2232
|
+
return "app.openscout";
|
|
2070
2233
|
case "custom":
|
|
2071
|
-
return "
|
|
2234
|
+
return "app.openscout.custom";
|
|
2072
2235
|
case "dev":
|
|
2073
2236
|
default:
|
|
2074
|
-
return "
|
|
2237
|
+
return "app.openscout";
|
|
2075
2238
|
}
|
|
2076
2239
|
}
|
|
2077
2240
|
function resolveBrokerServiceConfig() {
|
|
@@ -2238,13 +2401,16 @@ function readRuntimeFreshness(value) {
|
|
|
2238
2401
|
state,
|
|
2239
2402
|
intentional: readBoolean(value.intentional) ?? false,
|
|
2240
2403
|
basis,
|
|
2404
|
+
reasonCode: readString2(value.reasonCode) ?? null,
|
|
2241
2405
|
artifactCommit: readString2(value.artifactCommit) ?? null,
|
|
2242
2406
|
expectedCommit: readString2(value.expectedCommit) ?? null,
|
|
2243
2407
|
pin: readString2(value.pin) ?? null,
|
|
2244
2408
|
pinReason: readString2(value.pinReason) ?? null,
|
|
2245
2409
|
manifestPath: readString2(value.manifestPath) ?? null,
|
|
2246
2410
|
version: readString2(value.version) ?? null,
|
|
2247
|
-
|
|
2411
|
+
actualBuiltAt: readString2(value.actualBuiltAt) ?? readString2(value.builtAt) ?? null,
|
|
2412
|
+
expectedBuiltAt: readString2(value.expectedBuiltAt) ?? null,
|
|
2413
|
+
builtAt: readString2(value.builtAt) ?? readString2(value.actualBuiltAt) ?? null,
|
|
2248
2414
|
sourceDirty: readBoolean(value.sourceDirty) ?? null,
|
|
2249
2415
|
detail
|
|
2250
2416
|
};
|
|
@@ -2374,7 +2540,30 @@ function spawnScoutdJson(scoutdPath, command, env, timeoutMs) {
|
|
|
2374
2540
|
});
|
|
2375
2541
|
});
|
|
2376
2542
|
}
|
|
2543
|
+
var SCHEMA_GUARDED_SERVICE_COMMANDS = new Set([
|
|
2544
|
+
"install",
|
|
2545
|
+
"start",
|
|
2546
|
+
"restart"
|
|
2547
|
+
]);
|
|
2548
|
+
function assertBrokerServiceSchemaCompatible(config) {
|
|
2549
|
+
const databasePath = join5(config.controlHome, "control-plane.sqlite");
|
|
2550
|
+
if (!existsSync5(databasePath))
|
|
2551
|
+
return;
|
|
2552
|
+
const database = openControlPlaneSqliteDatabase(databasePath, { readonly: true });
|
|
2553
|
+
try {
|
|
2554
|
+
const row = database.query("PRAGMA user_version").get();
|
|
2555
|
+
const databaseVersion = row?.user_version ?? 0;
|
|
2556
|
+
if (databaseVersion > CONTROL_PLANE_SCHEMA_VERSION) {
|
|
2557
|
+
throw new Error(`Refusing to change the Scout service: candidate runtime schema v${CONTROL_PLANE_SCHEMA_VERSION} ` + `is older than control-plane database schema v${databaseVersion}. ` + "The existing service was left untouched. Update or rebase this checkout before restarting Scout.");
|
|
2558
|
+
}
|
|
2559
|
+
} finally {
|
|
2560
|
+
database.close?.();
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2377
2563
|
async function runScoutdServiceCommand(command, config, timeoutMs = SCOUTD_DEFAULT_TIMEOUT_MS, runScoutdJson = spawnScoutdJson) {
|
|
2564
|
+
if (SCHEMA_GUARDED_SERVICE_COMMANDS.has(command)) {
|
|
2565
|
+
assertBrokerServiceSchemaCompatible(config);
|
|
2566
|
+
}
|
|
2378
2567
|
const scoutd = resolveScoutdCommand(config);
|
|
2379
2568
|
if (!scoutd) {
|
|
2380
2569
|
throw new Error("Unable to locate scoutd for broker service management. Build scoutd with `npm run scoutd:build`, install a package that includes scoutd, or set OPENSCOUT_SCOUTD_BIN.");
|
|
@@ -2609,6 +2798,9 @@ function formatBrokerServiceStatus(status) {
|
|
|
2609
2798
|
];
|
|
2610
2799
|
if (status.runtimeFreshness) {
|
|
2611
2800
|
lines.push(`runtime freshness detail: ${status.runtimeFreshness.detail}`);
|
|
2801
|
+
if (status.runtimeFreshness.reasonCode) {
|
|
2802
|
+
lines.push(`runtime freshness reason: ${status.runtimeFreshness.reasonCode}`);
|
|
2803
|
+
}
|
|
2612
2804
|
}
|
|
2613
2805
|
if (status.health.socketFallbackError) {
|
|
2614
2806
|
lines.push(`socket fallback: ${status.health.socketFallbackError}`);
|
|
@@ -2626,6 +2818,141 @@ if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1] && !pr
|
|
|
2626
2818
|
});
|
|
2627
2819
|
}
|
|
2628
2820
|
|
|
2821
|
+
// packages/runtime/src/scout-ascii-mark.ts
|
|
2822
|
+
var ORB_COLS = 60;
|
|
2823
|
+
var ORB_ROWS = 47;
|
|
2824
|
+
var ORB_FIELD = "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";
|
|
2825
|
+
var ORB_CEIL = 0.83;
|
|
2826
|
+
var ORB_GAMMA = 0.72;
|
|
2827
|
+
var ORB_GAIN = 1.55;
|
|
2828
|
+
var ORB_TONES = 4;
|
|
2829
|
+
var ORB_GLYPH = "\u2591";
|
|
2830
|
+
var ORB_BAYER = [
|
|
2831
|
+
[0.125, 0.625],
|
|
2832
|
+
[0.875, 0.375]
|
|
2833
|
+
];
|
|
2834
|
+
var ORB_SHIMMER_AMP = 0.34;
|
|
2835
|
+
var ORB_STILL = 0.42;
|
|
2836
|
+
var ORB_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2837
|
+
function clamp01(v) {
|
|
2838
|
+
return Math.max(0, Math.min(1, v));
|
|
2839
|
+
}
|
|
2840
|
+
function fieldRaw(x, y) {
|
|
2841
|
+
return ORB_ALPHABET.indexOf(ORB_FIELD[y * ORB_COLS + x]) / 63;
|
|
2842
|
+
}
|
|
2843
|
+
function isOccupied(raw, x, y) {
|
|
2844
|
+
let base = clamp01(raw) / ORB_CEIL;
|
|
2845
|
+
base = Math.pow(clamp01(base), ORB_GAMMA);
|
|
2846
|
+
return base * ORB_GAIN > ORB_BAYER[y % 2][x % 2];
|
|
2847
|
+
}
|
|
2848
|
+
function orbShimmer(x, y, t) {
|
|
2849
|
+
const nx = x / (ORB_COLS - 1) * 2 - 1;
|
|
2850
|
+
const ny = y / (ORB_ROWS - 1) * 2 - 1;
|
|
2851
|
+
const a = 120 * Math.PI / 180;
|
|
2852
|
+
const u = nx * Math.cos(a) + ny * Math.sin(a) - t;
|
|
2853
|
+
const c = Math.pow(Math.cos(u * Math.PI * 2) * 0.5 + 0.5, 2.8);
|
|
2854
|
+
return 1 - ORB_SHIMMER_AMP + ORB_SHIMMER_AMP * c * 2;
|
|
2855
|
+
}
|
|
2856
|
+
function toneFor(raw, x, y, t) {
|
|
2857
|
+
let v = clamp01(raw * orbShimmer(x, y, t)) / ORB_CEIL;
|
|
2858
|
+
v = Math.pow(clamp01(v), ORB_GAMMA);
|
|
2859
|
+
const step = Math.min(ORB_TONES - 1, Math.max(0, Math.floor(v * ORB_TONES)));
|
|
2860
|
+
return Math.round(step * 4 / (ORB_TONES - 1));
|
|
2861
|
+
}
|
|
2862
|
+
function renderScoutAsciiMarkFrame(t) {
|
|
2863
|
+
const layers = [[], [], [], [], []];
|
|
2864
|
+
for (let y = 0;y < ORB_ROWS; y += 1) {
|
|
2865
|
+
const rows = ["", "", "", "", ""];
|
|
2866
|
+
for (let x = 0;x < ORB_COLS; x += 1) {
|
|
2867
|
+
const raw = fieldRaw(x, y);
|
|
2868
|
+
if (!isOccupied(raw, x, y)) {
|
|
2869
|
+
for (let i = 0;i < 5; i += 1)
|
|
2870
|
+
rows[i] += " ";
|
|
2871
|
+
continue;
|
|
2872
|
+
}
|
|
2873
|
+
const tone = toneFor(raw, x, y, t);
|
|
2874
|
+
for (let i = 0;i < 5; i += 1) {
|
|
2875
|
+
rows[i] += i === tone ? ORB_GLYPH : " ";
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
for (let i = 0;i < 5; i += 1)
|
|
2879
|
+
layers[i].push(rows[i]);
|
|
2880
|
+
}
|
|
2881
|
+
return layers.map((rows) => rows.join(`
|
|
2882
|
+
`));
|
|
2883
|
+
}
|
|
2884
|
+
function renderScoutAsciiMarkHtml() {
|
|
2885
|
+
return renderScoutAsciiMarkFrame(ORB_STILL).map((text, i) => `<pre class="orb-l" data-t="${i}">${text}</pre>`).join("");
|
|
2886
|
+
}
|
|
2887
|
+
function renderScoutAsciiMarkScript() {
|
|
2888
|
+
return `<script>
|
|
2889
|
+
(function () {
|
|
2890
|
+
var els = document.querySelectorAll(".orb-l");
|
|
2891
|
+
if (els.length !== 5 || !window.requestAnimationFrame) return;
|
|
2892
|
+
var mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
2893
|
+
var F = "${ORB_FIELD}";
|
|
2894
|
+
var A = "${ORB_ALPHABET}";
|
|
2895
|
+
var COLS = ${ORB_COLS}, ROWS = ${ORB_ROWS};
|
|
2896
|
+
var BAYER = [[0.125, 0.625], [0.875, 0.375]];
|
|
2897
|
+
var CEIL = ${ORB_CEIL}, GAMMA = ${ORB_GAMMA}, GAIN = ${ORB_GAIN};
|
|
2898
|
+
var TONES = ${ORB_TONES}, AMP = ${ORB_SHIMMER_AMP};
|
|
2899
|
+
var STILL = ${ORB_STILL};
|
|
2900
|
+
var raf = 0, last = 0;
|
|
2901
|
+
|
|
2902
|
+
function clamp01(v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
|
2903
|
+
|
|
2904
|
+
function occupied(raw, x, y) {
|
|
2905
|
+
var base = Math.pow(clamp01(clamp01(raw) / CEIL), GAMMA);
|
|
2906
|
+
return base * GAIN > BAYER[y % 2][x % 2];
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
function toneOf(raw, x, y, t) {
|
|
2910
|
+
var nx = (x / (COLS - 1)) * 2 - 1;
|
|
2911
|
+
var ny = (y / (ROWS - 1)) * 2 - 1;
|
|
2912
|
+
var u = nx * Math.cos(2.0943951) + ny * Math.sin(2.0943951) - t;
|
|
2913
|
+
var c = Math.pow(Math.cos(u * Math.PI * 2) * 0.5 + 0.5, 2.8);
|
|
2914
|
+
var shimmer = 1 - AMP + AMP * c * 2;
|
|
2915
|
+
var v = Math.pow(clamp01(clamp01(raw * shimmer) / CEIL), GAMMA);
|
|
2916
|
+
var step = Math.min(TONES - 1, Math.max(0, Math.floor(v * TONES)));
|
|
2917
|
+
return Math.round(step * 4 / (TONES - 1));
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
function frame(t) {
|
|
2921
|
+
var out = ["", "", "", "", ""];
|
|
2922
|
+
for (var y = 0; y < ROWS; y++) {
|
|
2923
|
+
for (var x = 0; x < COLS; x++) {
|
|
2924
|
+
var raw = A.indexOf(F.charAt(y * COLS + x)) / 63;
|
|
2925
|
+
if (!occupied(raw, x, y)) {
|
|
2926
|
+
for (var i = 0; i < 5; i++) out[i] += " ";
|
|
2927
|
+
} else {
|
|
2928
|
+
var tone = toneOf(raw, x, y, t);
|
|
2929
|
+
for (var j = 0; j < 5; j++) out[j] += j === tone ? "\\u2591" : " ";
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
if (y < ROWS - 1) for (var k = 0; k < 5; k++) out[k] += "\\n";
|
|
2933
|
+
}
|
|
2934
|
+
for (var m = 0; m < 5; m++) els[m].textContent = out[m];
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
function loop(ts) {
|
|
2938
|
+
raf = requestAnimationFrame(loop);
|
|
2939
|
+
if (ts - last < 48) return;
|
|
2940
|
+
last = ts;
|
|
2941
|
+
frame(STILL + (ts / 1000) * 0.38);
|
|
2942
|
+
}
|
|
2943
|
+
function sync() {
|
|
2944
|
+
cancelAnimationFrame(raf);
|
|
2945
|
+
raf = 0;
|
|
2946
|
+
if (mq.matches || document.hidden) frame(STILL);
|
|
2947
|
+
else raf = requestAnimationFrame(loop);
|
|
2948
|
+
}
|
|
2949
|
+
if (mq.addEventListener) mq.addEventListener("change", sync);
|
|
2950
|
+
document.addEventListener("visibilitychange", sync);
|
|
2951
|
+
sync();
|
|
2952
|
+
})();
|
|
2953
|
+
</script>`;
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2629
2956
|
// packages/runtime/src/local-edge.ts
|
|
2630
2957
|
function normalizeViteHmrPath(value) {
|
|
2631
2958
|
const trimmed = value?.trim();
|
|
@@ -2719,91 +3046,180 @@ function renderOpenScoutStartPage(config) {
|
|
|
2719
3046
|
<meta charset="utf-8">
|
|
2720
3047
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
2721
3048
|
<title>Start Scout</title>
|
|
3049
|
+
<script>
|
|
3050
|
+
(function () {
|
|
3051
|
+
var theme = "dark";
|
|
3052
|
+
try {
|
|
3053
|
+
var query = new URLSearchParams(window.location.search).get("theme");
|
|
3054
|
+
var stored = JSON.parse(window.localStorage.getItem("openscout.theme") || "{}").theme;
|
|
3055
|
+
var preference = query || stored;
|
|
3056
|
+
if (preference === "light") theme = "light";
|
|
3057
|
+
if (preference === "system") {
|
|
3058
|
+
theme = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
|
|
3059
|
+
}
|
|
3060
|
+
} catch {}
|
|
3061
|
+
document.documentElement.dataset.scoutTheme = theme;
|
|
3062
|
+
})();
|
|
3063
|
+
</script>
|
|
2722
3064
|
<style>
|
|
2723
3065
|
:root {
|
|
2724
3066
|
color-scheme: light dark;
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
3067
|
+
--bg: #080a07;
|
|
3068
|
+
--surface: #10130e;
|
|
3069
|
+
--ink: #f5f1e8;
|
|
3070
|
+
--muted: #aaa69b;
|
|
3071
|
+
--edge: #303729;
|
|
3072
|
+
--accent: #a6e15e;
|
|
3073
|
+
--orb-0: #2a2723;
|
|
3074
|
+
--orb-1: #444038;
|
|
3075
|
+
--orb-2: #6d675a;
|
|
3076
|
+
--orb-3: #9a9181;
|
|
3077
|
+
--orb-4: #d8d0c0;
|
|
3078
|
+
font-family: "Inter Tight", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
3079
|
+
background: var(--bg);
|
|
3080
|
+
color: var(--ink);
|
|
2728
3081
|
}
|
|
2729
3082
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2730
3083
|
body {
|
|
2731
3084
|
min-height: 100vh;
|
|
2732
3085
|
display: grid;
|
|
2733
3086
|
place-items: center;
|
|
2734
|
-
padding: 32px;
|
|
2735
|
-
background:
|
|
2736
|
-
radial-gradient(ellipse at 15% 30%, rgba(91, 141, 239, 0.16) 0%, transparent 50%),
|
|
2737
|
-
radial-gradient(ellipse at 85% 70%, rgba(74, 222, 128, 0.06) 0%, transparent 40%),
|
|
2738
|
-
#111827;
|
|
3087
|
+
padding: 32px 28px;
|
|
3088
|
+
background: var(--bg);
|
|
2739
3089
|
}
|
|
2740
3090
|
main {
|
|
2741
|
-
width: min(
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
background: rgba(15, 23, 32, 0.9);
|
|
2746
|
-
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 20px 60px rgba(0, 0, 0, 0.45);
|
|
2747
|
-
}
|
|
2748
|
-
.badge {
|
|
2749
|
-
display: inline-flex;
|
|
3091
|
+
width: min(640px, 100%);
|
|
3092
|
+
}
|
|
3093
|
+
.brand {
|
|
3094
|
+
display: flex;
|
|
2750
3095
|
align-items: center;
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
3096
|
+
justify-content: space-between;
|
|
3097
|
+
gap: 16px;
|
|
3098
|
+
padding-bottom: 14px;
|
|
3099
|
+
margin-bottom: 36px;
|
|
3100
|
+
border-bottom: 1px solid color-mix(in srgb, var(--edge) 80%, transparent);
|
|
3101
|
+
}
|
|
3102
|
+
.host {
|
|
3103
|
+
overflow: hidden;
|
|
3104
|
+
color: var(--muted);
|
|
3105
|
+
font: 500 11px/1.2 ui-monospace, "SF Mono", Menlo, monospace;
|
|
3106
|
+
letter-spacing: 0.08em;
|
|
3107
|
+
text-overflow: ellipsis;
|
|
2756
3108
|
text-transform: uppercase;
|
|
2757
|
-
|
|
3109
|
+
white-space: nowrap;
|
|
2758
3110
|
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
3111
|
+
.service {
|
|
3112
|
+
color: var(--muted);
|
|
3113
|
+
font-size: 12px;
|
|
3114
|
+
letter-spacing: 0.01em;
|
|
3115
|
+
white-space: nowrap;
|
|
2762
3116
|
}
|
|
2763
|
-
.
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
flex-shrink: 0;
|
|
2769
|
-
animation: blink 2.4s ease-in-out infinite;
|
|
3117
|
+
.hero {
|
|
3118
|
+
display: grid;
|
|
3119
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
3120
|
+
gap: 24px 36px;
|
|
3121
|
+
align-items: center;
|
|
2770
3122
|
}
|
|
3123
|
+
/* The mark is a second way into the app, not just decoration \u2014 it is the
|
|
3124
|
+
largest, most inviting thing on the page, so clicking it should do what
|
|
3125
|
+
clicking it looks like it should do. It stays aria-hidden and outside the
|
|
3126
|
+
tab order on purpose: 2820 glyph cells are noise to a screen reader, and
|
|
3127
|
+
the real #start button sits beside it as the accessible, keyboard-
|
|
3128
|
+
reachable path. This is a redundant mouse affordance, never the only one. */
|
|
3129
|
+
.orb {
|
|
3130
|
+
position: relative;
|
|
3131
|
+
justify-self: end;
|
|
3132
|
+
user-select: none;
|
|
3133
|
+
cursor: pointer;
|
|
3134
|
+
transition: transform 160ms ease, filter 160ms ease;
|
|
3135
|
+
}
|
|
3136
|
+
.orb:hover { transform: translateY(-1px); filter: brightness(1.18); }
|
|
3137
|
+
.orb:active { transform: translateY(0); filter: brightness(1.05); }
|
|
3138
|
+
.orb[data-busy="true"] { cursor: progress; }
|
|
3139
|
+
.orb[data-busy="true"]:hover { transform: none; filter: none; }
|
|
3140
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3141
|
+
.orb { transition: none; }
|
|
3142
|
+
.orb:hover, .orb:active { transform: none; }
|
|
3143
|
+
}
|
|
3144
|
+
.orb-l {
|
|
3145
|
+
margin: 0;
|
|
3146
|
+
color: var(--orb-0);
|
|
3147
|
+
font: 400 5px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
3148
|
+
letter-spacing: 0;
|
|
3149
|
+
white-space: pre;
|
|
3150
|
+
-webkit-font-smoothing: none;
|
|
3151
|
+
-moz-osx-font-smoothing: unset;
|
|
3152
|
+
font-smooth: never;
|
|
3153
|
+
text-rendering: geometricPrecision;
|
|
3154
|
+
font-variant-ligatures: none;
|
|
3155
|
+
font-kerning: none;
|
|
3156
|
+
}
|
|
3157
|
+
.orb-l + .orb-l { position: absolute; inset: 0; }
|
|
3158
|
+
.orb-l[data-t="1"] { color: var(--orb-1); }
|
|
3159
|
+
.orb-l[data-t="2"] { color: var(--orb-2); }
|
|
3160
|
+
.orb-l[data-t="3"] { color: var(--orb-3); }
|
|
3161
|
+
.orb-l[data-t="4"] { color: var(--orb-4); }
|
|
2771
3162
|
h1 {
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
3163
|
+
margin-bottom: 10px;
|
|
3164
|
+
color: var(--ink);
|
|
3165
|
+
font-size: clamp(24px, 3.6vw, 28px);
|
|
3166
|
+
font-weight: 560;
|
|
3167
|
+
letter-spacing: -0.04em;
|
|
3168
|
+
line-height: 1.12;
|
|
2777
3169
|
}
|
|
2778
3170
|
p {
|
|
3171
|
+
max-width: 34ch;
|
|
3172
|
+
color: var(--muted);
|
|
2779
3173
|
font-size: 14px;
|
|
2780
|
-
color: rgba(245, 247, 251, 0.5);
|
|
2781
3174
|
line-height: 1.55;
|
|
2782
3175
|
margin-bottom: 22px;
|
|
2783
3176
|
}
|
|
2784
3177
|
button {
|
|
2785
|
-
width: 100%;
|
|
2786
3178
|
min-height: 44px;
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
3179
|
+
display: inline-flex;
|
|
3180
|
+
align-items: center;
|
|
3181
|
+
justify-content: center;
|
|
3182
|
+
gap: 8px;
|
|
3183
|
+
border: 1px solid var(--edge);
|
|
3184
|
+
border-radius: 8px;
|
|
3185
|
+
padding: 0 14px;
|
|
3186
|
+
background: var(--surface);
|
|
3187
|
+
color: var(--ink);
|
|
2791
3188
|
font: inherit;
|
|
2792
|
-
font-size:
|
|
2793
|
-
font-weight:
|
|
3189
|
+
font-size: 13px;
|
|
3190
|
+
font-weight: 550;
|
|
3191
|
+
letter-spacing: -0.015em;
|
|
2794
3192
|
cursor: pointer;
|
|
2795
|
-
transition: background
|
|
3193
|
+
transition: background 120ms ease, border-color 120ms ease, color 120ms ease, opacity 120ms ease;
|
|
3194
|
+
}
|
|
3195
|
+
button:hover:not(:disabled) {
|
|
3196
|
+
border-color: color-mix(in srgb, var(--accent) 42%, var(--edge));
|
|
3197
|
+
background: color-mix(in srgb, var(--surface) 88%, var(--accent));
|
|
3198
|
+
}
|
|
3199
|
+
button:active:not(:disabled) {
|
|
3200
|
+
background: color-mix(in srgb, var(--surface) 78%, var(--accent));
|
|
2796
3201
|
}
|
|
2797
|
-
button:
|
|
2798
|
-
button:
|
|
2799
|
-
button
|
|
3202
|
+
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
3203
|
+
button:disabled { cursor: progress; opacity: 0.55; }
|
|
3204
|
+
.button-arrow {
|
|
3205
|
+
color: var(--accent);
|
|
3206
|
+
font-size: 14px;
|
|
3207
|
+
font-weight: 500;
|
|
3208
|
+
line-height: 1;
|
|
3209
|
+
transition: transform 120ms ease;
|
|
3210
|
+
}
|
|
3211
|
+
button:hover:not(:disabled) .button-arrow { transform: translateX(1px); }
|
|
2800
3212
|
.progress {
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
3213
|
+
width: min(220px, 100%);
|
|
3214
|
+
height: 1px;
|
|
3215
|
+
margin-top: 18px;
|
|
3216
|
+
border-radius: 1px;
|
|
3217
|
+
background: color-mix(in srgb, var(--edge) 70%, transparent);
|
|
2805
3218
|
overflow: hidden;
|
|
3219
|
+
opacity: 0;
|
|
3220
|
+
transition: opacity 120ms ease;
|
|
2806
3221
|
}
|
|
3222
|
+
main.is-waiting .progress { opacity: 1; }
|
|
2807
3223
|
@keyframes sweep {
|
|
2808
3224
|
0% { transform: translateX(-100%); }
|
|
2809
3225
|
100% { transform: translateX(500%); }
|
|
@@ -2811,8 +3227,8 @@ function renderOpenScoutStartPage(config) {
|
|
|
2811
3227
|
.progress-bar {
|
|
2812
3228
|
height: 100%;
|
|
2813
3229
|
width: 20%;
|
|
2814
|
-
border-radius:
|
|
2815
|
-
background:
|
|
3230
|
+
border-radius: 1px;
|
|
3231
|
+
background: var(--accent);
|
|
2816
3232
|
transform: translateX(-100%);
|
|
2817
3233
|
}
|
|
2818
3234
|
.progress-bar.running {
|
|
@@ -2822,36 +3238,82 @@ function renderOpenScoutStartPage(config) {
|
|
|
2822
3238
|
display: block;
|
|
2823
3239
|
min-height: 16px;
|
|
2824
3240
|
margin-top: 10px;
|
|
2825
|
-
color:
|
|
3241
|
+
color: var(--muted);
|
|
2826
3242
|
font-family: ui-monospace, "SF Mono", Menlo, "Cascadia Code", monospace;
|
|
2827
|
-
font-size:
|
|
3243
|
+
font-size: 11px;
|
|
2828
3244
|
line-height: 1.4;
|
|
2829
3245
|
}
|
|
3246
|
+
:root[data-scout-theme="dark"] { color-scheme: dark; }
|
|
3247
|
+
:root[data-scout-theme="light"] {
|
|
3248
|
+
color-scheme: light;
|
|
3249
|
+
--bg: #f3f1ea;
|
|
3250
|
+
--surface: #fbfaf5;
|
|
3251
|
+
--ink: #171914;
|
|
3252
|
+
--muted: #65655d;
|
|
3253
|
+
--edge: #c6c8ba;
|
|
3254
|
+
--accent: #3a6807;
|
|
3255
|
+
--orb-0: #d2cec4;
|
|
3256
|
+
--orb-1: #a19d94;
|
|
3257
|
+
--orb-2: #717068;
|
|
3258
|
+
--orb-3: #484b44;
|
|
3259
|
+
--orb-4: #1c2019;
|
|
3260
|
+
}
|
|
3261
|
+
@media (max-width: 520px) {
|
|
3262
|
+
body { place-items: start center; padding: 24px 20px; }
|
|
3263
|
+
main { padding-top: 10vh; }
|
|
3264
|
+
.brand { margin-bottom: 28px; }
|
|
3265
|
+
.service { display: none; }
|
|
3266
|
+
.hero { grid-template-columns: 1fr; gap: 28px; }
|
|
3267
|
+
.orb { order: -1; justify-self: start; }
|
|
3268
|
+
.orb-l { font-size: 4.5px; }
|
|
3269
|
+
h1 { font-size: clamp(22px, 6.5vw, 26px); }
|
|
3270
|
+
p { max-width: none; }
|
|
3271
|
+
button { width: 100%; }
|
|
3272
|
+
.progress { width: 100%; }
|
|
3273
|
+
}
|
|
3274
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3275
|
+
button, .button-arrow, .progress { transition: none; }
|
|
3276
|
+
button:hover:not(:disabled) .button-arrow { transform: none; }
|
|
3277
|
+
.progress-bar.running { animation: none; transform: none; width: 100%; }
|
|
3278
|
+
}
|
|
2830
3279
|
</style>
|
|
2831
3280
|
</head>
|
|
2832
3281
|
<body>
|
|
2833
|
-
<main>
|
|
2834
|
-
<div class="
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
<div class="
|
|
2839
|
-
|
|
3282
|
+
<main id="shell">
|
|
3283
|
+
<div class="brand">
|
|
3284
|
+
<span class="host" id="host">Scout local</span>
|
|
3285
|
+
<span class="service">Local web service</span>
|
|
3286
|
+
</div>
|
|
3287
|
+
<div class="hero">
|
|
3288
|
+
<section>
|
|
3289
|
+
<h1>Bring Scout online.</h1>
|
|
3290
|
+
<p>The web interface is not running yet. Start it to return to your agents, messages, and activity.</p>
|
|
3291
|
+
<button id="start" type="button"><span>Start Scout</span><span class="button-arrow" aria-hidden="true">\u2192</span></button>
|
|
3292
|
+
<div class="progress"><div class="progress-bar" id="bar"></div></div>
|
|
3293
|
+
<output id="status" role="status"></output>
|
|
3294
|
+
</section>
|
|
3295
|
+
<div class="orb" aria-hidden="true">${renderScoutAsciiMarkHtml()}</div>
|
|
3296
|
+
</div>
|
|
2840
3297
|
</main>
|
|
3298
|
+
${renderScoutAsciiMarkScript()}
|
|
2841
3299
|
<script>
|
|
2842
3300
|
const config = ${pageConfig};
|
|
3301
|
+
const shell = document.getElementById('shell');
|
|
3302
|
+
const host = document.getElementById('host');
|
|
2843
3303
|
const button = document.getElementById('start');
|
|
2844
3304
|
const bar = document.getElementById('bar');
|
|
2845
3305
|
const status = document.getElementById('status');
|
|
2846
3306
|
const targetPath = window.location.pathname + window.location.search + window.location.hash;
|
|
2847
3307
|
const healthUrl = new URL('/api/health', window.location.origin);
|
|
2848
3308
|
const startUrl = new URL(config.startPath, window.location.origin);
|
|
3309
|
+
host.textContent = window.location.host;
|
|
2849
3310
|
|
|
2850
3311
|
function setStatus(message) {
|
|
2851
3312
|
status.textContent = message;
|
|
2852
3313
|
}
|
|
2853
3314
|
|
|
2854
3315
|
function setWaiting(on) {
|
|
3316
|
+
shell.classList.toggle('is-waiting', on);
|
|
2855
3317
|
bar.classList.toggle('running', on);
|
|
2856
3318
|
}
|
|
2857
3319
|
|
|
@@ -2873,8 +3335,14 @@ function renderOpenScoutStartPage(config) {
|
|
|
2873
3335
|
return false;
|
|
2874
3336
|
}
|
|
2875
3337
|
|
|
2876
|
-
|
|
3338
|
+
const orb = document.querySelector('.orb');
|
|
3339
|
+
|
|
3340
|
+
async function startScout() {
|
|
3341
|
+
// Both entry points share one guard: the mark can be clicked while the
|
|
3342
|
+
// button is mid-flight, and a second POST would race the first.
|
|
3343
|
+
if (button.disabled) return;
|
|
2877
3344
|
button.disabled = true;
|
|
3345
|
+
if (orb) orb.dataset.busy = 'true';
|
|
2878
3346
|
setWaiting(true);
|
|
2879
3347
|
setStatus('Starting Scout web...');
|
|
2880
3348
|
try {
|
|
@@ -2896,13 +3364,18 @@ function renderOpenScoutStartPage(config) {
|
|
|
2896
3364
|
setWaiting(false);
|
|
2897
3365
|
setStatus('Scout web did not become ready. Try again in a moment.');
|
|
2898
3366
|
button.disabled = false;
|
|
3367
|
+
if (orb) orb.dataset.busy = 'false';
|
|
2899
3368
|
}
|
|
2900
3369
|
} catch (error) {
|
|
2901
3370
|
setWaiting(false);
|
|
2902
3371
|
setStatus(error instanceof Error ? error.message : String(error));
|
|
2903
3372
|
button.disabled = false;
|
|
3373
|
+
if (orb) orb.dataset.busy = 'false';
|
|
2904
3374
|
}
|
|
2905
|
-
}
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
button.addEventListener('click', startScout);
|
|
3378
|
+
if (orb) orb.addEventListener('click', startScout);
|
|
2906
3379
|
</script>
|
|
2907
3380
|
</body>
|
|
2908
3381
|
</html>`;
|
|
@@ -2962,12 +3435,11 @@ var RESTART_MIN_DELAY_MS = 1000;
|
|
|
2962
3435
|
var RESTART_MAX_DELAY_MS = 30000;
|
|
2963
3436
|
var BROKER_HEALTH_TIMEOUT_MS = 30000;
|
|
2964
3437
|
var BROKER_HEALTH_POLL_MS = 250;
|
|
2965
|
-
var CHILD_SHUTDOWN_TIMEOUT_MS =
|
|
3438
|
+
var CHILD_SHUTDOWN_TIMEOUT_MS = 15000;
|
|
2966
3439
|
var WEB_START_RETRY_MS = 5000;
|
|
2967
3440
|
var MENU_BUNDLE_ID = "app.openscout.scout.menu";
|
|
2968
|
-
var MENU_PROCESS_NAME = "ScoutMenu";
|
|
2969
3441
|
var PROCESS_NAME = "scout-base";
|
|
2970
|
-
var
|
|
3442
|
+
var BROKER_PROCESS_NAME = "scout-broker";
|
|
2971
3443
|
var EDGE_PROCESS_NAME = "scout-edge";
|
|
2972
3444
|
var MDNS_PROCESS_NAME = "scout-mdns";
|
|
2973
3445
|
process.title = PROCESS_NAME;
|
|
@@ -2977,10 +3449,11 @@ var caddyProcess = null;
|
|
|
2977
3449
|
var mdnsProcesses = [];
|
|
2978
3450
|
var brokerRestartDelayMs = RESTART_MIN_DELAY_MS;
|
|
2979
3451
|
var edgeRestartDelayMs = RESTART_MIN_DELAY_MS;
|
|
2980
|
-
var supervisedWebPid = null;
|
|
2981
3452
|
var baseKeepAlive = null;
|
|
2982
3453
|
var webStartRetryTimer = null;
|
|
2983
3454
|
var webStartInFlight = false;
|
|
3455
|
+
var parentWatcher = null;
|
|
3456
|
+
var parentPid = Number.parseInt(process.env.OPENSCOUT_PARENT_PID ?? "0", 10);
|
|
2984
3457
|
var config = resolveBrokerServiceConfig();
|
|
2985
3458
|
var brokerControlUrl = buildLocalBrokerControlUrl(config.brokerHost, config.brokerPort);
|
|
2986
3459
|
function log(message, details) {
|
|
@@ -3049,7 +3522,7 @@ function spawnBroker() {
|
|
|
3049
3522
|
runtimeEntrypoint(config),
|
|
3050
3523
|
"broker"
|
|
3051
3524
|
], {
|
|
3052
|
-
argv0:
|
|
3525
|
+
argv0: BROKER_PROCESS_NAME,
|
|
3053
3526
|
cwd: config.runtimePackageDir,
|
|
3054
3527
|
env: {
|
|
3055
3528
|
...process.env,
|
|
@@ -3069,7 +3542,6 @@ function spawnBroker() {
|
|
|
3069
3542
|
brokerProcess.once("exit", (code, signal) => {
|
|
3070
3543
|
log("broker exited", { code, signal });
|
|
3071
3544
|
brokerProcess = null;
|
|
3072
|
-
supervisedWebPid = null;
|
|
3073
3545
|
if (!shuttingDown) {
|
|
3074
3546
|
scheduleBrokerRestart();
|
|
3075
3547
|
}
|
|
@@ -3262,13 +3734,12 @@ async function startWebWhenBrokerIsReady() {
|
|
|
3262
3734
|
signal: AbortSignal.timeout(15000)
|
|
3263
3735
|
});
|
|
3264
3736
|
const body = await response.json();
|
|
3265
|
-
supervisedWebPid = typeof body.pid === "number" ? body.pid : resolvePortListenerPid(Number.parseInt(process.env.OPENSCOUT_WEB_PORT ?? "", 10) || resolveWebPort());
|
|
3266
3737
|
if (!response.ok || body.ok !== true) {
|
|
3267
3738
|
warn("web server did not report healthy", body.error ?? response.statusText);
|
|
3268
3739
|
scheduleWebStartRetry();
|
|
3269
3740
|
return;
|
|
3270
3741
|
}
|
|
3271
|
-
log("web server ready", { pid:
|
|
3742
|
+
log("web server ready", { pid: body.pid ?? null });
|
|
3272
3743
|
} catch (error) {
|
|
3273
3744
|
warn("web server startup failed", error instanceof Error ? error.message : String(error));
|
|
3274
3745
|
scheduleWebStartRetry();
|
|
@@ -3287,22 +3758,17 @@ function scheduleWebStartRetry() {
|
|
|
3287
3758
|
}, WEB_START_RETRY_MS);
|
|
3288
3759
|
webStartRetryTimer.unref();
|
|
3289
3760
|
}
|
|
3290
|
-
function resolvePortListenerPid(port) {
|
|
3291
|
-
const result = spawnSync2("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"], {
|
|
3292
|
-
encoding: "utf8"
|
|
3293
|
-
});
|
|
3294
|
-
if ((result.status ?? 1) !== 0) {
|
|
3295
|
-
return null;
|
|
3296
|
-
}
|
|
3297
|
-
const pid = Number.parseInt(result.stdout.trim().split(/\s+/)[0] ?? "", 10);
|
|
3298
|
-
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
3299
|
-
}
|
|
3300
3761
|
function findRepoMenuBundle() {
|
|
3301
3762
|
let current = dirname4(fileURLToPath2(import.meta.url));
|
|
3302
3763
|
while (true) {
|
|
3303
|
-
const
|
|
3304
|
-
|
|
3305
|
-
|
|
3764
|
+
const distRoot = resolve3(current, "apps", "macos", "dist");
|
|
3765
|
+
const candidates = [
|
|
3766
|
+
resolve3(distRoot, "Scout.app", "Contents", "Library", "LoginItems", "ScoutMenu.app"),
|
|
3767
|
+
resolve3(distRoot, "ScoutMenu.app")
|
|
3768
|
+
];
|
|
3769
|
+
for (const candidate of candidates) {
|
|
3770
|
+
if (existsSync6(candidate))
|
|
3771
|
+
return candidate;
|
|
3306
3772
|
}
|
|
3307
3773
|
const parent = dirname4(current);
|
|
3308
3774
|
if (parent === current) {
|
|
@@ -3329,12 +3795,6 @@ function startMenuBarApp() {
|
|
|
3329
3795
|
warn("menu bar app launch failed", { target: repoBundle ?? MENU_BUNDLE_ID, code });
|
|
3330
3796
|
});
|
|
3331
3797
|
}
|
|
3332
|
-
function stopMenuBarApp() {
|
|
3333
|
-
if (process.platform !== "darwin" || process.env.OPENSCOUT_BASE_MENU_ENABLED === "0") {
|
|
3334
|
-
return;
|
|
3335
|
-
}
|
|
3336
|
-
spawn3("pkill", ["-x", MENU_PROCESS_NAME], { stdio: "ignore" }).unref();
|
|
3337
|
-
}
|
|
3338
3798
|
function isChildExited(child) {
|
|
3339
3799
|
return child.exitCode !== null || child.signalCode !== null;
|
|
3340
3800
|
}
|
|
@@ -3373,14 +3833,6 @@ async function terminateChildProcess(child, label, timeoutMs = CHILD_SHUTDOWN_TI
|
|
|
3373
3833
|
}
|
|
3374
3834
|
await waitForChildExit(child, 2000);
|
|
3375
3835
|
}
|
|
3376
|
-
function stopSupervisedWeb() {
|
|
3377
|
-
if (supervisedWebPid && supervisedWebPid > 0) {
|
|
3378
|
-
try {
|
|
3379
|
-
process.kill(supervisedWebPid, "SIGTERM");
|
|
3380
|
-
} catch {}
|
|
3381
|
-
}
|
|
3382
|
-
supervisedWebPid = null;
|
|
3383
|
-
}
|
|
3384
3836
|
async function shutdown(exitCode = 0) {
|
|
3385
3837
|
if (shuttingDown) {
|
|
3386
3838
|
return;
|
|
@@ -3390,12 +3842,14 @@ async function shutdown(exitCode = 0) {
|
|
|
3390
3842
|
clearInterval(baseKeepAlive);
|
|
3391
3843
|
baseKeepAlive = null;
|
|
3392
3844
|
}
|
|
3845
|
+
if (parentWatcher) {
|
|
3846
|
+
clearInterval(parentWatcher);
|
|
3847
|
+
parentWatcher = null;
|
|
3848
|
+
}
|
|
3393
3849
|
if (webStartRetryTimer) {
|
|
3394
3850
|
clearTimeout(webStartRetryTimer);
|
|
3395
3851
|
webStartRetryTimer = null;
|
|
3396
3852
|
}
|
|
3397
|
-
stopSupervisedWeb();
|
|
3398
|
-
stopMenuBarApp();
|
|
3399
3853
|
const activeCaddyProcess = caddyProcess;
|
|
3400
3854
|
stopEdgeProcesses();
|
|
3401
3855
|
await terminateChildProcess(brokerProcess, "broker");
|
|
@@ -3421,6 +3875,20 @@ for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
|
3421
3875
|
});
|
|
3422
3876
|
});
|
|
3423
3877
|
}
|
|
3878
|
+
if (Number.isFinite(parentPid) && parentPid > 0 && parentPid !== process.pid) {
|
|
3879
|
+
parentWatcher = setInterval(() => {
|
|
3880
|
+
try {
|
|
3881
|
+
process.kill(parentPid, 0);
|
|
3882
|
+
} catch {
|
|
3883
|
+
log(`parent ${parentPid} is gone, shutting down base`);
|
|
3884
|
+
shutdown(0).catch((error) => {
|
|
3885
|
+
warn("shutdown failed", error instanceof Error ? error.message : String(error));
|
|
3886
|
+
process.exit(1);
|
|
3887
|
+
});
|
|
3888
|
+
}
|
|
3889
|
+
}, 2000);
|
|
3890
|
+
parentWatcher.unref();
|
|
3891
|
+
}
|
|
3424
3892
|
log("starting Scout base service", {
|
|
3425
3893
|
label: config.label,
|
|
3426
3894
|
brokerUrl: config.brokerUrl,
|