@openscout/scout 0.2.92 → 0.2.94
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 +22 -28
- package/bin/scoutd +0 -0
- package/dist/build-manifest.json +3 -3
- package/dist/client/apple-touch-icon.png +0 -0
- package/dist/client/assets/ActivityScreen--eANwuxa.js +1 -0
- package/dist/client/assets/{AddProjectForm-CpyytDf2.js → AddProjectForm-CcD6qvV8.js} +1 -1
- package/dist/client/assets/AgentAvatar-CYhf6twS.js +1 -0
- package/dist/client/assets/AgentConfigurationScreen-BTI24HQX.js +1 -0
- package/dist/client/assets/AgentDefinitionsWorkspace-srmN6-vj.js +1 -0
- package/dist/client/assets/{AgentDetailCard-BTiOmh-a.js → AgentDetailCard-UqPNpcvB.js} +1 -1
- package/dist/client/assets/AgentFloorView-XXNgI5Cj.js +1 -0
- package/dist/client/assets/AgentInfoScreen-CimdOnZ9.js +1 -0
- package/dist/client/assets/{AgentLaneCard-lfRNb7JD.js → AgentLaneCard-Z-aOBR3W.js} +1 -1
- package/dist/client/assets/{AgentLaneChrome-Dlwrbq3g.js → AgentLaneChrome-CyhA1reW.js} +1 -1
- package/dist/client/assets/AgentLaneDetailSheet-BNzjMjIH.js +4 -0
- package/dist/client/assets/{AgentLaneSummaryResize-6SOEWUnr.js → AgentLaneSummaryResize-Box8-_rS.js} +1 -1
- package/dist/client/assets/AgentLanesEmbedScreen-BmLnN4on.js +1 -0
- package/dist/client/assets/{AgentLanesPreflight-C3uOiOzd.js → AgentLanesPreflight-5B6sXvRB.js} +1 -1
- package/dist/client/assets/AgentLanesView-DHyzVBk6.js +2 -0
- package/dist/client/assets/{AgentLiveActions-BJ5dIfL3.js → AgentLiveActions-BwuzOE8h.js} +1 -1
- package/dist/client/assets/AgentSessions-CsZwoukw.js +6 -0
- package/dist/client/assets/AgentsConsole-KCao4XmX.js +1 -0
- package/dist/client/assets/AgentsScreen-CtPAmwRX.js +1 -0
- package/dist/client/assets/AgentsSubnav-CDMjKeYC.js +1 -0
- package/dist/client/assets/AstronautSuit-Ckx7lu7G.js +1 -0
- package/dist/client/assets/AtopView-DYlpgEHf.js +1 -0
- package/dist/client/assets/{BackToPicker-D1LV6Cqp.js → BackToPicker-4JaeRvDm.js} +1 -1
- package/dist/client/assets/BriefingDetailScreen-D6-xqrpo.js +1 -0
- package/dist/client/assets/BriefingsScreen-DKxSDEmk.js +1 -0
- package/dist/client/assets/{BrokerMetadataPanel-BhjECqOK.js → BrokerMetadataPanel-BbREmsbK.js} +1 -1
- package/dist/client/assets/BrokerScreen-fbPIouMw.js +5 -0
- package/dist/client/assets/CastPicker-BcA2vDDV.js +1 -0
- package/dist/client/assets/CastPicker-zXsnkTIy.css +1 -0
- package/dist/client/assets/ChatCollapsedStrip-Ycm0ecaX.js +1 -0
- package/dist/client/assets/{CodeDiffPane-Bx_2VAzv.js → CodeDiffPane-Cn8Y9hAt.js} +1 -1
- package/dist/client/assets/{CodeProjectPicker-C1yOJKvs.js → CodeProjectPicker-nPFktrco.js} +1 -1
- package/dist/client/assets/CodeScreen-BlAxtxE5.js +1 -0
- package/dist/client/assets/ConversationComposer-2HjbGPL9.js +1 -0
- package/dist/client/assets/ConversationFeedRows-C6wUqJrx.js +1 -0
- package/dist/client/assets/ConversationHeader-C8vfXaTF.js +1 -0
- package/dist/client/assets/ConversationPanels-CNCIbpqU.js +6 -0
- package/dist/client/assets/ConversationScreen-BNULZAp2.js +2 -0
- package/dist/client/assets/ConversationScreen-CkWnKXt6.css +1 -0
- package/dist/client/assets/ConversationStatus-DZuyKsWN.js +1 -0
- package/dist/client/assets/CrewAvatar-CTIuxp4G.js +1 -0
- package/dist/client/assets/CrewAvatar-D0c9z5Qr.css +1 -0
- package/dist/client/assets/CrewWorkspaces-CJhBKVoZ.css +1 -0
- package/dist/client/assets/CrewWorkspaces-CkPYIA46.js +1 -0
- package/dist/client/assets/{DataTable-CJbbgBdA.js → DataTable-6IDhanr5.js} +1 -1
- package/dist/client/assets/DispatchAftermath-DC1u9itO.js +1 -0
- package/dist/client/assets/DocumentFocusViewer-DZVhS7as.js +1 -0
- package/dist/client/assets/{EmbeddableSurfacesLab-BdsYRDky.js → EmbeddableSurfacesLab-BKUFJMCV.js} +1 -1
- package/dist/client/assets/{EmptyState-BRY5jTpz.js → EmptyState-CeBl0iGd.js} +1 -1
- package/dist/client/assets/{FileViewerPane-9Bveqm9c.js → FileViewerPane-DQlpNt2S.js} +2 -2
- package/dist/client/assets/FlightObserveScreen-CDWGSKZg.js +1 -0
- package/dist/client/assets/FollowScreen-BXHOp3gb.js +1 -0
- package/dist/client/assets/{HarnessMark-BPAphNjx.js → HarnessMark-D5CA5uSp.js} +1 -1
- package/dist/client/assets/HarnessesScreen-DhFXq1qz.js +1 -0
- package/dist/client/assets/{HerdrSession-BujfGzrP.js → HerdrSession-BRhs5LIR.js} +1 -1
- package/dist/client/assets/HomeHero-7JwycwFY.css +1 -0
- package/dist/client/assets/HomeHero-DMABJuze.js +1 -0
- package/dist/client/assets/HostAdvisorView-RAociATV.js +1 -0
- package/dist/client/assets/{KnowledgeSearchInspector-B4ZY24xE.js → KnowledgeSearchInspector-CZPyVNSw.js} +1 -1
- package/dist/client/assets/KnowledgeSearchScreen-mGTKIg00.js +1 -0
- package/dist/client/assets/{LaneToolHoverCard-B7KdvQvf.js → LaneToolHoverCard-D_DMlBeT.js} +1 -1
- package/dist/client/assets/LaneTraceDetailSheet-BEHg3LmH.js +1 -0
- package/dist/client/assets/{LaneTraceEventFocus-mkMw2wJU.js → LaneTraceEventFocus-DVimcizS.js} +1 -1
- package/dist/client/assets/{MeshCanvas-CpKcWxKy.js → MeshCanvas-BOuZx4AM.js} +2 -2
- package/dist/client/assets/{MeshCanvasMinimap-C9IoGHbe.js → MeshCanvasMinimap-wL-1N94e.js} +1 -1
- package/dist/client/assets/MeshScreen-DMY9Bmh5.js +1 -0
- package/dist/client/assets/{MeshTopologyView-DFzr0IZM.js → MeshTopologyView-DiDcX5f4.js} +2 -2
- package/dist/client/assets/MessagesScreen-Eulveud3.js +1 -0
- package/dist/client/assets/{MissionContextRail-Y8QxUZGE.js → MissionContextRail-DrNKXG5u.js} +1 -1
- package/dist/client/assets/MissionControlView-ByBlHVN8.js +1 -0
- package/dist/client/assets/MissionFocusOverlay-D1i6R6Zt.js +1 -0
- package/dist/client/assets/MissionLeftAgentRow-DN9NcCML.js +1 -0
- package/dist/client/assets/MissionLogPane-DSeIv3Xo.js +1 -0
- package/dist/client/assets/NewAgentModal-V7yK6J6j.js +1 -0
- package/dist/client/assets/NewChatComposer-hlWT-nbR.js +19 -0
- package/dist/client/assets/{NewChatOrigin-DmuJ32wa.js → NewChatOrigin-DdpzE4kz.js} +1 -1
- package/dist/client/assets/ObserveEmbedScreen-l_Q3ts2q.js +2 -0
- package/dist/client/assets/ObserveTextFlow-BSEtYTxU.js +2 -0
- package/dist/client/assets/ObservedTopologyPanel-CdGUXxGR.js +2 -0
- package/dist/client/assets/OpenScoutAppShell-DN8dOSK4.js +79 -0
- package/dist/client/assets/OpsAgentsView-ntGr4pz4.js +1 -0
- package/dist/client/assets/OpsScreen-Ppen_Lmj.js +1 -0
- package/dist/client/assets/OpsSubnav-GAKsoSor.js +1 -0
- package/dist/client/assets/ProjectAgentProfile-BLlp2e6t.js +1 -0
- package/dist/client/assets/{ProjectAgentProfileBar-BLVg5EeA.js → ProjectAgentProfileBar-BQET-qrY.js} +1 -1
- package/dist/client/assets/ProjectAgentProfileHero-Ck8mThtx.js +1 -0
- package/dist/client/assets/ProjectsInbox-Dlt8OQ8O.js +2 -0
- package/dist/client/assets/ProjectsRail-DCfNMmnW.js +1 -0
- package/dist/client/assets/ProjectsScreen-BP-hmI1m.js +1 -0
- package/dist/client/assets/ProjectsThreadAside-CWpMjGIH.js +1 -0
- package/dist/client/assets/Provider-B2xuo3rf.js +1 -0
- package/dist/client/assets/RailRow-B-GycCBx.js +1 -0
- package/dist/client/assets/RailRow-B0sRaJc6.css +1 -0
- package/dist/client/assets/RawSessionsTable-AQThi6sm.js +1 -0
- package/dist/client/assets/RealtimeVoiceScreen-D7zZHK_t.js +1 -0
- package/dist/client/assets/{RepoDiffEmbedScreen-BCDXFE3D.js → RepoDiffEmbedScreen-DXWoRF_c.js} +1 -1
- package/dist/client/assets/{RepoDiffPageScreen-m62FiWXC.js → RepoDiffPageScreen-D_274ExO.js} +1 -1
- package/dist/client/assets/RepoDiffViewer-DbedmHDX.js +7 -0
- package/dist/client/assets/RepoDiffViewerLazy-C0--fPtk.js +2 -0
- package/dist/client/assets/ReposScreen-D39_YG4H.js +6 -0
- package/dist/client/assets/ScoutDeckSurface-CKT3qdqY.js +1 -0
- package/dist/client/assets/{ScoutSurface-CkgT7A-c.js → ScoutSurface-UsRy0t-I.js} +1 -1
- package/dist/client/assets/{ScoutbotFxLab-D-kV5j4T.js → ScoutbotFxLab-Fmdfboxs.js} +1 -1
- package/dist/client/assets/{SecondaryNav-_wyKjwNf.js → SecondaryNav-o2RL9H8H.js} +1 -1
- package/dist/client/assets/{SessionEmbedScreen-CJZmIBV7.js → SessionEmbedScreen-RD5XOx7R.js} +1 -1
- package/dist/client/assets/{SessionObserve-yYA8Gy5s.js → SessionObserve-Dsd0j05N.js} +9 -9
- package/dist/client/assets/{SessionObserveEvidence-cHdjYOJe.js → SessionObserveEvidence-DopQYDkD.js} +1 -1
- package/dist/client/assets/SessionRefScreen-B_cTv47v.js +1 -0
- package/dist/client/assets/SessionsScreen-Bq0Z77On.js +1 -0
- package/dist/client/assets/SettingsDrawer-R8a0TlJD.css +1 -0
- package/dist/client/assets/SettingsDrawer-_AwuopMS.js +3 -0
- package/dist/client/assets/SettingsScreen-Cw4DDfJP.js +1 -0
- package/dist/client/assets/{ShikiPane-dBS9hD-z.js → ShikiPane-BfHc_3pM.js} +1 -1
- package/dist/client/assets/{SlidePanel-CH-3-8_2.js → SlidePanel-C-q7XwTa.js} +1 -1
- package/dist/client/assets/SpriteAvatar-Bs68ZENy.js +1 -0
- package/dist/client/assets/{StatusPill-C8m9ZymF.js → StatusPill-ZZQwxB1a.js} +1 -1
- package/dist/client/assets/{TailView-B0BSopPs.js → TailView-Q4FVMsUH.js} +2 -2
- package/dist/client/assets/Terminal-D7zqHwHV.js +1 -0
- package/dist/client/assets/TerminalEmbedScreen-CXIJ7qv6.js +1 -0
- package/dist/client/assets/TerminalHeaderMount-BnBLOPbb.js +1 -0
- package/dist/client/assets/{TextDocumentSurface-BWJCGBZf.js → TextDocumentSurface-CKQP-cBT.js} +1 -1
- package/dist/client/assets/{TmuxPeek-B4QdHbGm.js → TmuxPeek-V9dGESfO.js} +1 -1
- package/dist/client/assets/{VoicePermissionsPanel-Dd4ITJy_.js → VoicePermissionsPanel-k7sbLXx2.js} +1 -1
- package/dist/client/assets/WorkDetailScreen-60p9litn.js +5 -0
- package/dist/client/assets/WorkFilesViewer-BjJS7GyM.js +1 -0
- package/dist/client/assets/{activity-CC8JzJNH.js → activity-Bj3Hnbj3.js} +1 -1
- package/dist/client/assets/{addon-fit-CaZ-uLrg.js → addon-fit-BL-NTWRU.js} +1 -1
- package/dist/client/assets/{addon-webgl-B8utL3bM.js → addon-webgl-CIMgmNjg.js} +1 -1
- package/dist/client/assets/{ScoutbotBroadcastChip-CxtYZWPZ.css → agent-autocomplete-C7xwIcwd.css} +1 -1
- package/dist/client/assets/agent-autocomplete-DXlvdc4b.js +10 -0
- package/dist/client/assets/{agent-essentials-B3wcxg_v.js → agent-essentials-BOMHR0_U.js} +1 -1
- package/dist/client/assets/{agent-lane-card-model-q4cwzLX4.js → agent-lane-card-model-CTLxf3R4.js} +1 -1
- package/dist/client/assets/agent-lane-detail-ppJId6Jc.js +2 -0
- package/dist/client/assets/{agent-lane-preview-C33Dwpn7.js → agent-lane-preview-BhplDYGf.js} +1 -1
- package/dist/client/assets/{agent-lanes-BDNktFBZ.css → agent-lanes-DlqcEf0l.css} +1 -1
- package/dist/client/assets/{agent-lanes-model-VYQ5a68i.js → agent-lanes-model-AfrjRNK5.js} +2 -2
- package/dist/client/assets/agent-specialization-BIPIBW8u.js +1 -0
- package/dist/client/assets/api-Co9aQ2Jw.js +1 -0
- package/dist/client/assets/{api-BkjHJfgJ.js → api-HFH8wFyb.js} +1 -1
- package/dist/client/assets/{arc.es-uFv9UrHn.js → arc.es-IR5r6sj_.js} +1 -1
- package/dist/client/assets/archive-BjcGiAy8.js +1 -0
- package/dist/client/assets/{arrow-down-w1HPzDSE.js → arrow-down-BydciYFZ.js} +1 -1
- package/dist/client/assets/{arrow-left-B-3GJ7ct.js → arrow-left-CghA0kTw.js} +1 -1
- package/dist/client/assets/arrow-right-iJFv3jNh.js +1 -0
- package/dist/client/assets/{arrow-up-right-G6bJXxhK.js → arrow-up-right-CCfZXPqD.js} +1 -1
- package/dist/client/assets/{bot-DzCOGKi6.js → bot-B5sub1-i.js} +1 -1
- package/dist/client/assets/broker-display-Q75fupqG.js +2 -0
- package/dist/client/assets/{cache-Dr0why2k.js → cache-CeWH_KzJ.js} +1 -1
- package/dist/client/assets/{check-BX8nRgop.js → check-C18YQC90.js} +1 -1
- package/dist/client/assets/{chevron-down-B3VVRJcV.js → chevron-down-Mp9mu_yd.js} +1 -1
- package/dist/client/assets/{chevron-right-BYMV1511.js → chevron-right-CzH-TaSF.js} +1 -1
- package/dist/client/assets/{chunk-HRAB3GC3-dRd2eQMJ.js → chunk-HRAB3GC3-swV8PA2k.js} +1 -1
- package/dist/client/assets/{chunk-JTPDIGGW-BjX67kHU.js → chunk-JTPDIGGW-BKXqcLKw.js} +3 -3
- package/dist/client/assets/{chunk-T65CQEWV-kP6nJjkU.js → chunk-T65CQEWV-vYbNJ8E6.js} +1 -1
- package/dist/client/assets/{chunk-YOZR3KYS-C13bZPVd.js → chunk-YOZR3KYS-U65yUmqt.js} +1 -1
- package/dist/client/assets/{clock-B9ukVaVn.js → clock-B4PTFi5m.js} +1 -1
- package/dist/client/assets/{code-xml-BFc3TMSm.js → code-xml-Jtxsp5d1.js} +1 -1
- package/dist/client/assets/collapsed-strip-raJWthAH.css +1 -0
- package/dist/client/assets/compass-0_54-vz3.js +1 -0
- package/dist/client/assets/content-6RvWTrtk.js +1 -0
- package/dist/client/assets/content-BCgwMUqz.js +1 -0
- package/dist/client/assets/content-Bf2VLhx0.js +1 -0
- package/dist/client/assets/content-BrU_38-m.js +1 -0
- package/dist/client/assets/content-BvvJN8rN.js +1 -0
- package/dist/client/assets/content-CAeEqYPw.js +1 -0
- package/dist/client/assets/content-CHghn-rT.js +1 -0
- package/dist/client/assets/{content-Uqt8AG-s.css → content-CINHz-rZ.css} +1 -1
- package/dist/client/assets/content-CI_Z9DXk.js +1 -0
- package/dist/client/assets/content-CbyKONhW.js +1 -0
- package/dist/client/assets/content-Czogvp43.js +1 -0
- package/dist/client/assets/content-DFk0zNzX.js +1 -0
- package/dist/client/assets/content-DHe4DgkA.js +1 -0
- package/dist/client/assets/content-DMbawvqU.js +1 -0
- package/dist/client/assets/content-DTz7cKjo.js +1 -0
- package/dist/client/assets/content-E3kudY-W.js +1 -0
- package/dist/client/assets/content-LpO0aO_U.js +1 -0
- package/dist/client/assets/{conversation-icons-gpsv650H.js → conversation-icons-BV10B2Me.js} +1 -1
- package/dist/client/assets/conversation-model-CwF6Y9gx.js +1 -0
- package/dist/client/assets/conversation-motion-features-BKkCRaWR.js +1 -0
- package/dist/client/assets/{copy-BFmOcWof.js → copy-Dtpx4FOE.js} +1 -1
- package/dist/client/assets/cpu-BjVis9mc.js +1 -0
- package/dist/client/assets/{createLucideIcon-CFBn0Sdk.js → createLucideIcon-DXpqZP7I.js} +1 -1
- package/dist/client/assets/credentials-BTce3VP1.js +1 -0
- package/dist/client/assets/ctx-panel-D_HJ3nhb.css +1 -0
- package/dist/client/assets/discover-CHbrEItO.js +2 -0
- package/dist/client/assets/embed-entry-vil28MyU.js +2 -0
- package/dist/client/assets/{external-link-B1TI5yIt.js → external-link-Ckiyzjwo.js} +1 -1
- package/dist/client/assets/{eye-1J4yOUoG.js → eye-CpfyvdLq.js} +1 -1
- package/dist/client/assets/file-code-corner-7mo7EviR.js +1 -0
- package/dist/client/assets/{file-text-DcYSrI4v.js → file-text-KijGBnME.js} +1 -1
- package/dist/client/assets/gauge-y-Xg8Mrv.js +1 -0
- package/dist/client/assets/gestures-Bq9XnSqY.js +1 -0
- package/dist/client/assets/git-branch-BQ_x8KZL.js +1 -0
- package/dist/client/assets/harnesses-screen-2z36fJKE.css +1 -0
- package/dist/client/assets/home-moving-signal-DMguaRWR.css +1 -0
- package/dist/client/assets/home-moving-signal-DtRpiNa0.js +1 -0
- package/dist/client/assets/home-now-card-DFb4GOgM.js +1 -0
- package/dist/client/assets/{home-now-card-nano-y1EhBvVL.js → home-now-card-nano-D--m9jpq.js} +1 -1
- package/dist/client/assets/hooks-9d1SoaQA.js +2 -0
- package/dist/client/assets/host-advisor-B2Fqs5Dd.css +1 -0
- package/dist/client/assets/index-BVlMw8x_.js +1 -0
- package/dist/client/assets/index-CZ-05hKz.js +10 -0
- package/dist/client/assets/index-Cn0GR-q1.js +1 -0
- package/dist/client/assets/index-DosI4AG9.js +1 -0
- package/dist/client/assets/index-i7TMxlwW.css +1 -0
- package/dist/client/assets/index-wLwc74Pu.css +1 -0
- package/dist/client/assets/inspector-panel-C-EhEDYy.js +2 -0
- package/dist/client/assets/{keyboard-nav-h1IdakpD.js → keyboard-nav-DFhAJkW3.js} +1 -1
- package/dist/client/assets/{lane-observe-BA3g9aVd.js → lane-observe-vfyACHi0.js} +1 -1
- package/dist/client/assets/{lane-roster-store-71vFgAem.js → lane-roster-store-gUBsydNf.js} +1 -1
- package/dist/client/assets/layers-CGou-LwV.js +1 -0
- package/dist/client/assets/layout-grid-BrZt31QH.js +1 -0
- package/dist/client/assets/left-B_o51JV6.js +1 -0
- package/dist/client/assets/left-BpgWnaah.js +1 -0
- package/dist/client/assets/left-CwHZCGO3.js +2 -0
- package/dist/client/assets/left-CwLs0okF.js +1 -0
- package/dist/client/assets/left-Cx0kv6pe.js +1 -0
- package/dist/client/assets/left-DA0amyfu.js +1 -0
- package/dist/client/assets/left-DH44V4I_.css +1 -0
- package/dist/client/assets/left-R2OOE7VG.css +1 -0
- package/dist/client/assets/left-advisor-DU3s01gk.js +1 -0
- package/dist/client/assets/left-agents-qL5PpUY-.js +1 -0
- package/dist/client/assets/left-default-uvuvDmt0.js +1 -0
- package/dist/client/assets/left-lanes-DnNLgec8.js +1 -0
- package/dist/client/assets/left-mission-DN3-NLPC.js +1 -0
- package/dist/client/assets/left-z-6CkuBe.js +2 -0
- package/dist/client/assets/library-DIo5NiGP.js +1 -0
- package/dist/client/assets/{loader-circle-d6PKL_KD.js → loader-circle-BiohlpM3.js} +1 -1
- package/dist/client/assets/{local-agents-B5pq17tZ.js → local-agents-wUIaBcEr.js} +1 -1
- package/dist/client/assets/{mentions-agCGDgyA.js → mentions-CcPFMbmZ.js} +1 -1
- package/dist/client/assets/mesh-buckets-ByyFXdKT.js +1 -0
- package/dist/client/assets/{mesh-ops-5pZCYptW.js → mesh-ops-CvGyjK84.js} +1 -1
- package/dist/client/assets/mesh-roster-n2nDpEmA.js +1 -0
- package/dist/client/assets/{mesh-screen-BSDUjrnV.css → mesh-screen-D1Yvo8fU.css} +1 -1
- package/dist/client/assets/{mesh-view-store-KJzABIkN.js → mesh-view-store-BpxGm71b.js} +1 -1
- package/dist/client/assets/{message-circle-CJO-pi7b.js → message-circle-B2ddzBrX.js} +1 -1
- package/dist/client/assets/{message-markup-CyRDLdOn.js → message-markup-RkfmDfME.js} +1 -1
- package/dist/client/assets/{message-square-D1hMsMj_.js → message-square-D9YYWE0x.js} +1 -1
- package/dist/client/assets/message-visibility-DwxgcgYK.js +1 -0
- package/dist/client/assets/mission-control-CnU7dNt1.css +1 -0
- package/dist/client/assets/{mission-control-store-Ce6dOvnZ.js → mission-control-store-Bf4b54MV.js} +1 -1
- package/dist/client/assets/{observe-BSWVM8YA.js → observe-CJRIvOCn.js} +1 -1
- package/dist/client/assets/{operator-attention-BwSPeheT.js → operator-attention-RqieiSY8.js} +1 -1
- package/dist/client/assets/{page-status-D2FQLJOX.js → page-status-BptpTdQ-.js} +1 -1
- package/dist/client/assets/{paperclip-iZmDMOS5.js → paperclip-B1UNGl5d.js} +1 -1
- package/dist/client/assets/perf-PX8Rx0EP.js +1 -0
- package/dist/client/assets/persistent-state-YI-WHSCF.js +1 -0
- package/dist/client/assets/{plus-gZ0T0eBI.js → plus-CuU_X0-8.js} +1 -1
- package/dist/client/assets/profile-rY8jO38P.js +1 -0
- package/dist/client/assets/projects-inbox-BBs1hG13.css +1 -0
- package/dist/client/assets/projects-inbox-D-zAb9Gp.js +1 -0
- package/dist/client/assets/proxy-DnLpZIi9.js +1 -0
- package/dist/client/assets/{radio-RMLfV4EO.js → radio-Dm1ItnA4.js} +1 -1
- package/dist/client/assets/{refresh-cw-C4x1x6b_.js → refresh-cw-BRn9Oxxl.js} +1 -1
- package/dist/client/assets/resolve-panes-DO6LkwhQ.js +1 -0
- package/dist/client/assets/resolve-sidebar-context-CIF288wY.js +1 -0
- package/dist/client/assets/right-BJltPRnd.js +1 -0
- package/dist/client/assets/right-BbyYdzHn.js +1 -0
- package/dist/client/assets/right-Beh3nCUB.js +1 -0
- package/dist/client/assets/right-C1yumXNx.js +1 -0
- package/dist/client/assets/{right-D-k9Z1Fe.js → right-CJnB_Bg7.js} +2 -2
- package/dist/client/assets/right-CPP7GyOm.js +1 -0
- package/dist/client/assets/right-D3aTKf1F.js +1 -0
- package/dist/client/assets/right-DI1B79nR.js +1 -0
- package/dist/client/assets/right-DtsRNX5b.js +1 -0
- package/dist/client/assets/right-Shpw_xDy.js +1 -0
- package/dist/client/assets/{rocket-CMM-IdLy.js → rocket-DOwXHKWA.js} +1 -1
- package/dist/client/assets/router-DJj2WbDg.js +1 -0
- package/dist/client/assets/{scope-views-BIfMTXU4.js → scope-views-A4_vP97W.js} +1 -1
- package/dist/client/assets/scout-voice-BhPzrc6P.js +1 -0
- package/dist/client/assets/{scoutbot-BTIErYHo.js → scoutbot-BJIamJOH.js} +2 -2
- package/dist/client/assets/scoutbot-markdown-jh7tzFB1.js +6 -0
- package/dist/client/assets/{scroll-text-DPPYrqB9.js → scroll-text-DO0GQzvN.js} +1 -1
- package/dist/client/assets/{search-DAyagUtF.js → search-D1tJSAWe.js} +1 -1
- package/dist/client/assets/secondaryNavConfig-B9IF8wXl.js +1 -0
- package/dist/client/assets/{selection-bridge-BXw09aRF.js → selection-bridge-i2S9zpf8.js} +1 -1
- package/dist/client/assets/{send-horizontal-IcG46D2M.js → send-horizontal-CgLppsIC.js} +1 -1
- package/dist/client/assets/{server-BySujhDV.js → server-Dymv5Emh.js} +1 -1
- package/dist/client/assets/{session-catalog-ClS9xf6i.js → session-catalog-DNaOEzoQ.js} +1 -1
- package/dist/client/assets/{session-table-BdpHs1GN.js → session-table-PTQVoTyc.js} +1 -1
- package/dist/client/assets/settings-2fC_G9nX.js +1 -0
- package/dist/client/assets/{sliders-horizontal-R5pWUUcH.js → sliders-horizontal-BPSMHhbm.js} +1 -1
- package/dist/client/assets/{sparkles-DJOBD_8l.js → sparkles-Dy8p5xN8.js} +1 -1
- package/dist/client/assets/sse-CiOSzE5n.js +1 -0
- package/dist/client/assets/system-surfaces-redesign-QVXNeGYw.css +1 -0
- package/dist/client/assets/{tail-display-BRcJltQa.js → tail-display-DcliDVkW.js} +1 -1
- package/dist/client/assets/{tail-events-BdvqZHLr.js → tail-events-BMQmSx1n.js} +1 -1
- package/dist/client/assets/{terminal-relay-TffuSPGs.js → terminal-relay-9lhzEp2V.js} +1 -1
- package/dist/client/assets/terminal-screen-BLk4PAYt.css +1 -0
- package/dist/client/assets/terminal-sessions-BQ6t92tJ.js +1 -0
- package/dist/client/assets/{terminal-takeover-BOFPRPjR.js → terminal-takeover-DANQfTcy.js} +1 -1
- package/dist/client/assets/{terminal-DJPUp_Qn.js → terminal-yN9xN-h9.js} +1 -1
- package/dist/client/assets/{runtime-picker--IW3cRry.js → text-CnZ0e1-V.js} +1 -1
- package/dist/client/assets/text-rLpBg4_z.css +1 -0
- package/dist/client/assets/use-conversation-list-D9BNLfnW.js +1 -0
- package/dist/client/assets/{use-fleet-active-asks-BHzeBZSW.js → use-fleet-active-asks-BeAdcl09.js} +1 -1
- package/dist/client/assets/{use-mesh-ops-items-KmaauBr_.js → use-mesh-ops-items-BIvIHlqe.js} +1 -1
- package/dist/client/assets/use-reduced-motion-CKkhq9c5.js +1 -0
- package/dist/client/assets/{use-scout-dev-flags-BJbw87PK.js → use-scout-dev-flags-B2KCzPxn.js} +1 -1
- package/dist/client/assets/{useAgentHoverCard-C6o0tlat.js → useAgentHoverCard-CHBsxcbp.js} +1 -1
- package/dist/client/assets/useContentSecondaryNav-D0mUhxTF.js +1 -0
- package/dist/client/assets/{usePierreRuntime-Cm7-qdm0.js → usePierreRuntime-DUuXH5yp.js} +1 -1
- package/dist/client/assets/{wrench-CvRjjByE.js → wrench-YcXMlsh2.js} +1 -1
- package/dist/client/assets/{x-C8ayPBtj.js → x-e3h2hDsp.js} +1 -1
- package/dist/client/assets/{xterm-B0ci4Q9a.js → xterm-Byp1Hep_.js} +1 -1
- package/dist/client/assets/zap-nMcjPoWB.js +1 -0
- package/dist/client/favicon-16.png +0 -0
- package/dist/client/favicon-32.png +0 -0
- package/dist/client/favicon.ico +0 -0
- package/dist/client/favicon.svg +20 -47
- package/dist/client/index.html +5 -5
- package/dist/client/openscout-icon.png +0 -0
- package/dist/client/site.webmanifest +2 -2
- package/dist/client/web-app-icon-192.png +0 -0
- package/dist/client/web-app-icon-512.png +0 -0
- package/dist/main.mjs +20093 -78203
- package/dist/node/main.mjs +322 -252
- package/dist/pairing-runtime-controller.mjs +1032 -804
- package/dist/runtime/base-daemon.mjs +49 -121
- package/dist/runtime/broker-daemon.mjs +1105 -281
- package/dist/runtime/broker-process-manager.mjs +6 -0
- package/dist/runtime/mesh-discover.mjs +6 -0
- package/dist/scout-control-plane-web.mjs +3326 -1912
- package/package.json +7 -4
- package/dist/client/assets/ActivityScreen-DkUP7V7M.js +0 -1
- package/dist/client/assets/AgentAvatar-D8ZtMluU.js +0 -1
- package/dist/client/assets/AgentConfigurationScreen-BlGI6fuM.js +0 -1
- package/dist/client/assets/AgentDefinitionsWorkspace-CfaDVCVt.js +0 -1
- package/dist/client/assets/AgentFloorView-DjNLILLt.js +0 -1
- package/dist/client/assets/AgentInfoScreen-DG5dlHb_.js +0 -1
- package/dist/client/assets/AgentLaneDetailSheet-BzYzBfcW.js +0 -4
- package/dist/client/assets/AgentLanesEmbedScreen-Crxx1srt.js +0 -1
- package/dist/client/assets/AgentLanesView-ChNlmY-F.js +0 -2
- package/dist/client/assets/AgentSessions-DpY0htZV.js +0 -6
- package/dist/client/assets/AgentsConsole-CHyXrjhm.js +0 -1
- package/dist/client/assets/AgentsScreen-BhCjX2lD.js +0 -1
- package/dist/client/assets/AgentsSubnav-az_VDkri.js +0 -1
- package/dist/client/assets/AtopView-BjjPM8OX.js +0 -1
- package/dist/client/assets/BriefingDetailScreen-B7qJ90Np.js +0 -6
- package/dist/client/assets/BriefingsScreen-CW6N829d.js +0 -1
- package/dist/client/assets/BrokerScreen-X3z50712.js +0 -5
- package/dist/client/assets/ChatCollapsedStrip-DNR9osDy.js +0 -1
- package/dist/client/assets/CodeScreen-CIKK1LcZ.js +0 -1
- package/dist/client/assets/ContextMenu-CHIuVKz7.js +0 -1
- package/dist/client/assets/ConversationComposer-Bf7Ga_49.js +0 -1
- package/dist/client/assets/ConversationFeedRows-Cm1Lgo43.js +0 -1
- package/dist/client/assets/ConversationHeader-B_GXrKR0.js +0 -1
- package/dist/client/assets/ConversationPanels-BTBbEvrP.js +0 -2
- package/dist/client/assets/ConversationScreen-B3l2m3JI.js +0 -1
- package/dist/client/assets/ConversationScreen-yIKEsm-8.css +0 -1
- package/dist/client/assets/ConversationStatus-BqhUHD85.js +0 -1
- package/dist/client/assets/DispatchAftermath-BDA9CrOd.js +0 -1
- package/dist/client/assets/DocumentFocusViewer-B9vodVmG.js +0 -1
- package/dist/client/assets/FleetSearch-Bj9SCl2f.js +0 -1
- package/dist/client/assets/FleetSearch-EXOe8ulE.css +0 -1
- package/dist/client/assets/FlightObserveScreen-BVMdsiCC.js +0 -1
- package/dist/client/assets/FollowScreen-BifwHWOV.js +0 -1
- package/dist/client/assets/HarnessesScreen-fMnbnrD4.js +0 -1
- package/dist/client/assets/HomeHero-BgM6S39l.js +0 -1
- package/dist/client/assets/HomeHero-DEl-WBsT.css +0 -1
- package/dist/client/assets/KnowledgeSearchScreen-Ch_WENUC.js +0 -1
- package/dist/client/assets/LaneTraceDetailSheet-H3AnN-vN.js +0 -1
- package/dist/client/assets/MeshScreen-48QkJSDI.js +0 -1
- package/dist/client/assets/MessageComposerSuggestions-FdVHnT_q.js +0 -1
- package/dist/client/assets/MessagesScreen-BMOOfbWX.js +0 -1
- package/dist/client/assets/MissionControlView-BpsHKu1F.js +0 -1
- package/dist/client/assets/MissionFocusOverlay-BPnAEA3F.js +0 -1
- package/dist/client/assets/MissionLeftAgentRow-iOZ6ds9L.js +0 -1
- package/dist/client/assets/MissionLogPane-B0csI89E.js +0 -1
- package/dist/client/assets/NewAgentModal-DBHJR9Qm.js +0 -1
- package/dist/client/assets/NewChatComposer-Hd7pI5Ac.js +0 -19
- package/dist/client/assets/ObserveEmbedScreen-DyArn7Id.js +0 -2
- package/dist/client/assets/ObserveTextFlow-CkMrtT8s.js +0 -2
- package/dist/client/assets/ObservedTopologyPanel-CaSZZP05.js +0 -2
- package/dist/client/assets/OpenScoutAppShell-BtlKkiuF.js +0 -87
- package/dist/client/assets/OpsAgentsView-CnqrwbC2.js +0 -1
- package/dist/client/assets/OpsScreen-DOlmlVkP.js +0 -1
- package/dist/client/assets/OpsSubnav-Dj3ShAKv.js +0 -1
- package/dist/client/assets/PlanView-BLGdWDx6.js +0 -1
- package/dist/client/assets/ProjectAgentProfile-Dv1sVnQl.js +0 -1
- package/dist/client/assets/ProjectAgentProfileHero-0-GDhsPT.js +0 -1
- package/dist/client/assets/ProjectsInbox-B3DpAI5b.js +0 -2
- package/dist/client/assets/ProjectsRail-BDl7U9Jq.js +0 -1
- package/dist/client/assets/ProjectsScreen-Dl2FcGrR.js +0 -1
- package/dist/client/assets/ProjectsThreadAside-BcGC5mHE.js +0 -1
- package/dist/client/assets/Provider-cJCdHAxu.js +0 -1
- package/dist/client/assets/RailRow-CLcVmywd.js +0 -1
- package/dist/client/assets/RailRow-Cf9LOiEj.css +0 -1
- package/dist/client/assets/RawSessionsTable-DBto4Ts-.js +0 -1
- package/dist/client/assets/RealtimeVoiceScreen-DXEU5v3g.js +0 -1
- package/dist/client/assets/RepoDiffViewer-PaNeZMhJ.js +0 -7
- package/dist/client/assets/RepoDiffViewerLazy-CWE5GxMP.js +0 -2
- package/dist/client/assets/ReposScreen-Cksv1cAD.js +0 -6
- package/dist/client/assets/ScoutDeckSurface-BCjPl7C4.js +0 -1
- package/dist/client/assets/ScoutbotBroadcastChip-DkiRCHuK.js +0 -2
- package/dist/client/assets/ScoutbotRealtimeVoiceCall-1ixiEn1L.js +0 -1
- package/dist/client/assets/SessionRefScreen-OkTY7Szg.js +0 -1
- package/dist/client/assets/SessionsScreen-B-GFjxIA.js +0 -1
- package/dist/client/assets/SettingsDrawer-Co11RFX0.js +0 -3
- package/dist/client/assets/SettingsDrawer-UX7pFJU_.css +0 -1
- package/dist/client/assets/SettingsScreen-Cn09nq5_.js +0 -1
- package/dist/client/assets/SpriteAvatar-DS6Tmyua.js +0 -1
- package/dist/client/assets/Terminal-U8gjIdm3.js +0 -1
- package/dist/client/assets/TerminalEmbedScreen-CTmdE7us.js +0 -1
- package/dist/client/assets/WorkDetailScreen-mJs0mb99.js +0 -5
- package/dist/client/assets/WorkFilesViewer-ODzLXKxj.js +0 -1
- package/dist/client/assets/agent-identity-BxCsXnDp.js +0 -1
- package/dist/client/assets/agent-lane-detail-BNNm6FNu.js +0 -2
- package/dist/client/assets/api-h5zurxmi.js +0 -1
- package/dist/client/assets/broker-display-pp33bLsu.js +0 -2
- package/dist/client/assets/collapsed-strip-Dz-of2SM.css +0 -1
- package/dist/client/assets/content-B8gahuBy.js +0 -1
- package/dist/client/assets/content-BIqX06OQ.js +0 -1
- package/dist/client/assets/content-BKDZ6Fxe.js +0 -1
- package/dist/client/assets/content-C15Ya-iu.js +0 -1
- package/dist/client/assets/content-CDE9tJDF.js +0 -1
- package/dist/client/assets/content-CSAfI-PX.js +0 -1
- package/dist/client/assets/content-CTF9D60D.js +0 -1
- package/dist/client/assets/content-CbAGkYQO.js +0 -1
- package/dist/client/assets/content-CtqLJOVp.js +0 -1
- package/dist/client/assets/content-Dvs1KRfo.js +0 -1
- package/dist/client/assets/content-DyJdVZjI.js +0 -1
- package/dist/client/assets/content-Ji7ATaf7.js +0 -1
- package/dist/client/assets/content-eqZXKWcP.js +0 -1
- package/dist/client/assets/content-iyyQKwvA.js +0 -1
- package/dist/client/assets/content-pDE7Fpb9.js +0 -1
- package/dist/client/assets/content-pPSd2dua.js +0 -1
- package/dist/client/assets/conversation-model-CHwHZNw-.js +0 -1
- package/dist/client/assets/conversation-motion-features-DXtKlmuM.js +0 -1
- package/dist/client/assets/ctx-panel-B4s49N9e.css +0 -1
- package/dist/client/assets/discover-DKf0aTr_.js +0 -2
- package/dist/client/assets/embed-entry-RlQUTtc4.js +0 -2
- package/dist/client/assets/gestures-CcEOV6Sr.js +0 -1
- package/dist/client/assets/harnesses-screen-DBZoTZz8.css +0 -1
- package/dist/client/assets/home-moving-signal-Bh2FugbH.js +0 -1
- package/dist/client/assets/home-moving-signal-CAa0V91u.css +0 -1
- package/dist/client/assets/home-now-card-ByRH5fFx.js +0 -1
- package/dist/client/assets/hooks-DUZwL3Aq.js +0 -2
- package/dist/client/assets/index-BBznYVWk.css +0 -1
- package/dist/client/assets/index-BTuq-8Iv.js +0 -1
- package/dist/client/assets/index-CmwGCxUk.js +0 -1
- package/dist/client/assets/index-CvF09yvf.css +0 -1
- package/dist/client/assets/index-DmFAhGPj.js +0 -10
- package/dist/client/assets/index-Dtaswdsh.js +0 -1
- package/dist/client/assets/inspector-panel-DzgS5_Mv.js +0 -2
- package/dist/client/assets/left-8NITBvFX.js +0 -1
- package/dist/client/assets/left-B2HEqrTM.js +0 -2
- package/dist/client/assets/left-Bk3XnxPD.css +0 -1
- package/dist/client/assets/left-CCoobxPS.css +0 -1
- package/dist/client/assets/left-CTYUvXbe.js +0 -1
- package/dist/client/assets/left-CwDRT50z.js +0 -2
- package/dist/client/assets/left-CxlDLJlw.js +0 -1
- package/dist/client/assets/left-XFXxNd4g.js +0 -1
- package/dist/client/assets/left-agents-Ck4Xn-R8.js +0 -1
- package/dist/client/assets/left-default-BeOyS0bR.js +0 -1
- package/dist/client/assets/left-lanes-DZp3jJMo.js +0 -1
- package/dist/client/assets/left-mission-CuKFQ5xL.js +0 -1
- package/dist/client/assets/left-p1hkO6P0.js +0 -1
- package/dist/client/assets/left-plan-3rrFENhp.js +0 -2
- package/dist/client/assets/library-E--gKzEZ.js +0 -1
- package/dist/client/assets/mesh-buckets-CfAukILK.js +0 -1
- package/dist/client/assets/message-visibility-kJM8XcSG.js +0 -1
- package/dist/client/assets/mission-control-m3BTDQ9l.css +0 -1
- package/dist/client/assets/model-Co0zkMIc.js +0 -1
- package/dist/client/assets/plan-view-D56fneVF.css +0 -1
- package/dist/client/assets/profile-Dxj3VVOM.js +0 -1
- package/dist/client/assets/projects-inbox-COZ23dLR.css +0 -1
- package/dist/client/assets/projects-inbox-Dzt_GQDv.js +0 -1
- package/dist/client/assets/resolve-panes-C9gF0w4e.js +0 -1
- package/dist/client/assets/resolve-sidebar-context-DxbY5RCH.js +0 -1
- package/dist/client/assets/right-5L7Tn0zG.js +0 -1
- package/dist/client/assets/right-CYtkMmRu.js +0 -1
- package/dist/client/assets/right-CreoQzPP.js +0 -1
- package/dist/client/assets/right-D9xFfy2b.js +0 -1
- package/dist/client/assets/right-DI7zHADe.js +0 -1
- package/dist/client/assets/right-DUbJ3WVc.js +0 -1
- package/dist/client/assets/right-DiybhsiK.js +0 -1
- package/dist/client/assets/right-Jh_1Q88s.js +0 -1
- package/dist/client/assets/right-udr1qTJG.js +0 -1
- package/dist/client/assets/router-Cn_s9IGH.js +0 -1
- package/dist/client/assets/runtime-picker-vhm0gtLs.css +0 -1
- package/dist/client/assets/scout-voice-CwbOz6EN.js +0 -1
- package/dist/client/assets/secondaryNavConfig-Dw3gS1jR.js +0 -1
- package/dist/client/assets/sse-CxXt4tqI.js +0 -1
- package/dist/client/assets/system-surfaces-redesign-B7GQhfpw.css +0 -1
- package/dist/client/assets/terminal-screen-BqVnCwl0.css +0 -1
- package/dist/client/assets/terminal-sessions-AmSgHklm.js +0 -1
- package/dist/client/assets/text-DsBWV_4k.js +0 -1
- package/dist/client/assets/use-conversation-list-C-dPcjQe.js +0 -1
- package/dist/client/assets/use-reduced-motion-CYqhYqHO.js +0 -1
- package/dist/client/assets/useContentSecondaryNav-DjHBrgnS.js +0 -1
- package/dist/highlights-eq9cgrbb.scm +0 -604
- package/dist/highlights-ghv9g403.scm +0 -205
- package/dist/highlights-hk7bwhj4.scm +0 -284
- package/dist/highlights-r812a2qc.scm +0 -150
- package/dist/highlights-x6tmsnaa.scm +0 -115
- package/dist/injections-73j83es3.scm +0 -27
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- /package/dist/client/assets/{document-focus-viewer-BSC_JwVE.css → DocumentFocusViewer-BSC_JwVE.css} +0 -0
|
@@ -3182,12 +3182,12 @@ function checkDaemonBinaryStale() {
|
|
|
3182
3182
|
debug22(`daemon binary path changed: ${info.binaryPath} \u2192 ${currentBinaryPath}`);
|
|
3183
3183
|
} else {
|
|
3184
3184
|
try {
|
|
3185
|
-
const
|
|
3186
|
-
if (
|
|
3185
|
+
const stat8 = fs2.statSync(currentBinaryPath);
|
|
3186
|
+
if (stat8.mtimeMs === info.binaryMtimeMs) {
|
|
3187
3187
|
debug22("daemon binary is current \u2014 no restart needed");
|
|
3188
3188
|
return;
|
|
3189
3189
|
}
|
|
3190
|
-
debug22(`daemon binary mtime changed: ${info.binaryMtimeMs} \u2192 ${
|
|
3190
|
+
debug22(`daemon binary mtime changed: ${info.binaryMtimeMs} \u2192 ${stat8.mtimeMs}`);
|
|
3191
3191
|
} catch {
|
|
3192
3192
|
return;
|
|
3193
3193
|
}
|
|
@@ -3207,10 +3207,10 @@ function checkDaemonBinaryStale() {
|
|
|
3207
3207
|
}
|
|
3208
3208
|
function writeDaemonInfo(binaryPath) {
|
|
3209
3209
|
try {
|
|
3210
|
-
const
|
|
3210
|
+
const stat8 = fs2.statSync(binaryPath);
|
|
3211
3211
|
fs2.writeFileSync(getDaemonInfoPath(), JSON.stringify({
|
|
3212
3212
|
binaryPath,
|
|
3213
|
-
binaryMtimeMs:
|
|
3213
|
+
binaryMtimeMs: stat8.mtimeMs
|
|
3214
3214
|
}));
|
|
3215
3215
|
} catch {}
|
|
3216
3216
|
}
|
|
@@ -3448,8 +3448,8 @@ function getParentSessionId() {
|
|
|
3448
3448
|
const chain = [process.pid];
|
|
3449
3449
|
let current = process.pid;
|
|
3450
3450
|
for (let i = 0;i < 64; i++) {
|
|
3451
|
-
const
|
|
3452
|
-
const fields =
|
|
3451
|
+
const stat8 = fs2.readFileSync(`/proc/${current}/stat`, "utf-8");
|
|
3452
|
+
const fields = stat8.split(") ");
|
|
3453
3453
|
if (fields.length < 2)
|
|
3454
3454
|
break;
|
|
3455
3455
|
const ppid = parseInt(fields[1].split(" ")[1], 10);
|
|
@@ -4594,8 +4594,8 @@ async function withDirLock(lockPath, opts, fn) {
|
|
|
4594
4594
|
}
|
|
4595
4595
|
try {
|
|
4596
4596
|
const owner = readLockOwner(lockPath);
|
|
4597
|
-
const
|
|
4598
|
-
const ageMs = Date.now() -
|
|
4597
|
+
const stat8 = fs.statSync(lockPath);
|
|
4598
|
+
const ageMs = Date.now() - stat8.mtimeMs;
|
|
4599
4599
|
if (owner ? !isLockOwnerAlive(owner) : ageMs > OWNER_GRACE_MS) {
|
|
4600
4600
|
debug4("stealing abandoned lock %s (owner pid %s)", lockPath, owner?.pid ?? "unknown");
|
|
4601
4601
|
stealLock(lockPath);
|
|
@@ -23960,8 +23960,8 @@ function writeBackValue(itemKey, newValueStr, sourceFilePath) {
|
|
|
23960
23960
|
}
|
|
23961
23961
|
function getParentPidViaProc(pid) {
|
|
23962
23962
|
try {
|
|
23963
|
-
const
|
|
23964
|
-
const after =
|
|
23963
|
+
const stat8 = readFileSync19(`/proc/${pid}/stat`, "utf8");
|
|
23964
|
+
const after = stat8.slice(stat8.lastIndexOf(")") + 2);
|
|
23965
23965
|
const fields = after.split(" ");
|
|
23966
23966
|
const ppid = Number(fields[1]);
|
|
23967
23967
|
return Number.isFinite(ppid) ? ppid : undefined;
|
|
@@ -26972,7 +26972,7 @@ var require_tslib2 = __commonJS((exports, module) => {
|
|
|
26972
26972
|
// packages/runtime/src/broker-daemon.ts
|
|
26973
26973
|
import { createHash as createHash16, randomUUID as randomUUID9 } from "crypto";
|
|
26974
26974
|
import { createServer } from "http";
|
|
26975
|
-
import { mkdir as mkdir14, readFile as readFile15, rename as rename3, stat as
|
|
26975
|
+
import { mkdir as mkdir14, readFile as readFile15, rename as rename3, stat as stat8, unlink as unlink3, writeFile as writeFile11 } from "fs/promises";
|
|
26976
26976
|
import { createRequire as createRequire4 } from "module";
|
|
26977
26977
|
import { hostname as hostname4 } from "os";
|
|
26978
26978
|
import { basename as basename24, dirname as dirname33, join as join56, resolve as resolve22 } from "path";
|
|
@@ -43866,7 +43866,6 @@ function formatScoutPermissionProfiles() {
|
|
|
43866
43866
|
|
|
43867
43867
|
// packages/protocol/src/presence.ts
|
|
43868
43868
|
var PRESENCE_STALE_AFTER_MS = 45000;
|
|
43869
|
-
var PRESENCE_REFRESH_INTERVAL_MS = 30000;
|
|
43870
43869
|
var PRESENCE_GONE_AFTER_STALE_MS = 60000;
|
|
43871
43870
|
function presenceLifecycle(beat, now, options = {}) {
|
|
43872
43871
|
if (now < beat.staleAt)
|
|
@@ -44660,7 +44659,7 @@ function isScoutLaunchableHarness(value) {
|
|
|
44660
44659
|
if (!value)
|
|
44661
44660
|
return false;
|
|
44662
44661
|
const normalized = value.trim().toLowerCase();
|
|
44663
|
-
return SCOUT_LAUNCHABLE_HARNESSES.includes(normalized);
|
|
44662
|
+
return normalized === "oc" || SCOUT_LAUNCHABLE_HARNESSES.includes(normalized);
|
|
44664
44663
|
}
|
|
44665
44664
|
function normalizeScoutReasoningEffort(value) {
|
|
44666
44665
|
const normalized = value?.trim().toLowerCase();
|
|
@@ -45353,12 +45352,12 @@ function patchConsoleForSecrets() {
|
|
|
45353
45352
|
}
|
|
45354
45353
|
|
|
45355
45354
|
// packages/runtime/src/tail/claude-source.ts
|
|
45356
|
-
import { closeSync, existsSync as existsSync4, openSync, readdirSync, readSync, statSync } from "fs";
|
|
45355
|
+
import { closeSync, existsSync as existsSync4, openSync, readdirSync, readSync, statSync as statSync2 } from "fs";
|
|
45357
45356
|
import { homedir as homedir4 } from "os";
|
|
45358
45357
|
import { basename, join as join4, relative } from "path";
|
|
45359
45358
|
|
|
45360
45359
|
// packages/runtime/src/user-config.ts
|
|
45361
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
45360
|
+
import { existsSync as existsSync2, readFileSync, statSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
45362
45361
|
import { homedir as homedir2 } from "os";
|
|
45363
45362
|
import { dirname, join as join2 } from "path";
|
|
45364
45363
|
|
|
@@ -45441,15 +45440,41 @@ function ensureOpenScoutCleanSlateSync() {
|
|
|
45441
45440
|
function userConfigPath() {
|
|
45442
45441
|
return join2(process.env.OPENSCOUT_HOME ?? join2(homedir2(), ".openscout"), "user.json");
|
|
45443
45442
|
}
|
|
45444
|
-
|
|
45445
|
-
|
|
45446
|
-
|
|
45447
|
-
return {};
|
|
45443
|
+
var userConfigCache = null;
|
|
45444
|
+
var USER_CONFIG_STAT_INTERVAL_MS = 100;
|
|
45445
|
+
function userConfigFileKey(configPath) {
|
|
45448
45446
|
try {
|
|
45449
|
-
|
|
45447
|
+
const stats = statSync(configPath);
|
|
45448
|
+
return `${stats.ino}:${stats.mtimeMs}:${stats.size}`;
|
|
45450
45449
|
} catch {
|
|
45451
|
-
return
|
|
45450
|
+
return "missing";
|
|
45451
|
+
}
|
|
45452
|
+
}
|
|
45453
|
+
function readUserConfigFromDisk(configPath, now) {
|
|
45454
|
+
const fileKey = userConfigFileKey(configPath);
|
|
45455
|
+
let value = {};
|
|
45456
|
+
if (existsSync2(configPath)) {
|
|
45457
|
+
try {
|
|
45458
|
+
value = JSON.parse(readFileSync(configPath, "utf8"));
|
|
45459
|
+
} catch {
|
|
45460
|
+
value = {};
|
|
45461
|
+
}
|
|
45462
|
+
}
|
|
45463
|
+
userConfigCache = { path: configPath, value, fileKey, statCheckedAt: now };
|
|
45464
|
+
return { ...value };
|
|
45465
|
+
}
|
|
45466
|
+
function loadUserConfig(now = Date.now()) {
|
|
45467
|
+
const configPath = userConfigPath();
|
|
45468
|
+
if (userConfigCache && userConfigCache.path === configPath) {
|
|
45469
|
+
if (now - userConfigCache.statCheckedAt < USER_CONFIG_STAT_INTERVAL_MS) {
|
|
45470
|
+
return { ...userConfigCache.value };
|
|
45471
|
+
}
|
|
45472
|
+
if (userConfigFileKey(configPath) === userConfigCache.fileKey) {
|
|
45473
|
+
userConfigCache.statCheckedAt = now;
|
|
45474
|
+
return { ...userConfigCache.value };
|
|
45475
|
+
}
|
|
45452
45476
|
}
|
|
45477
|
+
return readUserConfigFromDisk(configPath, now);
|
|
45453
45478
|
}
|
|
45454
45479
|
function readSettingsOperatorName() {
|
|
45455
45480
|
const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
|
|
@@ -47558,7 +47583,7 @@ function listRecentClaudeProjectTranscripts(root, scope) {
|
|
|
47558
47583
|
for (const entry of projectDirs) {
|
|
47559
47584
|
const projectDir = join4(root, entry);
|
|
47560
47585
|
try {
|
|
47561
|
-
if (!
|
|
47586
|
+
if (!statSync2(projectDir).isDirectory())
|
|
47562
47587
|
continue;
|
|
47563
47588
|
} catch {
|
|
47564
47589
|
continue;
|
|
@@ -47566,13 +47591,13 @@ function listRecentClaudeProjectTranscripts(root, scope) {
|
|
|
47566
47591
|
for (const file2 of listJsonlFiles(projectDir)) {
|
|
47567
47592
|
const path = join4(projectDir, file2);
|
|
47568
47593
|
try {
|
|
47569
|
-
const stats =
|
|
47594
|
+
const stats = statSync2(path);
|
|
47570
47595
|
const subagentsDir = join4(projectDir, basename(path, ".jsonl"), "subagents");
|
|
47571
47596
|
const activeSubagents = [];
|
|
47572
47597
|
for (const subagentFile of listClaudeSubagentFiles(subagentsDir)) {
|
|
47573
47598
|
const subagentPath = join4(subagentsDir, subagentFile);
|
|
47574
47599
|
try {
|
|
47575
|
-
const subagentStats =
|
|
47600
|
+
const subagentStats = statSync2(subagentPath);
|
|
47576
47601
|
if (subagentStats.mtimeMs < cutoff)
|
|
47577
47602
|
continue;
|
|
47578
47603
|
activeSubagents.push({
|
|
@@ -47809,7 +47834,7 @@ var ClaudeSource = {
|
|
|
47809
47834
|
};
|
|
47810
47835
|
|
|
47811
47836
|
// packages/runtime/src/tail/codex-source.ts
|
|
47812
|
-
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readdirSync as readdirSync2, readSync as readSync2, statSync as
|
|
47837
|
+
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readdirSync as readdirSync2, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
47813
47838
|
import { homedir as homedir5 } from "os";
|
|
47814
47839
|
import { basename as basename2, join as join5 } from "path";
|
|
47815
47840
|
var SOURCE_NAME2 = "codex";
|
|
@@ -47962,7 +47987,7 @@ function walkRecentJsonlFiles(root, scope) {
|
|
|
47962
47987
|
const path = join5(dir, entry);
|
|
47963
47988
|
let stats;
|
|
47964
47989
|
try {
|
|
47965
|
-
stats =
|
|
47990
|
+
stats = statSync3(path);
|
|
47966
47991
|
} catch {
|
|
47967
47992
|
continue;
|
|
47968
47993
|
}
|
|
@@ -48230,7 +48255,7 @@ var CodexSource = {
|
|
|
48230
48255
|
};
|
|
48231
48256
|
|
|
48232
48257
|
// packages/runtime/src/tail/cursor-source.ts
|
|
48233
|
-
import { closeSync as closeSync3, existsSync as existsSync6, openSync as openSync3, readdirSync as readdirSync3, readSync as readSync3, statSync as
|
|
48258
|
+
import { closeSync as closeSync3, existsSync as existsSync6, openSync as openSync3, readdirSync as readdirSync3, readSync as readSync3, statSync as statSync4 } from "fs";
|
|
48234
48259
|
import { homedir as homedir6 } from "os";
|
|
48235
48260
|
import { basename as basename3, join as join6 } from "path";
|
|
48236
48261
|
var SOURCE_NAME3 = "cursor";
|
|
@@ -48357,7 +48382,7 @@ function walkRecentMonitorLogs(root, scope) {
|
|
|
48357
48382
|
continue;
|
|
48358
48383
|
const path = join6(root, entry);
|
|
48359
48384
|
try {
|
|
48360
|
-
const stats =
|
|
48385
|
+
const stats = statSync4(path);
|
|
48361
48386
|
if (!stats.isFile() || stats.mtimeMs < cutoff)
|
|
48362
48387
|
continue;
|
|
48363
48388
|
found.push({ path, mtimeMs: stats.mtimeMs, size: stats.size });
|
|
@@ -48430,7 +48455,7 @@ var CursorSource = {
|
|
|
48430
48455
|
};
|
|
48431
48456
|
|
|
48432
48457
|
// packages/runtime/src/tail/grok-source.ts
|
|
48433
|
-
import { closeSync as closeSync4, existsSync as existsSync7, openSync as openSync4, readdirSync as readdirSync4, readFileSync as readFileSync2, readSync as readSync4, statSync as
|
|
48458
|
+
import { closeSync as closeSync4, existsSync as existsSync7, openSync as openSync4, readdirSync as readdirSync4, readFileSync as readFileSync2, readSync as readSync4, statSync as statSync5 } from "fs";
|
|
48434
48459
|
import { homedir as homedir7 } from "os";
|
|
48435
48460
|
import { basename as basename4, dirname as dirname2, join as join7 } from "path";
|
|
48436
48461
|
var SOURCE_NAME4 = "grok";
|
|
@@ -48600,7 +48625,7 @@ function walkRecentGrokEventFiles(root, scope) {
|
|
|
48600
48625
|
const path = join7(dir, entry);
|
|
48601
48626
|
let stats;
|
|
48602
48627
|
try {
|
|
48603
|
-
stats =
|
|
48628
|
+
stats = statSync5(path);
|
|
48604
48629
|
} catch {
|
|
48605
48630
|
continue;
|
|
48606
48631
|
}
|
|
@@ -48722,7 +48747,7 @@ function grokMatcherForTranscript(transcriptPath) {
|
|
|
48722
48747
|
return null;
|
|
48723
48748
|
let updatesMtimeMs = 0;
|
|
48724
48749
|
try {
|
|
48725
|
-
updatesMtimeMs =
|
|
48750
|
+
updatesMtimeMs = statSync5(updatesPath).mtimeMs;
|
|
48726
48751
|
} catch {
|
|
48727
48752
|
return null;
|
|
48728
48753
|
}
|
|
@@ -48912,7 +48937,7 @@ var GrokSource = {
|
|
|
48912
48937
|
};
|
|
48913
48938
|
|
|
48914
48939
|
// packages/runtime/src/tail/kimi-source.ts
|
|
48915
|
-
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync3, statSync as
|
|
48940
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync3, statSync as statSync6 } from "fs";
|
|
48916
48941
|
import { homedir as homedir8 } from "os";
|
|
48917
48942
|
import { basename as basename5, dirname as dirname3, join as join8 } from "path";
|
|
48918
48943
|
var SOURCE_NAME5 = "kimi";
|
|
@@ -49014,7 +49039,7 @@ function walkRecentKimiWireFiles(root, scope) {
|
|
|
49014
49039
|
const path = join8(directory, entry);
|
|
49015
49040
|
let stats;
|
|
49016
49041
|
try {
|
|
49017
|
-
stats =
|
|
49042
|
+
stats = statSync6(path);
|
|
49018
49043
|
} catch {
|
|
49019
49044
|
continue;
|
|
49020
49045
|
}
|
|
@@ -49034,7 +49059,7 @@ function readKimiTranscriptMetadata(file2) {
|
|
|
49034
49059
|
let stateMtimeMs = null;
|
|
49035
49060
|
let stateSize = null;
|
|
49036
49061
|
try {
|
|
49037
|
-
const stateStat =
|
|
49062
|
+
const stateStat = statSync6(statePath);
|
|
49038
49063
|
stateMtimeMs = stateStat.mtimeMs;
|
|
49039
49064
|
stateSize = stateStat.size;
|
|
49040
49065
|
} catch {}
|
|
@@ -49253,7 +49278,7 @@ var KimiSource = {
|
|
|
49253
49278
|
};
|
|
49254
49279
|
|
|
49255
49280
|
// packages/runtime/src/tail/opencode-source.ts
|
|
49256
|
-
import { closeSync as closeSync5, existsSync as existsSync9, openSync as openSync5, readdirSync as readdirSync6, readFileSync as readFileSync4, readSync as readSync5, statSync as
|
|
49281
|
+
import { closeSync as closeSync5, existsSync as existsSync9, openSync as openSync5, readdirSync as readdirSync6, readFileSync as readFileSync4, readSync as readSync5, statSync as statSync7 } from "fs";
|
|
49257
49282
|
import { homedir as homedir9 } from "os";
|
|
49258
49283
|
import { basename as basename6, join as join9, sep } from "path";
|
|
49259
49284
|
var SOURCE_NAME6 = "opencode";
|
|
@@ -49390,7 +49415,7 @@ function walkRecentSessionFiles(root, scope) {
|
|
|
49390
49415
|
const path = join9(dir, entry);
|
|
49391
49416
|
let stats;
|
|
49392
49417
|
try {
|
|
49393
|
-
stats =
|
|
49418
|
+
stats = statSync7(path);
|
|
49394
49419
|
} catch {
|
|
49395
49420
|
continue;
|
|
49396
49421
|
}
|
|
@@ -49418,38 +49443,63 @@ function walkRecentMessageSessionFiles(root, scope) {
|
|
|
49418
49443
|
for (const sessionId of sessionDirs) {
|
|
49419
49444
|
const dir = join9(messageRoot, sessionId);
|
|
49420
49445
|
let entries = [];
|
|
49446
|
+
let messageDirectoryMtime = 0;
|
|
49421
49447
|
try {
|
|
49422
|
-
const stats =
|
|
49448
|
+
const stats = statSync7(dir);
|
|
49423
49449
|
if (!stats.isDirectory())
|
|
49424
49450
|
continue;
|
|
49451
|
+
messageDirectoryMtime = stats.mtimeMs;
|
|
49425
49452
|
entries = readdirSync6(dir);
|
|
49426
49453
|
} catch {
|
|
49427
49454
|
continue;
|
|
49428
49455
|
}
|
|
49429
|
-
let
|
|
49456
|
+
let latestDependencyMtime = messageDirectoryMtime;
|
|
49457
|
+
let dependencySize = entries.length;
|
|
49430
49458
|
for (const entry of entries) {
|
|
49431
49459
|
if (!entry.endsWith(".json"))
|
|
49432
49460
|
continue;
|
|
49433
49461
|
try {
|
|
49434
|
-
const stats =
|
|
49435
|
-
if (stats.isFile()
|
|
49436
|
-
|
|
49462
|
+
const stats = statSync7(join9(dir, entry));
|
|
49463
|
+
if (!stats.isFile())
|
|
49464
|
+
continue;
|
|
49465
|
+
latestDependencyMtime = Math.max(latestDependencyMtime, stats.mtimeMs);
|
|
49466
|
+
dependencySize += stats.size;
|
|
49467
|
+
const messageId = entry.replace(/\.json$/u, "");
|
|
49468
|
+
const partDir = join9(root, "part", messageId);
|
|
49469
|
+
const partDirStats = statSync7(partDir);
|
|
49470
|
+
if (!partDirStats.isDirectory())
|
|
49471
|
+
continue;
|
|
49472
|
+
latestDependencyMtime = Math.max(latestDependencyMtime, partDirStats.mtimeMs);
|
|
49473
|
+
const partEntries = readdirSync6(partDir);
|
|
49474
|
+
dependencySize += partEntries.length;
|
|
49475
|
+
for (const partEntry of partEntries) {
|
|
49476
|
+
if (!partEntry.endsWith(".json"))
|
|
49477
|
+
continue;
|
|
49478
|
+
try {
|
|
49479
|
+
const partStats = statSync7(join9(partDir, partEntry));
|
|
49480
|
+
if (!partStats.isFile())
|
|
49481
|
+
continue;
|
|
49482
|
+
latestDependencyMtime = Math.max(latestDependencyMtime, partStats.mtimeMs);
|
|
49483
|
+
dependencySize += partStats.size;
|
|
49484
|
+
} catch {
|
|
49485
|
+
continue;
|
|
49486
|
+
}
|
|
49437
49487
|
}
|
|
49438
49488
|
} catch {
|
|
49439
49489
|
continue;
|
|
49440
49490
|
}
|
|
49441
49491
|
}
|
|
49442
|
-
if (
|
|
49492
|
+
if (latestDependencyMtime < cutoff)
|
|
49443
49493
|
continue;
|
|
49444
49494
|
const sessionPath = join9(root, "session", "global", `${sessionId}.json`);
|
|
49445
49495
|
try {
|
|
49446
|
-
const sessionStats =
|
|
49496
|
+
const sessionStats = statSync7(sessionPath);
|
|
49447
49497
|
if (!sessionStats.isFile())
|
|
49448
49498
|
continue;
|
|
49449
49499
|
found.set(sessionPath, {
|
|
49450
49500
|
path: sessionPath,
|
|
49451
|
-
mtimeMs: Math.max(sessionStats.mtimeMs,
|
|
49452
|
-
size: sessionStats.size
|
|
49501
|
+
mtimeMs: Math.max(sessionStats.mtimeMs, latestDependencyMtime),
|
|
49502
|
+
size: sessionStats.size + dependencySize
|
|
49453
49503
|
});
|
|
49454
49504
|
} catch {
|
|
49455
49505
|
continue;
|
|
@@ -49475,8 +49525,15 @@ function discoverOpenCodeTranscripts(scope) {
|
|
|
49475
49525
|
...walkRecentMessageSessionFiles(root, scope)
|
|
49476
49526
|
]) {
|
|
49477
49527
|
const existing = byPath.get(file2.path);
|
|
49478
|
-
if (!existing
|
|
49528
|
+
if (!existing) {
|
|
49479
49529
|
byPath.set(file2.path, file2);
|
|
49530
|
+
} else {
|
|
49531
|
+
byPath.set(file2.path, {
|
|
49532
|
+
path: file2.path,
|
|
49533
|
+
mtimeMs: Math.max(existing.mtimeMs, file2.mtimeMs),
|
|
49534
|
+
size: Math.max(existing.size, file2.size)
|
|
49535
|
+
});
|
|
49536
|
+
}
|
|
49480
49537
|
}
|
|
49481
49538
|
}
|
|
49482
49539
|
return [...byPath.values()].sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, discoveryLimit6(scope)).map((file2) => {
|
|
@@ -49511,7 +49568,7 @@ function readOpenCodeMessages(root, sessionId) {
|
|
|
49511
49568
|
const path = join9(dir, entry);
|
|
49512
49569
|
let stats;
|
|
49513
49570
|
try {
|
|
49514
|
-
stats =
|
|
49571
|
+
stats = statSync7(path);
|
|
49515
49572
|
} catch {
|
|
49516
49573
|
continue;
|
|
49517
49574
|
}
|
|
@@ -49539,7 +49596,7 @@ function readOpenCodeParts(root, messageId) {
|
|
|
49539
49596
|
const path = join9(dir, entry);
|
|
49540
49597
|
let stats;
|
|
49541
49598
|
try {
|
|
49542
|
-
stats =
|
|
49599
|
+
stats = statSync7(path);
|
|
49543
49600
|
} catch {
|
|
49544
49601
|
continue;
|
|
49545
49602
|
}
|
|
@@ -49666,7 +49723,7 @@ var OpenCodeSource = {
|
|
|
49666
49723
|
};
|
|
49667
49724
|
|
|
49668
49725
|
// packages/runtime/src/tail/pi-source.ts
|
|
49669
|
-
import { closeSync as closeSync6, existsSync as existsSync10, openSync as openSync6, readdirSync as readdirSync7, readSync as readSync6, statSync as
|
|
49726
|
+
import { closeSync as closeSync6, existsSync as existsSync10, openSync as openSync6, readdirSync as readdirSync7, readSync as readSync6, statSync as statSync8 } from "fs";
|
|
49670
49727
|
import { homedir as homedir10 } from "os";
|
|
49671
49728
|
import { basename as basename7, join as join10, relative as relative2 } from "path";
|
|
49672
49729
|
var SOURCE_NAME7 = "pi";
|
|
@@ -49821,7 +49878,7 @@ function listRecentPiProjectTranscripts(root, scope) {
|
|
|
49821
49878
|
for (const entry of projectDirs) {
|
|
49822
49879
|
const projectDir = join10(root, entry);
|
|
49823
49880
|
try {
|
|
49824
|
-
if (!
|
|
49881
|
+
if (!statSync8(projectDir).isDirectory())
|
|
49825
49882
|
continue;
|
|
49826
49883
|
} catch {
|
|
49827
49884
|
continue;
|
|
@@ -49829,7 +49886,7 @@ function listRecentPiProjectTranscripts(root, scope) {
|
|
|
49829
49886
|
for (const file2 of listJsonlFiles2(projectDir)) {
|
|
49830
49887
|
const path = join10(projectDir, file2);
|
|
49831
49888
|
try {
|
|
49832
|
-
const stats =
|
|
49889
|
+
const stats = statSync8(path);
|
|
49833
49890
|
if (stats.mtimeMs < cutoff)
|
|
49834
49891
|
continue;
|
|
49835
49892
|
found.push({ path, mtimeMs: stats.mtimeMs, size: stats.size });
|
|
@@ -50011,6 +50068,7 @@ var SHALLOW_DISCOVERY_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_SHALLOW_
|
|
|
50011
50068
|
var DEEP_DISCOVERY_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_DEEP_DISCOVERY_INTERVAL_MS", 60 * 60000);
|
|
50012
50069
|
var PER_SESSION_BUFFER_LIMIT = 2000;
|
|
50013
50070
|
var AGGREGATE_BUFFER_LIMIT = 1e4;
|
|
50071
|
+
var ASSISTANT_BUFFER_LIMIT = 1e4;
|
|
50014
50072
|
var QUIET_EVENT_COALESCE_WINDOW_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_WINDOW_MS", 5000);
|
|
50015
50073
|
var QUIET_EVENT_COALESCE_MAX_KEYS = readPositiveIntEnv8("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_MAX_KEYS", 2000);
|
|
50016
50074
|
var RAW_MAX_DEPTH = 5;
|
|
@@ -50019,12 +50077,19 @@ var RAW_MAX_ARRAY_ITEMS = 25;
|
|
|
50019
50077
|
var RAW_MAX_OBJECT_KEYS = 50;
|
|
50020
50078
|
var RECENT_TRANSCRIPT_READ_BYTES = 512 * 1024;
|
|
50021
50079
|
var SESSION_TRANSCRIPT_READ_BYTES = 8 * 1024 * 1024;
|
|
50080
|
+
var RECENT_TRANSCRIPT_KIND_SCAN_READ_BYTES = 32 * 1024 * 1024;
|
|
50022
50081
|
var RECENT_TRANSCRIPT_LINES_PER_FILE = 200;
|
|
50082
|
+
var RECENT_TRANSCRIPT_KIND_SCAN_MAX_LINES = 65536;
|
|
50023
50083
|
var RECENT_TRANSCRIPT_MAX_FILES = readPositiveIntEnv8("OPENSCOUT_TAIL_RECENT_TRANSCRIPT_MAX_FILES", 24);
|
|
50024
50084
|
var NATIVE_TAIL_SOURCES = new Set(["grok", "kimi", "opencode", "cursor"]);
|
|
50085
|
+
var TRANSCRIPT_REPLAY_MEMO_MAX_ENTRIES = readPositiveIntEnv8("OPENSCOUT_TAIL_REPLAY_MEMO_MAX_ENTRIES", 256);
|
|
50086
|
+
var TRANSCRIPT_REPLAY_ACTIVE_GRACE_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_REPLAY_MEMO_ACTIVE_GRACE_MS", 2000);
|
|
50087
|
+
var transcriptReplayMemo = new Map;
|
|
50088
|
+
var transcriptReplayInFlight = new Map;
|
|
50025
50089
|
var sources = [GrokSource, KimiSource, ClaudeSource, CodexSource, CursorSource, OpenCodeSource, PiSource];
|
|
50026
50090
|
var watchers = new Map;
|
|
50027
50091
|
var aggregateBuffer = [];
|
|
50092
|
+
var assistantBuffer = [];
|
|
50028
50093
|
var perSessionBuffer = new Map;
|
|
50029
50094
|
var subscribers2 = new Set;
|
|
50030
50095
|
var knownTranscripts = new Map;
|
|
@@ -50232,6 +50297,12 @@ function pushEvent(rawEvent) {
|
|
|
50232
50297
|
if (aggregateBuffer.length > AGGREGATE_BUFFER_LIMIT) {
|
|
50233
50298
|
aggregateBuffer.splice(0, aggregateBuffer.length - AGGREGATE_BUFFER_LIMIT);
|
|
50234
50299
|
}
|
|
50300
|
+
if (event.kind === "assistant") {
|
|
50301
|
+
assistantBuffer.push(event);
|
|
50302
|
+
if (assistantBuffer.length > ASSISTANT_BUFFER_LIMIT) {
|
|
50303
|
+
assistantBuffer.splice(0, assistantBuffer.length - ASSISTANT_BUFFER_LIMIT);
|
|
50304
|
+
}
|
|
50305
|
+
}
|
|
50235
50306
|
let bucket = perSessionBuffer.get(event.sessionId);
|
|
50236
50307
|
if (!bucket) {
|
|
50237
50308
|
bucket = [];
|
|
@@ -50562,14 +50633,16 @@ function subscribeTail(handler) {
|
|
|
50562
50633
|
function snapshotRecentEvents(limit = 500) {
|
|
50563
50634
|
return aggregateBuffer.slice(-limit);
|
|
50564
50635
|
}
|
|
50565
|
-
async function readRecentLiveEvents(limit = 500) {
|
|
50636
|
+
async function readRecentLiveEvents(limit = 500, options) {
|
|
50566
50637
|
if (watchers.size === 0) {
|
|
50567
50638
|
scheduleDiscovery("shallow", { pruneMissing: true });
|
|
50568
50639
|
} else if (!lastDiscovery || Date.now() - lastDiscovery.generatedAt > DISCOVERY_CACHE_MAX_AGE_MS) {
|
|
50569
50640
|
scheduleDiscovery("hot", { pruneMissing: false });
|
|
50570
50641
|
}
|
|
50571
50642
|
pumpAllWatchers();
|
|
50572
|
-
|
|
50643
|
+
const kinds = options?.kinds?.length ? new Set(options.kinds) : null;
|
|
50644
|
+
const source = kinds?.size === 1 && kinds.has("assistant") ? assistantBuffer : aggregateBuffer;
|
|
50645
|
+
return kinds ? source.filter((event) => kinds.has(event.kind)).slice(-limit) : snapshotRecentEvents(limit);
|
|
50573
50646
|
}
|
|
50574
50647
|
async function readRecentTranscriptLines(path, maxLines = RECENT_TRANSCRIPT_LINES_PER_FILE, maxBytes = RECENT_TRANSCRIPT_READ_BYTES) {
|
|
50575
50648
|
let handle = null;
|
|
@@ -50594,6 +50667,44 @@ async function readRecentTranscriptLines(path, maxLines = RECENT_TRANSCRIPT_LINE
|
|
|
50594
50667
|
await handle?.close().catch(() => {});
|
|
50595
50668
|
}
|
|
50596
50669
|
}
|
|
50670
|
+
async function parseRecentTranscriptLineEvents(input) {
|
|
50671
|
+
let fileSize = 0;
|
|
50672
|
+
try {
|
|
50673
|
+
fileSize = (await stat(input.transcriptPath)).size;
|
|
50674
|
+
} catch {
|
|
50675
|
+
return [];
|
|
50676
|
+
}
|
|
50677
|
+
let lineLimit = Math.max(1, input.lineLimit);
|
|
50678
|
+
let readBytes = Math.max(1, Math.min(input.initialReadBytes, input.maxReadBytes));
|
|
50679
|
+
const kindQuota = input.kinds?.size ? Math.max(1, input.kindQuota ?? 1) : null;
|
|
50680
|
+
const maxLines = kindQuota ? Math.max(lineLimit, RECENT_TRANSCRIPT_KIND_SCAN_MAX_LINES) : lineLimit;
|
|
50681
|
+
while (true) {
|
|
50682
|
+
const lines = await readRecentTranscriptLines(input.transcriptPath, lineLimit, readBytes);
|
|
50683
|
+
const parseState = {};
|
|
50684
|
+
const parsed = [];
|
|
50685
|
+
let index = 0;
|
|
50686
|
+
for (const line of lines) {
|
|
50687
|
+
const event = input.source.parseLine(line, {
|
|
50688
|
+
...input.context,
|
|
50689
|
+
lineOffset: index,
|
|
50690
|
+
state: parseState
|
|
50691
|
+
});
|
|
50692
|
+
index++;
|
|
50693
|
+
if (event)
|
|
50694
|
+
parsed.push(compactEvent(event));
|
|
50695
|
+
}
|
|
50696
|
+
const matchingCount = kindQuota ? parsed.reduce((count, event) => count + (input.kinds.has(event.kind) ? 1 : 0), 0) : 0;
|
|
50697
|
+
const exhaustedFile = readBytes >= fileSize && lines.length < lineLimit;
|
|
50698
|
+
if (!kindQuota || matchingCount >= kindQuota || exhaustedFile)
|
|
50699
|
+
return parsed;
|
|
50700
|
+
const nextLineLimit = Math.min(maxLines, lineLimit * 2);
|
|
50701
|
+
const nextReadBytes = Math.min(input.maxReadBytes, readBytes * 2);
|
|
50702
|
+
if (nextLineLimit === lineLimit && nextReadBytes === readBytes)
|
|
50703
|
+
return parsed;
|
|
50704
|
+
lineLimit = nextLineLimit;
|
|
50705
|
+
readBytes = nextReadBytes;
|
|
50706
|
+
}
|
|
50707
|
+
}
|
|
50597
50708
|
function rememberTranscriptEvent(events, seenEvents, event, dedupeKey) {
|
|
50598
50709
|
const compacted = compactEvent(event);
|
|
50599
50710
|
const key = dedupeKey ?? compacted.id;
|
|
@@ -50602,45 +50713,108 @@ function rememberTranscriptEvent(events, seenEvents, event, dedupeKey) {
|
|
|
50602
50713
|
seenEvents.add(key);
|
|
50603
50714
|
events.push(compacted);
|
|
50604
50715
|
}
|
|
50605
|
-
async function
|
|
50716
|
+
async function memoizedTranscriptReplay(transcriptPath, variant, load, dependency) {
|
|
50717
|
+
const cacheKey = `${transcriptPath}\x00${variant}`;
|
|
50718
|
+
const inFlight = transcriptReplayInFlight.get(cacheKey);
|
|
50719
|
+
if (inFlight)
|
|
50720
|
+
return [...await inFlight];
|
|
50721
|
+
let stats;
|
|
50722
|
+
try {
|
|
50723
|
+
stats = await stat(transcriptPath);
|
|
50724
|
+
} catch {
|
|
50725
|
+
transcriptReplayMemo.delete(cacheKey);
|
|
50726
|
+
return [];
|
|
50727
|
+
}
|
|
50728
|
+
const fingerprint = [
|
|
50729
|
+
stats.size,
|
|
50730
|
+
stats.mtimeMs,
|
|
50731
|
+
dependency?.size ?? "",
|
|
50732
|
+
dependency?.mtimeMs ?? ""
|
|
50733
|
+
].join(":");
|
|
50734
|
+
const effectiveMtimeMs = Math.max(stats.mtimeMs, dependency?.mtimeMs ?? 0);
|
|
50735
|
+
const cached2 = transcriptReplayMemo.get(cacheKey);
|
|
50736
|
+
const unchanged = cached2 && cached2.fingerprint === fingerprint;
|
|
50737
|
+
if (unchanged) {
|
|
50738
|
+
cached2.staleSinceMs = undefined;
|
|
50739
|
+
return [...cached2.events];
|
|
50740
|
+
}
|
|
50741
|
+
const now = Date.now();
|
|
50742
|
+
if (cached2 && now - effectiveMtimeMs < TRANSCRIPT_REPLAY_ACTIVE_GRACE_MS) {
|
|
50743
|
+
cached2.staleSinceMs ??= now;
|
|
50744
|
+
if (now - cached2.staleSinceMs < TRANSCRIPT_REPLAY_ACTIVE_GRACE_MS) {
|
|
50745
|
+
return [...cached2.events];
|
|
50746
|
+
}
|
|
50747
|
+
}
|
|
50748
|
+
const promise2 = (async () => {
|
|
50749
|
+
const events = await load();
|
|
50750
|
+
transcriptReplayMemo.delete(cacheKey);
|
|
50751
|
+
transcriptReplayMemo.set(cacheKey, {
|
|
50752
|
+
events: [...events],
|
|
50753
|
+
fingerprint
|
|
50754
|
+
});
|
|
50755
|
+
while (transcriptReplayMemo.size > TRANSCRIPT_REPLAY_MEMO_MAX_ENTRIES) {
|
|
50756
|
+
const oldest = transcriptReplayMemo.keys().next().value;
|
|
50757
|
+
if (typeof oldest !== "string")
|
|
50758
|
+
break;
|
|
50759
|
+
transcriptReplayMemo.delete(oldest);
|
|
50760
|
+
}
|
|
50761
|
+
return events;
|
|
50762
|
+
})().finally(() => transcriptReplayInFlight.delete(cacheKey));
|
|
50763
|
+
transcriptReplayInFlight.set(cacheKey, promise2);
|
|
50764
|
+
return [...await promise2];
|
|
50765
|
+
}
|
|
50766
|
+
async function appendWatcherTranscriptEvents(events, seenEvents, watcher, options) {
|
|
50606
50767
|
const { source, transcript, process: process3, transcriptPath } = watcher;
|
|
50607
50768
|
if (source.parseFile) {
|
|
50608
|
-
const
|
|
50609
|
-
|
|
50610
|
-
|
|
50611
|
-
|
|
50612
|
-
|
|
50613
|
-
|
|
50614
|
-
|
|
50615
|
-
|
|
50616
|
-
|
|
50617
|
-
|
|
50618
|
-
|
|
50769
|
+
const readBytes = options?.kinds?.size ? RECENT_TRANSCRIPT_KIND_SCAN_READ_BYTES : RECENT_TRANSCRIPT_READ_BYTES;
|
|
50770
|
+
const parsed2 = await memoizedTranscriptReplay(transcriptPath, `recent:file:${source.name}:${sessionRegistryKey(transcript)}:${readBytes}:${[...options?.kinds ?? []].sort().join(",")}`, async () => {
|
|
50771
|
+
const text2 = await readTranscriptText(transcriptPath, readBytes);
|
|
50772
|
+
if (!text2)
|
|
50773
|
+
return [];
|
|
50774
|
+
return parsedEventsToArray(source.parseFile(text2, {
|
|
50775
|
+
process: process3,
|
|
50776
|
+
transcript,
|
|
50777
|
+
transcriptPath,
|
|
50778
|
+
lineOffset: 0,
|
|
50779
|
+
state: {}
|
|
50780
|
+
}));
|
|
50781
|
+
}, { size: transcript.size, mtimeMs: transcript.mtimeMs });
|
|
50782
|
+
for (const event of parsed2) {
|
|
50783
|
+
if (options?.kinds?.size && !options.kinds.has(event.kind))
|
|
50784
|
+
continue;
|
|
50619
50785
|
rememberTranscriptEvent(events, seenEvents, event);
|
|
50620
50786
|
}
|
|
50621
50787
|
return;
|
|
50622
50788
|
}
|
|
50623
|
-
const
|
|
50624
|
-
const
|
|
50625
|
-
lines.
|
|
50626
|
-
|
|
50789
|
+
const lineLimit = options?.perTranscriptLineLimit ?? RECENT_TRANSCRIPT_LINES_PER_FILE;
|
|
50790
|
+
const kindKey = [...options?.kinds ?? []].sort().join(",");
|
|
50791
|
+
const parsed = await memoizedTranscriptReplay(transcriptPath, `recent:lines:${source.name}:${sessionRegistryKey(transcript)}:${lineLimit}:${RECENT_TRANSCRIPT_READ_BYTES}:${kindKey}:${options?.kindQuota ?? ""}`, () => parseRecentTranscriptLineEvents({
|
|
50792
|
+
source,
|
|
50793
|
+
transcriptPath,
|
|
50794
|
+
context: {
|
|
50627
50795
|
process: process3,
|
|
50628
50796
|
transcript,
|
|
50629
50797
|
transcriptPath,
|
|
50630
|
-
lineOffset:
|
|
50631
|
-
state:
|
|
50632
|
-
}
|
|
50633
|
-
|
|
50634
|
-
|
|
50635
|
-
|
|
50798
|
+
lineOffset: 0,
|
|
50799
|
+
state: {}
|
|
50800
|
+
},
|
|
50801
|
+
lineLimit,
|
|
50802
|
+
initialReadBytes: RECENT_TRANSCRIPT_READ_BYTES,
|
|
50803
|
+
maxReadBytes: options?.kinds?.size ? RECENT_TRANSCRIPT_KIND_SCAN_READ_BYTES : RECENT_TRANSCRIPT_READ_BYTES,
|
|
50804
|
+
kinds: options?.kinds,
|
|
50805
|
+
kindQuota: options?.kindQuota
|
|
50806
|
+
}));
|
|
50807
|
+
for (const event of parsed) {
|
|
50808
|
+
if (options?.kinds?.size && !options.kinds.has(event.kind))
|
|
50809
|
+
continue;
|
|
50636
50810
|
const eventKey = [
|
|
50637
|
-
|
|
50638
|
-
|
|
50639
|
-
|
|
50640
|
-
|
|
50811
|
+
event.source,
|
|
50812
|
+
event.sessionId,
|
|
50813
|
+
event.kind,
|
|
50814
|
+
event.summary
|
|
50641
50815
|
].join("\x00");
|
|
50642
50816
|
rememberTranscriptEvent(events, seenEvents, event, eventKey);
|
|
50643
|
-
}
|
|
50817
|
+
}
|
|
50644
50818
|
}
|
|
50645
50819
|
async function readRecentTranscriptEvents(limit = 50, options) {
|
|
50646
50820
|
if (watchers.size === 0) {
|
|
@@ -50657,24 +50831,34 @@ async function readRecentTranscriptEvents(limit = 50, options) {
|
|
|
50657
50831
|
const seenTranscriptPaths = new Set;
|
|
50658
50832
|
const transcriptReadLimit = Math.min(RECENT_TRANSCRIPT_MAX_FILES, Math.max(12, limit));
|
|
50659
50833
|
const lineLimit = options?.perTranscriptLineLimit ?? RECENT_TRANSCRIPT_LINES_PER_FILE;
|
|
50834
|
+
const kinds = options?.kinds?.length ? new Set(options.kinds) : null;
|
|
50835
|
+
const kindQuota = kinds ? Math.max(1, options?.perTranscriptKindLimit ?? limit) : undefined;
|
|
50660
50836
|
const activeWatchers = [...watchers.values()].sort((left, right) => right.transcript.mtimeMs - left.transcript.mtimeMs).slice(0, transcriptReadLimit);
|
|
50661
50837
|
for (const watcher of activeWatchers) {
|
|
50662
50838
|
seenTranscriptPaths.add(watcher.transcriptPath);
|
|
50663
|
-
await appendWatcherTranscriptEvents(events, seenEvents, watcher,
|
|
50839
|
+
await appendWatcherTranscriptEvents(events, seenEvents, watcher, {
|
|
50840
|
+
perTranscriptLineLimit: lineLimit,
|
|
50841
|
+
kinds,
|
|
50842
|
+
kindQuota
|
|
50843
|
+
});
|
|
50664
50844
|
}
|
|
50665
50845
|
if (options?.discovery?.transcripts?.length) {
|
|
50666
50846
|
const discoveryTranscripts = [...options.discovery.transcripts].filter((transcript) => !seenTranscriptPaths.has(transcript.transcriptPath)).sort((left, right) => right.mtimeMs - left.mtimeMs).slice(0, transcriptReadLimit);
|
|
50667
50847
|
for (const transcript of discoveryTranscripts) {
|
|
50668
|
-
const parsed = await parseTranscriptSessionEvents(transcript, options.discovery.processes, lineLimit
|
|
50848
|
+
const parsed = await parseTranscriptSessionEvents(transcript, options.discovery.processes, lineLimit, {
|
|
50849
|
+
kinds,
|
|
50850
|
+
kindQuota,
|
|
50851
|
+
initialReadBytes: RECENT_TRANSCRIPT_READ_BYTES
|
|
50852
|
+
});
|
|
50669
50853
|
for (const event of parsed) {
|
|
50670
50854
|
rememberTranscriptEvent(events, seenEvents, event);
|
|
50671
50855
|
}
|
|
50672
50856
|
seenTranscriptPaths.add(transcript.transcriptPath);
|
|
50673
50857
|
}
|
|
50674
50858
|
}
|
|
50675
|
-
return events.sort((left, right) => right.ts - left.ts).slice(0, limit);
|
|
50859
|
+
return events.filter((event) => !kinds || kinds.has(event.kind)).sort((left, right) => right.ts - left.ts).slice(0, limit);
|
|
50676
50860
|
}
|
|
50677
|
-
async function parseTranscriptSessionEvents(transcript, processes, limit) {
|
|
50861
|
+
async function parseTranscriptSessionEvents(transcript, processes, limit, options) {
|
|
50678
50862
|
const source = sources.find((candidate) => candidate.name === transcript.source);
|
|
50679
50863
|
if (!source)
|
|
50680
50864
|
return [];
|
|
@@ -50686,25 +50870,29 @@ async function parseTranscriptSessionEvents(transcript, processes, limit) {
|
|
|
50686
50870
|
lineOffset: 0,
|
|
50687
50871
|
state: {}
|
|
50688
50872
|
};
|
|
50689
|
-
if (source.parseFile) {
|
|
50690
|
-
const text2 = await readTranscriptText(transcript.transcriptPath, SESSION_TRANSCRIPT_READ_BYTES);
|
|
50691
|
-
if (!text2)
|
|
50692
|
-
return [];
|
|
50693
|
-
return parsedEventsToArray(source.parseFile(text2, ctxBase)).map(redactTailEvent).sort((left, right) => left.ts - right.ts).slice(-limit);
|
|
50694
|
-
}
|
|
50695
50873
|
const lineBudget = Math.max(limit, RECENT_TRANSCRIPT_LINES_PER_FILE);
|
|
50696
|
-
const
|
|
50697
|
-
const
|
|
50698
|
-
lines.
|
|
50699
|
-
|
|
50700
|
-
|
|
50701
|
-
|
|
50702
|
-
|
|
50703
|
-
|
|
50704
|
-
|
|
50874
|
+
const kindKey = [...options?.kinds ?? []].sort().join(",");
|
|
50875
|
+
const maxReadBytes = options?.kinds?.size ? RECENT_TRANSCRIPT_KIND_SCAN_READ_BYTES : SESSION_TRANSCRIPT_READ_BYTES;
|
|
50876
|
+
const replayVariant = source.parseFile ? `session:file:${source.name}:${sessionRegistryKey(transcript)}:${maxReadBytes}:${kindKey}` : `session:lines:${source.name}:${sessionRegistryKey(transcript)}:${lineBudget}:${maxReadBytes}:${kindKey}:${options?.kindQuota ?? ""}`;
|
|
50877
|
+
const parsed = await memoizedTranscriptReplay(transcript.transcriptPath, replayVariant, async () => {
|
|
50878
|
+
if (source.parseFile) {
|
|
50879
|
+
const text2 = await readTranscriptText(transcript.transcriptPath, maxReadBytes);
|
|
50880
|
+
if (!text2)
|
|
50881
|
+
return [];
|
|
50882
|
+
return parsedEventsToArray(source.parseFile(text2, ctxBase)).map(redactTailEvent);
|
|
50705
50883
|
}
|
|
50706
|
-
|
|
50707
|
-
|
|
50884
|
+
return parseRecentTranscriptLineEvents({
|
|
50885
|
+
source,
|
|
50886
|
+
transcriptPath: transcript.transcriptPath,
|
|
50887
|
+
context: ctxBase,
|
|
50888
|
+
lineLimit: lineBudget,
|
|
50889
|
+
initialReadBytes: options?.initialReadBytes ?? SESSION_TRANSCRIPT_READ_BYTES,
|
|
50890
|
+
maxReadBytes,
|
|
50891
|
+
kinds: options?.kinds,
|
|
50892
|
+
kindQuota: options?.kindQuota
|
|
50893
|
+
});
|
|
50894
|
+
}, source.parseFile ? { size: transcript.size, mtimeMs: transcript.mtimeMs } : undefined);
|
|
50895
|
+
return parsed.filter((event) => !options?.kinds?.size || options.kinds.has(event.kind)).sort((left, right) => left.ts - right.ts).slice(-limit);
|
|
50708
50896
|
}
|
|
50709
50897
|
// packages/runtime/src/tail/display.ts
|
|
50710
50898
|
var GROK_STREAMING_PHASES = new Set([
|
|
@@ -50771,7 +50959,7 @@ import { createHash } from "crypto";
|
|
|
50771
50959
|
import { homedir as homedir15 } from "os";
|
|
50772
50960
|
|
|
50773
50961
|
// packages/agent-sessions/src/adapters/claude-code/team-topology.ts
|
|
50774
|
-
import { existsSync as existsSync11, readdirSync as readdirSync8, readFileSync as readFileSync5, statSync as
|
|
50962
|
+
import { existsSync as existsSync11, readdirSync as readdirSync8, readFileSync as readFileSync5, statSync as statSync9 } from "fs";
|
|
50775
50963
|
import { homedir as homedir11 } from "os";
|
|
50776
50964
|
import { basename as basename8, dirname as dirname4, join as join11, relative as relative3 } from "path";
|
|
50777
50965
|
var TOPOLOGY_SCHEMA_VERSION = "openscout.observed-harness-topology.v1";
|
|
@@ -50824,14 +51012,14 @@ function readJsonObject(path) {
|
|
|
50824
51012
|
}
|
|
50825
51013
|
function statIsDirectory(path) {
|
|
50826
51014
|
try {
|
|
50827
|
-
return
|
|
51015
|
+
return statSync9(path).isDirectory();
|
|
50828
51016
|
} catch {
|
|
50829
51017
|
return false;
|
|
50830
51018
|
}
|
|
50831
51019
|
}
|
|
50832
51020
|
function statIsFile(path) {
|
|
50833
51021
|
try {
|
|
50834
|
-
return
|
|
51022
|
+
return statSync9(path).isFile();
|
|
50835
51023
|
} catch {
|
|
50836
51024
|
return false;
|
|
50837
51025
|
}
|
|
@@ -51224,7 +51412,7 @@ function readClaudeAgentTeamTopology(options = {}) {
|
|
|
51224
51412
|
}
|
|
51225
51413
|
|
|
51226
51414
|
// packages/agent-sessions/src/adapters/claude-code/subagent-topology.ts
|
|
51227
|
-
import { existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync6, statSync as
|
|
51415
|
+
import { existsSync as existsSync12, readdirSync as readdirSync9, readFileSync as readFileSync6, statSync as statSync10 } from "fs";
|
|
51228
51416
|
import { homedir as homedir12 } from "os";
|
|
51229
51417
|
import { join as join12, normalize, sep as sep2 } from "path";
|
|
51230
51418
|
var TOPOLOGY_SCHEMA_VERSION2 = "openscout.observed-harness-topology.v1";
|
|
@@ -51248,21 +51436,21 @@ function sourceRefId2(kind, value) {
|
|
|
51248
51436
|
}
|
|
51249
51437
|
function statIsDirectory2(path) {
|
|
51250
51438
|
try {
|
|
51251
|
-
return
|
|
51439
|
+
return statSync10(path).isDirectory();
|
|
51252
51440
|
} catch {
|
|
51253
51441
|
return false;
|
|
51254
51442
|
}
|
|
51255
51443
|
}
|
|
51256
51444
|
function statIsFile2(path) {
|
|
51257
51445
|
try {
|
|
51258
|
-
return
|
|
51446
|
+
return statSync10(path).isFile();
|
|
51259
51447
|
} catch {
|
|
51260
51448
|
return false;
|
|
51261
51449
|
}
|
|
51262
51450
|
}
|
|
51263
51451
|
function statMtimeMs(path) {
|
|
51264
51452
|
try {
|
|
51265
|
-
return
|
|
51453
|
+
return statSync10(path).mtimeMs;
|
|
51266
51454
|
} catch {
|
|
51267
51455
|
return 0;
|
|
51268
51456
|
}
|
|
@@ -51744,7 +51932,7 @@ function readClaudeSubagentTopology(options = {}) {
|
|
|
51744
51932
|
}
|
|
51745
51933
|
|
|
51746
51934
|
// packages/agent-sessions/src/adapters/claude-code/workflow-topology.ts
|
|
51747
|
-
import { existsSync as existsSync13, readdirSync as readdirSync10, readFileSync as readFileSync7, statSync as
|
|
51935
|
+
import { existsSync as existsSync13, readdirSync as readdirSync10, readFileSync as readFileSync7, statSync as statSync11 } from "fs";
|
|
51748
51936
|
import { homedir as homedir13 } from "os";
|
|
51749
51937
|
import { basename as basename10, join as join13, normalize as normalize2, relative as relative4, sep as sep3 } from "path";
|
|
51750
51938
|
var TOPOLOGY_SCHEMA_VERSION3 = "openscout.observed-harness-topology.v1";
|
|
@@ -51767,21 +51955,21 @@ function sourceRefId3(kind, value) {
|
|
|
51767
51955
|
}
|
|
51768
51956
|
function statIsDirectory3(path) {
|
|
51769
51957
|
try {
|
|
51770
|
-
return
|
|
51958
|
+
return statSync11(path).isDirectory();
|
|
51771
51959
|
} catch {
|
|
51772
51960
|
return false;
|
|
51773
51961
|
}
|
|
51774
51962
|
}
|
|
51775
51963
|
function statIsFile3(path) {
|
|
51776
51964
|
try {
|
|
51777
|
-
return
|
|
51965
|
+
return statSync11(path).isFile();
|
|
51778
51966
|
} catch {
|
|
51779
51967
|
return false;
|
|
51780
51968
|
}
|
|
51781
51969
|
}
|
|
51782
51970
|
function statMtimeMs2(path) {
|
|
51783
51971
|
try {
|
|
51784
|
-
return
|
|
51972
|
+
return statSync11(path).mtimeMs;
|
|
51785
51973
|
} catch {
|
|
51786
51974
|
return 0;
|
|
51787
51975
|
}
|
|
@@ -52469,7 +52657,7 @@ function readClaudeWorkflowTopology(options = {}) {
|
|
|
52469
52657
|
}
|
|
52470
52658
|
|
|
52471
52659
|
// packages/agent-sessions/src/adapters/codex/topology.ts
|
|
52472
|
-
import { existsSync as existsSync14, readdirSync as readdirSync11, readFileSync as readFileSync8, statSync as
|
|
52660
|
+
import { existsSync as existsSync14, readdirSync as readdirSync11, readFileSync as readFileSync8, statSync as statSync12 } from "fs";
|
|
52473
52661
|
import { homedir as homedir14 } from "os";
|
|
52474
52662
|
import { basename as basename11, join as join14 } from "path";
|
|
52475
52663
|
var TOPOLOGY_SCHEMA_VERSION4 = "openscout.observed-harness-topology.v1";
|
|
@@ -52496,14 +52684,14 @@ function sourceRefId4(kind, value) {
|
|
|
52496
52684
|
}
|
|
52497
52685
|
function statIsDirectory4(path) {
|
|
52498
52686
|
try {
|
|
52499
|
-
return
|
|
52687
|
+
return statSync12(path).isDirectory();
|
|
52500
52688
|
} catch {
|
|
52501
52689
|
return false;
|
|
52502
52690
|
}
|
|
52503
52691
|
}
|
|
52504
52692
|
function statIsFile4(path) {
|
|
52505
52693
|
try {
|
|
52506
|
-
return
|
|
52694
|
+
return statSync12(path).isFile();
|
|
52507
52695
|
} catch {
|
|
52508
52696
|
return false;
|
|
52509
52697
|
}
|
|
@@ -52914,7 +53102,12 @@ class CodexObservedTopologyTracker {
|
|
|
52914
53102
|
|
|
52915
53103
|
// packages/runtime/src/harness-topology/service.ts
|
|
52916
53104
|
var DEFAULT_POLL_INTERVAL_MS = readPositiveIntEnv9("OPENSCOUT_TOPOLOGY_POLL_INTERVAL_MS", 1e4);
|
|
53105
|
+
var DEFAULT_MIN_SCAN_INTERVAL_MS = 15000;
|
|
52917
53106
|
var EVENT_BUFFER_LIMIT = 500;
|
|
53107
|
+
function minScanIntervalMs() {
|
|
53108
|
+
const raw = Number.parseInt(process.env.SCOUT_TOPOLOGY_MIN_SCAN_INTERVAL_MS ?? "", 10);
|
|
53109
|
+
return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_MIN_SCAN_INTERVAL_MS;
|
|
53110
|
+
}
|
|
52918
53111
|
function readPositiveIntEnv9(name, fallback) {
|
|
52919
53112
|
const raw = Number.parseInt(process.env[name] ?? "", 10);
|
|
52920
53113
|
return Number.isFinite(raw) && raw > 0 ? raw : fallback;
|
|
@@ -53016,6 +53209,7 @@ class HarnessTopologyObserver {
|
|
|
53016
53209
|
scanInFlight = null;
|
|
53017
53210
|
eventCounter = 0;
|
|
53018
53211
|
lastSnapshot = null;
|
|
53212
|
+
lastScanCompletedAt = 0;
|
|
53019
53213
|
constructor(options = {}) {
|
|
53020
53214
|
this.options = options;
|
|
53021
53215
|
}
|
|
@@ -53027,16 +53221,28 @@ class HarnessTopologyObserver {
|
|
|
53027
53221
|
});
|
|
53028
53222
|
return this.scanInFlight;
|
|
53029
53223
|
}
|
|
53224
|
+
scanThrottled() {
|
|
53225
|
+
if (this.scanInFlight)
|
|
53226
|
+
return this.scanInFlight;
|
|
53227
|
+
const interval = minScanIntervalMs();
|
|
53228
|
+
if (this.lastSnapshot && interval > 0 && Date.now() - this.lastScanCompletedAt < interval) {
|
|
53229
|
+
return Promise.resolve(this.lastSnapshot);
|
|
53230
|
+
}
|
|
53231
|
+
return this.scan();
|
|
53232
|
+
}
|
|
53030
53233
|
async getSnapshot(force = false) {
|
|
53031
|
-
if (force
|
|
53234
|
+
if (force) {
|
|
53032
53235
|
return this.scan();
|
|
53033
53236
|
}
|
|
53237
|
+
if (!this.lastSnapshot) {
|
|
53238
|
+
return this.scanThrottled();
|
|
53239
|
+
}
|
|
53034
53240
|
return this.lastSnapshot;
|
|
53035
53241
|
}
|
|
53036
53242
|
subscribe(handler) {
|
|
53037
53243
|
this.subscribers.add(handler);
|
|
53038
53244
|
this.ensureLoopRunning();
|
|
53039
|
-
this.
|
|
53245
|
+
this.scanThrottled();
|
|
53040
53246
|
return () => {
|
|
53041
53247
|
this.subscribers.delete(handler);
|
|
53042
53248
|
if (this.subscribers.size === 0) {
|
|
@@ -53084,6 +53290,7 @@ class HarnessTopologyObserver {
|
|
|
53084
53290
|
});
|
|
53085
53291
|
}
|
|
53086
53292
|
this.lastSnapshot = this.buildSnapshot(nowMs2);
|
|
53293
|
+
this.lastScanCompletedAt = Date.now();
|
|
53087
53294
|
return this.lastSnapshot;
|
|
53088
53295
|
}
|
|
53089
53296
|
buildSnapshot(generatedAt) {
|
|
@@ -53127,7 +53334,7 @@ class HarnessTopologyObserver {
|
|
|
53127
53334
|
if (this.timer)
|
|
53128
53335
|
return;
|
|
53129
53336
|
this.timer = setInterval(() => {
|
|
53130
|
-
this.
|
|
53337
|
+
this.scanThrottled();
|
|
53131
53338
|
}, this.options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
|
|
53132
53339
|
}
|
|
53133
53340
|
stopLoop() {
|
|
@@ -53148,7 +53355,7 @@ function snapshotRecentHarnessTopologyEvents(limit = EVENT_BUFFER_LIMIT) {
|
|
|
53148
53355
|
return defaultObserver.snapshotRecentEvents(limit);
|
|
53149
53356
|
}
|
|
53150
53357
|
function nudgeHarnessTopologyScan() {
|
|
53151
|
-
return defaultObserver.
|
|
53358
|
+
return defaultObserver.getSnapshot(true);
|
|
53152
53359
|
}
|
|
53153
53360
|
// packages/runtime/src/broker-trpc-router.ts
|
|
53154
53361
|
var t = initTRPC.create();
|
|
@@ -53367,41 +53574,28 @@ var controlRouter = t.router({
|
|
|
53367
53574
|
events: t.procedure.input(controlEventsInput).subscription(async function* ({ input, signal }) {
|
|
53368
53575
|
const kinds = input?.kinds;
|
|
53369
53576
|
const filter = kinds && kinds.length > 0 ? new Set(kinds) : null;
|
|
53370
|
-
const
|
|
53371
|
-
|
|
53372
|
-
|
|
53373
|
-
const
|
|
53374
|
-
|
|
53375
|
-
|
|
53376
|
-
|
|
53377
|
-
|
|
53378
|
-
|
|
53379
|
-
|
|
53380
|
-
|
|
53381
|
-
|
|
53382
|
-
|
|
53383
|
-
|
|
53384
|
-
|
|
53385
|
-
|
|
53386
|
-
|
|
53387
|
-
|
|
53388
|
-
|
|
53389
|
-
|
|
53390
|
-
|
|
53391
|
-
|
|
53392
|
-
replayedIds.add(event.id);
|
|
53393
|
-
yield tracked(event.id, event);
|
|
53394
|
-
}
|
|
53395
|
-
while (true) {
|
|
53396
|
-
const next = await liveIterator.next();
|
|
53397
|
-
if (next.done)
|
|
53398
|
-
return;
|
|
53399
|
-
if (replayedIds.delete(next.value.id))
|
|
53400
|
-
continue;
|
|
53401
|
-
yield tracked(next.value.id, next.value);
|
|
53402
|
-
}
|
|
53403
|
-
} finally {
|
|
53404
|
-
await liveIterator.return?.();
|
|
53577
|
+
const backlog = snapshotRecentControlEvents(CONTROL_BACKLOG_LIMIT);
|
|
53578
|
+
let startIdx = 0;
|
|
53579
|
+
if (input?.since) {
|
|
53580
|
+
const idx = backlog.findIndex((event) => event.id === input.since);
|
|
53581
|
+
if (idx >= 0)
|
|
53582
|
+
startIdx = idx + 1;
|
|
53583
|
+
}
|
|
53584
|
+
for (let i = startIdx;i < backlog.length; i++) {
|
|
53585
|
+
const event = backlog[i];
|
|
53586
|
+
if (!event)
|
|
53587
|
+
continue;
|
|
53588
|
+
if (filter && !filter.has(event.kind))
|
|
53589
|
+
continue;
|
|
53590
|
+
yield tracked(event.id, event);
|
|
53591
|
+
}
|
|
53592
|
+
for (const event of snapshotPresenceControlEvents()) {
|
|
53593
|
+
if (filter && !filter.has(event.kind))
|
|
53594
|
+
continue;
|
|
53595
|
+
yield tracked(event.id, event);
|
|
53596
|
+
}
|
|
53597
|
+
for await (const event of controlEventIterable(kinds, signal)) {
|
|
53598
|
+
yield tracked(event.id, event);
|
|
53405
53599
|
}
|
|
53406
53600
|
})
|
|
53407
53601
|
});
|
|
@@ -53636,18 +53830,20 @@ function activeCollaboration(record3) {
|
|
|
53636
53830
|
}
|
|
53637
53831
|
function queryRuntimeRegistrySnapshot(snapshot, query = {}) {
|
|
53638
53832
|
const since = finiteTimestamp(query.since);
|
|
53639
|
-
|
|
53833
|
+
const conversationScoped = query.scope === "conversations";
|
|
53834
|
+
if (since === null && !conversationScoped) {
|
|
53640
53835
|
return snapshot;
|
|
53641
53836
|
}
|
|
53642
|
-
const
|
|
53643
|
-
const
|
|
53644
|
-
const
|
|
53837
|
+
const cutoff = since ?? 0;
|
|
53838
|
+
const messages = Object.values(snapshot.messages).filter((message) => message.createdAt >= cutoff);
|
|
53839
|
+
const recentInvocationIds = new Set(Object.values(snapshot.invocations).filter((invocation) => invocation.createdAt >= cutoff).map((invocation) => invocation.id));
|
|
53840
|
+
const flights = Object.values(snapshot.flights).filter((flight) => ACTIVE_FLIGHT_STATES.has(flight.state) || recordTimestamp(flight) >= cutoff || recentInvocationIds.has(flight.invocationId));
|
|
53645
53841
|
const retainedInvocationIds = new Set([
|
|
53646
53842
|
...recentInvocationIds,
|
|
53647
53843
|
...flights.map((flight) => flight.invocationId)
|
|
53648
53844
|
]);
|
|
53649
53845
|
const invocations = Object.values(snapshot.invocations).filter((invocation) => retainedInvocationIds.has(invocation.id));
|
|
53650
|
-
const collaborationRecords = Object.values(snapshot.collaborationRecords).filter((record3) => activeCollaboration(record3) || record3.updatedAt >=
|
|
53846
|
+
const collaborationRecords = Object.values(snapshot.collaborationRecords).filter((record3) => activeCollaboration(record3) || record3.updatedAt >= cutoff);
|
|
53651
53847
|
const conversationIds = new Set;
|
|
53652
53848
|
for (const message of messages)
|
|
53653
53849
|
conversationIds.add(message.conversationId);
|
|
@@ -53661,7 +53857,7 @@ function queryRuntimeRegistrySnapshot(snapshot, query = {}) {
|
|
|
53661
53857
|
}
|
|
53662
53858
|
for (const conversation of Object.values(snapshot.conversations)) {
|
|
53663
53859
|
const timestamp = recordTimestamp(conversation);
|
|
53664
|
-
if (timestamp === 0 || timestamp >=
|
|
53860
|
+
if (timestamp === 0 || timestamp >= cutoff)
|
|
53665
53861
|
conversationIds.add(conversation.id);
|
|
53666
53862
|
}
|
|
53667
53863
|
const conversations = [];
|
|
@@ -53677,22 +53873,52 @@ function queryRuntimeRegistrySnapshot(snapshot, query = {}) {
|
|
|
53677
53873
|
pendingConversationIds.push(conversation.parentConversationId);
|
|
53678
53874
|
}
|
|
53679
53875
|
}
|
|
53876
|
+
let scopedInvocations = invocations;
|
|
53877
|
+
let scopedFlights = flights;
|
|
53878
|
+
if (conversationScoped) {
|
|
53879
|
+
const activeFlightInvocationIds = new Set(flights.filter((flight) => ACTIVE_FLIGHT_STATES.has(flight.state)).map((flight) => flight.invocationId));
|
|
53880
|
+
const newestByConversation = new Map;
|
|
53881
|
+
for (const invocation of invocations) {
|
|
53882
|
+
const conversationId = invocation.conversationId;
|
|
53883
|
+
if (!conversationId || !conversationIds.has(conversationId))
|
|
53884
|
+
continue;
|
|
53885
|
+
const bucket = newestByConversation.get(conversationId) ?? [];
|
|
53886
|
+
bucket.push(invocation);
|
|
53887
|
+
newestByConversation.set(conversationId, bucket);
|
|
53888
|
+
}
|
|
53889
|
+
scopedInvocations = [...newestByConversation.values()].flatMap((bucket) => {
|
|
53890
|
+
const sorted = bucket.sort((left, right) => right.createdAt - left.createdAt);
|
|
53891
|
+
const selected = sorted.slice(0, 12);
|
|
53892
|
+
const selectedIds = new Set(selected.map((invocation) => invocation.id));
|
|
53893
|
+
for (const invocation of sorted) {
|
|
53894
|
+
if (activeFlightInvocationIds.has(invocation.id) && !selectedIds.has(invocation.id)) {
|
|
53895
|
+
selected.push(invocation);
|
|
53896
|
+
selectedIds.add(invocation.id);
|
|
53897
|
+
}
|
|
53898
|
+
}
|
|
53899
|
+
return selected;
|
|
53900
|
+
});
|
|
53901
|
+
const scopedInvocationIds = new Set(scopedInvocations.map((invocation) => invocation.id));
|
|
53902
|
+
scopedFlights = flights.filter((flight) => scopedInvocationIds.has(flight.invocationId));
|
|
53903
|
+
}
|
|
53680
53904
|
const actorIds = new Set;
|
|
53681
53905
|
const agentIds = new Set;
|
|
53682
|
-
|
|
53683
|
-
|
|
53684
|
-
|
|
53906
|
+
const currentEndpointAgentIds = new Set(Object.values(snapshot.endpoints).filter((endpoint) => currentOrRecentEndpoint(endpoint, cutoff)).map((endpoint) => endpoint.agentId));
|
|
53907
|
+
for (const conversation of conversations) {
|
|
53908
|
+
const keepWholeRoster = !conversationScoped || conversation.kind === "direct" || conversation.kind === "group_direct";
|
|
53909
|
+
for (const [index, participantId] of conversation.participantIds.entries()) {
|
|
53910
|
+
if (keepWholeRoster || index < 32 || snapshot.actors[participantId]?.kind === "person" || currentEndpointAgentIds.has(participantId)) {
|
|
53911
|
+
actorIds.add(participantId);
|
|
53912
|
+
}
|
|
53913
|
+
}
|
|
53685
53914
|
}
|
|
53686
|
-
const endpoints = Object.values(snapshot.endpoints).filter((endpoint) => currentOrRecentEndpoint(endpoint, since));
|
|
53687
|
-
for (const endpoint of endpoints)
|
|
53688
|
-
agentIds.add(endpoint.agentId);
|
|
53689
53915
|
for (const message of messages)
|
|
53690
53916
|
actorIds.add(message.actorId);
|
|
53691
|
-
for (const invocation of
|
|
53917
|
+
for (const invocation of scopedInvocations) {
|
|
53692
53918
|
actorIds.add(invocation.requesterId);
|
|
53693
53919
|
agentIds.add(invocation.targetAgentId);
|
|
53694
53920
|
}
|
|
53695
|
-
for (const flight of
|
|
53921
|
+
for (const flight of scopedFlights) {
|
|
53696
53922
|
actorIds.add(flight.requesterId);
|
|
53697
53923
|
agentIds.add(flight.targetAgentId);
|
|
53698
53924
|
}
|
|
@@ -53703,10 +53929,19 @@ function queryRuntimeRegistrySnapshot(snapshot, query = {}) {
|
|
|
53703
53929
|
if (record3.nextMoveOwnerId)
|
|
53704
53930
|
actorIds.add(record3.nextMoveOwnerId);
|
|
53705
53931
|
}
|
|
53706
|
-
|
|
53707
|
-
for (const
|
|
53708
|
-
|
|
53932
|
+
if (!conversationScoped) {
|
|
53933
|
+
for (const agent of Object.values(snapshot.agents)) {
|
|
53934
|
+
if (currentAgent(agent))
|
|
53935
|
+
agentIds.add(agent.id);
|
|
53936
|
+
}
|
|
53709
53937
|
}
|
|
53938
|
+
for (const actorId of actorIds) {
|
|
53939
|
+
if (snapshot.agents[actorId])
|
|
53940
|
+
agentIds.add(actorId);
|
|
53941
|
+
}
|
|
53942
|
+
const endpoints = Object.values(snapshot.endpoints).filter((endpoint) => currentOrRecentEndpoint(endpoint, cutoff) && (!conversationScoped || agentIds.has(endpoint.agentId) || actorIds.has(endpoint.agentId)));
|
|
53943
|
+
for (const endpoint of endpoints)
|
|
53944
|
+
agentIds.add(endpoint.agentId);
|
|
53710
53945
|
for (const agentId of agentIds)
|
|
53711
53946
|
actorIds.add(agentId);
|
|
53712
53947
|
const agents = Object.values(snapshot.agents).filter((agent) => agentIds.has(agent.id) || actorIds.has(agent.id));
|
|
@@ -53725,8 +53960,8 @@ function queryRuntimeRegistrySnapshot(snapshot, query = {}) {
|
|
|
53725
53960
|
bindings: recordById(Object.values(snapshot.bindings).filter((binding) => conversationIds.has(binding.conversationId))),
|
|
53726
53961
|
messages: recordById(messages),
|
|
53727
53962
|
readCursors: Object.fromEntries(Object.entries(snapshot.readCursors).filter(([, cursor]) => conversationIds.has(cursor.conversationId))),
|
|
53728
|
-
invocations: recordById(
|
|
53729
|
-
flights: recordById(
|
|
53963
|
+
invocations: recordById(scopedInvocations),
|
|
53964
|
+
flights: recordById(scopedFlights),
|
|
53730
53965
|
collaborationRecords: recordById(collaborationRecords)
|
|
53731
53966
|
});
|
|
53732
53967
|
}
|
|
@@ -54844,12 +55079,9 @@ function isTransportInferredStall(status) {
|
|
|
54844
55079
|
class BrokerPresenceService {
|
|
54845
55080
|
deps;
|
|
54846
55081
|
presence;
|
|
54847
|
-
lastPublished = new Map;
|
|
54848
|
-
refreshIntervalMs;
|
|
54849
55082
|
constructor(deps) {
|
|
54850
55083
|
this.deps = deps;
|
|
54851
55084
|
this.presence = new BrokerPresenceMap(deps.map);
|
|
54852
|
-
this.refreshIntervalMs = Math.max(1, deps.refreshIntervalMs ?? PRESENCE_REFRESH_INTERVAL_MS);
|
|
54853
55085
|
}
|
|
54854
55086
|
snapshot(now = this.now()) {
|
|
54855
55087
|
return this.presence.snapshot(now);
|
|
@@ -54873,23 +55105,16 @@ class BrokerPresenceService {
|
|
|
54873
55105
|
needRef: needRefForStatus(status),
|
|
54874
55106
|
boundConversationId: boundConversationIdForStatus(status, snapshot)
|
|
54875
55107
|
}, now);
|
|
54876
|
-
if (!result)
|
|
55108
|
+
if (!result?.transitioned)
|
|
54877
55109
|
continue;
|
|
54878
|
-
|
|
54879
|
-
const refreshDue = !result.transitioned && lastPublished !== undefined && result.beat.updatedAt > lastPublished.updatedAt && now - lastPublished.at >= this.refreshIntervalMs;
|
|
54880
|
-
if (!result.transitioned && !refreshDue)
|
|
54881
|
-
continue;
|
|
54882
|
-
this.deps.publish(this.presenceEvent(result.beat, result.transitioned ? result.previousActivity : undefined, now));
|
|
54883
|
-
this.lastPublished.set(agentId, { at: now, updatedAt: result.beat.updatedAt });
|
|
55110
|
+
this.deps.publish(this.presenceEvent(result.beat, result.previousActivity, now));
|
|
54884
55111
|
published += 1;
|
|
54885
55112
|
}
|
|
54886
|
-
this.
|
|
55113
|
+
this.presence.prune(now);
|
|
54887
55114
|
return published;
|
|
54888
55115
|
}
|
|
54889
55116
|
sweep(now = this.now()) {
|
|
54890
|
-
|
|
54891
|
-
this.forgetPublished(dropped);
|
|
54892
|
-
return dropped;
|
|
55117
|
+
return this.presence.prune(now);
|
|
54893
55118
|
}
|
|
54894
55119
|
presenceEvent(beat, previousActivity, now) {
|
|
54895
55120
|
return {
|
|
@@ -54904,10 +55129,6 @@ class BrokerPresenceService {
|
|
|
54904
55129
|
now() {
|
|
54905
55130
|
return this.deps.now?.() ?? Date.now();
|
|
54906
55131
|
}
|
|
54907
|
-
forgetPublished(agentIds) {
|
|
54908
|
-
for (const agentId of agentIds)
|
|
54909
|
-
this.lastPublished.delete(agentId);
|
|
54910
|
-
}
|
|
54911
55132
|
}
|
|
54912
55133
|
function needRefForStatus(status) {
|
|
54913
55134
|
if (status.subjectKind !== "question")
|
|
@@ -55058,7 +55279,7 @@ class BrokerDeliveryStore {
|
|
|
55058
55279
|
// packages/runtime/src/broker-journal.ts
|
|
55059
55280
|
import { once as once2 } from "events";
|
|
55060
55281
|
import { createReadStream, createWriteStream } from "fs";
|
|
55061
|
-
import { appendFile, mkdir, rename, unlink } from "fs/promises";
|
|
55282
|
+
import { appendFile, mkdir, rename, stat as stat2, unlink } from "fs/promises";
|
|
55062
55283
|
import { dirname as dirname6 } from "path";
|
|
55063
55284
|
import { createInterface } from "readline";
|
|
55064
55285
|
function cloneSnapshot(snapshot) {
|
|
@@ -55146,19 +55367,30 @@ class FileBackedBrokerJournal {
|
|
|
55146
55367
|
scoutDispatches: []
|
|
55147
55368
|
};
|
|
55148
55369
|
loaded = false;
|
|
55370
|
+
latestLoadReport = null;
|
|
55149
55371
|
writeQueue = Promise.resolve();
|
|
55150
55372
|
constructor(filePath) {
|
|
55151
55373
|
this.filePath = filePath;
|
|
55152
55374
|
}
|
|
55153
55375
|
async load() {
|
|
55154
55376
|
if (this.loaded) {
|
|
55155
|
-
return;
|
|
55377
|
+
return this.latestLoadReport;
|
|
55156
55378
|
}
|
|
55379
|
+
const startedAt = Date.now();
|
|
55380
|
+
const sourceBytes = await stat2(this.filePath).then((value) => value.size).catch((error48) => {
|
|
55381
|
+
const code = error48 && typeof error48 === "object" && "code" in error48 ? error48.code : undefined;
|
|
55382
|
+
if (code === "ENOENT")
|
|
55383
|
+
return 0;
|
|
55384
|
+
throw error48;
|
|
55385
|
+
});
|
|
55157
55386
|
const latestIndexByKey = new Map;
|
|
55158
55387
|
const lastFlightById = new Map;
|
|
55388
|
+
const countsByKind = {};
|
|
55159
55389
|
let compactionRequired = false;
|
|
55160
|
-
|
|
55390
|
+
const scanStartedAt = Date.now();
|
|
55391
|
+
const scan = await this.visitEntries((entry, index) => {
|
|
55161
55392
|
this.apply(entry);
|
|
55393
|
+
countsByKind[entry.kind] = (countsByKind[entry.kind] ?? 0) + 1;
|
|
55162
55394
|
const key = dedupeKey(entry);
|
|
55163
55395
|
if (key) {
|
|
55164
55396
|
if (latestIndexByKey.has(key)) {
|
|
@@ -55174,10 +55406,37 @@ class FileBackedBrokerJournal {
|
|
|
55174
55406
|
lastFlightById.set(entry.flight.id, entry.flight);
|
|
55175
55407
|
}
|
|
55176
55408
|
});
|
|
55409
|
+
const scanMs = Date.now() - scanStartedAt;
|
|
55410
|
+
let compactionMs = 0;
|
|
55177
55411
|
if (compactionRequired) {
|
|
55412
|
+
const compactionStartedAt = Date.now();
|
|
55178
55413
|
await this.rewriteCompactedEntries(latestIndexByKey);
|
|
55414
|
+
compactionMs = Date.now() - compactionStartedAt;
|
|
55179
55415
|
}
|
|
55180
55416
|
this.loaded = true;
|
|
55417
|
+
const completedAt = Date.now();
|
|
55418
|
+
const compactedBytes = await stat2(this.filePath).then((value) => value.size).catch(() => 0);
|
|
55419
|
+
this.latestLoadReport = {
|
|
55420
|
+
startedAt,
|
|
55421
|
+
completedAt,
|
|
55422
|
+
totalMs: completedAt - startedAt,
|
|
55423
|
+
scanMs,
|
|
55424
|
+
compactionMs,
|
|
55425
|
+
sourceBytes,
|
|
55426
|
+
compactedBytes,
|
|
55427
|
+
validEntries: scan.validEntries,
|
|
55428
|
+
invalidLines: scan.invalidLines,
|
|
55429
|
+
blankLines: scan.blankLines,
|
|
55430
|
+
compactionRequired,
|
|
55431
|
+
countsByKind
|
|
55432
|
+
};
|
|
55433
|
+
return this.latestLoadReport;
|
|
55434
|
+
}
|
|
55435
|
+
loadReport() {
|
|
55436
|
+
return this.latestLoadReport ? {
|
|
55437
|
+
...this.latestLoadReport,
|
|
55438
|
+
countsByKind: { ...this.latestLoadReport.countsByKind }
|
|
55439
|
+
} : null;
|
|
55181
55440
|
}
|
|
55182
55441
|
async readEntries() {
|
|
55183
55442
|
const entries = [];
|
|
@@ -55186,8 +55445,27 @@ class FileBackedBrokerJournal {
|
|
|
55186
55445
|
});
|
|
55187
55446
|
return entries;
|
|
55188
55447
|
}
|
|
55189
|
-
|
|
55190
|
-
|
|
55448
|
+
captureReplayBoundary() {
|
|
55449
|
+
let boundary = { endByteExclusive: 0 };
|
|
55450
|
+
const capture = this.writeQueue.then(async () => {
|
|
55451
|
+
boundary = {
|
|
55452
|
+
endByteExclusive: await stat2(this.filePath).then((value) => value.size).catch((error48) => {
|
|
55453
|
+
const code = error48 && typeof error48 === "object" && "code" in error48 ? error48.code : undefined;
|
|
55454
|
+
if (code === "ENOENT")
|
|
55455
|
+
return 0;
|
|
55456
|
+
throw error48;
|
|
55457
|
+
})
|
|
55458
|
+
};
|
|
55459
|
+
});
|
|
55460
|
+
this.writeQueue = capture.then(() => {
|
|
55461
|
+
return;
|
|
55462
|
+
}, () => {
|
|
55463
|
+
return;
|
|
55464
|
+
});
|
|
55465
|
+
return capture.then(() => boundary);
|
|
55466
|
+
}
|
|
55467
|
+
async replay(visitor, boundary) {
|
|
55468
|
+
await this.visitEntries((entry) => visitor(entry), boundary ? { endByteExclusive: boundary.endByteExclusive } : {});
|
|
55191
55469
|
}
|
|
55192
55470
|
snapshot() {
|
|
55193
55471
|
return cloneSnapshot(this.state.snapshot);
|
|
@@ -55255,17 +55533,43 @@ class FileBackedBrokerJournal {
|
|
|
55255
55533
|
const limit = options.limit ?? 1000;
|
|
55256
55534
|
return [...this.state.invocationDispatchJobs.values()].filter((job) => !options.state || job.state === options.state).sort((left, right) => left.createdAt - right.createdAt).slice(0, limit);
|
|
55257
55535
|
}
|
|
55258
|
-
async visitEntries(visitor) {
|
|
55259
|
-
const
|
|
55536
|
+
async visitEntries(visitor, options = {}) {
|
|
55537
|
+
const endByteExclusive = options.endByteExclusive;
|
|
55538
|
+
if (endByteExclusive !== undefined && endByteExclusive <= 0) {
|
|
55539
|
+
return {
|
|
55540
|
+
rawLines: 0,
|
|
55541
|
+
validEntries: 0,
|
|
55542
|
+
invalidLines: 0,
|
|
55543
|
+
blankLines: 0
|
|
55544
|
+
};
|
|
55545
|
+
}
|
|
55546
|
+
const input = createReadStream(this.filePath, {
|
|
55547
|
+
encoding: "utf8",
|
|
55548
|
+
...endByteExclusive === undefined ? {} : { end: endByteExclusive - 1 }
|
|
55549
|
+
});
|
|
55260
55550
|
const lines = createInterface({ input, crlfDelay: Infinity });
|
|
55261
55551
|
let index = 0;
|
|
55552
|
+
const report = {
|
|
55553
|
+
rawLines: 0,
|
|
55554
|
+
validEntries: 0,
|
|
55555
|
+
invalidLines: 0,
|
|
55556
|
+
blankLines: 0
|
|
55557
|
+
};
|
|
55262
55558
|
try {
|
|
55263
55559
|
for await (const rawLine of lines) {
|
|
55560
|
+
report.rawLines += 1;
|
|
55561
|
+
if (!rawLine.trim()) {
|
|
55562
|
+
report.blankLines += 1;
|
|
55563
|
+
continue;
|
|
55564
|
+
}
|
|
55264
55565
|
const entry = parseEntry(rawLine);
|
|
55265
|
-
if (!entry)
|
|
55566
|
+
if (!entry) {
|
|
55567
|
+
report.invalidLines += 1;
|
|
55266
55568
|
continue;
|
|
55569
|
+
}
|
|
55267
55570
|
await visitor(entry, index);
|
|
55268
55571
|
index += 1;
|
|
55572
|
+
report.validEntries += 1;
|
|
55269
55573
|
}
|
|
55270
55574
|
} catch (error48) {
|
|
55271
55575
|
const code = error48 && typeof error48 === "object" && "code" in error48 ? error48.code : undefined;
|
|
@@ -55276,6 +55580,7 @@ class FileBackedBrokerJournal {
|
|
|
55276
55580
|
lines.close();
|
|
55277
55581
|
input.destroy();
|
|
55278
55582
|
}
|
|
55583
|
+
return report;
|
|
55279
55584
|
}
|
|
55280
55585
|
async rewriteCompactedEntries(latestIndexByKey) {
|
|
55281
55586
|
await mkdir(dirname6(this.filePath), { recursive: true });
|
|
@@ -55538,18 +55843,18 @@ class BrokerDurableRecordStore {
|
|
|
55538
55843
|
constructor(options) {
|
|
55539
55844
|
this.options = options;
|
|
55540
55845
|
}
|
|
55541
|
-
upsertNode = async (node) => {
|
|
55846
|
+
upsertNode = async (node, options = {}) => {
|
|
55542
55847
|
await this.options.durableStore.runWrite(async () => {
|
|
55543
55848
|
await this.options.durableStore.commitEntries({ kind: "node.upsert", node }, async () => {
|
|
55544
55849
|
await this.options.runtime.upsertNode(node);
|
|
55545
|
-
});
|
|
55850
|
+
}, options);
|
|
55546
55851
|
});
|
|
55547
55852
|
};
|
|
55548
|
-
upsertActor = async (actor) => {
|
|
55853
|
+
upsertActor = async (actor, options = {}) => {
|
|
55549
55854
|
await this.options.durableStore.runWrite(async () => {
|
|
55550
55855
|
await this.options.durableStore.commitEntries({ kind: "actor.upsert", actor }, async () => {
|
|
55551
55856
|
await this.options.runtime.upsertActor(actor);
|
|
55552
|
-
});
|
|
55857
|
+
}, options);
|
|
55553
55858
|
});
|
|
55554
55859
|
};
|
|
55555
55860
|
upsertAgent = async (agent) => {
|
|
@@ -55700,6 +56005,41 @@ class BrokerDurableStore {
|
|
|
55700
56005
|
};
|
|
55701
56006
|
}
|
|
55702
56007
|
|
|
56008
|
+
// packages/runtime/src/broker-startup-traffic-gate.ts
|
|
56009
|
+
var RESTORING_READ_PATHS = new Set([
|
|
56010
|
+
"/health",
|
|
56011
|
+
"/v1/home",
|
|
56012
|
+
"/v1/node",
|
|
56013
|
+
"/v1/snapshot"
|
|
56014
|
+
]);
|
|
56015
|
+
|
|
56016
|
+
class BrokerStartupTrafficGate {
|
|
56017
|
+
mutationsAdmitted = false;
|
|
56018
|
+
admits(method, requestTarget = "/") {
|
|
56019
|
+
if (this.mutationsAdmitted) {
|
|
56020
|
+
return true;
|
|
56021
|
+
}
|
|
56022
|
+
const normalizedMethod = (method ?? "GET").toUpperCase();
|
|
56023
|
+
if (normalizedMethod === "OPTIONS") {
|
|
56024
|
+
return true;
|
|
56025
|
+
}
|
|
56026
|
+
if (normalizedMethod !== "GET" && normalizedMethod !== "HEAD") {
|
|
56027
|
+
return false;
|
|
56028
|
+
}
|
|
56029
|
+
const path = requestTarget.split("?", 1)[0] || "/";
|
|
56030
|
+
return RESTORING_READ_PATHS.has(path);
|
|
56031
|
+
}
|
|
56032
|
+
admitMutations() {
|
|
56033
|
+
this.mutationsAdmitted = true;
|
|
56034
|
+
}
|
|
56035
|
+
snapshot() {
|
|
56036
|
+
return {
|
|
56037
|
+
state: this.mutationsAdmitted ? "ready" : "restoring",
|
|
56038
|
+
mutationsAdmitted: this.mutationsAdmitted
|
|
56039
|
+
};
|
|
56040
|
+
}
|
|
56041
|
+
}
|
|
56042
|
+
|
|
55703
56043
|
// packages/runtime/src/broker-read-cursor-store.ts
|
|
55704
56044
|
function finitePositiveNumber(value) {
|
|
55705
56045
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
@@ -56125,7 +56465,7 @@ class BrokerWorkItemStore {
|
|
|
56125
56465
|
// packages/runtime/src/local-agents.ts
|
|
56126
56466
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
56127
56467
|
import { existsSync as existsSync34, readFileSync as readFileSync18 } from "fs";
|
|
56128
|
-
import { mkdir as mkdir9, readFile as readFile9, rm as rm4, stat as
|
|
56468
|
+
import { mkdir as mkdir9, readFile as readFile9, rm as rm4, stat as stat7, writeFile as writeFile7 } from "fs/promises";
|
|
56129
56469
|
import { basename as basename16, dirname as dirname20, join as join37, resolve as resolve11 } from "path";
|
|
56130
56470
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
56131
56471
|
|
|
@@ -56766,7 +57106,7 @@ async function requestJsonWithBun2(connect, socketPath, payload, timeoutMs) {
|
|
|
56766
57106
|
}
|
|
56767
57107
|
|
|
56768
57108
|
// packages/runtime/src/system-probes/git-build-info.ts
|
|
56769
|
-
import { existsSync as existsSync16, realpathSync, statSync as
|
|
57109
|
+
import { existsSync as existsSync16, realpathSync, statSync as statSync13 } from "fs";
|
|
56770
57110
|
import { dirname as dirname8, resolve as resolve2 } from "path";
|
|
56771
57111
|
var staticMetadataByRepo = new Map;
|
|
56772
57112
|
function realpathOrResolved(path) {
|
|
@@ -56779,8 +57119,8 @@ function realpathOrResolved(path) {
|
|
|
56779
57119
|
function directoryOrParent(path) {
|
|
56780
57120
|
const resolved = resolve2(path);
|
|
56781
57121
|
try {
|
|
56782
|
-
const
|
|
56783
|
-
return
|
|
57122
|
+
const stat3 = statSync13(resolved);
|
|
57123
|
+
return stat3.isDirectory() ? resolved : dirname8(resolved);
|
|
56784
57124
|
} catch {
|
|
56785
57125
|
return resolved;
|
|
56786
57126
|
}
|
|
@@ -57776,7 +58116,7 @@ var herdrSessionsProbe = defineProbeFamily({
|
|
|
57776
58116
|
var herdrTopologyCache = new Map;
|
|
57777
58117
|
// packages/runtime/src/system-probes/sessions.ts
|
|
57778
58118
|
import { createReadStream as createReadStream2 } from "fs";
|
|
57779
|
-
import { readdir, stat as
|
|
58119
|
+
import { readdir, stat as stat3 } from "fs/promises";
|
|
57780
58120
|
import { homedir as homedir18 } from "os";
|
|
57781
58121
|
import { basename as basename12, dirname as dirname9, join as join17, resolve as resolve3 } from "path";
|
|
57782
58122
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -57822,7 +58162,7 @@ function detectAgent(filePath, fallback = "unknown") {
|
|
|
57822
58162
|
}
|
|
57823
58163
|
async function directoryExists(path) {
|
|
57824
58164
|
try {
|
|
57825
|
-
return (await
|
|
58165
|
+
return (await stat3(path)).isDirectory();
|
|
57826
58166
|
} catch {
|
|
57827
58167
|
return false;
|
|
57828
58168
|
}
|
|
@@ -57851,7 +58191,7 @@ async function scanJsonlFiles(input) {
|
|
|
57851
58191
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl"))
|
|
57852
58192
|
continue;
|
|
57853
58193
|
try {
|
|
57854
|
-
const info = await
|
|
58194
|
+
const info = await stat3(filePath);
|
|
57855
58195
|
if (!info.isFile() || info.mtimeMs < input.cutoffMs)
|
|
57856
58196
|
continue;
|
|
57857
58197
|
out.push({
|
|
@@ -61346,7 +61686,7 @@ class SessionRegistry {
|
|
|
61346
61686
|
|
|
61347
61687
|
// packages/agent-sessions/src/local/transports/codex-app-server.ts
|
|
61348
61688
|
import { spawn as spawn4 } from "child_process";
|
|
61349
|
-
import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile3, rm, stat as
|
|
61689
|
+
import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile3, rm, stat as stat4, writeFile as writeFile2 } from "fs/promises";
|
|
61350
61690
|
import { join as join23 } from "path";
|
|
61351
61691
|
|
|
61352
61692
|
// packages/agent-sessions/src/codex-launch-config.ts
|
|
@@ -61521,6 +61861,21 @@ class CodexAppServerRequesterTimeoutError extends Error {
|
|
|
61521
61861
|
this.timeoutMs = input.timeoutMs;
|
|
61522
61862
|
}
|
|
61523
61863
|
}
|
|
61864
|
+
|
|
61865
|
+
class CodexThreadHeldExternallyError extends Error {
|
|
61866
|
+
code = "CODEX_THREAD_HELD_EXTERNALLY";
|
|
61867
|
+
threadId;
|
|
61868
|
+
agentName;
|
|
61869
|
+
constructor(input) {
|
|
61870
|
+
super(`Codex thread ${input.threadId} is open in another application` + (input.detail ? ` (${input.detail})` : "") + "; it will accept turns once that application releases it.");
|
|
61871
|
+
this.name = "CodexThreadHeldExternallyError";
|
|
61872
|
+
this.threadId = input.threadId;
|
|
61873
|
+
this.agentName = input.agentName;
|
|
61874
|
+
}
|
|
61875
|
+
}
|
|
61876
|
+
function isCodexThreadHeldExternallyError(error48) {
|
|
61877
|
+
return error48 instanceof CodexThreadHeldExternallyError || Boolean(error48 && typeof error48 === "object" && error48.code === "CODEX_THREAD_HELD_EXTERNALLY");
|
|
61878
|
+
}
|
|
61524
61879
|
function codexAppServerExitMessage(input) {
|
|
61525
61880
|
if (input.exitKind === "proactive_shutdown") {
|
|
61526
61881
|
return `Codex app-server session for ${input.agentName} was stopped by OpenScout` + (input.reason ? `: ${input.reason}` : "") + ".";
|
|
@@ -61786,7 +62141,7 @@ async function readOptionalFile(filePath) {
|
|
|
61786
62141
|
}
|
|
61787
62142
|
async function assertCodexWorkingDirectory(cwd, agentName) {
|
|
61788
62143
|
try {
|
|
61789
|
-
const stats = await
|
|
62144
|
+
const stats = await stat4(cwd);
|
|
61790
62145
|
if (!stats.isDirectory()) {
|
|
61791
62146
|
throw new Error(`Codex app-server cwd is not a directory for ${agentName}: ${cwd}`);
|
|
61792
62147
|
}
|
|
@@ -61899,6 +62254,10 @@ function isMissingCodexRolloutError(error48) {
|
|
|
61899
62254
|
const message = errorMessage2(error48).toLowerCase();
|
|
61900
62255
|
return message.includes("no rollout found for thread id");
|
|
61901
62256
|
}
|
|
62257
|
+
function isCodexThreadWriterConflictError(error48) {
|
|
62258
|
+
const message = errorMessage2(error48).toLowerCase();
|
|
62259
|
+
return message.includes("already has an active writer") || message.includes("thread-store conflict");
|
|
62260
|
+
}
|
|
61902
62261
|
|
|
61903
62262
|
class CodexAppServerTransport {
|
|
61904
62263
|
options;
|
|
@@ -61933,6 +62292,9 @@ class CodexAppServerTransport {
|
|
|
61933
62292
|
get currentThreadPath() {
|
|
61934
62293
|
return this.threadPath;
|
|
61935
62294
|
}
|
|
62295
|
+
get currentDurableThreadId() {
|
|
62296
|
+
return this.durableThreadId;
|
|
62297
|
+
}
|
|
61936
62298
|
get stdoutLogFile() {
|
|
61937
62299
|
return this.stdoutLogPath;
|
|
61938
62300
|
}
|
|
@@ -61969,7 +62331,8 @@ class CodexAppServerTransport {
|
|
|
61969
62331
|
throw new Error(`Codex app-server session for ${this.options.agentName} has no active thread.`);
|
|
61970
62332
|
}
|
|
61971
62333
|
return {
|
|
61972
|
-
threadId: this.threadId
|
|
62334
|
+
threadId: this.threadId,
|
|
62335
|
+
durableThreadId: this.durableThreadId
|
|
61973
62336
|
};
|
|
61974
62337
|
}
|
|
61975
62338
|
async startTurn(prompt) {
|
|
@@ -62187,6 +62550,13 @@ class CodexAppServerTransport {
|
|
|
62187
62550
|
await this.persistState();
|
|
62188
62551
|
}
|
|
62189
62552
|
if (requestedThreadId || this.options.requireExistingThread) {
|
|
62553
|
+
if (isCodexThreadWriterConflictError(error48)) {
|
|
62554
|
+
throw new CodexThreadHeldExternallyError({
|
|
62555
|
+
agentName: this.options.agentName,
|
|
62556
|
+
threadId: storedThreadId,
|
|
62557
|
+
detail: errorMessage2(error48)
|
|
62558
|
+
});
|
|
62559
|
+
}
|
|
62190
62560
|
throw new Error(`Failed to resume ${threadOrigin} Codex thread ${storedThreadId}: ${errorMessage2(error48)}`);
|
|
62191
62561
|
}
|
|
62192
62562
|
}
|
|
@@ -62359,7 +62729,7 @@ class CodexAppServerTransport {
|
|
|
62359
62729
|
let rolloutExists = false;
|
|
62360
62730
|
if (this.threadPath) {
|
|
62361
62731
|
try {
|
|
62362
|
-
rolloutExists = (await
|
|
62732
|
+
rolloutExists = (await stat4(this.threadPath)).isFile();
|
|
62363
62733
|
} catch {
|
|
62364
62734
|
rolloutExists = false;
|
|
62365
62735
|
}
|
|
@@ -66449,7 +66819,7 @@ function buildInvocationCollaborationContextPrompt(invocation) {
|
|
|
66449
66819
|
}
|
|
66450
66820
|
|
|
66451
66821
|
// packages/runtime/src/pi-rpc.ts
|
|
66452
|
-
import { existsSync as existsSync26, readFileSync as readFileSync10, statSync as
|
|
66822
|
+
import { existsSync as existsSync26, readFileSync as readFileSync10, statSync as statSync14 } from "fs";
|
|
66453
66823
|
import { mkdir as mkdir6, writeFile as writeFile4 } from "fs/promises";
|
|
66454
66824
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
66455
66825
|
import { homedir as homedir26 } from "os";
|
|
@@ -66556,13 +66926,13 @@ function readPiRpcCredentialFile(name, options = {}) {
|
|
|
66556
66926
|
return;
|
|
66557
66927
|
}
|
|
66558
66928
|
try {
|
|
66559
|
-
const directoryStat =
|
|
66929
|
+
const directoryStat = statSync14(directory);
|
|
66560
66930
|
if (!directoryStat.isDirectory() || (directoryStat.mode & 63) !== 0) {
|
|
66561
66931
|
return;
|
|
66562
66932
|
}
|
|
66563
66933
|
const path = join28(directory, name);
|
|
66564
|
-
const
|
|
66565
|
-
if (!
|
|
66934
|
+
const stat5 = statSync14(path);
|
|
66935
|
+
if (!stat5.isFile() || (stat5.mode & 63) !== 0 || stat5.size > 16 * 1024) {
|
|
66566
66936
|
return;
|
|
66567
66937
|
}
|
|
66568
66938
|
const value = readFileSync10(path, "utf8").trim();
|
|
@@ -66913,7 +67283,7 @@ async function shutdownPiRpcAgent(options) {
|
|
|
66913
67283
|
// packages/runtime/src/setup.ts
|
|
66914
67284
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
66915
67285
|
import { existsSync as existsSync29, readFileSync as readFileSync13 } from "fs";
|
|
66916
|
-
import { access, chmod, mkdir as mkdir8, readdir as readdir3, readFile as readFile8, realpath, rm as rm3, stat as
|
|
67286
|
+
import { access, chmod, mkdir as mkdir8, readdir as readdir3, readFile as readFile8, realpath, rm as rm3, stat as stat6, writeFile as writeFile6 } from "fs/promises";
|
|
66917
67287
|
import { homedir as homedir29, hostname as hostname3, userInfo } from "os";
|
|
66918
67288
|
import { basename as basename15, dirname as dirname16, isAbsolute as isAbsolute2, join as join32, relative as relative6, resolve as resolve9 } from "path";
|
|
66919
67289
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -67866,7 +68236,7 @@ function parse5(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
|
|
|
67866
68236
|
|
|
67867
68237
|
// packages/runtime/src/harness-catalog.ts
|
|
67868
68238
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
67869
|
-
import { existsSync as existsSync27, statSync as
|
|
68239
|
+
import { existsSync as existsSync27, statSync as statSync15 } from "fs";
|
|
67870
68240
|
import { mkdir as mkdir7, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
|
|
67871
68241
|
import { homedir as homedir27 } from "os";
|
|
67872
68242
|
import { dirname as dirname13, join as join29 } from "path";
|
|
@@ -68452,7 +68822,7 @@ function defaultRequirementExists(requirement) {
|
|
|
68452
68822
|
if (requirement.fileType === "any" || !requirement.fileType)
|
|
68453
68823
|
return true;
|
|
68454
68824
|
try {
|
|
68455
|
-
const fileStat =
|
|
68825
|
+
const fileStat = statSync15(expanded);
|
|
68456
68826
|
return requirement.fileType === "directory" ? fileStat.isDirectory() : fileStat.isFile();
|
|
68457
68827
|
} catch {
|
|
68458
68828
|
return false;
|
|
@@ -68754,6 +69124,38 @@ var NODE_IDENTITY_FILE = "node-identity.json";
|
|
|
68754
69124
|
var NODE_FINGERPRINT_PREFIX = "osc1";
|
|
68755
69125
|
var NODE_CARD_TTL_MS = 24 * 60 * 60 * 1000;
|
|
68756
69126
|
var stableNodeQualifierCache = new Map;
|
|
69127
|
+
function stripBonjourCollisionSuffix(value) {
|
|
69128
|
+
if (!value || typeof value !== "string")
|
|
69129
|
+
return "";
|
|
69130
|
+
let trimmed = value.trim();
|
|
69131
|
+
const isDotLocal = /\.local\.?$/i.test(trimmed);
|
|
69132
|
+
if (isDotLocal) {
|
|
69133
|
+
trimmed = trimmed.replace(/\.local\.?$/i, "");
|
|
69134
|
+
}
|
|
69135
|
+
const isHyphenLocalOpenscout = /-local-openscout$/i.test(trimmed);
|
|
69136
|
+
const isHyphenLocal = !isHyphenLocalOpenscout && /-local$/i.test(trimmed);
|
|
69137
|
+
if (isHyphenLocalOpenscout) {
|
|
69138
|
+
trimmed = trimmed.replace(/-local-openscout$/i, "");
|
|
69139
|
+
} else if (isHyphenLocal) {
|
|
69140
|
+
trimmed = trimmed.replace(/-local$/i, "");
|
|
69141
|
+
}
|
|
69142
|
+
if (!isDotLocal && !isHyphenLocalOpenscout && !isHyphenLocal) {
|
|
69143
|
+
return trimmed;
|
|
69144
|
+
}
|
|
69145
|
+
trimmed = trimmed.replace(/(?<=[a-zA-Z].*?)(?:-\d+)+$/, "");
|
|
69146
|
+
if (isDotLocal)
|
|
69147
|
+
return `${trimmed}.local`;
|
|
69148
|
+
if (isHyphenLocalOpenscout)
|
|
69149
|
+
return `${trimmed}-local-openscout`;
|
|
69150
|
+
if (isHyphenLocal)
|
|
69151
|
+
return `${trimmed}-local`;
|
|
69152
|
+
return trimmed;
|
|
69153
|
+
}
|
|
69154
|
+
function canonicalMeshNodeId(nodeId) {
|
|
69155
|
+
if (!nodeId || typeof nodeId !== "string")
|
|
69156
|
+
return "";
|
|
69157
|
+
return stripBonjourCollisionSuffix(nodeId);
|
|
69158
|
+
}
|
|
68757
69159
|
function nodeIdentityPath(supportDirectory) {
|
|
68758
69160
|
const dir = supportDirectory ?? resolveOpenScoutSupportPaths().supportDirectory;
|
|
68759
69161
|
return join30(dir, NODE_IDENTITY_FILE);
|
|
@@ -68774,6 +69176,12 @@ function loadOrCreateStableNodeQualifier(fallbackName, supportDirectory) {
|
|
|
68774
69176
|
const identity2 = loadOrCreateNodeIdentity(supportDirectory);
|
|
68775
69177
|
const existing = normalizeNodeQualifier(identity2.nodeQualifier);
|
|
68776
69178
|
if (existing) {
|
|
69179
|
+
if (identity2.nodeQualifier !== existing) {
|
|
69180
|
+
persistNodeIdentity(path, {
|
|
69181
|
+
...identity2,
|
|
69182
|
+
nodeQualifier: existing
|
|
69183
|
+
});
|
|
69184
|
+
}
|
|
68777
69185
|
stableNodeQualifierCache.set(path, existing);
|
|
68778
69186
|
return existing;
|
|
68779
69187
|
}
|
|
@@ -68819,7 +69227,7 @@ function readAndValidateNodeIdentity(path) {
|
|
|
68819
69227
|
if (parsed.version !== 1 || !parsed.publicKey || !parsed.privateKey) {
|
|
68820
69228
|
throw new Error(`Corrupt node identity at ${path}; remove it to generate a fresh one.`);
|
|
68821
69229
|
}
|
|
68822
|
-
if (parsed.nodeQualifier !== undefined &&
|
|
69230
|
+
if (parsed.nodeQualifier !== undefined && normalizePersistedNodeQualifier(parsed.nodeQualifier) !== parsed.nodeQualifier) {
|
|
68823
69231
|
throw new Error(`Corrupt node identity at ${path}; remove it to generate a fresh one.`);
|
|
68824
69232
|
}
|
|
68825
69233
|
try {
|
|
@@ -68832,9 +69240,12 @@ function readAndValidateNodeIdentity(path) {
|
|
|
68832
69240
|
}
|
|
68833
69241
|
return parsed;
|
|
68834
69242
|
}
|
|
68835
|
-
function
|
|
69243
|
+
function normalizePersistedNodeQualifier(value) {
|
|
68836
69244
|
return typeof value === "string" ? value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "") : "";
|
|
68837
69245
|
}
|
|
69246
|
+
function normalizeNodeQualifier(value) {
|
|
69247
|
+
return stripBonjourCollisionSuffix(normalizePersistedNodeQualifier(value));
|
|
69248
|
+
}
|
|
68838
69249
|
function persistNodeIdentity(path, identity2) {
|
|
68839
69250
|
const tempPath = `${path}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
68840
69251
|
mkdirSync3(dirname14(path), { recursive: true });
|
|
@@ -69033,7 +69444,7 @@ function isRecord9(value) {
|
|
|
69033
69444
|
}
|
|
69034
69445
|
|
|
69035
69446
|
// packages/runtime/src/user-project-hints.ts
|
|
69036
|
-
import { readdir as readdir2, readFile as readFile7, stat as
|
|
69447
|
+
import { readdir as readdir2, readFile as readFile7, stat as stat5 } from "fs/promises";
|
|
69037
69448
|
import { homedir as homedir28 } from "os";
|
|
69038
69449
|
import { dirname as dirname15, join as join31, resolve as resolve8 } from "path";
|
|
69039
69450
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -69067,7 +69478,7 @@ function encodeClaudeProjectsSlug(absolutePath) {
|
|
|
69067
69478
|
async function resolveExistingDirectoryHint(pathLike) {
|
|
69068
69479
|
const absolutePath = resolve8(pathLike);
|
|
69069
69480
|
try {
|
|
69070
|
-
const info = await
|
|
69481
|
+
const info = await stat5(absolutePath);
|
|
69071
69482
|
if (info.isDirectory()) {
|
|
69072
69483
|
return absolutePath;
|
|
69073
69484
|
}
|
|
@@ -69081,7 +69492,7 @@ async function resolveExistingDirectoryHint(pathLike) {
|
|
|
69081
69492
|
}
|
|
69082
69493
|
async function pathExists(pathLike) {
|
|
69083
69494
|
try {
|
|
69084
|
-
await
|
|
69495
|
+
await stat5(pathLike);
|
|
69085
69496
|
return true;
|
|
69086
69497
|
} catch {
|
|
69087
69498
|
return false;
|
|
@@ -69159,7 +69570,7 @@ async function appendCodexHistoryPaths(home, roots) {
|
|
|
69159
69570
|
for (const filePath of candidates) {
|
|
69160
69571
|
let st;
|
|
69161
69572
|
try {
|
|
69162
|
-
st = await
|
|
69573
|
+
st = await stat5(filePath);
|
|
69163
69574
|
} catch {
|
|
69164
69575
|
continue;
|
|
69165
69576
|
}
|
|
@@ -69231,7 +69642,7 @@ async function appendCursorWorkspacePaths(home, roots) {
|
|
|
69231
69642
|
}
|
|
69232
69643
|
let wsStat;
|
|
69233
69644
|
try {
|
|
69234
|
-
wsStat = await
|
|
69645
|
+
wsStat = await stat5(wsFile);
|
|
69235
69646
|
} catch {
|
|
69236
69647
|
continue;
|
|
69237
69648
|
}
|
|
@@ -69298,7 +69709,7 @@ async function appendClaudeSessionPaths(home, roots) {
|
|
|
69298
69709
|
const sessionPath = join31(projectsDir, projectName, entry);
|
|
69299
69710
|
let info;
|
|
69300
69711
|
try {
|
|
69301
|
-
info = await
|
|
69712
|
+
info = await stat5(sessionPath);
|
|
69302
69713
|
} catch {
|
|
69303
69714
|
continue;
|
|
69304
69715
|
}
|
|
@@ -69986,6 +70397,9 @@ function defaultSettings() {
|
|
|
69986
70397
|
quickHits: [],
|
|
69987
70398
|
preparedAt: null
|
|
69988
70399
|
},
|
|
70400
|
+
voice: {
|
|
70401
|
+
realtimeEnabled: false
|
|
70402
|
+
},
|
|
69989
70403
|
ui: {
|
|
69990
70404
|
scenes: [],
|
|
69991
70405
|
activeSceneIdBySurface: {}
|
|
@@ -70011,7 +70425,7 @@ async function pathExists2(filePath) {
|
|
|
70011
70425
|
}
|
|
70012
70426
|
async function isDirectory(filePath) {
|
|
70013
70427
|
try {
|
|
70014
|
-
const fileStat = await
|
|
70428
|
+
const fileStat = await stat6(filePath);
|
|
70015
70429
|
return fileStat.isDirectory();
|
|
70016
70430
|
} catch {
|
|
70017
70431
|
return false;
|
|
@@ -70373,6 +70787,7 @@ async function normalizeSettingsRecord(value, options = {}) {
|
|
|
70373
70787
|
const telegram = typeof bridges.telegram === "object" && bridges.telegram ? bridges.telegram : {};
|
|
70374
70788
|
const network = typeof candidate.network === "object" && candidate.network ? candidate.network : {};
|
|
70375
70789
|
const phone = typeof candidate.phone === "object" && candidate.phone ? candidate.phone : {};
|
|
70790
|
+
const voice = typeof candidate.voice === "object" && candidate.voice ? candidate.voice : {};
|
|
70376
70791
|
const ui = typeof candidate.ui === "object" && candidate.ui ? candidate.ui : {};
|
|
70377
70792
|
const oldOperatorName = typeof candidate.operatorName === "string" ? candidate.operatorName : undefined;
|
|
70378
70793
|
const seededWorkspaceRoots = await seedWorkspaceRoots({
|
|
@@ -70445,6 +70860,9 @@ async function normalizeSettingsRecord(value, options = {}) {
|
|
|
70445
70860
|
quickHits: normalizeStringList(phone.quickHits),
|
|
70446
70861
|
preparedAt: normalizeOptionalTimestamp(phone.preparedAt)
|
|
70447
70862
|
},
|
|
70863
|
+
voice: {
|
|
70864
|
+
realtimeEnabled: typeof voice.realtimeEnabled === "boolean" ? voice.realtimeEnabled : base.voice.realtimeEnabled
|
|
70865
|
+
},
|
|
70448
70866
|
ui: normalizeUi(ui)
|
|
70449
70867
|
};
|
|
70450
70868
|
}
|
|
@@ -73416,6 +73834,14 @@ async function readLocalAgentRegistry() {
|
|
|
73416
73834
|
localAgentRecordFromRelayAgentOverride(agentId, override)
|
|
73417
73835
|
]));
|
|
73418
73836
|
}
|
|
73837
|
+
var archivedLocalAgentIdsCache = null;
|
|
73838
|
+
function invalidateArchivedLocalAgentIdsCache() {
|
|
73839
|
+
archivedLocalAgentIdsCache = null;
|
|
73840
|
+
}
|
|
73841
|
+
async function writeRelayAgentOverrides2(overrides) {
|
|
73842
|
+
await writeRelayAgentOverrides(overrides);
|
|
73843
|
+
invalidateArchivedLocalAgentIdsCache();
|
|
73844
|
+
}
|
|
73419
73845
|
async function writeLocalAgentRegistry(registry3) {
|
|
73420
73846
|
const overrides = await readRelayAgentOverrides();
|
|
73421
73847
|
const nextOverrides = {
|
|
@@ -73424,7 +73850,7 @@ async function writeLocalAgentRegistry(registry3) {
|
|
|
73424
73850
|
for (const [agentId, record3] of Object.entries(registry3)) {
|
|
73425
73851
|
nextOverrides[agentId] = relayAgentOverrideFromLocalAgentRecord(agentId, record3, overrides[agentId]);
|
|
73426
73852
|
}
|
|
73427
|
-
await
|
|
73853
|
+
await writeRelayAgentOverrides2(nextOverrides);
|
|
73428
73854
|
}
|
|
73429
73855
|
function expandHomePath4(value) {
|
|
73430
73856
|
if (value === "~") {
|
|
@@ -74063,7 +74489,7 @@ function providerSessionIdFromMetadata(metadata) {
|
|
|
74063
74489
|
async function ensureLocalSessionEndpointOnline(endpoint) {
|
|
74064
74490
|
if (endpoint.transport === "codex_app_server") {
|
|
74065
74491
|
const result = await ensureCodexAppServerAgentOnline(buildCodexEndpointSessionOptions(endpoint));
|
|
74066
|
-
return { externalSessionId: result.
|
|
74492
|
+
return { externalSessionId: result.durableThreadId };
|
|
74067
74493
|
}
|
|
74068
74494
|
if (endpoint.transport === "claude_stream_json") {
|
|
74069
74495
|
const result = await ensureClaudeStreamJsonAgentOnline(buildClaudeEndpointSessionOptions(endpoint));
|
|
@@ -74240,7 +74666,7 @@ function buildCodexEndpointSessionOptions(endpoint) {
|
|
|
74240
74666
|
logsDirectory: relayAgentLogsDirectory(agentName),
|
|
74241
74667
|
env: {
|
|
74242
74668
|
CODEX_HOME: codexHomeForEndpoint(endpoint),
|
|
74243
|
-
...endpoint.metadata?.placement === "background" ? {
|
|
74669
|
+
...endpoint.metadata?.placement === "background" && codexHomeForEndpoint(endpoint) !== operatorCodexHome() ? {
|
|
74244
74670
|
OPENSCOUT_CODEX_AUTH_SOURCE: join37(operatorCodexHome(), "auth.json")
|
|
74245
74671
|
} : {}
|
|
74246
74672
|
},
|
|
@@ -74252,6 +74678,12 @@ function buildCodexEndpointSessionOptions(endpoint) {
|
|
|
74252
74678
|
});
|
|
74253
74679
|
}
|
|
74254
74680
|
function codexHomeForEndpoint(endpoint) {
|
|
74681
|
+
const source = endpointMetadataString(endpoint, "source");
|
|
74682
|
+
const scoutOwnsThread = source === "scoutbot" || source?.startsWith("scout-") === true;
|
|
74683
|
+
const externalThreadId = scoutOwnsThread ? undefined : endpointMetadataString(endpoint, "threadId") ?? endpointMetadataString(endpoint, "externalSessionId");
|
|
74684
|
+
if (externalThreadId) {
|
|
74685
|
+
return operatorCodexHome();
|
|
74686
|
+
}
|
|
74255
74687
|
const placement = endpoint.metadata?.placement === "background" ? "background" : "foreground";
|
|
74256
74688
|
if (placement === "background") {
|
|
74257
74689
|
return join37(resolveOpenScoutSupportPaths().runtimeDirectory, "codex-background-home");
|
|
@@ -78683,7 +79115,7 @@ class BrokerDeliveryAcceptanceService {
|
|
|
78683
79115
|
};
|
|
78684
79116
|
const aliasResolution = resolved.aliasResolution;
|
|
78685
79117
|
const receiptSessionId = requestedTargetSessionId ?? (aliasResolution?.target.kind === "session" ? aliasResolution.target.sessionId : undefined) ?? (resolved.kind === "resolved_session" ? resolved.session.sessionId : undefined);
|
|
78686
|
-
const unavailable = resolved.kind === "resolved" ? this.options.describeUnavailableDeliveryTarget(this.options.runtimeSnapshot(), resolved.agent, requestedTargetSessionId) :
|
|
79118
|
+
const unavailable = resolved.kind === "resolved" ? this.options.describeUnavailableDeliveryTarget(this.options.runtimeSnapshot(), resolved.agent, requestedTargetSessionId) : null;
|
|
78687
79119
|
if (unavailable) {
|
|
78688
79120
|
const targetLabel2 = askedLabel || target.label;
|
|
78689
79121
|
const { record: record3 } = await this.options.recordScoutDispatch(this.options.buildUnavailableDispatchEnvelope(targetLabel2, unavailable), {
|
|
@@ -80131,6 +80563,62 @@ function parsePositiveIntParam(url2, key, cap) {
|
|
|
80131
80563
|
return;
|
|
80132
80564
|
return Math.min(value, cap);
|
|
80133
80565
|
}
|
|
80566
|
+
var TAIL_RECENT_ASSISTANT_REPLIES_MODE = "assistant-replies";
|
|
80567
|
+
function isAssistantRepliesMode(url2) {
|
|
80568
|
+
return url2.searchParams.get("mode") === TAIL_RECENT_ASSISTANT_REPLIES_MODE;
|
|
80569
|
+
}
|
|
80570
|
+
function tailEventMessageRole(event) {
|
|
80571
|
+
if (!event.raw || typeof event.raw !== "object" || Array.isArray(event.raw))
|
|
80572
|
+
return null;
|
|
80573
|
+
const payload = event.raw.payload;
|
|
80574
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
80575
|
+
return null;
|
|
80576
|
+
const role = payload.role;
|
|
80577
|
+
return typeof role === "string" ? role.trim().toLowerCase() : null;
|
|
80578
|
+
}
|
|
80579
|
+
function isApprovalReviewerDecision(summary) {
|
|
80580
|
+
const trimmed = summary.trim();
|
|
80581
|
+
if (!trimmed.startsWith("{"))
|
|
80582
|
+
return false;
|
|
80583
|
+
if (trimmed.startsWith('{"risk_level":') && trimmed.includes('"user_authorization":') && trimmed.includes('"outcome":') && trimmed.includes('"rationale":')) {
|
|
80584
|
+
return true;
|
|
80585
|
+
}
|
|
80586
|
+
try {
|
|
80587
|
+
const parsed = JSON.parse(trimmed);
|
|
80588
|
+
return typeof parsed.risk_level === "string" && typeof parsed.user_authorization === "string" && typeof parsed.outcome === "string" && typeof parsed.rationale === "string";
|
|
80589
|
+
} catch {
|
|
80590
|
+
return false;
|
|
80591
|
+
}
|
|
80592
|
+
}
|
|
80593
|
+
function isAssistantReply(event) {
|
|
80594
|
+
if (event.kind !== "assistant")
|
|
80595
|
+
return false;
|
|
80596
|
+
const summary = event.summary.trim();
|
|
80597
|
+
if (!summary || /^\[(?:assistant|message)\]$/iu.test(summary))
|
|
80598
|
+
return false;
|
|
80599
|
+
const role = tailEventMessageRole(event);
|
|
80600
|
+
if (role && role !== "assistant")
|
|
80601
|
+
return false;
|
|
80602
|
+
return !isApprovalReviewerDecision(summary);
|
|
80603
|
+
}
|
|
80604
|
+
function assistantReplySessionKey(event) {
|
|
80605
|
+
const source = event.source.trim().toLowerCase();
|
|
80606
|
+
const sessionId = event.sessionId.trim();
|
|
80607
|
+
return source && sessionId ? `${source}\x00${sessionId}` : `event\x00${event.id}`;
|
|
80608
|
+
}
|
|
80609
|
+
function latestAssistantReplies(events) {
|
|
80610
|
+
const latestBySession = new Map;
|
|
80611
|
+
for (const event of events) {
|
|
80612
|
+
if (!isAssistantReply(event))
|
|
80613
|
+
continue;
|
|
80614
|
+
const key = assistantReplySessionKey(event);
|
|
80615
|
+
const current = latestBySession.get(key);
|
|
80616
|
+
if (!current || event.ts > current.ts || event.ts === current.ts && event.id.localeCompare(current.id) > 0) {
|
|
80617
|
+
latestBySession.set(key, event);
|
|
80618
|
+
}
|
|
80619
|
+
}
|
|
80620
|
+
return [...latestBySession.values()];
|
|
80621
|
+
}
|
|
80134
80622
|
function booleanQuery(url2, key) {
|
|
80135
80623
|
return url2.searchParams.get(key) === "1" || url2.searchParams.get(key) === "true";
|
|
80136
80624
|
}
|
|
@@ -80138,6 +80626,8 @@ function booleanQuery(url2, key) {
|
|
|
80138
80626
|
class BrokerRepoTailService {
|
|
80139
80627
|
options;
|
|
80140
80628
|
repoWatchWarmInFlight = null;
|
|
80629
|
+
tailRecentCache = null;
|
|
80630
|
+
tailRecentInFlight = null;
|
|
80141
80631
|
constructor(options) {
|
|
80142
80632
|
this.options = options;
|
|
80143
80633
|
}
|
|
@@ -80215,6 +80705,48 @@ class BrokerRepoTailService {
|
|
|
80215
80705
|
return snapshot;
|
|
80216
80706
|
}
|
|
80217
80707
|
async readTailRecentPayloadWithTiming(url2) {
|
|
80708
|
+
const cacheTtlMs = this.options.tailRecentServeCacheTtlMs ?? 0;
|
|
80709
|
+
const cacheKey = `${parseTailLimit(url2)}:${url2.searchParams.get("transcripts") === "true" || url2.searchParams.get("transcripts") === "1"}:${isAssistantRepliesMode(url2) ? TAIL_RECENT_ASSISTANT_REPLIES_MODE : "all"}`;
|
|
80710
|
+
const now = this.now();
|
|
80711
|
+
if (cacheTtlMs > 0 && this.tailRecentCache?.key === cacheKey && this.tailRecentCache.expiresAtMs > now) {
|
|
80712
|
+
const cached2 = this.tailRecentCache;
|
|
80713
|
+
return {
|
|
80714
|
+
payload: {
|
|
80715
|
+
...cached2.result.payload,
|
|
80716
|
+
events: [...cached2.result.payload.events]
|
|
80717
|
+
},
|
|
80718
|
+
timings: [
|
|
80719
|
+
...cached2.result.timings,
|
|
80720
|
+
{ name: "tail-serve-cache", dur: Math.max(0, now - (cached2.expiresAtMs - cacheTtlMs)) }
|
|
80721
|
+
]
|
|
80722
|
+
};
|
|
80723
|
+
}
|
|
80724
|
+
const inFlight = this.tailRecentInFlight;
|
|
80725
|
+
if (cacheTtlMs > 0 && inFlight && inFlight.key === cacheKey)
|
|
80726
|
+
return inFlight.promise;
|
|
80727
|
+
const request = (async () => {
|
|
80728
|
+
const result = await this.computeTailRecentPayloadWithTiming(url2);
|
|
80729
|
+
if (cacheTtlMs > 0) {
|
|
80730
|
+
this.tailRecentCache = {
|
|
80731
|
+
key: cacheKey,
|
|
80732
|
+
result,
|
|
80733
|
+
expiresAtMs: this.now() + cacheTtlMs
|
|
80734
|
+
};
|
|
80735
|
+
}
|
|
80736
|
+
return result;
|
|
80737
|
+
})();
|
|
80738
|
+
if (cacheTtlMs > 0) {
|
|
80739
|
+
this.tailRecentInFlight = { key: cacheKey, promise: request };
|
|
80740
|
+
try {
|
|
80741
|
+
return await request;
|
|
80742
|
+
} finally {
|
|
80743
|
+
if (this.tailRecentInFlight?.promise === request)
|
|
80744
|
+
this.tailRecentInFlight = null;
|
|
80745
|
+
}
|
|
80746
|
+
}
|
|
80747
|
+
return request;
|
|
80748
|
+
}
|
|
80749
|
+
async computeTailRecentPayloadWithTiming(url2) {
|
|
80218
80750
|
const timings = [];
|
|
80219
80751
|
const measure = async (name, fn) => {
|
|
80220
80752
|
const start = performance2.now();
|
|
@@ -80225,24 +80757,29 @@ class BrokerRepoTailService {
|
|
|
80225
80757
|
}
|
|
80226
80758
|
};
|
|
80227
80759
|
const limit = parseTailLimit(url2);
|
|
80760
|
+
const assistantRepliesOnly = isAssistantRepliesMode(url2);
|
|
80761
|
+
const kinds = assistantRepliesOnly ? ["assistant"] : undefined;
|
|
80228
80762
|
const includeTranscripts = url2.searchParams.get("transcripts") === "true" || url2.searchParams.get("transcripts") === "1";
|
|
80229
80763
|
const eventsById = new Map;
|
|
80230
80764
|
if (includeTranscripts) {
|
|
80231
80765
|
const discovery = await measure("tail-discover", () => this.options.getTailDiscovery(false));
|
|
80232
80766
|
const transcriptEvents = filterTailEventsForDisplay(await measure("tail-transcripts", () => this.options.readRecentTranscriptEvents(Math.max(limit, 800), {
|
|
80233
80767
|
discovery,
|
|
80234
|
-
perTranscriptLineLimit: Math.min(200, Math.max(50, limit))
|
|
80768
|
+
perTranscriptLineLimit: Math.min(200, Math.max(50, limit)),
|
|
80769
|
+
kinds,
|
|
80770
|
+
...assistantRepliesOnly ? { perTranscriptKindLimit: 1 } : {}
|
|
80235
80771
|
})));
|
|
80236
80772
|
for (const event of transcriptEvents) {
|
|
80237
80773
|
eventsById.set(event.id, event);
|
|
80238
80774
|
}
|
|
80239
80775
|
}
|
|
80240
80776
|
const mergeStart = performance2.now();
|
|
80241
|
-
const bufferedEvents = filterTailEventsForDisplay(await measure("tail-live", () => this.options.readRecentLiveEvents(limit)));
|
|
80777
|
+
const bufferedEvents = filterTailEventsForDisplay(await measure("tail-live", () => this.options.readRecentLiveEvents(limit, { kinds })));
|
|
80242
80778
|
for (const event of bufferedEvents) {
|
|
80243
80779
|
eventsById.set(event.id, event);
|
|
80244
80780
|
}
|
|
80245
|
-
const
|
|
80781
|
+
const candidates = assistantRepliesOnly ? latestAssistantReplies(eventsById.values()) : [...eventsById.values()];
|
|
80782
|
+
const events = candidates.sort((left, right) => {
|
|
80246
80783
|
if (left.ts === right.ts)
|
|
80247
80784
|
return left.id.localeCompare(right.id);
|
|
80248
80785
|
return left.ts - right.ts;
|
|
@@ -80258,12 +80795,12 @@ class BrokerRepoTailService {
|
|
|
80258
80795
|
timings
|
|
80259
80796
|
};
|
|
80260
80797
|
}
|
|
80261
|
-
async readTailRecentPayload(url2) {
|
|
80262
|
-
return (await this.readTailRecentPayloadWithTiming(url2)).payload;
|
|
80263
|
-
}
|
|
80264
80798
|
now() {
|
|
80265
80799
|
return (this.options.now ?? Date.now)();
|
|
80266
80800
|
}
|
|
80801
|
+
async readTailRecentPayload(url2) {
|
|
80802
|
+
return (await this.readTailRecentPayloadWithTiming(url2)).payload;
|
|
80803
|
+
}
|
|
80267
80804
|
}
|
|
80268
80805
|
|
|
80269
80806
|
// packages/runtime/src/broker-rendezvous-service.ts
|
|
@@ -101776,6 +102313,10 @@ function hasColumn(database, tableName, columnName) {
|
|
|
101776
102313
|
const rows = database.query(`SELECT name FROM pragma_table_info('${escapedTableName}')`).all();
|
|
101777
102314
|
return rows.some((row) => row.name === columnName);
|
|
101778
102315
|
}
|
|
102316
|
+
function hasTable(database, tableName) {
|
|
102317
|
+
const row = database.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?1").get(tableName);
|
|
102318
|
+
return Boolean(row);
|
|
102319
|
+
}
|
|
101779
102320
|
var CONTROL_PLANE_SCHEMA_MIGRATIONS = [
|
|
101780
102321
|
{
|
|
101781
102322
|
id: "runtime-session-mapping-read-model",
|
|
@@ -101954,6 +102495,46 @@ WHERE latest.invocation_id = inv.id
|
|
|
101954
102495
|
database.exec("ALTER TABLE trusted_peers ADD COLUMN tls_spki_fingerprint TEXT");
|
|
101955
102496
|
}
|
|
101956
102497
|
}
|
|
102498
|
+
},
|
|
102499
|
+
{
|
|
102500
|
+
id: "canonicalize-mesh-nodes-and-rehome",
|
|
102501
|
+
description: "Re-homes foreign key references on Bonjour collision-suffixed ghost nodes to canonical stable node IDs and prunes ghost nodes.",
|
|
102502
|
+
apply(database) {
|
|
102503
|
+
if (!hasTable(database, "nodes"))
|
|
102504
|
+
return;
|
|
102505
|
+
const nodeRows = database.query("SELECT * FROM nodes").all();
|
|
102506
|
+
for (const row of nodeRows) {
|
|
102507
|
+
const canonicalId = canonicalMeshNodeId(row.id);
|
|
102508
|
+
if (canonicalId && canonicalId !== row.id) {
|
|
102509
|
+
const existing = nodeRows.find((r) => r.id === canonicalId);
|
|
102510
|
+
if (!existing) {
|
|
102511
|
+
database.query(`INSERT INTO nodes (
|
|
102512
|
+
id, mesh_id, name, host_name, advertise_scope, broker_url, tailnet_name,
|
|
102513
|
+
capabilities_json, labels_json, metadata_json, last_seen_at, registered_at
|
|
102514
|
+
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
|
|
102515
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
102516
|
+
last_seen_at = MAX(COALESCE(nodes.last_seen_at, 0), COALESCE(excluded.last_seen_at, 0)),
|
|
102517
|
+
broker_url = COALESCE(excluded.broker_url, nodes.broker_url),
|
|
102518
|
+
tailnet_name = COALESCE(excluded.tailnet_name, nodes.tailnet_name)`).run(canonicalId, row.mesh_id, stripBonjourCollisionSuffix(row.name) || row.name, stripBonjourCollisionSuffix(row.host_name ?? "") || (row.host_name ?? null), row.advertise_scope, row.broker_url ?? null, row.tailnet_name ?? null, row.capabilities_json ?? null, row.labels_json ?? null, row.metadata_json ?? null, row.last_seen_at ?? null, row.registered_at);
|
|
102519
|
+
}
|
|
102520
|
+
database.query("UPDATE agents SET home_node_id = ?1 WHERE home_node_id = ?2").run(canonicalId, row.id);
|
|
102521
|
+
database.query("UPDATE agents SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, row.id);
|
|
102522
|
+
database.query("UPDATE agent_endpoints SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, row.id);
|
|
102523
|
+
database.query("UPDATE runtime_sessions SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, row.id);
|
|
102524
|
+
database.query("UPDATE runtime_session_aliases SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, row.id);
|
|
102525
|
+
database.query("UPDATE conversations SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, row.id);
|
|
102526
|
+
database.query("UPDATE conversation_read_cursors SET reader_node_id = ?1 WHERE reader_node_id = ?2").run(canonicalId, row.id);
|
|
102527
|
+
database.query("UPDATE messages SET origin_node_id = ?1 WHERE origin_node_id = ?2").run(canonicalId, row.id);
|
|
102528
|
+
database.query("UPDATE deliveries SET target_node_id = ?1 WHERE target_node_id = ?2").run(canonicalId, row.id);
|
|
102529
|
+
database.query("UPDATE invocations SET requester_node_id = ?1 WHERE requester_node_id = ?2").run(canonicalId, row.id);
|
|
102530
|
+
database.query("UPDATE invocations SET target_node_id = ?1 WHERE target_node_id = ?2").run(canonicalId, row.id);
|
|
102531
|
+
database.query("UPDATE thread_events SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, row.id);
|
|
102532
|
+
database.query("UPDATE thread_cursors SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, row.id);
|
|
102533
|
+
database.query("UPDATE trusted_peers SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, row.id);
|
|
102534
|
+
database.query("DELETE FROM nodes WHERE id = ?1").run(row.id);
|
|
102535
|
+
}
|
|
102536
|
+
}
|
|
102537
|
+
}
|
|
101957
102538
|
}
|
|
101958
102539
|
];
|
|
101959
102540
|
function configureControlPlaneDatabase(database) {
|
|
@@ -102980,11 +103561,65 @@ class SQLiteControlPlaneStore {
|
|
|
102980
103561
|
const now = options.now ?? currentTimestampMs();
|
|
102981
103562
|
const maxStaleAgeMs = options.maxStaleAgeMs ?? 7 * 24 * 60 * 60 * 1000;
|
|
102982
103563
|
const staleCutoff = now - maxStaleAgeMs;
|
|
103564
|
+
const nodeRows = this.db.query("SELECT * FROM nodes").all();
|
|
102983
103565
|
const peerRows = this.db.query("SELECT * FROM trusted_peers").all();
|
|
102984
103566
|
const rehomedMappings = [];
|
|
102985
|
-
const
|
|
103567
|
+
const rehomeMap = new Map;
|
|
103568
|
+
for (const row of nodeRows) {
|
|
103569
|
+
const canonicalId = canonicalMeshNodeId(row.id);
|
|
103570
|
+
if (canonicalId && canonicalId !== row.id) {
|
|
103571
|
+
rehomeMap.set(row.id, { to: canonicalId, candidateRow: row });
|
|
103572
|
+
}
|
|
103573
|
+
}
|
|
103574
|
+
let rehomedNodeCount = 0;
|
|
102986
103575
|
let prunedNodeCount = 0;
|
|
102987
103576
|
this.db.transaction(() => {
|
|
103577
|
+
for (const [staleId, { to: canonicalId, candidateRow }] of rehomeMap.entries()) {
|
|
103578
|
+
const existingCanonical = nodeRows.find((r) => r.id === canonicalId);
|
|
103579
|
+
if (!existingCanonical) {
|
|
103580
|
+
this.db.query(`INSERT INTO nodes (
|
|
103581
|
+
id, mesh_id, name, host_name, advertise_scope, broker_url, tailnet_name,
|
|
103582
|
+
capabilities_json, labels_json, metadata_json, last_seen_at, registered_at
|
|
103583
|
+
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
|
|
103584
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
103585
|
+
last_seen_at = MAX(COALESCE(nodes.last_seen_at, 0), COALESCE(excluded.last_seen_at, 0)),
|
|
103586
|
+
broker_url = COALESCE(excluded.broker_url, nodes.broker_url),
|
|
103587
|
+
tailnet_name = COALESCE(excluded.tailnet_name, nodes.tailnet_name)`).run(canonicalId, candidateRow.mesh_id, stripBonjourCollisionSuffix(candidateRow.name) || candidateRow.name, stripBonjourCollisionSuffix(candidateRow.host_name ?? "") || (candidateRow.host_name ?? null), candidateRow.advertise_scope, candidateRow.broker_url ?? null, candidateRow.tailnet_name ?? null, candidateRow.capabilities_json ?? null, candidateRow.labels_json ?? null, candidateRow.metadata_json ?? null, candidateRow.last_seen_at ?? null, candidateRow.registered_at);
|
|
103588
|
+
} else {
|
|
103589
|
+
this.db.query(`UPDATE nodes SET
|
|
103590
|
+
last_seen_at = MAX(COALESCE(last_seen_at, 0), COALESCE(?1, 0)),
|
|
103591
|
+
broker_url = COALESCE(?2, broker_url)
|
|
103592
|
+
WHERE id = ?3`).run(candidateRow.last_seen_at ?? null, candidateRow.broker_url ?? null, canonicalId);
|
|
103593
|
+
}
|
|
103594
|
+
this.db.query("UPDATE agents SET home_node_id = ?1 WHERE home_node_id = ?2").run(canonicalId, staleId);
|
|
103595
|
+
this.db.query("UPDATE agents SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, staleId);
|
|
103596
|
+
this.db.query("UPDATE agent_endpoints SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, staleId);
|
|
103597
|
+
this.db.query("UPDATE runtime_sessions SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, staleId);
|
|
103598
|
+
this.db.query("UPDATE runtime_session_aliases SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, staleId);
|
|
103599
|
+
this.db.query("UPDATE conversations SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, staleId);
|
|
103600
|
+
this.db.query("UPDATE conversation_read_cursors SET reader_node_id = ?1 WHERE reader_node_id = ?2").run(canonicalId, staleId);
|
|
103601
|
+
this.db.query("UPDATE messages SET origin_node_id = ?1 WHERE origin_node_id = ?2").run(canonicalId, staleId);
|
|
103602
|
+
this.db.query("UPDATE deliveries SET target_node_id = ?1 WHERE target_node_id = ?2").run(canonicalId, staleId);
|
|
103603
|
+
this.db.query("UPDATE invocations SET requester_node_id = ?1 WHERE requester_node_id = ?2").run(canonicalId, staleId);
|
|
103604
|
+
this.db.query("UPDATE invocations SET target_node_id = ?1 WHERE target_node_id = ?2").run(canonicalId, staleId);
|
|
103605
|
+
this.db.query("UPDATE thread_events SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, staleId);
|
|
103606
|
+
this.db.query("UPDATE thread_cursors SET authority_node_id = ?1 WHERE authority_node_id = ?2").run(canonicalId, staleId);
|
|
103607
|
+
this.db.query("UPDATE trusted_peers SET node_id = ?1 WHERE node_id = ?2").run(canonicalId, staleId);
|
|
103608
|
+
const delRes = this.db.query("DELETE FROM nodes WHERE id = ?1").run(staleId);
|
|
103609
|
+
if ((delRes.changes ?? 0) > 0) {
|
|
103610
|
+
prunedNodeCount++;
|
|
103611
|
+
rehomedNodeCount++;
|
|
103612
|
+
rehomedMappings.push({ from: staleId, to: canonicalId });
|
|
103613
|
+
}
|
|
103614
|
+
}
|
|
103615
|
+
for (const peer of peerRows) {
|
|
103616
|
+
if (peer.node_id) {
|
|
103617
|
+
const canonical2 = canonicalMeshNodeId(peer.node_id);
|
|
103618
|
+
if (canonical2 && canonical2 !== peer.node_id) {
|
|
103619
|
+
this.db.query("UPDATE trusted_peers SET node_id = ?1 WHERE key_id = ?2").run(canonical2, peer.key_id);
|
|
103620
|
+
}
|
|
103621
|
+
}
|
|
103622
|
+
}
|
|
102988
103623
|
const remainingNodes = this.db.query("SELECT * FROM nodes").all();
|
|
102989
103624
|
for (const row of remainingNodes) {
|
|
102990
103625
|
if (row.id === options.localNodeId)
|
|
@@ -105139,6 +105774,10 @@ class RecoverableSQLiteProjection {
|
|
|
105139
105774
|
queue = Promise.resolve();
|
|
105140
105775
|
closed = false;
|
|
105141
105776
|
lastUnavailableReason = null;
|
|
105777
|
+
warming = false;
|
|
105778
|
+
warmBoundaryReady = null;
|
|
105779
|
+
startupRecoveryInitiated = false;
|
|
105780
|
+
deferredStartupEvents = [];
|
|
105142
105781
|
constructor(dbPath, journal, options = {}) {
|
|
105143
105782
|
this.dbPath = dbPath;
|
|
105144
105783
|
this.journal = journal;
|
|
@@ -105154,21 +105793,57 @@ class RecoverableSQLiteProjection {
|
|
|
105154
105793
|
if (this.store) {
|
|
105155
105794
|
return { state: "ready", detail: null };
|
|
105156
105795
|
}
|
|
105796
|
+
if (this.warming) {
|
|
105797
|
+
return {
|
|
105798
|
+
state: "warming",
|
|
105799
|
+
detail: "SQLite activity projection is rebuilding from the broker journal."
|
|
105800
|
+
};
|
|
105801
|
+
}
|
|
105157
105802
|
return {
|
|
105158
105803
|
state: "degraded",
|
|
105159
105804
|
detail: this.lastUnavailableReason ?? (this.closed ? "SQLite projection is closed." : "SQLite projection is not ready.")
|
|
105160
105805
|
};
|
|
105161
105806
|
}
|
|
105162
105807
|
warm() {
|
|
105808
|
+
if (this.options.disabled || this.closed || this.store || this.warming) {
|
|
105809
|
+
return this.warmBoundaryReady ?? Promise.resolve();
|
|
105810
|
+
}
|
|
105811
|
+
this.startupRecoveryInitiated = true;
|
|
105812
|
+
const deferredStartupEvents = this.deferredStartupEvents.splice(0);
|
|
105813
|
+
this.warming = true;
|
|
105814
|
+
let resolveBoundary = () => {};
|
|
105815
|
+
let rejectBoundary = () => {};
|
|
105816
|
+
let boundaryCaptured = false;
|
|
105817
|
+
this.warmBoundaryReady = new Promise((resolve16, reject) => {
|
|
105818
|
+
resolveBoundary = resolve16;
|
|
105819
|
+
rejectBoundary = reject;
|
|
105820
|
+
});
|
|
105163
105821
|
this.enqueue(async () => {
|
|
105164
|
-
|
|
105822
|
+
try {
|
|
105823
|
+
await this.ensureStore(() => {
|
|
105824
|
+
boundaryCaptured = true;
|
|
105825
|
+
resolveBoundary();
|
|
105826
|
+
});
|
|
105827
|
+
} finally {
|
|
105828
|
+
this.warming = false;
|
|
105829
|
+
if (!boundaryCaptured) {
|
|
105830
|
+
rejectBoundary(new Error(this.lastUnavailableReason ?? "SQLite projection replay boundary could not be established."));
|
|
105831
|
+
}
|
|
105832
|
+
}
|
|
105165
105833
|
});
|
|
105834
|
+
for (const event of deferredStartupEvents) {
|
|
105835
|
+
this.enqueueEvent(event);
|
|
105836
|
+
}
|
|
105837
|
+
return this.warmBoundaryReady;
|
|
105166
105838
|
}
|
|
105167
105839
|
enqueueEntries(entriesInput) {
|
|
105168
105840
|
const entries = normalizeEntries(entriesInput);
|
|
105169
105841
|
if (entries.length === 0 || this.options.disabled || this.closed) {
|
|
105170
105842
|
return;
|
|
105171
105843
|
}
|
|
105844
|
+
if (!this.startupRecoveryInitiated) {
|
|
105845
|
+
return;
|
|
105846
|
+
}
|
|
105172
105847
|
this.enqueue(async () => {
|
|
105173
105848
|
const store = await this.ensureStore();
|
|
105174
105849
|
if (!store) {
|
|
@@ -105192,6 +105867,10 @@ class RecoverableSQLiteProjection {
|
|
|
105192
105867
|
if (this.options.disabled || this.closed) {
|
|
105193
105868
|
return;
|
|
105194
105869
|
}
|
|
105870
|
+
if (!this.startupRecoveryInitiated) {
|
|
105871
|
+
this.deferredStartupEvents.push(event);
|
|
105872
|
+
return;
|
|
105873
|
+
}
|
|
105195
105874
|
this.enqueue(async () => {
|
|
105196
105875
|
const store = await this.ensureStore();
|
|
105197
105876
|
if (!store) {
|
|
@@ -105369,7 +106048,7 @@ class RecoverableSQLiteProjection {
|
|
|
105369
106048
|
this.queue = next.then(() => {}, () => {});
|
|
105370
106049
|
return next;
|
|
105371
106050
|
}
|
|
105372
|
-
async replayJournal(visitor) {
|
|
106051
|
+
async replayJournal(visitor, boundary) {
|
|
105373
106052
|
const configuredBatchSize = this.options.replayYieldEvery ?? DEFAULT_REPLAY_YIELD_EVERY;
|
|
105374
106053
|
const batchSize = Math.max(1, Math.floor(configuredBatchSize));
|
|
105375
106054
|
let visited = 0;
|
|
@@ -105379,22 +106058,27 @@ class RecoverableSQLiteProjection {
|
|
|
105379
106058
|
if (visited % batchSize === 0) {
|
|
105380
106059
|
await new Promise((resolve16) => setImmediate(resolve16));
|
|
105381
106060
|
}
|
|
105382
|
-
});
|
|
106061
|
+
}, boundary);
|
|
105383
106062
|
}
|
|
105384
|
-
async ensureStore() {
|
|
106063
|
+
async ensureStore(onReplayBoundaryCaptured) {
|
|
105385
106064
|
if (this.options.disabled || this.closed) {
|
|
105386
106065
|
return null;
|
|
105387
106066
|
}
|
|
106067
|
+
if (!this.startupRecoveryInitiated) {
|
|
106068
|
+
return null;
|
|
106069
|
+
}
|
|
105388
106070
|
if (this.store) {
|
|
105389
106071
|
return this.store;
|
|
105390
106072
|
}
|
|
105391
106073
|
try {
|
|
106074
|
+
const replayBoundary = await this.journal.captureReplayBoundary();
|
|
106075
|
+
onReplayBoundaryCaptured?.();
|
|
105392
106076
|
const createStore = this.options.createStore ?? ((dbPath) => new SQLiteControlPlaneStore(dbPath));
|
|
105393
106077
|
const store = createStore(this.dbPath);
|
|
105394
106078
|
const parents = createReplayParentScan();
|
|
105395
106079
|
await this.replayJournal((entry) => {
|
|
105396
106080
|
collectReplayParents(parents, entry);
|
|
105397
|
-
});
|
|
106081
|
+
}, replayBoundary);
|
|
105398
106082
|
prepareReplayParents(store, parents);
|
|
105399
106083
|
await this.replayJournal((entry) => {
|
|
105400
106084
|
try {
|
|
@@ -105408,7 +106092,7 @@ class RecoverableSQLiteProjection {
|
|
|
105408
106092
|
}
|
|
105409
106093
|
reportSkippedEntry(entry, error48);
|
|
105410
106094
|
}
|
|
105411
|
-
});
|
|
106095
|
+
}, replayBoundary);
|
|
105412
106096
|
this.store = store;
|
|
105413
106097
|
this.lastUnavailableReason = null;
|
|
105414
106098
|
return store;
|
|
@@ -106300,6 +106984,7 @@ function createBrokerCoreService(deps) {
|
|
|
106300
106984
|
build: deps.build ?? loadOpenScoutRuntimeBuildIdentity(),
|
|
106301
106985
|
services: deps.readChildServices?.(),
|
|
106302
106986
|
...deps.readProjectionStatus ? { projection: deps.readProjectionStatus() } : {},
|
|
106987
|
+
...deps.readStartupStatus ? { startup: deps.readStartupStatus() } : {},
|
|
106303
106988
|
counts: {
|
|
106304
106989
|
nodes: Object.keys(snapshot.nodes).length,
|
|
106305
106990
|
actors: Object.keys(snapshot.actors).length,
|
|
@@ -110713,6 +111398,9 @@ class BrokerLocalEndpointResolver {
|
|
|
110713
111398
|
if (revived)
|
|
110714
111399
|
return revived;
|
|
110715
111400
|
} catch (error48) {
|
|
111401
|
+
if (isCodexThreadHeldExternallyError(error48)) {
|
|
111402
|
+
throw error48;
|
|
111403
|
+
}
|
|
110716
111404
|
await this.options.persistEndpoint({
|
|
110717
111405
|
...endpoint,
|
|
110718
111406
|
state: "offline",
|
|
@@ -110920,6 +111608,7 @@ function isWakeableSessionBackedEndpoint(endpoint) {
|
|
|
110920
111608
|
}
|
|
110921
111609
|
|
|
110922
111610
|
// packages/runtime/src/broker-local-invocation-service.ts
|
|
111611
|
+
var HELD_THREAD_RETRY_DELAY_MS = 30000;
|
|
110923
111612
|
function executionResolutionWithObservedEndpoint(resolution, endpoint, fallbackObservedAt) {
|
|
110924
111613
|
if (!resolution) {
|
|
110925
111614
|
return null;
|
|
@@ -111008,6 +111697,23 @@ class BrokerLocalInvocationService {
|
|
|
111008
111697
|
endpoint = await this.options.endpointResolver.prepareLocalEndpointForInvocation(endpoint);
|
|
111009
111698
|
}
|
|
111010
111699
|
} catch (error48) {
|
|
111700
|
+
if (isCodexThreadHeldExternallyError(error48)) {
|
|
111701
|
+
const checkedAt = this.now();
|
|
111702
|
+
await this.options.transitionInvocation(invocation.id, {
|
|
111703
|
+
state: "queued",
|
|
111704
|
+
summary: `${target2.displayName}'s Codex thread is open in another app. Message stored; will deliver when the thread is released.`,
|
|
111705
|
+
metadata: {
|
|
111706
|
+
dispatchOutcome: {
|
|
111707
|
+
status: "queued_until_online",
|
|
111708
|
+
reason: "thread_held_externally",
|
|
111709
|
+
checkedAt
|
|
111710
|
+
},
|
|
111711
|
+
heldThreadId: error48.threadId
|
|
111712
|
+
}
|
|
111713
|
+
});
|
|
111714
|
+
this.options.deferInvocationRetry?.(invocation.id, checkedAt + HELD_THREAD_RETRY_DELAY_MS);
|
|
111715
|
+
return;
|
|
111716
|
+
}
|
|
111011
111717
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
111012
111718
|
const failedFlight = await this.options.transitionInvocation(invocation.id, {
|
|
111013
111719
|
state: "failed",
|
|
@@ -111345,6 +112051,36 @@ class BrokerLocalInvocationService {
|
|
|
111345
112051
|
}
|
|
111346
112052
|
return;
|
|
111347
112053
|
}
|
|
112054
|
+
if (isCodexThreadHeldExternallyError(error48)) {
|
|
112055
|
+
const checkedAt = this.now();
|
|
112056
|
+
if (!this.currentFlightIsTerminal(invocation.id)) {
|
|
112057
|
+
await this.options.transitionInvocation(invocation.id, {
|
|
112058
|
+
state: "queued",
|
|
112059
|
+
summary: `${target2.displayName}'s Codex thread is open in another app. Message stored; will deliver when the thread is released.`,
|
|
112060
|
+
error: undefined,
|
|
112061
|
+
completedAt: undefined,
|
|
112062
|
+
metadata: {
|
|
112063
|
+
dispatchOutcome: {
|
|
112064
|
+
status: "queued_until_online",
|
|
112065
|
+
reason: "thread_held_externally",
|
|
112066
|
+
checkedAt
|
|
112067
|
+
},
|
|
112068
|
+
heldThreadId: error48.threadId
|
|
112069
|
+
}
|
|
112070
|
+
});
|
|
112071
|
+
}
|
|
112072
|
+
this.options.deferInvocationRetry?.(invocation.id, checkedAt + HELD_THREAD_RETRY_DELAY_MS);
|
|
112073
|
+
await this.options.persistEndpoint({
|
|
112074
|
+
...runningEndpoint,
|
|
112075
|
+
state: priorEndpointState,
|
|
112076
|
+
metadata: {
|
|
112077
|
+
...runningEndpoint.metadata ?? {},
|
|
112078
|
+
lastNotice: message,
|
|
112079
|
+
threadHeldExternallyAt: checkedAt
|
|
112080
|
+
}
|
|
112081
|
+
});
|
|
112082
|
+
return;
|
|
112083
|
+
}
|
|
111348
112084
|
const failedFlight = this.currentFlightIsTerminal(invocation.id) ? null : await this.options.transitionInvocation(invocation.id, {
|
|
111349
112085
|
state: "failed",
|
|
111350
112086
|
summary: `${target2.displayName} failed to respond.`,
|
|
@@ -111578,7 +112314,7 @@ function resolveProjectProvisionalAgentName(input) {
|
|
|
111578
112314
|
}
|
|
111579
112315
|
|
|
111580
112316
|
// packages/runtime/src/session-locator.ts
|
|
111581
|
-
import { existsSync as existsSync45, readdirSync as readdirSync14, readFileSync as readFileSync26, statSync as
|
|
112317
|
+
import { existsSync as existsSync45, readdirSync as readdirSync14, readFileSync as readFileSync26, statSync as statSync16 } from "fs";
|
|
111582
112318
|
import { homedir as homedir38 } from "os";
|
|
111583
112319
|
import { basename as basename23, join as join55, resolve as resolve21 } from "path";
|
|
111584
112320
|
var CODEX_HARNESS = "codex";
|
|
@@ -111595,7 +112331,7 @@ function pathExists4(path7) {
|
|
|
111595
112331
|
}
|
|
111596
112332
|
function safeStatMtimeMs(path7) {
|
|
111597
112333
|
try {
|
|
111598
|
-
return
|
|
112334
|
+
return statSync16(path7).mtimeMs;
|
|
111599
112335
|
} catch {
|
|
111600
112336
|
return 0;
|
|
111601
112337
|
}
|
|
@@ -111615,7 +112351,7 @@ function walkFiles(root, predicate, into = [], depth = 0) {
|
|
|
111615
112351
|
const full = join55(root, name2);
|
|
111616
112352
|
let isDir = false;
|
|
111617
112353
|
try {
|
|
111618
|
-
isDir =
|
|
112354
|
+
isDir = statSync16(full).isDirectory();
|
|
111619
112355
|
} catch {
|
|
111620
112356
|
continue;
|
|
111621
112357
|
}
|
|
@@ -112168,7 +112904,7 @@ function throwIfAborted2(signal) {
|
|
|
112168
112904
|
}
|
|
112169
112905
|
function json2(response, status, payload) {
|
|
112170
112906
|
response.writeHead(status, { "content-type": "application/json; charset=utf-8" });
|
|
112171
|
-
response.end(JSON.stringify(payload
|
|
112907
|
+
response.end(JSON.stringify(payload));
|
|
112172
112908
|
}
|
|
112173
112909
|
function a2aJson(response, status, payload, headers = {}) {
|
|
112174
112910
|
response.writeHead(status, {
|
|
@@ -112176,14 +112912,14 @@ function a2aJson(response, status, payload, headers = {}) {
|
|
|
112176
112912
|
...headers,
|
|
112177
112913
|
"content-type": `${A2A_JSON_RPC_CONTENT_TYPE}; charset=utf-8`
|
|
112178
112914
|
});
|
|
112179
|
-
response.end(JSON.stringify(payload
|
|
112915
|
+
response.end(JSON.stringify(payload));
|
|
112180
112916
|
}
|
|
112181
112917
|
function jsonWithHeaders(response, status, payload, headers) {
|
|
112182
112918
|
response.writeHead(status, {
|
|
112183
112919
|
...headers,
|
|
112184
112920
|
"content-type": "application/json; charset=utf-8"
|
|
112185
112921
|
});
|
|
112186
|
-
response.end(JSON.stringify(payload
|
|
112922
|
+
response.end(JSON.stringify(payload));
|
|
112187
112923
|
}
|
|
112188
112924
|
var MAX_SERVER_TIMING_HEADER_LENGTH = 2048;
|
|
112189
112925
|
var TRUNCATED_SERVER_TIMING_HEADER = 'server-timing-truncated;desc="oversize"';
|
|
@@ -114710,7 +115446,10 @@ function createBrokerHttpRouter(deps) {
|
|
|
114710
115446
|
return;
|
|
114711
115447
|
}
|
|
114712
115448
|
if (method === "GET" && (url2.pathname === "/v1/snapshot" || url2.pathname === "/v1/mesh/snapshot")) {
|
|
114713
|
-
json2(response, 200, await brokerService.readSnapshot({
|
|
115449
|
+
json2(response, 200, await brokerService.readSnapshot({
|
|
115450
|
+
since: parseSince(url2),
|
|
115451
|
+
scope: url2.searchParams.get("scope") === "conversations" ? "conversations" : undefined
|
|
115452
|
+
}));
|
|
114714
115453
|
return;
|
|
114715
115454
|
}
|
|
114716
115455
|
if (method === "GET" && url2.pathname === "/v1/capabilities/availability") {
|
|
@@ -116016,6 +116755,28 @@ async function discoverMeshNodes(options) {
|
|
|
116016
116755
|
};
|
|
116017
116756
|
}
|
|
116018
116757
|
|
|
116758
|
+
// packages/runtime/src/mesh-peer-filter.ts
|
|
116759
|
+
var MESH_PEER_STALE_MS = 24 * 60 * 60 * 1000;
|
|
116760
|
+
function isCurrentMeshPeerNode(node, options) {
|
|
116761
|
+
if (!node.brokerUrl?.trim())
|
|
116762
|
+
return false;
|
|
116763
|
+
if (node.id === options.localNodeId)
|
|
116764
|
+
return false;
|
|
116765
|
+
if (node.advertiseScope !== "mesh")
|
|
116766
|
+
return false;
|
|
116767
|
+
const meshId = options.meshId;
|
|
116768
|
+
if (meshId && node.meshId !== meshId)
|
|
116769
|
+
return false;
|
|
116770
|
+
const now = options.now ?? Date.now();
|
|
116771
|
+
const lastSeen = node.lastSeenAt ?? node.registeredAt ?? 0;
|
|
116772
|
+
if (lastSeen > 0 && now - lastSeen > MESH_PEER_STALE_MS)
|
|
116773
|
+
return false;
|
|
116774
|
+
return true;
|
|
116775
|
+
}
|
|
116776
|
+
function collectCurrentMeshPeerNodes(input) {
|
|
116777
|
+
return Object.values(input.nodes).filter((node) => isCurrentMeshPeerNode(node, input));
|
|
116778
|
+
}
|
|
116779
|
+
|
|
116019
116780
|
// packages/runtime/src/broker-mesh-discovery-service.ts
|
|
116020
116781
|
function isNodeLocalProductAgentId(agentId, productAgentIds) {
|
|
116021
116782
|
return productAgentIds.has(agentId.trim().toLowerCase());
|
|
@@ -116074,9 +116835,11 @@ class BrokerMeshDiscoveryService {
|
|
|
116074
116835
|
const peersToSync = new Map;
|
|
116075
116836
|
for (const node of discovered)
|
|
116076
116837
|
peersToSync.set(node.id, node);
|
|
116077
|
-
for (const node of
|
|
116078
|
-
|
|
116079
|
-
|
|
116838
|
+
for (const node of collectCurrentMeshPeerNodes({
|
|
116839
|
+
nodes: this.deps.runtime.snapshot().nodes,
|
|
116840
|
+
localNodeId: this.deps.nodeId,
|
|
116841
|
+
meshId: this.deps.meshId
|
|
116842
|
+
})) {
|
|
116080
116843
|
peersToSync.set(node.id, node);
|
|
116081
116844
|
}
|
|
116082
116845
|
for (const node of peersToSync.values()) {
|
|
@@ -117185,14 +117948,28 @@ class BrokerCommandService {
|
|
|
117185
117948
|
class BrokerDispatchRecoveryService {
|
|
117186
117949
|
deps;
|
|
117187
117950
|
#recoveringInvocationIds = new Set;
|
|
117951
|
+
#deferredInvocations = new Map;
|
|
117188
117952
|
constructor(deps) {
|
|
117189
117953
|
this.deps = deps;
|
|
117190
117954
|
}
|
|
117955
|
+
deferInvocation(invocationId, notBeforeTs) {
|
|
117956
|
+
this.#deferredInvocations.set(invocationId, notBeforeTs);
|
|
117957
|
+
}
|
|
117958
|
+
#isDeferred(invocationId, now) {
|
|
117959
|
+
const notBefore = this.#deferredInvocations.get(invocationId);
|
|
117960
|
+
if (notBefore === undefined)
|
|
117961
|
+
return false;
|
|
117962
|
+
if (now >= notBefore) {
|
|
117963
|
+
this.#deferredInvocations.delete(invocationId);
|
|
117964
|
+
return false;
|
|
117965
|
+
}
|
|
117966
|
+
return true;
|
|
117967
|
+
}
|
|
117191
117968
|
async recoverQueuedFlights(input) {
|
|
117192
117969
|
const now = this.deps.now?.() ?? Date.now();
|
|
117193
|
-
const jobs = this.deps.dispatchJobs().filter((job) => isInvocationDispatchJobDue(job, now, { includeRunning: true })).filter((job) => !input.agentId || job.targetAgentId === input.agentId).sort((left, right) => left.createdAt - right.createdAt);
|
|
117970
|
+
const jobs = this.deps.dispatchJobs().filter((job) => isInvocationDispatchJobDue(job, now, { includeRunning: true })).filter((job) => !input.agentId || job.targetAgentId === input.agentId).filter((job) => !this.#isDeferred(job.invocationId, now)).sort((left, right) => left.createdAt - right.createdAt);
|
|
117194
117971
|
const jobInvocationIds = new Set(jobs.map((job) => job.invocationId));
|
|
117195
|
-
const queued = Object.values(this.deps.runtimeSnapshot().flights).filter((flight) => flight.state === "queued" || flight.state === "waking").filter((flight) => !input.agentId || flight.targetAgentId === input.agentId).filter((flight) => !jobInvocationIds.has(flight.invocationId)).sort((left, right) => flightSortTime(left) - flightSortTime(right));
|
|
117972
|
+
const queued = Object.values(this.deps.runtimeSnapshot().flights).filter((flight) => flight.state === "queued" || flight.state === "waking").filter((flight) => !input.agentId || flight.targetAgentId === input.agentId).filter((flight) => !jobInvocationIds.has(flight.invocationId)).filter((flight) => !this.#isDeferred(flight.invocationId, now)).sort((left, right) => flightSortTime(left) - flightSortTime(right));
|
|
117196
117973
|
const result = {
|
|
117197
117974
|
considered: jobs.length + queued.length,
|
|
117198
117975
|
dispatched: 0,
|
|
@@ -117259,10 +118036,14 @@ class BrokerHomeService {
|
|
|
117259
118036
|
}
|
|
117260
118037
|
async read() {
|
|
117261
118038
|
const snapshot = this.#deps.runtimeSnapshot();
|
|
118039
|
+
const projectionStatus = this.#deps.projectionStatus?.() ?? { state: "ready" };
|
|
118040
|
+
const projectionReady = projectionStatus.state === "ready";
|
|
117262
118041
|
return {
|
|
117263
118042
|
updatedAt: this.#now(),
|
|
117264
118043
|
agents: this.#agents(snapshot),
|
|
117265
|
-
activity: this.#activity(snapshot, await this.#deps.listActivityItems({ limit: 96 }))
|
|
118044
|
+
activity: projectionReady ? this.#activity(snapshot, await this.#deps.listActivityItems({ limit: 96 })) : this.#runtimeActivity(snapshot),
|
|
118045
|
+
activitySource: projectionReady ? "sqlite_projection" : "runtime_snapshot",
|
|
118046
|
+
activityState: projectionStatus.state
|
|
117266
118047
|
};
|
|
117267
118048
|
}
|
|
117268
118049
|
#agents(snapshot) {
|
|
@@ -117302,6 +118083,22 @@ class BrokerHomeService {
|
|
|
117302
118083
|
};
|
|
117303
118084
|
});
|
|
117304
118085
|
}
|
|
118086
|
+
#runtimeActivity(snapshot) {
|
|
118087
|
+
return Object.values(snapshot.messages).sort((left, right) => right.createdAt - left.createdAt || right.id.localeCompare(left.id)).slice(0, 24).map((message) => {
|
|
118088
|
+
const actorName = this.#deps.actorDisplayName(snapshot, message.actorId);
|
|
118089
|
+
return {
|
|
118090
|
+
id: message.id,
|
|
118091
|
+
kind: message.class === "system" || message.class === "status" || message.class === "log" ? "system" : "message",
|
|
118092
|
+
actorId: message.actorId,
|
|
118093
|
+
actorName,
|
|
118094
|
+
title: actorName,
|
|
118095
|
+
detail: message.body || null,
|
|
118096
|
+
conversationId: message.conversationId,
|
|
118097
|
+
channel: brokerConversationChannel(snapshot, message.conversationId),
|
|
118098
|
+
timestamp: message.createdAt
|
|
118099
|
+
};
|
|
118100
|
+
});
|
|
118101
|
+
}
|
|
117305
118102
|
#now() {
|
|
117306
118103
|
return this.#deps.now?.() ?? Date.now();
|
|
117307
118104
|
}
|
|
@@ -118488,7 +119285,9 @@ var relayAgentSweepIntervalMs = Number.parseInt(process.env.OPENSCOUT_RELAY_AGEN
|
|
|
118488
119285
|
var relayAgentIdleTtlMs = Number.parseInt(process.env.OPENSCOUT_RELAY_AGENT_IDLE_TTL_MS ?? String(DEFAULT_RELAY_AGENT_SESSION_IDLE_TTL_MS), 10);
|
|
118489
119286
|
var runtimeHeartbeatIntervalMs = 30000;
|
|
118490
119287
|
var repoWatchServeCacheTtlMs = Number.parseInt(process.env.OPENSCOUT_REPO_WATCH_CACHE_TTL_MS ?? "1200000", 10);
|
|
119288
|
+
var tailRecentServeCacheTtlMs = Number.parseInt(process.env.OPENSCOUT_TAIL_RECENT_SERVE_CACHE_TTL_MS ?? "4000", 10);
|
|
118491
119289
|
var repoWatchRehydrateAfterMs = Number.parseInt(process.env.OPENSCOUT_REPO_WATCH_REHYDRATE_AFTER_MS ?? "30000", 10);
|
|
119290
|
+
var startupBoundaryTestDelayMs = Number.parseInt(process.env.OPENSCOUT_TEST_STARTUP_BOUNDARY_DELAY_MS ?? "0", 10);
|
|
118492
119291
|
var meshGateMode = resolveMeshGateMode(process.env);
|
|
118493
119292
|
ensureOpenScoutCleanSlateSync();
|
|
118494
119293
|
var existingBroker = await probeExistingBroker();
|
|
@@ -118504,7 +119303,7 @@ nodeId = resolveStableLocalNodeId({
|
|
|
118504
119303
|
supportDirectory
|
|
118505
119304
|
});
|
|
118506
119305
|
var journal = new FileBackedBrokerJournal(journalPath);
|
|
118507
|
-
await journal.load();
|
|
119306
|
+
var journalLoadReport = await journal.load();
|
|
118508
119307
|
var initialSnapshot = journal.snapshot();
|
|
118509
119308
|
assertNoReservedStoredAgentNames(initialSnapshot.agents, { localNodeId: nodeId });
|
|
118510
119309
|
var sqliteDisabled = process.env.OPENSCOUT_DISABLE_SQLITE === "1";
|
|
@@ -118514,6 +119313,8 @@ if (!sqliteDisabled) {
|
|
|
118514
119313
|
await mkdir14(dirname33(dbPath2), { recursive: true });
|
|
118515
119314
|
}
|
|
118516
119315
|
var projection = new RecoverableSQLiteProjection(dbPath2, journal, { disabled: sqliteDisabled });
|
|
119316
|
+
var projectionWarmStarted = false;
|
|
119317
|
+
var bootstrapProjectionOptions = () => projectionWarmStarted ? undefined : { enqueueProjection: false };
|
|
118517
119318
|
var routeAliasDatabase = sqliteDisabled ? null : openControlPlaneSqliteDatabase(dbPath2, { create: true });
|
|
118518
119319
|
if (routeAliasDatabase) {
|
|
118519
119320
|
configureControlPlaneDatabase(routeAliasDatabase);
|
|
@@ -119050,7 +119851,7 @@ async function migrateUnqualifiedRelayAgentKeys() {
|
|
|
119050
119851
|
async function readRelayAgentRegistrySignature() {
|
|
119051
119852
|
try {
|
|
119052
119853
|
const registryPath = resolveOpenScoutSupportPaths().relayAgentsRegistryPath;
|
|
119053
|
-
const info = await
|
|
119854
|
+
const info = await stat8(registryPath);
|
|
119054
119855
|
const contents = await readFile15(registryPath);
|
|
119055
119856
|
const hash2 = createHash16("sha256").update(contents).digest("base64url");
|
|
119056
119857
|
return `${info.mtimeMs}:${info.size}:${hash2}`;
|
|
@@ -119330,6 +120131,7 @@ var localInvocationService = new BrokerLocalInvocationService({
|
|
|
119330
120131
|
createId: createRuntimeId2,
|
|
119331
120132
|
transitionInvocation,
|
|
119332
120133
|
persistEndpoint,
|
|
120134
|
+
deferInvocationRetry: (invocationId, notBeforeTs) => dispatchRecoveryService.deferInvocation(invocationId, notBeforeTs),
|
|
119333
120135
|
postInvocationStatusMessage,
|
|
119334
120136
|
postConversationMessage,
|
|
119335
120137
|
existingBrokerReplyForInvocation,
|
|
@@ -119696,9 +120498,11 @@ var deliveryAcceptanceService = new BrokerDeliveryAcceptanceService({
|
|
|
119696
120498
|
queueOperatorSignal: (input) => operatorAttentionService.queueOperatorSignal(input),
|
|
119697
120499
|
warn: (message, detail) => console.warn(message, detail)
|
|
119698
120500
|
});
|
|
120501
|
+
var startupTrafficGate = new BrokerStartupTrafficGate;
|
|
119699
120502
|
var homeService = new BrokerHomeService({
|
|
119700
120503
|
runtimeSnapshot: () => runtime.snapshot(),
|
|
119701
120504
|
listActivityItems: (options) => projection.listActivityItems(options),
|
|
120505
|
+
projectionStatus: () => projection.statusSnapshot(),
|
|
119702
120506
|
actorDisplayName: brokerActorDisplayName2,
|
|
119703
120507
|
operatorActorId
|
|
119704
120508
|
});
|
|
@@ -119714,6 +120518,7 @@ var brokerService = createBrokerCoreService({
|
|
|
119714
120518
|
isReconciledStaleFlightActivityItem,
|
|
119715
120519
|
readChildServices: () => webControl.readChildServiceSnapshots(),
|
|
119716
120520
|
readProjectionStatus: () => projection.statusSnapshot(),
|
|
120521
|
+
readStartupStatus: () => startupTrafficGate.snapshot(),
|
|
119717
120522
|
readHome: () => homeService.read(),
|
|
119718
120523
|
readCapabilities: readBrokerCapabilityMatrixSnapshot,
|
|
119719
120524
|
readRuntimeCatalog: readBrokerRuntimeCatalogSnapshot,
|
|
@@ -119732,9 +120537,9 @@ var brokerRepoTailService = new BrokerRepoTailService({
|
|
|
119732
120537
|
readRecentTranscriptEvents,
|
|
119733
120538
|
repoWatchServeCacheTtlMs,
|
|
119734
120539
|
repoWatchRehydrateAfterMs,
|
|
120540
|
+
tailRecentServeCacheTtlMs,
|
|
119735
120541
|
warn: (message) => console.warn(message)
|
|
119736
120542
|
});
|
|
119737
|
-
registerActiveScoutBrokerService(brokerService);
|
|
119738
120543
|
var rendezvousService = new BrokerRendezvousService;
|
|
119739
120544
|
var routeRequest = createBrokerHttpRouter({
|
|
119740
120545
|
host,
|
|
@@ -119878,12 +120683,7 @@ function openRolesControlPlaneDb() {
|
|
|
119878
120683
|
}
|
|
119879
120684
|
function createBrokerHttpServer() {
|
|
119880
120685
|
return createServer((request, response) => {
|
|
119881
|
-
meshIngressGate.gateHttpRequest(request, response, (gatedRequest) =>
|
|
119882
|
-
json2(response, 500, {
|
|
119883
|
-
error: "internal_error",
|
|
119884
|
-
detail: error48 instanceof Error ? error48.message : String(error48)
|
|
119885
|
-
});
|
|
119886
|
-
})).catch((error48) => {
|
|
120686
|
+
meshIngressGate.gateHttpRequest(request, response, (gatedRequest) => routeBrokerHttpRequest(gatedRequest, response)).catch((error48) => {
|
|
119887
120687
|
json2(response, 500, {
|
|
119888
120688
|
error: "internal_error",
|
|
119889
120689
|
detail: error48 instanceof Error ? error48.message : String(error48)
|
|
@@ -119891,6 +120691,22 @@ function createBrokerHttpServer() {
|
|
|
119891
120691
|
});
|
|
119892
120692
|
});
|
|
119893
120693
|
}
|
|
120694
|
+
async function routeBrokerHttpRequest(request, response) {
|
|
120695
|
+
if (!startupTrafficGate.admits(request.method, request.url ?? "/")) {
|
|
120696
|
+
json2(response, 503, {
|
|
120697
|
+
error: "broker_restoring",
|
|
120698
|
+
detail: "Recovery reads are available; this route will resume after the startup projection boundary is established.",
|
|
120699
|
+
retryable: true
|
|
120700
|
+
});
|
|
120701
|
+
return;
|
|
120702
|
+
}
|
|
120703
|
+
await routeRequest(request, response).catch((error48) => {
|
|
120704
|
+
json2(response, 500, {
|
|
120705
|
+
error: "internal_error",
|
|
120706
|
+
detail: error48 instanceof Error ? error48.message : String(error48)
|
|
120707
|
+
});
|
|
120708
|
+
});
|
|
120709
|
+
}
|
|
119894
120710
|
var server = createBrokerHttpServer();
|
|
119895
120711
|
var socketServer = createBrokerHttpServer();
|
|
119896
120712
|
server.on("close", () => {
|
|
@@ -119923,12 +120739,7 @@ var secretRedaction = await bootstrapSecretRedaction({ patchConsole: true });
|
|
|
119923
120739
|
console.log(`[openscout-runtime] secret redaction armed (${secretRedaction.registered} value(s)${secretRedaction.schemaPath ? `, schema ${secretRedaction.schemaPath}` : ", no .env.schema found"})`);
|
|
119924
120740
|
try {
|
|
119925
120741
|
let handleBrokerHttp = function(request, response) {
|
|
119926
|
-
meshIngressGate.gateHttpRequest(request, response, (gatedRequest) =>
|
|
119927
|
-
json2(response, 500, {
|
|
119928
|
-
error: "internal_error",
|
|
119929
|
-
detail: error48 instanceof Error ? error48.message : String(error48)
|
|
119930
|
-
});
|
|
119931
|
-
})).catch((error48) => {
|
|
120742
|
+
meshIngressGate.gateHttpRequest(request, response, (gatedRequest) => routeBrokerHttpRequest(gatedRequest, response)).catch((error48) => {
|
|
119932
120743
|
json2(response, 500, {
|
|
119933
120744
|
error: "internal_error",
|
|
119934
120745
|
detail: error48 instanceof Error ? error48.message : String(error48)
|
|
@@ -119939,8 +120750,7 @@ try {
|
|
|
119939
120750
|
console.log(`[openscout-runtime] secret redaction armed (${secretRedaction2.registered} value(s)${secretRedaction2.schemaPath ? `, schema ${secretRedaction2.schemaPath}` : ", no .env.schema found"})`);
|
|
119940
120751
|
await listenTcp(server, { host: isLoopbackHost(host) || host === "0.0.0.0" || host === "::" ? "127.0.0.1" : host, port });
|
|
119941
120752
|
await listenUnixSocket(socketServer, brokerSocketPath);
|
|
119942
|
-
|
|
119943
|
-
upsertNodeDurably(localNode).then(() => upsertActorDurably(systemActor)).catch((error48) => {
|
|
120753
|
+
const bootstrapIdentityWrite = upsertNodeDurably(localNode, bootstrapProjectionOptions()).then(() => upsertActorDurably(systemActor, bootstrapProjectionOptions())).catch((error48) => {
|
|
119944
120754
|
console.error("[openscout-runtime] bootstrap identity persistence failed:", error48);
|
|
119945
120755
|
});
|
|
119946
120756
|
meshBindController = createMeshBindController({
|
|
@@ -119956,7 +120766,7 @@ try {
|
|
|
119956
120766
|
brokerUrl = state.brokerUrl;
|
|
119957
120767
|
const nextNode = localNodeWithBindState(currentLocalNode(), state);
|
|
119958
120768
|
Object.assign(localNode, nextNode);
|
|
119959
|
-
await upsertNodeDurably(nextNode).catch((error48) => {
|
|
120769
|
+
await upsertNodeDurably(nextNode, bootstrapProjectionOptions()).catch((error48) => {
|
|
119960
120770
|
console.warn("[openscout-runtime] mesh bind: failed to update node registry:", error48);
|
|
119961
120771
|
});
|
|
119962
120772
|
await writeHostInfo().catch((error48) => {
|
|
@@ -119970,14 +120780,13 @@ try {
|
|
|
119970
120780
|
advertiseScope = state.scope;
|
|
119971
120781
|
brokerUrl = state.brokerUrl;
|
|
119972
120782
|
Object.assign(localNode, localNodeWithBindState(localNode, state));
|
|
119973
|
-
await upsertNodeDurably(localNode).catch(() => {
|
|
120783
|
+
await upsertNodeDurably(localNode, bootstrapProjectionOptions()).catch(() => {
|
|
119974
120784
|
return;
|
|
119975
120785
|
});
|
|
119976
120786
|
}
|
|
119977
120787
|
await writeHostInfo().catch((error48) => {
|
|
119978
120788
|
console.warn("[openscout-runtime] failed to write .host-info:", error48);
|
|
119979
120789
|
});
|
|
119980
|
-
peerDelivery.start();
|
|
119981
120790
|
const meshRendezvousConfig = resolveMeshRendezvousPublishConfig();
|
|
119982
120791
|
if (meshRendezvousConfig) {
|
|
119983
120792
|
meshRendezvousPublisher = startMeshRendezvousPublisher(currentRendezvousNode, {
|
|
@@ -119985,6 +120794,15 @@ try {
|
|
|
119985
120794
|
logger: console
|
|
119986
120795
|
});
|
|
119987
120796
|
}
|
|
120797
|
+
if (Number.isFinite(startupBoundaryTestDelayMs) && startupBoundaryTestDelayMs > 0) {
|
|
120798
|
+
await sleep3(startupBoundaryTestDelayMs);
|
|
120799
|
+
}
|
|
120800
|
+
await bootstrapIdentityWrite;
|
|
120801
|
+
projectionWarmStarted = true;
|
|
120802
|
+
await projection.warm();
|
|
120803
|
+
startupTrafficGate.admitMutations();
|
|
120804
|
+
registerActiveScoutBrokerService(brokerService);
|
|
120805
|
+
peerDelivery.start();
|
|
119988
120806
|
console.log(`[openscout-runtime] broker listening on 127.0.0.1:${port} (scope: ${advertiseScope}, url: ${brokerUrl})`);
|
|
119989
120807
|
console.log(`[openscout-runtime] broker local socket ${brokerSocketPath}`);
|
|
119990
120808
|
const bindState = meshBindController.getState();
|
|
@@ -119996,6 +120814,7 @@ try {
|
|
|
119996
120814
|
console.log(`[openscout-runtime] node ${nodeId} in mesh ${meshId}`);
|
|
119997
120815
|
console.log(`[openscout-runtime] mesh trust: keyId ${nodeIdentityKeyId} fingerprint ${nodeIdentityFingerprint} (gate: ${effectiveGateMode()})`);
|
|
119998
120816
|
console.log(`[openscout-runtime] journal ${journalPath}`);
|
|
120817
|
+
console.log(`[openscout-runtime] journal load ${journalLoadReport.totalMs}ms (scan ${journalLoadReport.scanMs}ms, compaction ${journalLoadReport.compactionMs}ms, ${journalLoadReport.validEntries} entries, ${journalLoadReport.sourceBytes} -> ${journalLoadReport.compactedBytes} bytes)`);
|
|
119999
120818
|
console.log(`[openscout-runtime] sqlite ${sqliteDisabled ? "disabled" : dbPath2}`);
|
|
120000
120819
|
} catch (error48) {
|
|
120001
120820
|
unregisterActiveScoutBrokerService(brokerService);
|
|
@@ -120091,6 +120910,11 @@ if (Number.isFinite(relayAgentSweepIntervalMs) && relayAgentSweepIntervalMs > 0)
|
|
|
120091
120910
|
setInterval(() => {
|
|
120092
120911
|
sweepAndCompactMeshNodes();
|
|
120093
120912
|
}, 900000).unref();
|
|
120913
|
+
setInterval(() => {
|
|
120914
|
+
dispatchRecoveryService.recoverQueuedFlights({ reason: "queued_retry_sweep" }).catch((error48) => {
|
|
120915
|
+
console.error("[openscout-runtime] queued dispatch retry sweep failed:", error48);
|
|
120916
|
+
});
|
|
120917
|
+
}, 60000).unref();
|
|
120094
120918
|
if (routeAliasService) {
|
|
120095
120919
|
setInterval(() => {
|
|
120096
120920
|
routeAliasService.sweepExpired();
|