@openscout/scout 0.2.98 → 0.2.102
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/NOTICE +7 -0
- package/bin/scoutd +0 -0
- package/dist/build-manifest.json +3 -3
- package/dist/client/assets/ActivityScreen-DCALiEXY.js +1 -0
- package/dist/client/assets/{AddProjectForm-fXndbzXT.js → AddProjectForm-DfbjlFfy.js} +1 -1
- package/dist/client/assets/AdventureEvidence-Dzz9VbuE.js +5 -0
- package/dist/client/assets/AdventureReader-ClMxT0e4.js +4 -0
- package/dist/client/assets/AdventureScenery-D548O0x4.js +1 -0
- package/dist/client/assets/AgentAdventures-NwTKeF0F.js +1 -0
- package/dist/client/assets/AgentAvatar-BIwg54Tj.js +1 -0
- package/dist/client/assets/AgentConfigurationScreen-B2Hw0ce1.js +1 -0
- package/dist/client/assets/AgentDefinitionsWorkspace-CwZJ833X.js +1 -0
- package/dist/client/assets/AgentDetailCard-CFDE8TLi.js +1 -0
- package/dist/client/assets/AgentFloorView-l2wNKFob.js +1 -0
- package/dist/client/assets/AgentFloorWorld-BDJmXl3C.js +1 -0
- package/dist/client/assets/AgentInfoScreen-ClZM1wQb.js +1 -0
- package/dist/client/assets/{AgentLaneCard-Cc9uyfBr.js → AgentLaneCard-C6YmwPxQ.js} +1 -1
- package/dist/client/assets/{AgentLaneChrome-Dv2lBFoH.js → AgentLaneChrome-D9uJ4QY7.js} +1 -1
- package/dist/client/assets/{AgentLaneDetailSheet-CGqtqSHQ.js → AgentLaneDetailSheet-KYckCBCX.js} +2 -2
- package/dist/client/assets/{AgentLaneSummaryResize-Di4u6df2.js → AgentLaneSummaryResize-BBYBS3DO.js} +1 -1
- package/dist/client/assets/AgentLanesEmbedScreen-DqHwqY0X.js +1 -0
- package/dist/client/assets/{AgentLanesPreflight-CCGBArIb.js → AgentLanesPreflight-pw2vMO3Q.js} +1 -1
- package/dist/client/assets/AgentLanesView-aAyC7lHf.js +2 -0
- package/dist/client/assets/AgentLiveActions-lYzicnNa.js +1 -0
- package/dist/client/assets/AgentMasterScreen-By6DN0jF.js +1 -0
- package/dist/client/assets/AgentSessions-Cox2zS-e.js +6 -0
- package/dist/client/assets/AgentsConsole-Dq0S_hRA.js +1 -0
- package/dist/client/assets/AgentsScreen-Bi9Lx47B.js +1 -0
- package/dist/client/assets/AgentsSubnav-BOobgtGE.js +1 -0
- package/dist/client/assets/{AstronautSuit-CwB4Dw07.js → AstronautSuit-C-4I5YKi.js} +1 -1
- package/dist/client/assets/AtopView-DKm-ERYC.js +1 -0
- package/dist/client/assets/BackToPicker-Bys9ColC.js +1 -0
- package/dist/client/assets/BriefingDetailScreen-sprFl4Nk.js +1 -0
- package/dist/client/assets/BriefingsScreen-D4Zf31Y6.js +1 -0
- package/dist/client/assets/{BrokerMetadataPanel-BJSwU9XZ.js → BrokerMetadataPanel-1GoSl2BV.js} +1 -1
- package/dist/client/assets/BrokerScreen-CejzhRsB.js +8 -0
- package/dist/client/assets/{CastPicker-CkgTalIt.js → CastPicker-BuwE_JQp.js} +1 -1
- package/dist/client/assets/CharacterFamilyPreview-BniL8sEL.css +1 -0
- package/dist/client/assets/CharacterFamilyPreview-CfO3j8Of.js +1 -0
- package/dist/client/assets/ChatCollapsedStrip-TV0j1xTB.js +1 -0
- package/dist/client/assets/{CodeDiffPane-DfluIWmO.js → CodeDiffPane-DB6-mqtX.js} +1 -1
- package/dist/client/assets/{CodeProjectPicker-By_Wz9ex.js → CodeProjectPicker-B_LNLpIK.js} +1 -1
- package/dist/client/assets/CodeScreen-C9H160XS.js +1 -0
- package/dist/client/assets/CommsCanvas-BR2YS76H.css +1 -0
- package/dist/client/assets/CommsCanvas-DOKw3Q8i.js +1 -0
- package/dist/client/assets/CommsDeck-C18JA7rK.js +1 -0
- package/dist/client/assets/CommsFlowGraph-Czg-KTS0.js +1 -0
- package/dist/client/assets/CommsFlowGraph-vQucylxF.css +1 -0
- package/dist/client/assets/CommsFlowMap-CzBWvSa5.js +1 -0
- package/dist/client/assets/CommsSelection-g1twA-Lb.js +1 -0
- package/dist/client/assets/{ConversationComposer-BUIjWMBi.js → ConversationComposer-B7RU6LKd.js} +1 -1
- package/dist/client/assets/ConversationFeedRows-DVqnZQH0.js +1 -0
- package/dist/client/assets/ConversationHeader-CCSU8uo_.js +1 -0
- package/dist/client/assets/ConversationPanels-C9yCAoJy.js +6 -0
- package/dist/client/assets/ConversationScreen-Brfas2y0.css +1 -0
- package/dist/client/assets/ConversationScreen-tTP6B_F-.js +2 -0
- package/dist/client/assets/ConversationStatus-CK-YfLpi.js +1 -0
- package/dist/client/assets/{CrewAvatar-CZ_faQ_s.js → CrewAvatar-CJhuqTsJ.js} +1 -1
- package/dist/client/assets/CrewSprite-DsQJdu3Z.css +1 -0
- package/dist/client/assets/CrewSprite-hgpA3SWB.js +1 -0
- package/dist/client/assets/CrewWorkspaces-4O8dgRUD.js +1 -0
- package/dist/client/assets/{DataTable-C6aMSilS.js → DataTable-BMOZ1-z8.js} +1 -1
- package/dist/client/assets/DispatchAftermath-DDlwqSCY.js +1 -0
- package/dist/client/assets/DocumentFocusViewer-f12RRQpV.js +1 -0
- package/dist/client/assets/{EmbeddableSurfacesLab-D3iZiS8o.js → EmbeddableSurfacesLab-DGl9EMRV.js} +1 -1
- package/dist/client/assets/{EmptyState-CKPWFSjq.js → EmptyState-uyYN5piI.js} +1 -1
- package/dist/client/assets/{FileViewerPane-CxNbcTYf.js → FileViewerPane-HtiDbj9N.js} +2 -2
- package/dist/client/assets/FlightObserveScreen-DDXfNbsw.js +1 -0
- package/dist/client/assets/FloorContextSheet-DV-SYA0K.js +1 -0
- package/dist/client/assets/FloorExchangePanel-B3TFhjLk.css +1 -0
- package/dist/client/assets/FloorExchangePanel-D59nvRCF.js +1 -0
- package/dist/client/assets/FloorMessagePasses-BCwsz9VS.js +1 -0
- package/dist/client/assets/FloorMessagePasses-nxwwiUom.css +1 -0
- package/dist/client/assets/FloorReplay-BHo79HCD.js +1 -0
- package/dist/client/assets/FloorResourcesSheet-Djrgd_ZU.js +1 -0
- package/dist/client/assets/FloorSavedWork-2tjBoy06.js +1 -0
- package/dist/client/assets/FloorTacticalHUD-Bngao6sn.js +1 -0
- package/dist/client/assets/FollowScreen-eHXOlK-u.js +1 -0
- package/dist/client/assets/{HarnessMark-DttReffF.js → HarnessMark-Bt47OeHy.js} +1 -1
- package/dist/client/assets/HarnessesScreen-M84sFjWY.js +1 -0
- package/dist/client/assets/{HerdrSession-DsuxCtfX.js → HerdrSession-CtJOUn7H.js} +3 -3
- package/dist/client/assets/{HomeHero-DXJo2QSO.js → HomeHero-Cvwx2H0w.js} +1 -1
- package/dist/client/assets/HostAdvisorView-CTJXIc1Q.js +1 -0
- package/dist/client/assets/KnowledgeSearchInspector-DwGMVmFL.js +1 -0
- package/dist/client/assets/KnowledgeSearchScreen-WC0WhFio.js +1 -0
- package/dist/client/assets/{LaneToolHoverCard-t7-XJP-h.js → LaneToolHoverCard-C6YehJqD.js} +1 -1
- package/dist/client/assets/LaneTraceDetailSheet-mAhj7MJi.js +1 -0
- package/dist/client/assets/{LaneTraceEventFocus-BB5DhFQm.js → LaneTraceEventFocus-WLNZZVi_.js} +1 -1
- package/dist/client/assets/MeshCanvas-FDDGE69h.js +3 -0
- package/dist/client/assets/MeshCanvasMinimap-CGRzQCac.js +1 -0
- package/dist/client/assets/MeshScreen-DlfiMlaR.js +1 -0
- package/dist/client/assets/{MeshTopologyView-Dc0GSrKa.js → MeshTopologyView-C2Cv_2gx.js} +2 -2
- package/dist/client/assets/MessagesScreen-BZ7yaGJx.js +1 -0
- package/dist/client/assets/MissionContextRail-CVSZJnvX.js +1 -0
- package/dist/client/assets/MissionControlView-DpGhxG4a.js +1 -0
- package/dist/client/assets/MissionFocusOverlay-B9SiuO-i.js +1 -0
- package/dist/client/assets/MissionLeftAgentRow-DhhRRim0.js +1 -0
- package/dist/client/assets/MissionLogPane-CMBiI29U.js +1 -0
- package/dist/client/assets/NativeAreaScreen-BQyHHRAM.js +1 -0
- package/dist/client/assets/NativeAreaScreen-Ditv-TYW.js +1 -0
- package/dist/client/assets/NativeAreaScreen-Dq3uPSEI.js +1 -0
- package/dist/client/assets/NewAgentModal-Cl4nsGhu.js +1 -0
- package/dist/client/assets/NewChatComposer-JjLbm3W2.js +19 -0
- package/dist/client/assets/{NewChatOrigin-DCn5cWPZ.js → NewChatOrigin-CyPPWTJP.js} +1 -1
- package/dist/client/assets/NodeDetailPanel-BUG8rOb-.js +1 -0
- package/dist/client/assets/NodeMenu-Fw8ATWQA.js +1 -0
- package/dist/client/assets/ObserveEmbedScreen-BPiSXXvm.js +2 -0
- package/dist/client/assets/{ObserveTextFlow-DCJ5EmD8.js → ObserveTextFlow-ET0dD1wO.js} +2 -2
- package/dist/client/assets/{ObservedTopologyPanel-CJVqIqQ2.js → ObservedTopologyPanel-DkEkQzo-.js} +1 -1
- package/dist/client/assets/OpenScoutAppShell-CzKbjwCA.js +22 -0
- package/dist/client/assets/OpsAgentsView-CZbtkcQH.js +1 -0
- package/dist/client/assets/OpsScreen-DJq-aBmX.js +1 -0
- package/dist/client/assets/OpsSubnav-9sURjajO.js +1 -0
- package/dist/client/assets/ProjectAgentProfile-q_1tMJIL.js +1 -0
- package/dist/client/assets/{ProjectAgentProfileBar-CUzZ4Rpx.js → ProjectAgentProfileBar-C1fR65Eh.js} +1 -1
- package/dist/client/assets/ProjectAgentProfileHero-DyEFyTFs.js +1 -0
- package/dist/client/assets/ProjectsInbox-Bs8I__my.js +2 -0
- package/dist/client/assets/ProjectsRail-Deb38OJ1.js +1 -0
- package/dist/client/assets/ProjectsScreen-CgLiYiss.js +1 -0
- package/dist/client/assets/ProjectsThreadAside-C0Yw3yIL.js +1 -0
- package/dist/client/assets/Provider-5Hotn7NQ.js +5 -0
- package/dist/client/assets/{RailRow-B0sRaJc6.css → RailRow-B25zKEub.css} +1 -1
- package/dist/client/assets/RailRow-BYguXNm4.js +1 -0
- package/dist/client/assets/RawSessionsTable-DIhmlvk-.js +1 -0
- package/dist/client/assets/RealtimeVoiceScreen-3oU7b7V5.js +1 -0
- package/dist/client/assets/RenderedWorkerSprite-CvdWO32C.js +1 -0
- package/dist/client/assets/RenderedWorkerSprite-qnTfkd_4.css +1 -0
- package/dist/client/assets/ReplayClock-B7JLTp8A.js +1 -0
- package/dist/client/assets/ReplayLog-DZTpf2CW.js +1 -0
- package/dist/client/assets/ReplayOutpost-CvWQa30T.js +1 -0
- package/dist/client/assets/ReplayOutpost-Y1DvZgeu.css +1 -0
- package/dist/client/assets/{RepoDiffEmbedScreen-mexrJPhW.js → RepoDiffEmbedScreen-Cbu0_PJW.js} +1 -1
- package/dist/client/assets/{RepoDiffPageScreen-DbqX4L3q.js → RepoDiffPageScreen-Chwm6GXL.js} +1 -1
- package/dist/client/assets/RepoDiffViewer-C2mb0Wj-.js +7 -0
- package/dist/client/assets/RepoDiffViewerLazy-BQ6ZCrsq.js +2 -0
- package/dist/client/assets/{ReposScreen-CzbO1Fuy.js → ReposScreen-C7JZQmyh.js} +2 -2
- package/dist/client/assets/RiggedWorkerCharacter-BpYECnyK.css +1 -0
- package/dist/client/assets/RiggedWorkerCharacter-DNe731GE.js +1 -0
- package/dist/client/assets/SageModelStudio-768dRQr4.css +1 -0
- package/dist/client/assets/SageModelStudio-BR1J2D4R.js +4108 -0
- package/dist/client/assets/ScoutDeckSurface-flRamdvE.js +1 -0
- package/dist/client/assets/{ScoutSurface-NlhDsPzg.js → ScoutSurface-BpklGmDL.js} +1 -1
- package/dist/client/assets/{ScoutbotFxLab-l2WAahCg.js → ScoutbotFxLab-DeK7ySWZ.js} +1 -1
- package/dist/client/assets/{SecondaryNav-Cs0_FQdj.js → SecondaryNav-BkTn5tkq.js} +1 -1
- package/dist/client/assets/SessionEmbedScreen-CcQN6xlo.js +1 -0
- package/dist/client/assets/{SessionObserve-CLrHfAKZ.css → SessionObserve-BOBJSfs0.css} +1 -1
- package/dist/client/assets/SessionObserve-DaqDhqDI.js +12 -0
- package/dist/client/assets/SessionObserveEvidence-Drv-D8Oh.js +1 -0
- package/dist/client/assets/SessionRefScreen-BOQ1_ydg.js +1 -0
- package/dist/client/assets/SessionsScreen-R8QKvoey.js +1 -0
- package/dist/client/assets/SettingsDrawer-BDapR4E9.js +3 -0
- package/dist/client/assets/SettingsScreen-DirtO7Z0.js +1 -0
- package/dist/client/assets/SharedFloorCharacter-Bi5_md4R.css +1 -0
- package/dist/client/assets/SharedFloorCharacter-CSYG_t9t.js +1 -0
- package/dist/client/assets/SharedWorkFloor-BCmdeb3Q.css +1 -0
- package/dist/client/assets/SharedWorkFloor-yPWFLZwX.js +2 -0
- package/dist/client/assets/{ShikiPane-C0TuCATU.js → ShikiPane-BudrOxNK.js} +1 -1
- package/dist/client/assets/{SlidePanel-CETQ5NTx.js → SlidePanel-Datu7XG4.js} +1 -1
- package/dist/client/assets/SpriteAvatar-BW1JzkDt.js +1 -0
- package/dist/client/assets/SproutActionSprite-DveCzg6l.js +1 -0
- package/dist/client/assets/{StatusPill-BllrY-eg.js → StatusPill-MxYClPG5.js} +1 -1
- package/dist/client/assets/{TailView-_gKWfaQM.js → TailView-Dn7uWmPz.js} +2 -2
- package/dist/client/assets/Terminal-D-DsQlmV.js +4 -0
- package/dist/client/assets/TerminalEmbedScreen-9Gmln759.js +1 -0
- package/dist/client/assets/TerminalHeaderMount-DCGstkZ4.js +1 -0
- package/dist/client/assets/{TextDocumentSurface-2X1Gw4eA.js → TextDocumentSurface-BhYvAB0o.js} +1 -1
- package/dist/client/assets/{TmuxPeek-CqTJRhkI.js → TmuxPeek-BhK0V9Qt.js} +1 -1
- package/dist/client/assets/{VoicePermissionsPanel-C4vkU-sU.js → VoicePermissionsPanel-CecFWzva.js} +1 -1
- package/dist/client/assets/{WorkDetailScreen-DqGnuK0e.js → WorkDetailScreen-CwtRCm_-.js} +4 -4
- package/dist/client/assets/WorkFilesViewer-DJHftsH9.js +1 -0
- package/dist/client/assets/WorkRunView-CxwAZ2QQ.css +1 -0
- package/dist/client/assets/WorkRunView-x5PH1byG.js +1 -0
- package/dist/client/assets/WorldActorTalk-uIH2jGqA.js +1 -0
- package/dist/client/assets/WorldCharacter-Dn4sIXNP.js +1 -0
- package/dist/client/assets/WorldMinimap-Blqg0d5r.js +1 -0
- package/dist/client/assets/WorldSky-DV9bpvXj.js +1 -0
- package/dist/client/assets/{activity-CzTJ-YMX.js → activity-CSUhvjD0.js} +1 -1
- package/dist/client/assets/{addon-fit-Zx3A7pGS.js → addon-fit-MR98IWES.js} +1 -1
- package/dist/client/assets/{addon-webgl-DitJj-N0.js → addon-webgl-CIIKXrvK.js} +1 -1
- package/dist/client/assets/adventure-evidence-DgQbBmfa.css +1 -0
- package/dist/client/assets/adventure-habitats-v1-CVMbdB_Z.png +0 -0
- package/dist/client/assets/adventure-habitats-v1-M1lcpTJh.js +1 -0
- package/dist/client/assets/adventure-playback-DTfkhIc0.js +3 -0
- package/dist/client/assets/adventure-reader-DM5UDDm9.css +1 -0
- package/dist/client/assets/agent-adventures-DZtWpj6k.css +1 -0
- package/dist/client/assets/agent-autocomplete-CeHQpuG9.js +10 -0
- package/dist/client/assets/{agent-essentials-K9B6kbTS.js → agent-essentials-8t2il7PV.js} +1 -1
- package/dist/client/assets/{agent-floor-CuJr1iK1.css → agent-floor-Dmr9hZHL.css} +1 -1
- package/dist/client/assets/agent-floor-actor-3v9drnxh.js +1 -0
- package/dist/client/assets/agent-floor-world-Bnd1AtwK.css +1 -0
- package/dist/client/assets/agent-floor-world-layout-hfMjuoui.js +1 -0
- package/dist/client/assets/agent-lane-card-model-l0stnU9N.js +1 -0
- package/dist/client/assets/{agent-lane-detail-ppJId6Jc.js → agent-lane-detail-Db7KyAlf.js} +1 -1
- package/dist/client/assets/{agent-lane-preview-BhplDYGf.js → agent-lane-preview-B8lsQJOQ.js} +1 -1
- package/dist/client/assets/{agent-lanes-DlqcEf0l.css → agent-lanes-DmgipV9D.css} +1 -1
- package/dist/client/assets/agent-lanes-model-CX0wTcnF.js +4 -0
- package/dist/client/assets/agent-master-THmq-1k8.css +1 -0
- package/dist/client/assets/agent-master-model-C-KdOFDK.js +1 -0
- package/dist/client/assets/{agent-specialization-CtF_jI34.js → agent-specialization-CiVxQsFT.js} +1 -1
- package/dist/client/assets/agent-state-DDhnFEEP.js +1 -0
- package/dist/client/assets/{api-HFH8wFyb.js → api-B9_IqFKY.js} +1 -1
- package/dist/client/assets/api-CaROe5_H.js +1 -0
- package/dist/client/assets/{arc.es-BNXJqSw7.js → arc.es-BzhWalCl.js} +1 -1
- package/dist/client/assets/{arrow-down-BAGkhHA6.js → arrow-down-WoVlkUmg.js} +1 -1
- package/dist/client/assets/{arrow-left-eToA6GxC.js → arrow-left-PuKdO3NM.js} +1 -1
- package/dist/client/assets/{arrow-right-DTX42clh.js → arrow-right-ldbfp4SZ.js} +1 -1
- package/dist/client/assets/{arrow-up-right-B09GPwFl.js → arrow-up-right-Hn754ybA.js} +1 -1
- package/dist/client/assets/book-open-BlJnpf2U.js +1 -0
- package/dist/client/assets/{bot-WxKXYtEX.js → bot-CfN9PSBF.js} +1 -1
- package/dist/client/assets/broker-display-BkBzyvbR.js +2 -0
- package/dist/client/assets/{cache-CeWH_KzJ.js → cache-DEy9E34b.js} +1 -1
- package/dist/client/assets/{check-Dz2SRHft.js → check-B8dMv3Is.js} +1 -1
- package/dist/client/assets/{chevron-down-D120PY4g.js → chevron-down-B5eMsn5c.js} +1 -1
- package/dist/client/assets/{chevron-right-CowuvuE6.js → chevron-right-C7UGFpkl.js} +1 -1
- package/dist/client/assets/chevron-up-BHOEgHcn.js +1 -0
- package/dist/client/assets/{chunk-HRAB3GC3-KjjrTLCU.js → chunk-HRAB3GC3-C5X-kFhb.js} +1 -1
- package/dist/client/assets/chunk-JTPDIGGW-ZC-98AHT.js +46 -0
- package/dist/client/assets/{chunk-T65CQEWV-H2QEKfr1.js → chunk-T65CQEWV-CSVUz2rY.js} +1 -1
- package/dist/client/assets/chunk-YOZR3KYS-B59jqwO0.js +2 -0
- package/dist/client/assets/{clock-_9FDplIT.js → clock-DFcRbtrl.js} +1 -1
- package/dist/client/assets/{code-xml-CkkNdRmu.js → code-xml-BmyLM0I2.js} +1 -1
- package/dist/client/assets/coffee-C_D9zooM.js +1 -0
- package/dist/client/assets/colors-CFlbwC25.js +1 -0
- package/dist/client/assets/comms-deck-C8nVeMBh.css +1 -0
- package/dist/client/assets/comms-deck-CBhsXnY-.js +2 -0
- package/dist/client/assets/comms-gesture-_aGFo6g3.js +2 -0
- package/dist/client/assets/{compass-BdpImt_W.js → compass-DTZdCpv9.js} +1 -1
- package/dist/client/assets/content-B5Q4pb9R.js +1 -0
- package/dist/client/assets/content-BK1IfOZs.js +1 -0
- package/dist/client/assets/content-BeEsWLEm.js +1 -0
- package/dist/client/assets/content-BkOwEknW.js +1 -0
- package/dist/client/assets/content-C32W5kAG.js +1 -0
- package/dist/client/assets/content-CoqyLs9v.js +1 -0
- package/dist/client/assets/content-CwpdIS5b.js +1 -0
- package/dist/client/assets/content-DS2OkJ3Q.js +1 -0
- package/dist/client/assets/content-DXKaPDfn.js +1 -0
- package/dist/client/assets/content-DZt5-dkI.js +1 -0
- package/dist/client/assets/content-DbQJH8L1.js +1 -0
- package/dist/client/assets/content-DetoiaHq.js +1 -0
- package/dist/client/assets/content-Dhu3wL7J.js +1 -0
- package/dist/client/assets/content-Dpv34iZu.js +1 -0
- package/dist/client/assets/content-TtQJb61D.js +1 -0
- package/dist/client/assets/content-ymNb2R7g.js +1 -0
- package/dist/client/assets/{context-budget-DqxWzalx.js → context-budget-DemtXu7E.js} +1 -1
- package/dist/client/assets/{conversation-icons-DHGc9wbT.js → conversation-icons-BQ4OeOmr.js} +1 -1
- package/dist/client/assets/conversation-model-BGFHoxQ0.js +1 -0
- package/dist/client/assets/conversation-motion-features-9x8uZpwh.js +1 -0
- package/dist/client/assets/conversations-Cbg9h_Af.js +1 -0
- package/dist/client/assets/{copy-BzdzWsQd.js → copy-D9WUpQRf.js} +1 -1
- package/dist/client/assets/{cpu-CHFIGw87.js → cpu-Ck_4tB_-.js} +1 -1
- package/dist/client/assets/{createLucideIcon-Dv8H8m7J.js → createLucideIcon-DkjnzvcJ.js} +1 -1
- package/dist/client/assets/{credentials-BTce3VP1.js → credentials-C4VXz2hr.js} +1 -1
- package/dist/client/assets/discover-C8IOY7_K.js +2 -0
- package/dist/client/assets/embed-entry-CG3CfCbm.js +2 -0
- package/dist/client/assets/embed-navigation-DayfkQau.js +1 -0
- package/dist/client/assets/{external-link-BvX5PfLh.js → external-link-RT4Ph-6-.js} +1 -1
- package/dist/client/assets/{eye-C9cGk5z6.js → eye-CtqSV8BS.js} +1 -1
- package/dist/client/assets/{file-code-corner-jlGFdr8d.js → file-code-corner-D_Aptal2.js} +1 -1
- package/dist/client/assets/{file-text-BHro8MkG.js → file-text-ChtICwub.js} +1 -1
- package/dist/client/assets/flag-CqdOxVkI.js +1 -0
- package/dist/client/assets/floor-character-name-CqJPOlXb.js +1 -0
- package/dist/client/assets/floor-context-model-DZBpo_oD.js +1 -0
- package/dist/client/assets/floor-context-sheet-BFnkFiY3.css +1 -0
- package/dist/client/assets/floor-memory-YMM8AlLY.js +1 -0
- package/dist/client/assets/floor-message-passes-CJh9f8Jp.js +1 -0
- package/dist/client/assets/floor-preview-text-HrORUJ7D.js +1 -0
- package/dist/client/assets/floor-replay-CccYqE-f.css +1 -0
- package/dist/client/assets/floor-tactical-hud-HL5Vja5Y.css +1 -0
- package/dist/client/assets/folder-0fWevPvQ.js +1 -0
- package/dist/client/assets/{gauge-DSflSery.js → gauge-Dgtfxf_o.js} +1 -1
- package/dist/client/assets/{gestures-YA5IIwp-.js → gestures-BDCZ1FRG.js} +1 -1
- package/dist/client/assets/{git-branch-Bc_eDIpG.js → git-branch-CA3cHKCI.js} +1 -1
- package/dist/client/assets/go-shortcuts-DKtw4qYx.js +1 -0
- package/dist/client/assets/home-moving-signal-B7m-ngb2.js +1 -0
- package/dist/client/assets/home-now-card-DduXkHRR.js +1 -0
- package/dist/client/assets/{home-now-card-nano-Jmy7eJ6H.js → home-now-card-nano-D1ScGrgv.js} +1 -1
- package/dist/client/assets/hooks-C6VyQTQe.js +2 -0
- package/dist/client/assets/{hooks-D6NI15f6.css → hooks-D787lBmm.css} +1 -1
- package/dist/client/assets/index-C5cX8dkl.js +1 -0
- package/dist/client/assets/{index-C1VaWNuD.js → index-C8uS5szO.js} +5 -5
- package/dist/client/assets/index-Ck1__1yL.css +1 -0
- package/dist/client/assets/index-ClOOrVG1.js +1 -0
- package/dist/client/assets/index-Crtgfc9I.js +1 -0
- package/dist/client/assets/index-CvsM3jm8.js +1 -0
- package/dist/client/assets/{inspector-panel-CwrHjRaQ.js → inspector-panel-BLhDODb3.js} +2 -2
- package/dist/client/assets/{keyboard-nav-B8sQ_8IF.js → keyboard-nav-CXfav14z.js} +1 -1
- package/dist/client/assets/knowledge-search-BNdQweGz.css +1 -0
- package/dist/client/assets/{lane-edit-display-C_Aujldz.js → lane-edit-display-BjdT9oZl.js} +1 -1
- package/dist/client/assets/{lane-observe-vfyACHi0.js → lane-observe-BD21P8BB.js} +2 -2
- package/dist/client/assets/lane-roster-store-DzNHP392.js +1 -0
- package/dist/client/assets/{lane-tool-detail-0WhMf4Vj.js → lane-tool-detail-Czggx8oM.js} +1 -1
- package/dist/client/assets/{layers-CW2-qHsG.js → layers-Bolb8ejU.js} +1 -1
- package/dist/client/assets/{layout-grid-BoVnPOk-.js → layout-grid-DI9tVJ2E.js} +1 -1
- package/dist/client/assets/left-B-_z_nqj.js +2 -0
- package/dist/client/assets/left-B1LY7rJc.js +1 -0
- package/dist/client/assets/{left-DH44V4I_.css → left-BV9yMiTL.css} +1 -1
- package/dist/client/assets/left-C6bdjWcG.js +2 -0
- package/dist/client/assets/left-CF4iuqlz.js +1 -0
- package/dist/client/assets/left-DLtNyZl1.js +1 -0
- package/dist/client/assets/left-Fpxoq-VY.js +1 -0
- package/dist/client/assets/left-N2wXfTlp.js +1 -0
- package/dist/client/assets/left-advisor-CeIjCKbd.js +1 -0
- package/dist/client/assets/left-agents-upjHVlOj.js +1 -0
- package/dist/client/assets/left-default-08gmdCtb.js +1 -0
- package/dist/client/assets/left-lanes-Cvsp73Hw.js +1 -0
- package/dist/client/assets/left-mission-DENnfshd.css +1 -0
- package/dist/client/assets/left-mission-W1LLaz74.js +1 -0
- package/dist/client/assets/library-DLKBVUJ6.js +1 -0
- package/dist/client/assets/{loader-circle-DmUG_YC7.js → loader-circle-DurUYl7E.js} +1 -1
- package/dist/client/assets/{local-agents-VP1-ZlPw.js → local-agents-D9fYYRyj.js} +1 -1
- package/dist/client/assets/machine-children-RGS4Q0r6.js +1 -0
- package/dist/client/assets/machine-scope-DJt9RZ2w.js +1 -0
- package/dist/client/assets/mentions-Ctw1ECUC.js +1 -0
- package/dist/client/assets/{mesh-ops-CKSWgax2.js → mesh-ops-CGpRk4ik.js} +1 -1
- package/dist/client/assets/{mesh-screen-D1Yvo8fU.css → mesh-screen-DjA4mOaN.css} +1 -1
- package/dist/client/assets/mesh-view-store-CliSYsmt.js +1 -0
- package/dist/client/assets/{message-circle-joGFxfj1.js → message-circle-CSiJj6yo.js} +1 -1
- package/dist/client/assets/{message-markup-DC0QFEZn.js → message-markup-DgFSyb3f.js} +1 -1
- package/dist/client/assets/{message-square-BLiFqpe_.js → message-square-NmXWtWLR.js} +1 -1
- package/dist/client/assets/{message-visibility-CGOmSSKs.js → message-visibility-DwxgcgYK.js} +1 -1
- package/dist/client/assets/mission-control-CsX3Yc58.css +1 -0
- package/dist/client/assets/mission-control-model-C30vU1Fe.js +1 -0
- package/dist/client/assets/mission-control-store-DZ29Mlj1.js +1 -0
- package/dist/client/assets/{mission-wall-CocIM1cF.js → mission-wall-DOuGOxQy.js} +1 -1
- package/dist/client/assets/nav-destinations-CyXnw9kh.js +1 -0
- package/dist/client/assets/observe-CkfOxYx_.js +1 -0
- package/dist/client/assets/{operator-attention-RqieiSY8.js → operator-attention-DGR4kOog.js} +1 -1
- package/dist/client/assets/ops-screen-CxYM0VOW.css +1 -0
- package/dist/client/assets/page-status-CkS3SZu-.js +1 -0
- package/dist/client/assets/panel-right-BNTJhy8M.js +1 -0
- package/dist/client/assets/pause-DWS7YGQ3.js +1 -0
- package/dist/client/assets/{persistent-state-BubPQ7tT.js → persistent-state-xsuk6Kc-.js} +1 -1
- package/dist/client/assets/pin-DWlD1BOF.js +1 -0
- package/dist/client/assets/pip-idle-v1-Tt-CZsRG.png +0 -0
- package/dist/client/assets/pip-thinking-v1-BoHWSEye.png +0 -0
- package/dist/client/assets/pip-waiting-v1-DkuvJ-dN.png +0 -0
- package/dist/client/assets/pip-working-v1-wWQLRS1z.png +0 -0
- package/dist/client/assets/play-D_Pggug4.js +1 -0
- package/dist/client/assets/{plus-BWKhylds.js → plus-D_wLGJGT.js} +1 -1
- package/dist/client/assets/profile-C3KgiZvc.js +1 -0
- package/dist/client/assets/{projects-inbox-DFbgVlXL.js → projects-inbox-DvbqJO3q.js} +1 -1
- package/dist/client/assets/{proxy-DVDRhSRR.js → proxy-DOG46ja4.js} +1 -1
- package/dist/client/assets/{radio-CxIXS1nU.js → radio-C_jtwbFP.js} +1 -1
- package/dist/client/assets/{refresh-cw-Bkh7Cvnd.js → refresh-cw-Da9DDLk2.js} +1 -1
- package/dist/client/assets/resolve-panes-DuowGRTk.js +1 -0
- package/dist/client/assets/resolve-sidebar-context-BkTbqteq.js +1 -0
- package/dist/client/assets/right-B9OUA6Ho.js +1 -0
- package/dist/client/assets/right-BDQnjetX.js +1 -0
- package/dist/client/assets/{right-DVUq5374.js → right-BLJsc2-p.js} +2 -2
- package/dist/client/assets/right-BUbKHmRH.js +1 -0
- package/dist/client/assets/right-Ci2IcD4s.js +1 -0
- package/dist/client/assets/right-CmCce3e5.js +1 -0
- package/dist/client/assets/right-D7w0zM5a.js +1 -0
- package/dist/client/assets/right-DIoON_bv.js +1 -0
- package/dist/client/assets/right-E0Jr3VN5.js +1 -0
- package/dist/client/assets/right-lCdAk9dW.js +1 -0
- package/dist/client/assets/{rocket-CnxqjX_K.js → rocket-DyrYDo8V.js} +1 -1
- package/dist/client/assets/router-BKiMcYa7.js +1 -0
- package/dist/client/assets/{runtime-picker-BYAFNLNq.css → runtime-picker-C3JwrDKP.css} +1 -1
- package/dist/client/assets/runtime-picker-DdsttHHc.js +1 -0
- package/dist/client/assets/{scope-views-KPY85UUx.js → scope-views-B7PZGlhY.js} +1 -1
- package/dist/client/assets/scout-voice-DOQ_B77g.js +1 -0
- package/dist/client/assets/{scoutbot-D7kGGyK_.js → scoutbot-Bk3nyrkj.js} +2 -2
- package/dist/client/assets/{scoutbot-markdown-yb87JlSE.js → scoutbot-markdown-Bz0Vbto2.js} +1 -1
- package/dist/client/assets/{scroll-text-DFcBYy5J.js → scroll-text-DwC8r2g6.js} +1 -1
- package/dist/client/assets/{search-FB2vVxCp.js → search-C4VlW_0l.js} +1 -1
- package/dist/client/assets/secondaryNavConfig-DAXIFtVd.js +1 -0
- package/dist/client/assets/{selection-bridge-qBGFCJv8.js → selection-bridge-B5jqyMR9.js} +1 -1
- package/dist/client/assets/{send-horizontal-CS7mxVhX.js → send-horizontal-pOtGI7FM.js} +1 -1
- package/dist/client/assets/send-to-agent-session-BZGq_ycy.js +1 -0
- package/dist/client/assets/{server-WY6gsbZz.js → server-ms1yxUYJ.js} +1 -1
- package/dist/client/assets/{session-catalog-CG4oL_yN.js → session-catalog-s-T_w41t.js} +1 -1
- package/dist/client/assets/{session-table-uJh3v-ly.js → session-table-CDx_16xf.js} +1 -1
- package/dist/client/assets/sessions-view-DzYGsKWS.js +1 -0
- package/dist/client/assets/{settings-DQEtqkM9.js → settings-TJIkkZ0P.js} +1 -1
- package/dist/client/assets/shared-work-artifacts-4IIQXQfc.js +1 -0
- package/dist/client/assets/{sliders-horizontal-57e99_qO.js → sliders-horizontal-CHf3ntw0.js} +1 -1
- package/dist/client/assets/solar-system-scope-2k-stars-points-1FwHnkj0.png +0 -0
- package/dist/client/assets/{sparkles-D0vWLTyC.js → sparkles-BbOFw3d0.js} +1 -1
- package/dist/client/assets/sprout-action-sprite-DZ8C0fTl.css +1 -0
- package/dist/client/assets/sprout-actions-proof-v1-BzUdc812.png +0 -0
- package/dist/client/assets/{sse-B29iGBnw.js → sse-v5QLsOHV.js} +1 -1
- package/dist/client/assets/system-surfaces-redesign-DKFg4GB5.css +1 -0
- package/dist/client/assets/{tail-display-DcliDVkW.js → tail-display-DHSNmvor.js} +2 -2
- package/dist/client/assets/{tail-events-LK29oCKm.js → tail-events-DQ46QBW1.js} +1 -1
- package/dist/client/assets/{terminal-UDy4lzV1.js → terminal-96JWDYDL.js} +1 -1
- package/dist/client/assets/{terminal-relay-CXHMdain.js → terminal-relay-Bfx8pg80.js} +1 -1
- package/dist/client/assets/terminal-screen-Bpb2SZrn.css +1 -0
- package/dist/client/assets/{terminal-sessions-Bdt2W3Y4.js → terminal-sessions-Ch9aYlgi.js} +1 -1
- package/dist/client/assets/{terminal-takeover-BMeBjBB2.js → terminal-takeover-BlpxpvSp.js} +1 -1
- package/dist/client/assets/use-beside-Df-F2Uvg.js +1 -0
- package/dist/client/assets/use-conversation-list-A_YUf8lo.js +1 -0
- package/dist/client/assets/{use-fleet-active-asks-CCGrll5q.js → use-fleet-active-asks-DFs_u-vM.js} +1 -1
- package/dist/client/assets/use-mesh-node-state-Ck9CYplv.js +1 -0
- package/dist/client/assets/{use-mesh-ops-items-BjyeFJTz.js → use-mesh-ops-items-Be1WmwCg.js} +1 -1
- package/dist/client/assets/{use-reduced-motion-CPoX8iV2.js → use-reduced-motion-D7n3vK8t.js} +1 -1
- package/dist/client/assets/use-scout-dev-flags-0TXfQcG0.js +1 -0
- package/dist/client/assets/{useAgentHoverCard-BgTLNcF-.js → useAgentHoverCard-Dr-OjNFF.js} +1 -1
- package/dist/client/assets/useContentSecondaryNav-CGvMOVGY.js +1 -0
- package/dist/client/assets/{useEmbedHeadline-DuUnwTB7.js → useEmbedHeadline-BL8wQawZ.js} +1 -1
- package/dist/client/assets/{usePierreRuntime-35AHf9RQ.js → usePierreRuntime-DJkRHMoe.js} +1 -1
- package/dist/client/assets/worker-rendered-v1-DmGVMlVi.png +0 -0
- package/dist/client/assets/worker-thinking-v1-ujakpzrK.png +0 -0
- package/dist/client/assets/worker-waiting-v1-DbTSsfJJ.png +0 -0
- package/dist/client/assets/worker-working-v1-BROAvJ_z.png +0 -0
- package/dist/client/assets/world-outposts-v1-DOt0i98W.png +0 -0
- package/dist/client/assets/{wrench-BfVeded5.js → wrench-BsMTSeji.js} +1 -1
- package/dist/client/assets/{x-DgmmnPKt.js → x-DI1ktCYb.js} +1 -1
- package/dist/client/assets/{xterm-DnJJmrCA.js → xterm-B1YBE4Gq.js} +1 -1
- package/dist/client/assets/{zap-Bcja1lHG.js → zap-sKPkh4sQ.js} +1 -1
- package/dist/client/characters/sage/sage.glb +0 -0
- package/dist/client/crew/brik-bust.webp +0 -0
- package/dist/client/crew/brik-chip-id.webp +0 -0
- package/dist/client/crew/fenn-bust.webp +0 -0
- package/dist/client/crew/fenn-chip-id.webp +0 -0
- package/dist/client/crew/lulu-bust.webp +0 -0
- package/dist/client/crew/milo-bust.webp +0 -0
- package/dist/client/crew/milo-chip-id.webp +0 -0
- package/dist/client/crew/nori-bust.webp +0 -0
- package/dist/client/crew/pip-bust.webp +0 -0
- package/dist/client/crew/pip-chip-id.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/blink-half.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/blink-shut.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/look-left.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/look-right.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/look-up.webp +0 -0
- package/dist/client/crew/sheets/eye-plate-v1/rest.webp +0 -0
- package/dist/client/crew/sheets/sprout/blink-half.webp +0 -0
- package/dist/client/crew/sheets/sprout/blink-shut.webp +0 -0
- package/dist/client/crew/sheets/sprout/look-left.webp +0 -0
- package/dist/client/crew/sheets/sprout/look-right.webp +0 -0
- package/dist/client/crew/sheets/sprout/look-up.webp +0 -0
- package/dist/client/crew/sprout-bust.webp +0 -0
- package/dist/client/crew/sprout-chip-id.webp +0 -0
- package/dist/client/crew/tuck-bust.webp +0 -0
- package/dist/client/crew/tuck-chip-id.webp +0 -0
- package/dist/client/crew/vex-bust.webp +0 -0
- package/dist/client/crew/vex-chip-id.webp +0 -0
- package/dist/client/crew/wrench-bust.webp +0 -0
- package/dist/client/crew/wrench-chip-id.webp +0 -0
- package/dist/client/index.html +2 -2
- package/dist/drizzle/0017_wise_silver_sable.sql +26 -0
- package/dist/drizzle/0018_message_epoch_order.sql +1 -0
- package/dist/drizzle/meta/0017_snapshot.json +6785 -0
- package/dist/drizzle/meta/0018_snapshot.json +6804 -0
- package/dist/drizzle/meta/_journal.json +14 -0
- package/dist/main.mjs +26906 -24284
- package/dist/node/main.mjs +7077 -6284
- package/dist/openscout-terminal-relay.mjs +391 -9
- package/dist/pairing-runtime-controller.mjs +35541 -34446
- package/dist/runtime/base-daemon.mjs +31 -8
- package/dist/runtime/broker-daemon.mjs +7864 -2578
- package/dist/runtime/broker-process-manager.mjs +15 -3
- package/dist/runtime/mesh-discover.mjs +14 -3
- package/dist/scout-control-plane-web.mjs +37053 -33186
- package/dist/statusline.mjs +1021 -35
- package/dist/update-helper.mjs +32169 -0
- package/package.json +2 -2
- package/dist/client/assets/ActivityScreen-sfonf5SR.js +0 -1
- package/dist/client/assets/AgentAvatar-Dz79iTxB.js +0 -1
- package/dist/client/assets/AgentConfigurationScreen-DDc3udYM.js +0 -1
- package/dist/client/assets/AgentDefinitionsWorkspace-DHDS9Pgd.js +0 -1
- package/dist/client/assets/AgentDetailCard-8viaEY8b.js +0 -1
- package/dist/client/assets/AgentFloorView-DuyvyMMj.js +0 -1
- package/dist/client/assets/AgentInfoScreen-qntgg2q2.js +0 -1
- package/dist/client/assets/AgentLanesEmbedScreen-BA6fRwkD.js +0 -1
- package/dist/client/assets/AgentLanesView-96lHsoX7.js +0 -2
- package/dist/client/assets/AgentLiveActions-DlSKL60c.js +0 -1
- package/dist/client/assets/AgentMasterScreen-DHrMuQ6_.js +0 -1
- package/dist/client/assets/AgentSessions-DV9v34aq.js +0 -6
- package/dist/client/assets/AgentsConsole-DTpVhS67.js +0 -1
- package/dist/client/assets/AgentsScreen-hZ4o2I-e.js +0 -1
- package/dist/client/assets/AgentsSubnav-Ci7uWM7P.js +0 -1
- package/dist/client/assets/AtopView-D7vyQDtE.js +0 -1
- package/dist/client/assets/BackToPicker-BHicJyfc.js +0 -1
- package/dist/client/assets/BriefingDetailScreen-B-wD_Bot.js +0 -1
- package/dist/client/assets/BriefingsScreen-Cn4Mbam9.js +0 -1
- package/dist/client/assets/BrokerScreen-C8FQ5rlg.js +0 -5
- package/dist/client/assets/ChatCollapsedStrip-7Wrg8Ge0.js +0 -1
- package/dist/client/assets/CodeScreen-cLC0tJ4S.js +0 -1
- package/dist/client/assets/ConversationFeedRows-Bx0gFyG_.js +0 -1
- package/dist/client/assets/ConversationHeader-Bt2RBj93.js +0 -1
- package/dist/client/assets/ConversationPanels-o6W-cOoU.js +0 -6
- package/dist/client/assets/ConversationScreen-CkWnKXt6.css +0 -1
- package/dist/client/assets/ConversationScreen-DIU7m_aC.js +0 -2
- package/dist/client/assets/ConversationStatus-CTYOywFh.js +0 -1
- package/dist/client/assets/CrewWorkspaces-DNX-QQ1h.js +0 -1
- package/dist/client/assets/DispatchAftermath-ZCEB75hh.js +0 -1
- package/dist/client/assets/DocumentFocusViewer-D8iB6SMt.js +0 -1
- package/dist/client/assets/FlightObserveScreen-BTe1YRPr.js +0 -1
- package/dist/client/assets/FollowScreen-CkR-okdL.js +0 -1
- package/dist/client/assets/HarnessesScreen-COO_Q8VY.js +0 -1
- package/dist/client/assets/HostAdvisorView-DeJ-8RZV.js +0 -1
- package/dist/client/assets/KnowledgeSearchInspector-W_zNIBRV.js +0 -1
- package/dist/client/assets/KnowledgeSearchScreen-_rxJNUUh.js +0 -1
- package/dist/client/assets/LaneTraceDetailSheet-DNIECgEl.js +0 -1
- package/dist/client/assets/MeshCanvas-DZv2ipsy.js +0 -3
- package/dist/client/assets/MeshCanvasMinimap-BXHRNb7l.js +0 -1
- package/dist/client/assets/MeshScreen-DuNvpDC5.js +0 -1
- package/dist/client/assets/MessagesScreen-dNNPFwAc.js +0 -1
- package/dist/client/assets/MissionContextRail-DnCWPzAM.js +0 -1
- package/dist/client/assets/MissionControlView-DmaThhNR.js +0 -1
- package/dist/client/assets/MissionFocusOverlay-K21ssTxv.js +0 -1
- package/dist/client/assets/MissionLeftAgentRow-CbQm4BLv.js +0 -1
- package/dist/client/assets/MissionLogPane-BLvSSIdT.js +0 -1
- package/dist/client/assets/NewAgentModal-B7qxjZlW.js +0 -1
- package/dist/client/assets/NewChatComposer-D2Ah4T-W.js +0 -19
- package/dist/client/assets/ObserveEmbedScreen-DvKGsaLv.js +0 -2
- package/dist/client/assets/OpenScoutAppShell-C9TOLB7u.js +0 -79
- package/dist/client/assets/OpsAgentsView-vIoY-AW1.js +0 -1
- package/dist/client/assets/OpsScreen-CJBwshEp.js +0 -1
- package/dist/client/assets/OpsSubnav-CjDTnp64.js +0 -1
- package/dist/client/assets/ProjectAgentProfile-Br1eTD7G.js +0 -1
- package/dist/client/assets/ProjectAgentProfileHero-mjxNcRvw.js +0 -1
- package/dist/client/assets/ProjectsInbox-Bq29DE_o.js +0 -2
- package/dist/client/assets/ProjectsRail-kMDA0yn4.js +0 -1
- package/dist/client/assets/ProjectsScreen-BDaJYhc0.js +0 -1
- package/dist/client/assets/ProjectsThreadAside-B940p3vW.js +0 -1
- package/dist/client/assets/Provider-D0bB7q6y.js +0 -1
- package/dist/client/assets/RailRow-B88JVr62.js +0 -1
- package/dist/client/assets/RawSessionsTable-CzGhEdiZ.js +0 -1
- package/dist/client/assets/RealtimeVoiceScreen-CyP1CWsX.js +0 -1
- package/dist/client/assets/RepoDiffViewer-Bw5yMC4A.js +0 -7
- package/dist/client/assets/RepoDiffViewerLazy-DzfoFhbl.js +0 -2
- package/dist/client/assets/ScoutDeckSurface-DQoZofzH.js +0 -1
- package/dist/client/assets/SessionEmbedScreen-CpduQ0O9.js +0 -1
- package/dist/client/assets/SessionObserve-BVeTkcIl.js +0 -12
- package/dist/client/assets/SessionObserveEvidence-BkOezTGV.js +0 -1
- package/dist/client/assets/SessionRefScreen-DetLMkTT.js +0 -1
- package/dist/client/assets/SessionsScreen-B-McKw6d.js +0 -1
- package/dist/client/assets/SettingsDrawer-CPB32w0n.js +0 -3
- package/dist/client/assets/SettingsScreen-BEzYFdjz.js +0 -1
- package/dist/client/assets/SpriteAvatar-DFO4Kb4Z.js +0 -1
- package/dist/client/assets/Terminal-DWyZTZdY.js +0 -1
- package/dist/client/assets/TerminalEmbedScreen-_SSzwhWa.js +0 -1
- package/dist/client/assets/TerminalHeaderMount-CY7uIWBg.js +0 -1
- package/dist/client/assets/WorkFilesViewer-D8-4vF5l.js +0 -1
- package/dist/client/assets/agent-autocomplete-BlK8wY06.js +0 -10
- package/dist/client/assets/agent-lane-card-model-CY3OE1Xu.js +0 -1
- package/dist/client/assets/agent-lanes-model-tc-1hE6q.js +0 -2
- package/dist/client/assets/agent-master-I1W-5d-x.css +0 -1
- package/dist/client/assets/agent-master-model-DMcHeNq3.js +0 -1
- package/dist/client/assets/api-Co9aQ2Jw.js +0 -1
- package/dist/client/assets/broker-display-Q75fupqG.js +0 -2
- package/dist/client/assets/chunk-JTPDIGGW-COJ00z94.js +0 -46
- package/dist/client/assets/chunk-YOZR3KYS-CrCgXw9l.js +0 -2
- package/dist/client/assets/colors-BtO5_zlx.js +0 -1
- package/dist/client/assets/content-0RBfbCIJ.js +0 -1
- package/dist/client/assets/content-BTmnk2bl.js +0 -1
- package/dist/client/assets/content-Bk5DKhyP.js +0 -1
- package/dist/client/assets/content-Bw_8GE_S.js +0 -1
- package/dist/client/assets/content-CI4gLEWi.js +0 -1
- package/dist/client/assets/content-CLCtp9Rb.js +0 -1
- package/dist/client/assets/content-C_FAGTNk.js +0 -1
- package/dist/client/assets/content-CnnzWOE3.js +0 -1
- package/dist/client/assets/content-DKlY98pO.js +0 -1
- package/dist/client/assets/content-Df7ndXTG.js +0 -1
- package/dist/client/assets/content-DkZDzzx3.js +0 -1
- package/dist/client/assets/content-DnGmb2L0.js +0 -1
- package/dist/client/assets/content-Ds-zs-Ss.js +0 -1
- package/dist/client/assets/content-JIWSyC0f.js +0 -1
- package/dist/client/assets/content-Q3TIYC8q.js +0 -1
- package/dist/client/assets/content-evaBfvxD.js +0 -1
- package/dist/client/assets/conversation-model-C2KuZUXc.js +0 -1
- package/dist/client/assets/conversation-motion-features-BJnHs3Ul.js +0 -1
- package/dist/client/assets/discover-DutlV0ZU.js +0 -2
- package/dist/client/assets/embed-entry-CJG7WEVw.js +0 -2
- package/dist/client/assets/home-moving-signal-PHSqSBu_.js +0 -1
- package/dist/client/assets/home-now-card-C_qsI6C6.js +0 -1
- package/dist/client/assets/hooks-ME7rmhpE.js +0 -2
- package/dist/client/assets/index-C8UCRm2W.js +0 -1
- package/dist/client/assets/index-Cn0I2Hgi.js +0 -1
- package/dist/client/assets/index-Cx6Gbr6n.js +0 -1
- package/dist/client/assets/index-i7TMxlwW.css +0 -1
- package/dist/client/assets/knowledge-search-D_bLoYtC.css +0 -1
- package/dist/client/assets/lane-roster-store-DN2jxXF-.js +0 -1
- package/dist/client/assets/left-BRu9pnqx.js +0 -2
- package/dist/client/assets/left-BjS1dKNV.js +0 -2
- package/dist/client/assets/left-CL-TVLJ7.js +0 -1
- package/dist/client/assets/left-DLpsDi55.js +0 -1
- package/dist/client/assets/left-DPcM9o8Y.js +0 -1
- package/dist/client/assets/left-MmTJf1tK.js +0 -1
- package/dist/client/assets/left-P80i5V8L.js +0 -1
- package/dist/client/assets/left-advisor-CbXVzAqS.js +0 -1
- package/dist/client/assets/left-agents-7mJsiNyr.js +0 -1
- package/dist/client/assets/left-default-COK26l3H.js +0 -1
- package/dist/client/assets/left-lanes-Dbdm9Veu.js +0 -1
- package/dist/client/assets/left-mission-DSenPIyb.css +0 -1
- package/dist/client/assets/left-mission-DqGR5jby.js +0 -1
- package/dist/client/assets/library-COnWzUWv.js +0 -1
- package/dist/client/assets/mentions-BZ5SBMtc.js +0 -1
- package/dist/client/assets/mesh-buckets-CLYS8Jx8.js +0 -1
- package/dist/client/assets/mesh-view-store-CBM1za_N.js +0 -1
- package/dist/client/assets/mission-control-CnU7dNt1.css +0 -1
- package/dist/client/assets/mission-control-model-C0fByIjm.js +0 -1
- package/dist/client/assets/mission-control-store-CM8mQGg8.js +0 -1
- package/dist/client/assets/observe-BLmy4quB.js +0 -1
- package/dist/client/assets/ops-screen-giu3If_N.css +0 -1
- package/dist/client/assets/page-status-BE0-J1xY.js +0 -1
- package/dist/client/assets/paperclip-Br7wUDFl.js +0 -1
- package/dist/client/assets/perf-PX8Rx0EP.js +0 -1
- package/dist/client/assets/profile-BCvk8jOQ.js +0 -1
- package/dist/client/assets/resolve-panes-DhD5qmQO.js +0 -1
- package/dist/client/assets/resolve-sidebar-context-GqhZNRPY.js +0 -1
- package/dist/client/assets/right-B_08ilv6.js +0 -1
- package/dist/client/assets/right-Brm67HOL.js +0 -1
- package/dist/client/assets/right-BveAPKBW.js +0 -1
- package/dist/client/assets/right-CpTB_-Ya.js +0 -1
- package/dist/client/assets/right-CqC4Qdot.js +0 -1
- package/dist/client/assets/right-D91j9d5Y.js +0 -1
- package/dist/client/assets/right-DaLRhYl3.js +0 -1
- package/dist/client/assets/right-Dt1wOwA5.js +0 -1
- package/dist/client/assets/right-DtzqIZQF.js +0 -1
- package/dist/client/assets/router-kfcaYqZr.js +0 -1
- package/dist/client/assets/runtime-picker-C20lTGhV.js +0 -1
- package/dist/client/assets/scout-voice-Cg1qfepC.js +0 -1
- package/dist/client/assets/secondaryNavConfig-C0Srrmy8.js +0 -1
- package/dist/client/assets/system-surfaces-redesign-kuf3wuE_.css +0 -1
- package/dist/client/assets/terminal-screen-vMICbBJh.css +0 -1
- package/dist/client/assets/use-conversation-list-UG-tMN67.js +0 -1
- package/dist/client/assets/use-scout-dev-flags-DTseRrFi.js +0 -1
- package/dist/client/assets/useContentSecondaryNav-CoIoz7JU.js +0 -1
package/dist/statusline.mjs
CHANGED
|
@@ -6,55 +6,1034 @@ import { spawn } from "child_process";
|
|
|
6
6
|
|
|
7
7
|
// ../runtime/src/claude-statusline.ts
|
|
8
8
|
import { appendFile, mkdir, readFile, writeFile } from "fs/promises";
|
|
9
|
-
import { basename, dirname, join as
|
|
9
|
+
import { basename, dirname, join as join3 } from "path";
|
|
10
10
|
|
|
11
|
-
// ../runtime/src/
|
|
11
|
+
// ../runtime/src/system-probes/scoutd-client.ts
|
|
12
|
+
import { existsSync } from "fs";
|
|
12
13
|
import { homedir } from "os";
|
|
13
14
|
import { join } from "path";
|
|
15
|
+
import { Socket } from "net";
|
|
16
|
+
|
|
17
|
+
// ../runtime/src/system-probes/registry.ts
|
|
18
|
+
var DEFAULT_MIN_MAX_STALE_MS = 2 * 60000;
|
|
19
|
+
var PROBE_RUN_OUTPUT = Symbol("openscout.probeRunOutput");
|
|
20
|
+
class ProbeBackendError extends Error {
|
|
21
|
+
backend;
|
|
22
|
+
fallbackSince;
|
|
23
|
+
fallbackReason;
|
|
24
|
+
code;
|
|
25
|
+
timedOut;
|
|
26
|
+
constructor(message, metadata, cause) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "ProbeBackendError";
|
|
29
|
+
this.backend = metadata.backend;
|
|
30
|
+
this.fallbackSince = metadata.fallbackSince;
|
|
31
|
+
this.fallbackReason = metadata.fallbackReason;
|
|
32
|
+
const details = probeErrorDetails(cause);
|
|
33
|
+
if (details.code) {
|
|
34
|
+
this.code = details.code;
|
|
35
|
+
}
|
|
36
|
+
if (details.timedOut !== undefined) {
|
|
37
|
+
this.timedOut = details.timedOut;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function probeRunOutput(value, metadata) {
|
|
42
|
+
return {
|
|
43
|
+
[PROBE_RUN_OUTPUT]: true,
|
|
44
|
+
value,
|
|
45
|
+
...metadata
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function isProbeRunOutput(value) {
|
|
49
|
+
return typeof value === "object" && value !== null && value[PROBE_RUN_OUTPUT] === true;
|
|
50
|
+
}
|
|
51
|
+
function backendMetadataFromError(error) {
|
|
52
|
+
if (error instanceof ProbeBackendError) {
|
|
53
|
+
return {
|
|
54
|
+
backend: error.backend,
|
|
55
|
+
fallbackSince: error.fallbackSince,
|
|
56
|
+
fallbackReason: error.fallbackReason
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (typeof error === "object" && error !== null) {
|
|
60
|
+
const record = error;
|
|
61
|
+
if (record.backend === "local" || record.backend === "scoutd" || record.backend === "local-fallback") {
|
|
62
|
+
return {
|
|
63
|
+
backend: record.backend,
|
|
64
|
+
fallbackSince: typeof record.fallbackSince === "number" ? record.fallbackSince : undefined,
|
|
65
|
+
fallbackReason: typeof record.fallbackReason === "string" ? record.fallbackReason : undefined
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function probeErrorDetails(error) {
|
|
72
|
+
if (typeof error !== "object" || error === null) {
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
75
|
+
const record = error;
|
|
76
|
+
const code = typeof record.code === "string" && record.code.trim() ? record.code.trim() : undefined;
|
|
77
|
+
const timedOut = record.timedOut === true || code === "timeout" ? true : record.timedOut === false ? false : undefined;
|
|
78
|
+
return { code, timedOut };
|
|
79
|
+
}
|
|
80
|
+
function assertProbeSpec(spec) {
|
|
81
|
+
if (!spec.id.trim()) {
|
|
82
|
+
throw new Error("Probe id is required");
|
|
83
|
+
}
|
|
84
|
+
if (!Number.isFinite(spec.ttlMs) || spec.ttlMs <= 0) {
|
|
85
|
+
throw new Error(`Probe ${spec.id} must declare a positive ttlMs`);
|
|
86
|
+
}
|
|
87
|
+
if (!Number.isFinite(spec.timeoutMs) || spec.timeoutMs <= 0) {
|
|
88
|
+
throw new Error(`Probe ${spec.id} must declare a positive timeoutMs`);
|
|
89
|
+
}
|
|
90
|
+
if (spec.maxStaleMs !== undefined && (!Number.isFinite(spec.maxStaleMs) || spec.maxStaleMs <= 0)) {
|
|
91
|
+
throw new Error(`Probe ${spec.id} maxStaleMs must be positive when set`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function maxStaleMsFor(spec) {
|
|
95
|
+
return spec.maxStaleMs ?? Math.max(DEFAULT_MIN_MAX_STALE_MS, spec.ttlMs * 10);
|
|
96
|
+
}
|
|
97
|
+
function failureBackoffMs(consecutiveFailures) {
|
|
98
|
+
if (consecutiveFailures <= 0) {
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
return Math.min(30000, 1000 * 2 ** Math.min(consecutiveFailures - 1, 5));
|
|
102
|
+
}
|
|
103
|
+
function probeErrorFromUnknown(error, at, timedOut = false) {
|
|
104
|
+
if (typeof error === "object" && error !== null) {
|
|
105
|
+
const record = error;
|
|
106
|
+
const code = typeof record.code === "string" && record.code.trim() ? record.code.trim() : timedOut ? "timeout" : typeof record.name === "string" && record.name.trim() ? record.name.trim() : "error";
|
|
107
|
+
const message = typeof record.message === "string" && record.message.trim() ? record.message : String(error);
|
|
108
|
+
return { code, message, at, ...timedOut ? { timedOut: true } : {} };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
code: timedOut ? "timeout" : "error",
|
|
112
|
+
message: String(error),
|
|
113
|
+
at,
|
|
114
|
+
...timedOut ? { timedOut: true } : {}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function timeoutError(probeId, timeoutMs) {
|
|
118
|
+
return {
|
|
119
|
+
code: "timeout",
|
|
120
|
+
message: `Probe ${probeId} timed out after ${timeoutMs}ms`,
|
|
121
|
+
at: Date.now(),
|
|
122
|
+
timedOut: true
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function staleTooLongError(probeId, ageMs, maxStaleMs) {
|
|
126
|
+
return {
|
|
127
|
+
code: "max_stale_exceeded",
|
|
128
|
+
message: `Probe ${probeId} last good snapshot is ${ageMs}ms old, exceeding maxStaleMs ${maxStaleMs}`,
|
|
129
|
+
at: Date.now()
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function isFreshEnough(state, maxAgeMs) {
|
|
133
|
+
if (state.at === null || state.invalidated) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return Date.now() - state.at <= maxAgeMs;
|
|
137
|
+
}
|
|
138
|
+
function logBackendTransition(input) {
|
|
139
|
+
if (input.from === input.to) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const keySuffix = input.key === undefined ? "" : ` key=${JSON.stringify(input.key)}`;
|
|
143
|
+
const reasonSuffix = input.reason ? ` (${input.reason})` : "";
|
|
144
|
+
console.warn(`[openscout] system probe ${input.id}${keySuffix} backend ${input.from} -> ${input.to}${reasonSuffix}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
class ProbeInstance {
|
|
148
|
+
spec;
|
|
149
|
+
key;
|
|
150
|
+
runProbe;
|
|
151
|
+
scheduleRun;
|
|
152
|
+
state = {
|
|
153
|
+
value: null,
|
|
154
|
+
at: null,
|
|
155
|
+
error: null,
|
|
156
|
+
consecutiveFailures: 0,
|
|
157
|
+
inFlight: null,
|
|
158
|
+
invalidated: false,
|
|
159
|
+
invalidationReason: null,
|
|
160
|
+
invalidationSerial: 0,
|
|
161
|
+
nextRetryAt: 0,
|
|
162
|
+
backend: "local",
|
|
163
|
+
fallbackSince: null,
|
|
164
|
+
fallbackReason: null
|
|
165
|
+
};
|
|
166
|
+
metricState;
|
|
167
|
+
lastAccessAt = Date.now();
|
|
168
|
+
constructor(options) {
|
|
169
|
+
this.spec = options.spec;
|
|
170
|
+
this.key = options.key;
|
|
171
|
+
this.runProbe = options.run;
|
|
172
|
+
this.scheduleRun = options.scheduleRun ?? ((task) => task());
|
|
173
|
+
this.metricState = {
|
|
174
|
+
id: options.spec.id,
|
|
175
|
+
...options.key !== undefined ? { key: options.key } : {},
|
|
176
|
+
backend: "local",
|
|
177
|
+
runCount: 0,
|
|
178
|
+
failureCount: 0,
|
|
179
|
+
timeoutCount: 0,
|
|
180
|
+
staleServedCount: 0,
|
|
181
|
+
lastRunAt: null,
|
|
182
|
+
lastDurationMs: null,
|
|
183
|
+
lastSuccessAt: null
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
read() {
|
|
187
|
+
this.touch();
|
|
188
|
+
if (this.shouldRefreshForRead(Date.now())) {
|
|
189
|
+
this.ensureRefresh(false, this.spec.ttlMs);
|
|
190
|
+
}
|
|
191
|
+
const snap = this.snapshot();
|
|
192
|
+
if (snap.status === "stale" || snap.status === "failed" && snap.at !== null) {
|
|
193
|
+
this.metricState.staleServedCount += 1;
|
|
194
|
+
}
|
|
195
|
+
return snap;
|
|
196
|
+
}
|
|
197
|
+
async fresh(options = {}) {
|
|
198
|
+
this.touch();
|
|
199
|
+
const maxAgeMs = options.maxAgeMs ?? this.spec.ttlMs;
|
|
200
|
+
for (let attempt = 0;attempt < 3; attempt += 1) {
|
|
201
|
+
if (isFreshEnough(this.state, maxAgeMs)) {
|
|
202
|
+
return this.snapshot();
|
|
203
|
+
}
|
|
204
|
+
await this.ensureRefresh(true, maxAgeMs);
|
|
205
|
+
if (!this.state.invalidated) {
|
|
206
|
+
return this.snapshot();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return this.snapshot();
|
|
210
|
+
}
|
|
211
|
+
snapshot() {
|
|
212
|
+
const now = Date.now();
|
|
213
|
+
const ageMs = this.state.at === null ? null : Math.max(0, now - this.state.at);
|
|
214
|
+
const maxStaleMs = maxStaleMsFor(this.spec);
|
|
215
|
+
const exceededMaxStale = ageMs !== null && ageMs > maxStaleMs;
|
|
216
|
+
const fresh = ageMs !== null && !this.state.invalidated && ageMs <= this.spec.ttlMs;
|
|
217
|
+
const status = this.state.at === null ? this.state.error ? "failed" : "empty" : exceededMaxStale ? "failed" : fresh ? "fresh" : "stale";
|
|
218
|
+
const error = exceededMaxStale ? this.state.error ?? staleTooLongError(this.spec.id, ageMs ?? 0, maxStaleMs) : this.state.error;
|
|
219
|
+
return {
|
|
220
|
+
id: this.spec.id,
|
|
221
|
+
...this.key !== undefined ? { key: this.key } : {},
|
|
222
|
+
value: status === "failed" && exceededMaxStale ? null : this.state.value,
|
|
223
|
+
at: this.state.at,
|
|
224
|
+
ageMs,
|
|
225
|
+
stale: status === "stale" || status === "failed" && this.state.at !== null,
|
|
226
|
+
refreshing: this.state.inFlight !== null,
|
|
227
|
+
status,
|
|
228
|
+
error,
|
|
229
|
+
consecutiveFailures: this.state.consecutiveFailures,
|
|
230
|
+
backend: this.state.backend,
|
|
231
|
+
...this.state.fallbackSince !== null ? { fallbackSince: this.state.fallbackSince } : {},
|
|
232
|
+
...this.state.fallbackReason !== null ? { fallbackReason: this.state.fallbackReason } : {}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
invalidate(reason) {
|
|
236
|
+
this.touch();
|
|
237
|
+
this.state.invalidated = true;
|
|
238
|
+
this.state.invalidationReason = reason ?? null;
|
|
239
|
+
this.state.invalidationSerial += 1;
|
|
240
|
+
this.state.nextRetryAt = 0;
|
|
241
|
+
}
|
|
242
|
+
metrics() {
|
|
243
|
+
return {
|
|
244
|
+
...this.metricState,
|
|
245
|
+
consecutiveFailures: this.state.consecutiveFailures,
|
|
246
|
+
inFlight: this.state.inFlight !== null,
|
|
247
|
+
...this.state.fallbackSince !== null ? { fallbackSince: this.state.fallbackSince } : {},
|
|
248
|
+
...this.state.fallbackReason !== null ? { fallbackReason: this.state.fallbackReason } : {}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
isRefreshing() {
|
|
252
|
+
return this.state.inFlight !== null;
|
|
253
|
+
}
|
|
254
|
+
touch() {
|
|
255
|
+
this.lastAccessAt = Date.now();
|
|
256
|
+
}
|
|
257
|
+
shouldRefreshForRead(now) {
|
|
258
|
+
if (this.state.inFlight !== null) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (this.state.nextRetryAt > now) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (this.state.at === null) {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
if (this.state.invalidated) {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
return now - this.state.at > this.spec.ttlMs;
|
|
271
|
+
}
|
|
272
|
+
ensureRefresh(force, maxAgeMs) {
|
|
273
|
+
if (this.state.inFlight) {
|
|
274
|
+
return this.state.inFlight;
|
|
275
|
+
}
|
|
276
|
+
const now = Date.now();
|
|
277
|
+
if (!force && this.state.nextRetryAt > now) {
|
|
278
|
+
return Promise.resolve();
|
|
279
|
+
}
|
|
280
|
+
const inFlight = this.scheduleRun(() => this.executeRun(maxAgeMs)).finally(() => {
|
|
281
|
+
if (this.state.inFlight === inFlight) {
|
|
282
|
+
this.state.inFlight = null;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
this.state.inFlight = inFlight;
|
|
286
|
+
return inFlight;
|
|
287
|
+
}
|
|
288
|
+
async executeRun(maxAgeMs) {
|
|
289
|
+
const startedAt = Date.now();
|
|
290
|
+
const previousBackend = this.state.backend;
|
|
291
|
+
const invalidationSerialAtStart = this.state.invalidationSerial;
|
|
292
|
+
const controller = new AbortController;
|
|
293
|
+
let timeout = null;
|
|
294
|
+
this.metricState.runCount += 1;
|
|
295
|
+
this.metricState.lastRunAt = startedAt;
|
|
296
|
+
const ctx = {
|
|
297
|
+
probeId: this.spec.id,
|
|
298
|
+
...this.key !== undefined ? { key: this.key } : {},
|
|
299
|
+
signal: controller.signal,
|
|
300
|
+
timeoutMs: this.spec.timeoutMs,
|
|
301
|
+
maxAgeMs,
|
|
302
|
+
startedAt
|
|
303
|
+
};
|
|
304
|
+
const timeoutProbeError = timeoutError(this.spec.id, this.spec.timeoutMs);
|
|
305
|
+
const runPromise = this.runProbe(ctx);
|
|
306
|
+
runPromise.catch(() => {
|
|
307
|
+
return;
|
|
308
|
+
});
|
|
309
|
+
try {
|
|
310
|
+
const result = await new Promise((resolve, reject) => {
|
|
311
|
+
timeout = setTimeout(() => {
|
|
312
|
+
controller.abort(timeoutProbeError);
|
|
313
|
+
reject(timeoutProbeError);
|
|
314
|
+
}, this.spec.timeoutMs);
|
|
315
|
+
runPromise.then(resolve, reject);
|
|
316
|
+
});
|
|
317
|
+
const output = isProbeRunOutput(result) ? result : probeRunOutput(result, { backend: "local" });
|
|
318
|
+
this.state.value = output.value;
|
|
319
|
+
this.state.at = output.generatedAt ?? Date.now();
|
|
320
|
+
this.state.error = null;
|
|
321
|
+
this.state.consecutiveFailures = 0;
|
|
322
|
+
if (this.state.invalidationSerial === invalidationSerialAtStart) {
|
|
323
|
+
this.state.invalidated = false;
|
|
324
|
+
this.state.invalidationReason = null;
|
|
325
|
+
}
|
|
326
|
+
this.state.nextRetryAt = 0;
|
|
327
|
+
this.state.backend = output.backend;
|
|
328
|
+
this.state.fallbackSince = output.fallbackSince ?? null;
|
|
329
|
+
this.state.fallbackReason = output.fallbackReason ?? null;
|
|
330
|
+
this.metricState.backend = output.backend;
|
|
331
|
+
this.metricState.lastSuccessAt = this.state.at;
|
|
332
|
+
logBackendTransition({
|
|
333
|
+
id: this.spec.id,
|
|
334
|
+
key: this.key,
|
|
335
|
+
from: previousBackend,
|
|
336
|
+
to: output.backend,
|
|
337
|
+
reason: output.fallbackReason
|
|
338
|
+
});
|
|
339
|
+
} catch (error) {
|
|
340
|
+
const timedOut = error === timeoutProbeError || typeof error === "object" && error !== null && (error.code === "timeout" || error.timedOut === true);
|
|
341
|
+
const at = Date.now();
|
|
342
|
+
this.state.error = error === timeoutProbeError ? timeoutProbeError : probeErrorFromUnknown(error, at, timedOut);
|
|
343
|
+
this.state.consecutiveFailures += 1;
|
|
344
|
+
this.state.nextRetryAt = at + failureBackoffMs(this.state.consecutiveFailures);
|
|
345
|
+
const backendMetadata = backendMetadataFromError(error);
|
|
346
|
+
if (backendMetadata) {
|
|
347
|
+
this.state.backend = backendMetadata.backend;
|
|
348
|
+
this.state.fallbackSince = backendMetadata.fallbackSince ?? null;
|
|
349
|
+
this.state.fallbackReason = backendMetadata.fallbackReason ?? null;
|
|
350
|
+
this.metricState.backend = backendMetadata.backend;
|
|
351
|
+
logBackendTransition({
|
|
352
|
+
id: this.spec.id,
|
|
353
|
+
key: this.key,
|
|
354
|
+
from: previousBackend,
|
|
355
|
+
to: backendMetadata.backend,
|
|
356
|
+
reason: backendMetadata.fallbackReason
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
this.metricState.failureCount += 1;
|
|
360
|
+
if (this.state.error.timedOut || this.state.error.code === "timeout") {
|
|
361
|
+
this.metricState.timeoutCount += 1;
|
|
362
|
+
}
|
|
363
|
+
} finally {
|
|
364
|
+
if (timeout) {
|
|
365
|
+
clearTimeout(timeout);
|
|
366
|
+
}
|
|
367
|
+
this.metricState.lastDurationMs = Date.now() - startedAt;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
class FamilyLimiter {
|
|
373
|
+
maxConcurrent;
|
|
374
|
+
active = 0;
|
|
375
|
+
queue = [];
|
|
376
|
+
constructor(maxConcurrent) {
|
|
377
|
+
this.maxConcurrent = maxConcurrent;
|
|
378
|
+
}
|
|
379
|
+
queued() {
|
|
380
|
+
return this.queue.length;
|
|
381
|
+
}
|
|
382
|
+
async run(task) {
|
|
383
|
+
if (this.active >= this.maxConcurrent) {
|
|
384
|
+
await new Promise((resolve) => this.queue.push(resolve));
|
|
385
|
+
}
|
|
386
|
+
this.active += 1;
|
|
387
|
+
try {
|
|
388
|
+
return await task();
|
|
389
|
+
} finally {
|
|
390
|
+
this.active -= 1;
|
|
391
|
+
const next = this.queue.shift();
|
|
392
|
+
if (next) {
|
|
393
|
+
next();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
class ProbeFamily {
|
|
400
|
+
spec;
|
|
401
|
+
entries = new Map;
|
|
402
|
+
limiter;
|
|
403
|
+
constructor(spec) {
|
|
404
|
+
this.spec = spec;
|
|
405
|
+
assertProbeSpec(spec);
|
|
406
|
+
if (!Number.isInteger(spec.maxKeys) || spec.maxKeys <= 0) {
|
|
407
|
+
throw new Error(`Probe family ${spec.id} must declare a positive maxKeys`);
|
|
408
|
+
}
|
|
409
|
+
if (!Number.isFinite(spec.idleKeyTtlMs) || spec.idleKeyTtlMs <= 0) {
|
|
410
|
+
throw new Error(`Probe family ${spec.id} must declare a positive idleKeyTtlMs`);
|
|
411
|
+
}
|
|
412
|
+
if (!Number.isInteger(spec.maxConcurrentKeys) || spec.maxConcurrentKeys <= 0) {
|
|
413
|
+
throw new Error(`Probe family ${spec.id} must declare a positive maxConcurrentKeys`);
|
|
414
|
+
}
|
|
415
|
+
this.limiter = new FamilyLimiter(spec.maxConcurrentKeys);
|
|
416
|
+
}
|
|
417
|
+
for(rawKey) {
|
|
418
|
+
const key = this.normalize(rawKey);
|
|
419
|
+
this.cleanupIdle(Date.now());
|
|
420
|
+
let entry = this.entries.get(key);
|
|
421
|
+
if (!entry) {
|
|
422
|
+
entry = new ProbeInstance({
|
|
423
|
+
spec: this.spec,
|
|
424
|
+
key,
|
|
425
|
+
run: (ctx) => this.spec.run(key, ctx),
|
|
426
|
+
scheduleRun: (task) => this.limiter.run(task)
|
|
427
|
+
});
|
|
428
|
+
this.entries.set(key, entry);
|
|
429
|
+
}
|
|
430
|
+
entry.lastAccessAt = Date.now();
|
|
431
|
+
this.evictLruIfNeeded();
|
|
432
|
+
return entry;
|
|
433
|
+
}
|
|
434
|
+
snapshot(key) {
|
|
435
|
+
return this.for(key).snapshot();
|
|
436
|
+
}
|
|
437
|
+
invalidate(key, reason) {
|
|
438
|
+
this.for(key).invalidate(reason);
|
|
439
|
+
}
|
|
440
|
+
metrics() {
|
|
441
|
+
this.cleanupIdle(Date.now());
|
|
442
|
+
return {
|
|
443
|
+
id: this.spec.id,
|
|
444
|
+
keyCount: this.entries.size,
|
|
445
|
+
maxKeys: this.spec.maxKeys,
|
|
446
|
+
activeRuns: this.limiter.active,
|
|
447
|
+
queuedRuns: this.limiter.queued(),
|
|
448
|
+
keys: Array.from(this.entries.values(), (entry) => entry.metrics())
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
keys() {
|
|
452
|
+
this.cleanupIdle(Date.now());
|
|
453
|
+
return Array.from(this.entries.keys());
|
|
454
|
+
}
|
|
455
|
+
normalize(rawKey) {
|
|
456
|
+
const key = this.spec.normalizeKey(rawKey).trim();
|
|
457
|
+
if (!key) {
|
|
458
|
+
throw new Error(`Probe family ${this.spec.id} normalized an empty key`);
|
|
459
|
+
}
|
|
460
|
+
return key;
|
|
461
|
+
}
|
|
462
|
+
cleanupIdle(now) {
|
|
463
|
+
for (const [key, entry] of this.entries) {
|
|
464
|
+
if (!entry.isRefreshing() && now - entry.lastAccessAt > this.spec.idleKeyTtlMs) {
|
|
465
|
+
this.entries.delete(key);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
evictLruIfNeeded() {
|
|
470
|
+
while (this.entries.size > this.spec.maxKeys) {
|
|
471
|
+
let oldestKey = null;
|
|
472
|
+
let oldestAccess = Number.POSITIVE_INFINITY;
|
|
473
|
+
for (const [key, entry] of this.entries) {
|
|
474
|
+
if (entry.isRefreshing()) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
if (entry.lastAccessAt < oldestAccess) {
|
|
478
|
+
oldestAccess = entry.lastAccessAt;
|
|
479
|
+
oldestKey = key;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (!oldestKey) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
this.entries.delete(oldestKey);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// ../runtime/src/system-probes/scout-host-catalog.ts
|
|
491
|
+
var SCOUT_HOST_PROBE_SCHEMA_VERSIONS = {
|
|
492
|
+
"tailscale.status": 1,
|
|
493
|
+
"git.buildInfo": 1,
|
|
494
|
+
"git.revParse": 1,
|
|
495
|
+
"git.diffShortstat": 1,
|
|
496
|
+
"git.statusPorcelain": 1,
|
|
497
|
+
"git.mergeBase": 1,
|
|
498
|
+
"git.logLastCommitUnix": 1,
|
|
499
|
+
"git.worktreeListPorcelain": 1,
|
|
500
|
+
"tmux.sessions": 2,
|
|
501
|
+
"tmux.panes": 1,
|
|
502
|
+
"zellij.sessions": 1,
|
|
503
|
+
"ps.runtime": 1,
|
|
504
|
+
"ps.discovery": 1,
|
|
505
|
+
"ps.cwd": 1,
|
|
506
|
+
"net.listeners": 1,
|
|
507
|
+
"repo.scan": 1,
|
|
508
|
+
"repo.diff": 1
|
|
509
|
+
};
|
|
510
|
+
var SCOUT_HOST_EXEC_VERB_SCHEMA_VERSIONS = {
|
|
511
|
+
"tmux.sendKeys": 1,
|
|
512
|
+
"tmux.sendKeysLiteral": 1,
|
|
513
|
+
"tmux.loadBuffer": 1,
|
|
514
|
+
"tmux.pasteBuffer": 1,
|
|
515
|
+
"tmux.deleteBuffer": 1,
|
|
516
|
+
"tmux.killSession": 1,
|
|
517
|
+
"tmux.newSession": 1,
|
|
518
|
+
"tmux.detachClient": 1,
|
|
519
|
+
"tailscale.cert": 1,
|
|
520
|
+
"reveal.open": 1
|
|
521
|
+
};
|
|
522
|
+
function expectedScoutHostProbeSchemaVersion(probeId) {
|
|
523
|
+
return Object.hasOwn(SCOUT_HOST_PROBE_SCHEMA_VERSIONS, probeId) ? SCOUT_HOST_PROBE_SCHEMA_VERSIONS[probeId] : null;
|
|
524
|
+
}
|
|
525
|
+
function expectedScoutHostExecVerbSchemaVersion(verb) {
|
|
526
|
+
return Object.hasOwn(SCOUT_HOST_EXEC_VERB_SCHEMA_VERSIONS, verb) ? SCOUT_HOST_EXEC_VERB_SCHEMA_VERSIONS[verb] : null;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// ../runtime/src/system-probes/scoutd-client.ts
|
|
530
|
+
var CAPABILITIES_SCHEMA = "openscout.probe.capabilities/v1";
|
|
531
|
+
var REQUEST_SCHEMA = "openscout.probe.request/v1";
|
|
532
|
+
var SNAPSHOT_SCHEMA = "openscout.probe.snapshot/v1";
|
|
533
|
+
var ERROR_SCHEMA = "openscout.probe.error/v1";
|
|
534
|
+
var EXEC_REQUEST_SCHEMA = "openscout.exec.request/v1";
|
|
535
|
+
var EXEC_RESPONSE_SCHEMA = "openscout.exec.response/v1";
|
|
536
|
+
var CAPABILITY_RECHECK_MS = 1e4;
|
|
537
|
+
var SOCKET_TIMEOUT_MS = 900;
|
|
538
|
+
var MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
|
|
539
|
+
function readString(value) {
|
|
540
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
541
|
+
}
|
|
542
|
+
function readNumber(value) {
|
|
543
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
544
|
+
}
|
|
545
|
+
function isRecord(value) {
|
|
546
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
547
|
+
}
|
|
548
|
+
function fallbackMessage(error) {
|
|
549
|
+
if (error instanceof Error && error.message.trim()) {
|
|
550
|
+
return error.message;
|
|
551
|
+
}
|
|
552
|
+
return String(error);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
class ScoutdExecResponseError extends Error {
|
|
556
|
+
code;
|
|
557
|
+
timedOut;
|
|
558
|
+
constructor(message, options = {}) {
|
|
559
|
+
super(message);
|
|
560
|
+
this.name = "ScoutdExecResponseError";
|
|
561
|
+
this.code = options.code ?? "exec_error";
|
|
562
|
+
this.timedOut = options.timedOut ?? false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
class ScoutdProbeResponseError extends Error {
|
|
567
|
+
code;
|
|
568
|
+
timedOut;
|
|
569
|
+
constructor(message, options = {}) {
|
|
570
|
+
super(message);
|
|
571
|
+
this.name = "ScoutdProbeResponseError";
|
|
572
|
+
this.code = options.code ?? "probe_error";
|
|
573
|
+
this.timedOut = options.timedOut ?? false;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
function resolveScoutdProbesSocketPath(env = process.env) {
|
|
577
|
+
const explicit = env.OPENSCOUT_PROBES_SOCKET?.trim();
|
|
578
|
+
if (explicit) {
|
|
579
|
+
return explicit;
|
|
580
|
+
}
|
|
581
|
+
const openScoutHome = env.OPENSCOUT_HOME?.trim() || join(homedir(), ".openscout");
|
|
582
|
+
return join(openScoutHome, "run", "scoutd-probes.sock");
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
class ScoutdProbeClient {
|
|
586
|
+
env;
|
|
587
|
+
capabilities = null;
|
|
588
|
+
lastCapabilityCheckAt = null;
|
|
589
|
+
lastError = null;
|
|
590
|
+
daemonObserved = false;
|
|
591
|
+
fallbackByProbe = new Map;
|
|
592
|
+
fallbackByExec = new Map;
|
|
593
|
+
constructor(env = process.env) {
|
|
594
|
+
this.env = env;
|
|
595
|
+
}
|
|
596
|
+
async requestProbe(input) {
|
|
597
|
+
const socketPath = resolveScoutdProbesSocketPath(this.env);
|
|
598
|
+
const socketTimeoutMs = probeSocketTimeoutMs(input.timeoutMs);
|
|
599
|
+
const socketExists = existsSync(socketPath);
|
|
600
|
+
if (!socketExists) {
|
|
601
|
+
this.capabilities = null;
|
|
602
|
+
this.lastError = null;
|
|
603
|
+
return this.daemonObserved ? this.fallback(input.probeId, input.key, `probe socket is missing: ${socketPath}`) : { state: "local" };
|
|
604
|
+
}
|
|
605
|
+
this.daemonObserved = true;
|
|
606
|
+
const capabilities = await this.ensureCapabilities(socketPath, socketTimeoutMs);
|
|
607
|
+
if (!capabilities) {
|
|
608
|
+
return this.fallback(input.probeId, input.key, this.lastError ?? "probe capabilities unavailable");
|
|
609
|
+
}
|
|
610
|
+
const capability = capabilities.families.get(input.probeId);
|
|
611
|
+
if (!capability) {
|
|
612
|
+
return this.fallback(input.probeId, input.key, `scoutd does not serve ${input.probeId}`);
|
|
613
|
+
}
|
|
614
|
+
const expectedSchemaVersion = expectedScoutHostProbeSchemaVersion(input.probeId);
|
|
615
|
+
if (expectedSchemaVersion === null) {
|
|
616
|
+
return this.fallback(input.probeId, input.key, `client has no compiled schema version for ${input.probeId}`);
|
|
617
|
+
}
|
|
618
|
+
if (capability.schemaVersion !== expectedSchemaVersion) {
|
|
619
|
+
return this.fallback(input.probeId, input.key, `scoutd serves ${input.probeId} schema v${capability.schemaVersion}, expected v${expectedSchemaVersion}`);
|
|
620
|
+
}
|
|
621
|
+
try {
|
|
622
|
+
const response = await requestJson(socketPath, {
|
|
623
|
+
schema: REQUEST_SCHEMA,
|
|
624
|
+
schemaVersion: expectedSchemaVersion,
|
|
625
|
+
probeId: input.probeId,
|
|
626
|
+
key: input.key ?? null,
|
|
627
|
+
maxAgeMs: input.maxAgeMs,
|
|
628
|
+
opTimeoutMs: requestOpTimeoutMs(input.timeoutMs)
|
|
629
|
+
}, { timeoutMs: socketTimeoutMs });
|
|
630
|
+
if (!isRecord(response) || response.schema !== SNAPSHOT_SCHEMA) {
|
|
631
|
+
throw new Error("scoutd returned an invalid probe snapshot envelope");
|
|
632
|
+
}
|
|
633
|
+
if (response.error) {
|
|
634
|
+
const error = isRecord(response.error) ? response.error : {};
|
|
635
|
+
const code = readString(error.code) ?? "probe_error";
|
|
636
|
+
const message = readString(error.message) ?? code;
|
|
637
|
+
const timedOut = error.timedOut === true || error.timed_out === true;
|
|
638
|
+
throw new ScoutdProbeResponseError(message, { code, timedOut });
|
|
639
|
+
}
|
|
640
|
+
this.fallbackByProbe.delete(fallbackKey(input.probeId, input.key));
|
|
641
|
+
this.lastError = null;
|
|
642
|
+
return {
|
|
643
|
+
state: "scoutd",
|
|
644
|
+
value: response.value,
|
|
645
|
+
generatedAt: readNumber(response.generatedAt) ?? Date.now(),
|
|
646
|
+
daemonVersion: readString(response.daemonVersion) ?? capabilities.daemonVersion
|
|
647
|
+
};
|
|
648
|
+
} catch (error) {
|
|
649
|
+
if (!(error instanceof ScoutdProbeResponseError)) {
|
|
650
|
+
this.capabilities = null;
|
|
651
|
+
this.lastCapabilityCheckAt = null;
|
|
652
|
+
}
|
|
653
|
+
this.lastError = fallbackMessage(error);
|
|
654
|
+
return this.fallback(input.probeId, input.key, this.lastError);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
async requestExecVerb(input) {
|
|
658
|
+
const socketPath = resolveScoutdProbesSocketPath(this.env);
|
|
659
|
+
const socketTimeoutMs = execSocketTimeoutMs(input.args);
|
|
660
|
+
const socketExists = existsSync(socketPath);
|
|
661
|
+
if (!socketExists) {
|
|
662
|
+
this.capabilities = null;
|
|
663
|
+
this.lastError = null;
|
|
664
|
+
return this.daemonObserved ? this.execFallback(input.verb, `probe socket is missing: ${socketPath}`) : { state: "local" };
|
|
665
|
+
}
|
|
666
|
+
this.daemonObserved = true;
|
|
667
|
+
const capabilities = await this.ensureCapabilities(socketPath, socketTimeoutMs);
|
|
668
|
+
if (!capabilities) {
|
|
669
|
+
return this.execFallback(input.verb, this.lastError ?? "probe capabilities unavailable");
|
|
670
|
+
}
|
|
671
|
+
const capability = capabilities.verbs.get(input.verb);
|
|
672
|
+
if (!capability) {
|
|
673
|
+
return this.execFallback(input.verb, `scoutd does not serve ${input.verb}`);
|
|
674
|
+
}
|
|
675
|
+
const expectedSchemaVersion = expectedScoutHostExecVerbSchemaVersion(input.verb);
|
|
676
|
+
if (expectedSchemaVersion === null) {
|
|
677
|
+
return this.execFallback(input.verb, `client has no compiled schema version for ${input.verb}`);
|
|
678
|
+
}
|
|
679
|
+
if (capability.schemaVersion !== expectedSchemaVersion) {
|
|
680
|
+
return this.execFallback(input.verb, `scoutd serves ${input.verb} schema v${capability.schemaVersion}, expected v${expectedSchemaVersion}`);
|
|
681
|
+
}
|
|
682
|
+
try {
|
|
683
|
+
const response = await requestJson(socketPath, {
|
|
684
|
+
schema: EXEC_REQUEST_SCHEMA,
|
|
685
|
+
schemaVersion: expectedSchemaVersion,
|
|
686
|
+
verb: input.verb,
|
|
687
|
+
args: input.args
|
|
688
|
+
}, { timeoutMs: socketTimeoutMs });
|
|
689
|
+
if (!isRecord(response) || response.schema !== EXEC_RESPONSE_SCHEMA) {
|
|
690
|
+
throw new Error("scoutd returned an invalid exec response envelope");
|
|
691
|
+
}
|
|
692
|
+
if (!response.ok) {
|
|
693
|
+
const error = isRecord(response.error) ? response.error : {};
|
|
694
|
+
const code = readString(error.code) ?? "exec_error";
|
|
695
|
+
const message = readString(error.message) ?? code;
|
|
696
|
+
const timedOut = error.timedOut === true || error.timed_out === true;
|
|
697
|
+
throw new ScoutdExecResponseError(message, { code, timedOut });
|
|
698
|
+
}
|
|
699
|
+
this.fallbackByExec.delete(input.verb);
|
|
700
|
+
this.lastError = null;
|
|
701
|
+
return {
|
|
702
|
+
state: "scoutd",
|
|
703
|
+
value: response.value,
|
|
704
|
+
daemonVersion: readString(response.daemonVersion) ?? capabilities.daemonVersion
|
|
705
|
+
};
|
|
706
|
+
} catch (error) {
|
|
707
|
+
if (error instanceof ScoutdExecResponseError) {
|
|
708
|
+
throw error;
|
|
709
|
+
}
|
|
710
|
+
this.capabilities = null;
|
|
711
|
+
this.lastCapabilityCheckAt = null;
|
|
712
|
+
this.lastError = fallbackMessage(error);
|
|
713
|
+
return this.execFallback(input.verb, this.lastError);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
diagnostics() {
|
|
717
|
+
const socketPath = resolveScoutdProbesSocketPath(this.env);
|
|
718
|
+
return {
|
|
719
|
+
socketPath,
|
|
720
|
+
socketExists: existsSync(socketPath),
|
|
721
|
+
daemonObserved: this.daemonObserved,
|
|
722
|
+
daemonVersion: this.capabilities?.daemonVersion ?? null,
|
|
723
|
+
supportedProbeIds: this.capabilities ? [...this.capabilities.families.keys()].sort() : [],
|
|
724
|
+
supportedExecVerbs: this.capabilities ? [...this.capabilities.verbs.keys()].sort() : [],
|
|
725
|
+
lastCapabilityCheckAt: this.lastCapabilityCheckAt,
|
|
726
|
+
lastError: this.lastError
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
resetForTests() {
|
|
730
|
+
this.capabilities = null;
|
|
731
|
+
this.lastCapabilityCheckAt = null;
|
|
732
|
+
this.lastError = null;
|
|
733
|
+
this.daemonObserved = false;
|
|
734
|
+
this.fallbackByProbe.clear();
|
|
735
|
+
this.fallbackByExec.clear();
|
|
736
|
+
}
|
|
737
|
+
async ensureCapabilities(socketPath, timeoutMs = SOCKET_TIMEOUT_MS) {
|
|
738
|
+
const now = Date.now();
|
|
739
|
+
if (this.capabilities && this.lastCapabilityCheckAt !== null && now - this.lastCapabilityCheckAt < CAPABILITY_RECHECK_MS) {
|
|
740
|
+
return this.capabilities;
|
|
741
|
+
}
|
|
742
|
+
this.lastCapabilityCheckAt = now;
|
|
743
|
+
try {
|
|
744
|
+
const response = await requestJson(socketPath, { schema: CAPABILITIES_SCHEMA }, { timeoutMs });
|
|
745
|
+
if (!isRecord(response) || response.schema !== CAPABILITIES_SCHEMA) {
|
|
746
|
+
throw new Error("scoutd returned an invalid capabilities envelope");
|
|
747
|
+
}
|
|
748
|
+
const daemonVersion = readString(response.daemonVersion) ?? "unknown";
|
|
749
|
+
const families = new Map;
|
|
750
|
+
if (Array.isArray(response.families)) {
|
|
751
|
+
for (const entry of response.families) {
|
|
752
|
+
if (!isRecord(entry))
|
|
753
|
+
continue;
|
|
754
|
+
const probeId = readString(entry.probeId);
|
|
755
|
+
const schemaVersion = readNumber(entry.schemaVersion);
|
|
756
|
+
const ttlMs = readNumber(entry.ttlMs);
|
|
757
|
+
if (probeId && schemaVersion !== null && ttlMs !== null) {
|
|
758
|
+
families.set(probeId, { probeId, schemaVersion, ttlMs });
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const verbs = new Map;
|
|
763
|
+
if (Array.isArray(response.verbs)) {
|
|
764
|
+
for (const entry of response.verbs) {
|
|
765
|
+
if (!isRecord(entry))
|
|
766
|
+
continue;
|
|
767
|
+
const verb = readString(entry.verb);
|
|
768
|
+
const schemaVersion = readNumber(entry.schemaVersion);
|
|
769
|
+
if (verb && schemaVersion !== null) {
|
|
770
|
+
verbs.set(verb, { verb, schemaVersion });
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
this.capabilities = { daemonVersion, families, verbs };
|
|
775
|
+
this.daemonObserved = true;
|
|
776
|
+
this.lastError = null;
|
|
777
|
+
return this.capabilities;
|
|
778
|
+
} catch (error) {
|
|
779
|
+
this.capabilities = null;
|
|
780
|
+
this.lastError = fallbackMessage(error);
|
|
781
|
+
return null;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
fallback(probeId, key, reason) {
|
|
785
|
+
const id = fallbackKey(probeId, key);
|
|
786
|
+
let state = this.fallbackByProbe.get(id);
|
|
787
|
+
if (!state || state.reason !== reason) {
|
|
788
|
+
state = { since: Date.now(), reason };
|
|
789
|
+
this.fallbackByProbe.set(id, state);
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
state: "local",
|
|
793
|
+
fallbackSince: state.since,
|
|
794
|
+
fallbackReason: state.reason
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
execFallback(verb, reason) {
|
|
798
|
+
let state = this.fallbackByExec.get(verb);
|
|
799
|
+
if (!state || state.reason !== reason) {
|
|
800
|
+
state = { since: Date.now(), reason };
|
|
801
|
+
this.fallbackByExec.set(verb, state);
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
state: "local",
|
|
805
|
+
fallbackSince: state.since,
|
|
806
|
+
fallbackReason: state.reason
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function probeSocketTimeoutMs(timeoutMs) {
|
|
811
|
+
if (timeoutMs === undefined || !Number.isFinite(timeoutMs)) {
|
|
812
|
+
return SOCKET_TIMEOUT_MS;
|
|
813
|
+
}
|
|
814
|
+
return Math.max(SOCKET_TIMEOUT_MS, Math.min(Math.max(0, timeoutMs) + 1000, 31000));
|
|
815
|
+
}
|
|
816
|
+
function requestOpTimeoutMs(timeoutMs) {
|
|
817
|
+
if (timeoutMs === undefined || !Number.isFinite(timeoutMs)) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
return Math.max(0, Math.floor(timeoutMs));
|
|
821
|
+
}
|
|
822
|
+
function execSocketTimeoutMs(args) {
|
|
823
|
+
const timeoutMs = typeof args.timeoutMs === "number" && Number.isFinite(args.timeoutMs) ? Math.max(0, args.timeoutMs) : 5000;
|
|
824
|
+
return Math.max(SOCKET_TIMEOUT_MS, Math.min(timeoutMs + 1000, 31000));
|
|
825
|
+
}
|
|
826
|
+
async function requestJson(socketPath, payload, options = {}) {
|
|
827
|
+
const bun = globalThis.Bun;
|
|
828
|
+
if (bun?.connect) {
|
|
829
|
+
return await requestJsonWithBun(bun.connect, socketPath, payload, options);
|
|
830
|
+
}
|
|
831
|
+
return await new Promise((resolve, reject) => {
|
|
832
|
+
const socket = new Socket;
|
|
833
|
+
let response = "";
|
|
834
|
+
let settled = false;
|
|
835
|
+
const finish = (error, value) => {
|
|
836
|
+
if (settled)
|
|
837
|
+
return;
|
|
838
|
+
settled = true;
|
|
839
|
+
clearTimeout(timer);
|
|
840
|
+
socket.removeAllListeners();
|
|
841
|
+
socket.destroy();
|
|
842
|
+
if (error) {
|
|
843
|
+
reject(error);
|
|
844
|
+
} else {
|
|
845
|
+
resolve(value);
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
const timeoutMs = options.timeoutMs ?? SOCKET_TIMEOUT_MS;
|
|
849
|
+
const timer = setTimeout(() => {
|
|
850
|
+
finish(new Error(`scoutd probe socket timed out after ${timeoutMs}ms`));
|
|
851
|
+
}, timeoutMs);
|
|
852
|
+
timer.unref?.();
|
|
853
|
+
const finishFromResponse = () => {
|
|
854
|
+
if (settled)
|
|
855
|
+
return;
|
|
856
|
+
try {
|
|
857
|
+
const parsed = JSON.parse(response);
|
|
858
|
+
if (isRecord(parsed) && parsed.schema === ERROR_SCHEMA) {
|
|
859
|
+
const error = isRecord(parsed.error) ? parsed.error : {};
|
|
860
|
+
const message = readString(error.message) ?? readString(error.code) ?? "scoutd probe request failed";
|
|
861
|
+
finish(new Error(message));
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
finish(null, parsed);
|
|
865
|
+
} catch (error) {
|
|
866
|
+
finish(new Error(`scoutd probe response was not JSON: ${fallbackMessage(error)}`));
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
socket.setEncoding("utf8");
|
|
870
|
+
socket.on("connect", () => {
|
|
871
|
+
socket.write(`${JSON.stringify(payload)}
|
|
872
|
+
`);
|
|
873
|
+
});
|
|
874
|
+
socket.on("data", (chunk) => {
|
|
875
|
+
response += chunk;
|
|
876
|
+
if (Buffer.byteLength(response, "utf8") > MAX_RESPONSE_BYTES) {
|
|
877
|
+
finish(new Error("scoutd probe response exceeded output limit"));
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
socket.on("error", (error) => finish(error));
|
|
881
|
+
socket.on("end", finishFromResponse);
|
|
882
|
+
socket.on("close", () => {
|
|
883
|
+
if (!settled) {
|
|
884
|
+
if (response.length === 0) {
|
|
885
|
+
finish(new Error("scoutd probe socket closed without a response"));
|
|
886
|
+
} else {
|
|
887
|
+
finishFromResponse();
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
socket.connect(socketPath);
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
async function requestJsonWithBun(connect, socketPath, payload, options = {}) {
|
|
895
|
+
return await new Promise((resolve, reject) => {
|
|
896
|
+
let response = "";
|
|
897
|
+
let settled = false;
|
|
898
|
+
let socketRef = null;
|
|
899
|
+
const decoder = new TextDecoder;
|
|
900
|
+
const finish = (error, value) => {
|
|
901
|
+
if (settled)
|
|
902
|
+
return;
|
|
903
|
+
settled = true;
|
|
904
|
+
clearTimeout(timer);
|
|
905
|
+
try {
|
|
906
|
+
socketRef?.end?.();
|
|
907
|
+
} catch {}
|
|
908
|
+
if (error) {
|
|
909
|
+
reject(error);
|
|
910
|
+
} else {
|
|
911
|
+
resolve(value);
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
const finishFromResponse = () => {
|
|
915
|
+
if (settled)
|
|
916
|
+
return;
|
|
917
|
+
try {
|
|
918
|
+
const parsed = JSON.parse(response);
|
|
919
|
+
if (isRecord(parsed) && parsed.schema === ERROR_SCHEMA) {
|
|
920
|
+
const error = isRecord(parsed.error) ? parsed.error : {};
|
|
921
|
+
const message = readString(error.message) ?? readString(error.code) ?? "scoutd probe request failed";
|
|
922
|
+
finish(new Error(message));
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
finish(null, parsed);
|
|
926
|
+
} catch (error) {
|
|
927
|
+
finish(new Error(`scoutd probe response was not JSON: ${fallbackMessage(error)}`));
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
const timeoutMs = options.timeoutMs ?? SOCKET_TIMEOUT_MS;
|
|
931
|
+
const timer = setTimeout(() => {
|
|
932
|
+
finish(new Error(`scoutd probe socket timed out after ${timeoutMs}ms`));
|
|
933
|
+
}, timeoutMs);
|
|
934
|
+
timer.unref?.();
|
|
935
|
+
connect({
|
|
936
|
+
unix: socketPath,
|
|
937
|
+
socket: {
|
|
938
|
+
open(socket) {
|
|
939
|
+
socketRef = socket;
|
|
940
|
+
socket.write(`${JSON.stringify(payload)}
|
|
941
|
+
`);
|
|
942
|
+
},
|
|
943
|
+
data(_socket, data) {
|
|
944
|
+
response += decoder.decode(data, { stream: true });
|
|
945
|
+
if (Buffer.byteLength(response, "utf8") > MAX_RESPONSE_BYTES) {
|
|
946
|
+
finish(new Error("scoutd probe response exceeded output limit"));
|
|
947
|
+
}
|
|
948
|
+
},
|
|
949
|
+
close() {
|
|
950
|
+
if (response.length === 0) {
|
|
951
|
+
finish(new Error("scoutd probe socket closed without a response"));
|
|
952
|
+
} else {
|
|
953
|
+
response += decoder.decode();
|
|
954
|
+
finishFromResponse();
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
error(_socket, error) {
|
|
958
|
+
finish(error);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}).then((socket) => {
|
|
962
|
+
socketRef = socket;
|
|
963
|
+
}, (error) => {
|
|
964
|
+
finish(error instanceof Error ? error : new Error(String(error)));
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
function fallbackKey(probeId, key) {
|
|
969
|
+
return `${probeId}\x00${key ?? ""}`;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// ../runtime/src/system-probes/exec.ts
|
|
973
|
+
var DEFAULT_STDOUT_CAP_BYTES = 1024 * 1024;
|
|
974
|
+
var DEFAULT_STDERR_CAP_BYTES = 128 * 1024;
|
|
975
|
+
var EXEC_SYSTEM_TRANSPORT_METADATA = Symbol.for("openscout.execSystem.transport");
|
|
976
|
+
|
|
977
|
+
// ../runtime/src/claude-session-records.ts
|
|
978
|
+
var TRANSCRIPT_TAIL_BYTES = 256 * 1024;
|
|
979
|
+
|
|
980
|
+
// ../runtime/src/support-paths.ts
|
|
981
|
+
import { homedir as homedir2 } from "os";
|
|
982
|
+
import { join as join2 } from "path";
|
|
14
983
|
var OPENSCOUT_RPC_CUTOVER_MARKER = "rpc-runtime-cutover-v1";
|
|
15
984
|
function resolveOpenScoutSupportPaths() {
|
|
16
|
-
const home =
|
|
17
|
-
const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ??
|
|
18
|
-
const logsDirectory =
|
|
19
|
-
const runtimeDirectory =
|
|
20
|
-
const catalogDirectory =
|
|
21
|
-
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ??
|
|
22
|
-
const knowledgeDirectory =
|
|
985
|
+
const home = homedir2();
|
|
986
|
+
const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join2(home, "Library", "Application Support", "OpenScout");
|
|
987
|
+
const logsDirectory = join2(supportDirectory, "logs");
|
|
988
|
+
const runtimeDirectory = join2(supportDirectory, "runtime");
|
|
989
|
+
const catalogDirectory = join2(supportDirectory, "catalog");
|
|
990
|
+
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join2(home, ".openscout", "control-plane");
|
|
991
|
+
const knowledgeDirectory = join2(controlHome, "knowledge");
|
|
23
992
|
return {
|
|
24
993
|
supportDirectory,
|
|
25
994
|
logsDirectory,
|
|
26
|
-
appLogsDirectory:
|
|
27
|
-
brokerLogsDirectory:
|
|
995
|
+
appLogsDirectory: join2(logsDirectory, "app"),
|
|
996
|
+
brokerLogsDirectory: join2(logsDirectory, "broker"),
|
|
28
997
|
runtimeDirectory,
|
|
29
998
|
catalogDirectory,
|
|
30
|
-
relayAgentsDirectory:
|
|
31
|
-
settingsPath:
|
|
32
|
-
harnessCatalogPath:
|
|
33
|
-
relayAgentsRegistryPath:
|
|
34
|
-
managedInstallsPath:
|
|
35
|
-
hostInfoPath:
|
|
36
|
-
relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ??
|
|
999
|
+
relayAgentsDirectory: join2(runtimeDirectory, "agents"),
|
|
1000
|
+
settingsPath: join2(supportDirectory, "settings.json"),
|
|
1001
|
+
harnessCatalogPath: join2(catalogDirectory, "harness-catalog.json"),
|
|
1002
|
+
relayAgentsRegistryPath: join2(supportDirectory, "relay-agents.json"),
|
|
1003
|
+
managedInstallsPath: join2(supportDirectory, "managed-installs.json"),
|
|
1004
|
+
hostInfoPath: join2(supportDirectory, ".host-info"),
|
|
1005
|
+
relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ?? join2(home, ".openscout", "relay"),
|
|
37
1006
|
controlHome,
|
|
38
1007
|
knowledgeDirectory,
|
|
39
|
-
knowledgeQmdDirectory:
|
|
40
|
-
knowledgeSqlitePath:
|
|
41
|
-
desktopStatusPath:
|
|
42
|
-
workspaceStatePath:
|
|
43
|
-
cutoverMarkerPath:
|
|
1008
|
+
knowledgeQmdDirectory: join2(knowledgeDirectory, "qmd"),
|
|
1009
|
+
knowledgeSqlitePath: join2(knowledgeDirectory, "knowledge.sqlite"),
|
|
1010
|
+
desktopStatusPath: join2(supportDirectory, "agent-status.json"),
|
|
1011
|
+
workspaceStatePath: join2(supportDirectory, "workspace-state.json"),
|
|
1012
|
+
cutoverMarkerPath: join2(supportDirectory, OPENSCOUT_RPC_CUTOVER_MARKER)
|
|
44
1013
|
};
|
|
45
1014
|
}
|
|
46
1015
|
|
|
47
1016
|
// ../runtime/src/claude-statusline.ts
|
|
48
1017
|
function resolveClaudeStatuslineDirectory() {
|
|
49
|
-
return
|
|
1018
|
+
return join3(resolveOpenScoutSupportPaths().runtimeDirectory, "statusline");
|
|
1019
|
+
}
|
|
1020
|
+
function resolveClaudeStatuslineSessionsDirectory(directory = resolveClaudeStatuslineDirectory()) {
|
|
1021
|
+
return join3(directory, "sessions");
|
|
1022
|
+
}
|
|
1023
|
+
var CLAUDE_STATUSLINE_SESSION_ID_PATTERN = /^[A-Za-z0-9._-]{1,128}$/u;
|
|
1024
|
+
function resolveClaudeStatuslineSessionSnapshotPath(sessionId, directory) {
|
|
1025
|
+
const trimmed = sessionId.trim();
|
|
1026
|
+
if (!CLAUDE_STATUSLINE_SESSION_ID_PATTERN.test(trimmed))
|
|
1027
|
+
return null;
|
|
1028
|
+
return join3(resolveClaudeStatuslineSessionsDirectory(directory), `${trimmed}.json`);
|
|
50
1029
|
}
|
|
51
1030
|
function resolveClaudeStatuslineDelegatePath() {
|
|
52
|
-
return
|
|
1031
|
+
return join3(resolveClaudeStatuslineDirectory(), "claude-delegate.json");
|
|
53
1032
|
}
|
|
54
1033
|
function resolveClaudeStatuslineWrapperPath() {
|
|
55
|
-
return
|
|
1034
|
+
return join3(resolveClaudeStatuslineDirectory(), "claude-statusline.sh");
|
|
56
1035
|
}
|
|
57
|
-
function
|
|
1036
|
+
function isRecord2(value) {
|
|
58
1037
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
59
1038
|
}
|
|
60
1039
|
function stringValue(value) {
|
|
@@ -75,12 +1054,12 @@ function percentLabel(value) {
|
|
|
75
1054
|
return `${number.toFixed(1)}%`;
|
|
76
1055
|
}
|
|
77
1056
|
function recordValue(value) {
|
|
78
|
-
return
|
|
1057
|
+
return isRecord2(value) ? value : null;
|
|
79
1058
|
}
|
|
80
1059
|
function parseClaudeStatuslinePayload(input) {
|
|
81
1060
|
try {
|
|
82
1061
|
const parsed = JSON.parse(input);
|
|
83
|
-
return
|
|
1062
|
+
return isRecord2(parsed) ? parsed : null;
|
|
84
1063
|
} catch {
|
|
85
1064
|
return null;
|
|
86
1065
|
}
|
|
@@ -102,20 +1081,27 @@ async function captureClaudeStatuslineSnapshot(input, options = {}) {
|
|
|
102
1081
|
if (!parsed) {
|
|
103
1082
|
return { captured: false, reason: typeof input === "string" ? "invalid-json" : "invalid-record" };
|
|
104
1083
|
}
|
|
105
|
-
if (!
|
|
1084
|
+
if (!isRecord2(parsed)) {
|
|
106
1085
|
return { captured: false, reason: "invalid-record" };
|
|
107
1086
|
}
|
|
108
1087
|
const directory = options.directory ?? resolveClaudeStatuslineDirectory();
|
|
109
|
-
const latestPath =
|
|
110
|
-
const historyPath =
|
|
1088
|
+
const latestPath = join3(directory, "claude-latest.json");
|
|
1089
|
+
const historyPath = join3(directory, "claude-history.jsonl");
|
|
111
1090
|
const snapshot = normalizeClaudeStatuslineSnapshot(parsed, options.capturedAt);
|
|
112
1091
|
const line = JSON.stringify(snapshot);
|
|
1092
|
+
const sessionId = stringValue(snapshot.session_id);
|
|
1093
|
+
const sessionSnapshotPath = sessionId ? resolveClaudeStatuslineSessionSnapshotPath(sessionId, directory) : null;
|
|
113
1094
|
await mkdir(directory, { recursive: true });
|
|
1095
|
+
if (sessionSnapshotPath) {
|
|
1096
|
+
await mkdir(resolveClaudeStatuslineSessionsDirectory(directory), { recursive: true });
|
|
1097
|
+
}
|
|
114
1098
|
await Promise.all([
|
|
115
1099
|
writeFile(latestPath, `${line}
|
|
116
1100
|
`, "utf8"),
|
|
117
1101
|
appendFile(historyPath, `${line}
|
|
118
|
-
`, "utf8")
|
|
1102
|
+
`, "utf8"),
|
|
1103
|
+
...sessionSnapshotPath ? [writeFile(sessionSnapshotPath, `${line}
|
|
1104
|
+
`, "utf8")] : []
|
|
119
1105
|
]);
|
|
120
1106
|
return {
|
|
121
1107
|
captured: true,
|
|
@@ -127,7 +1113,7 @@ async function captureClaudeStatuslineSnapshot(input, options = {}) {
|
|
|
127
1113
|
async function readClaudeStatuslineDelegate(path = resolveClaudeStatuslineDelegatePath()) {
|
|
128
1114
|
try {
|
|
129
1115
|
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
130
|
-
if (!
|
|
1116
|
+
if (!isRecord2(parsed))
|
|
131
1117
|
return null;
|
|
132
1118
|
const command = stringValue(parsed.command);
|
|
133
1119
|
if (!command)
|
|
@@ -137,7 +1123,7 @@ async function readClaudeStatuslineDelegate(path = resolveClaudeStatuslineDelega
|
|
|
137
1123
|
command,
|
|
138
1124
|
source: parsed.source === "manual" ? "manual" : "claude-settings.statusLine",
|
|
139
1125
|
installedAt: numberValue(parsed.installedAt) ?? Date.now(),
|
|
140
|
-
...
|
|
1126
|
+
...isRecord2(parsed.statusLine) ? { statusLine: parsed.statusLine } : {}
|
|
141
1127
|
};
|
|
142
1128
|
} catch {
|
|
143
1129
|
return null;
|