@openscout/scout 0.2.84 → 0.2.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/README.md +1 -1
  2. package/bin/scoutd +0 -0
  3. package/dist/build-manifest.json +3 -3
  4. package/dist/client/assets/ActivityScreen-C7AwUogt.js +1 -0
  5. package/dist/client/assets/{AddProjectForm-Czb5uwou.js → AddProjectForm-BNRpRPod.js} +1 -1
  6. package/dist/client/assets/AgentAvatar-B1xvQ7ej.js +1 -0
  7. package/dist/client/assets/AgentConfigurationScreen-BoBQpyz5.js +1 -0
  8. package/dist/client/assets/AgentDefinitionsWorkspace-rw3vh8Lm.js +1 -0
  9. package/dist/client/assets/{AgentDetailCard-Biq8b2gv.js → AgentDetailCard-FelCxQrT.js} +1 -1
  10. package/dist/client/assets/AgentFloorView-Crdw8Uo5.js +1 -0
  11. package/dist/client/assets/AgentInfoScreen-Cge7HHbV.js +1 -0
  12. package/dist/client/assets/{AgentLaneCard-C4DMQR-c.js → AgentLaneCard-CRDG74C1.js} +1 -1
  13. package/dist/client/assets/{AgentLaneChrome-D1xNNf7A.js → AgentLaneChrome-CWFqUdch.js} +1 -1
  14. package/dist/client/assets/AgentLaneDetailSheet-DCIIg3Zp.js +4 -0
  15. package/dist/client/assets/{AgentLaneSummaryResize-C9loK-st.js → AgentLaneSummaryResize-yTM4GQAJ.js} +1 -1
  16. package/dist/client/assets/AgentLanesEmbedScreen-BJLwXSNp.js +1 -0
  17. package/dist/client/assets/{AgentLanesPreflight-M7iDXdP2.js → AgentLanesPreflight-DJeDRTAN.js} +1 -1
  18. package/dist/client/assets/AgentLanesView-CbY9qD0z.js +2 -0
  19. package/dist/client/assets/{AgentLiveActions-0iy8QZ1T.js → AgentLiveActions-Bn3zeZBN.js} +1 -1
  20. package/dist/client/assets/AgentSessions-czl5zT7A.js +6 -0
  21. package/dist/client/assets/AgentsConsole-CoT2crwq.js +1 -0
  22. package/dist/client/assets/{AgentsScreen-Bww6HgFs.js → AgentsScreen-BcPM-z1T.js} +1 -1
  23. package/dist/client/assets/AgentsSubnav-3_vpn2bT.js +1 -0
  24. package/dist/client/assets/AstronautSuit-BADl7m8x.js +1 -0
  25. package/dist/client/assets/{AtopView-h_aFoNkP.js → AtopView-DymBCiXv.js} +1 -1
  26. package/dist/client/assets/{BackToPicker-BXp5E2ck.js → BackToPicker-CqYhOaLB.js} +1 -1
  27. package/dist/client/assets/BriefingDetailScreen-DDfZ8ci1.js +1 -0
  28. package/dist/client/assets/{BriefingsScreen-BTsvr5fv.js → BriefingsScreen-CLvSOJjy.js} +1 -1
  29. package/dist/client/assets/{BrokerMetadataPanel-jg7odHQp.js → BrokerMetadataPanel-DFAH-NO6.js} +1 -1
  30. package/dist/client/assets/BrokerScreen-Bkvu92jk.js +5 -0
  31. package/dist/client/assets/{Canvas-BePL08RR.js → Canvas-KyTsDJlB.js} +1 -1
  32. package/dist/client/assets/ChatCollapsedStrip-Bjjqa30K.js +1 -0
  33. package/dist/client/assets/{CodeDiffPane-86odpBSt.js → CodeDiffPane-C9HT1dCT.js} +1 -1
  34. package/dist/client/assets/{CodeProjectPicker-8svr_S_A.js → CodeProjectPicker-5Y3GvXkM.js} +1 -1
  35. package/dist/client/assets/{CodeScreen-CJ2RgB32.js → CodeScreen-DpN9kQvm.js} +1 -1
  36. package/dist/client/assets/ConversationComposer-Ce7Byw48.js +1 -0
  37. package/dist/client/assets/ConversationFeedRows-DygDfQn_.js +1 -0
  38. package/dist/client/assets/ConversationHeader-C3sg0ULI.js +1 -0
  39. package/dist/client/assets/ConversationPanels-Dg4Y2GgX.js +6 -0
  40. package/dist/client/assets/ConversationScreen-BP5tdz2k.css +1 -0
  41. package/dist/client/assets/ConversationScreen-CjWWmuuh.js +1 -0
  42. package/dist/client/assets/ConversationStatus-BhVIYQza.js +1 -0
  43. package/dist/client/assets/CrewWorkspaces-B6YIyw1z.css +1 -0
  44. package/dist/client/assets/CrewWorkspaces-CDU-wy1Y.js +1 -0
  45. package/dist/client/assets/{DataTable-CGw5CECG.js → DataTable-oJP339bX.js} +1 -1
  46. package/dist/client/assets/{DispatchAftermath-DowTb7uO.js → DispatchAftermath-CH02HAVw.js} +1 -1
  47. package/dist/client/assets/DocumentFocusViewer-DmtFisY9.js +1 -0
  48. package/dist/client/assets/{EmbeddableSurfacesLab-CxfJXS2g.js → EmbeddableSurfacesLab-84b9I3fy.js} +1 -1
  49. package/dist/client/assets/{EmptyState-BUvllvA6.js → EmptyState-BnDda92b.js} +1 -1
  50. package/dist/client/assets/{FileViewerPane-BM4AD_bo.js → FileViewerPane-Dg7_88pv.js} +1 -1
  51. package/dist/client/assets/FlightObserveScreen-DL3Xhl0h.js +1 -0
  52. package/dist/client/assets/{FollowScreen-DG0osbUp.js → FollowScreen-DcFBqr6l.js} +1 -1
  53. package/dist/client/assets/{HarnessMark-MztYnrGK.js → HarnessMark-DGZ6o6Ct.js} +1 -1
  54. package/dist/client/assets/{HarnessesScreen-BWqirBjK.js → HarnessesScreen-DTDL-XaA.js} +1 -1
  55. package/dist/client/assets/{HerdrSession-6sFln7WX.js → HerdrSession-DV2hD6Yh.js} +1 -1
  56. package/dist/client/assets/HomeHero-7JwycwFY.css +1 -0
  57. package/dist/client/assets/HomeHero-CENwVZ45.js +1 -0
  58. package/dist/client/assets/HostAdvisorView-PgiZUkd_.js +1 -0
  59. package/dist/client/assets/{KnowledgeSearchInspector-BOIhFWd2.js → KnowledgeSearchInspector-DNQjeWZO.js} +1 -1
  60. package/dist/client/assets/KnowledgeSearchScreen-Bj80IgR0.js +1 -0
  61. package/dist/client/assets/{LaneToolHoverCard-CcEiQC6B.js → LaneToolHoverCard-197xYmRp.js} +1 -1
  62. package/dist/client/assets/LaneTraceDetailSheet-BztwvOv9.js +1 -0
  63. package/dist/client/assets/{LaneTraceEventFocus-Bl9L0EYb.js → LaneTraceEventFocus-C9cmqxnK.js} +1 -1
  64. package/dist/client/assets/{MeshCanvas-ZjIuMiRo.js → MeshCanvas-C3_2p9B6.js} +2 -2
  65. package/dist/client/assets/{MeshCanvasMinimap-C-LQtiX6.js → MeshCanvasMinimap-ZTjYWXTZ.js} +1 -1
  66. package/dist/client/assets/{MeshScreen-Bs3soujg.js → MeshScreen-lJKaOyGB.js} +1 -1
  67. package/dist/client/assets/{MeshTopologyView-C0LUyT3K.js → MeshTopologyView-CBjHbAZw.js} +2 -2
  68. package/dist/client/assets/MessagesScreen-D6MVLvdg.js +1 -0
  69. package/dist/client/assets/{MissionContextRail-CjGAEGu8.js → MissionContextRail-DXkrbcnZ.js} +1 -1
  70. package/dist/client/assets/MissionControlView-BCH-Zsp4.js +1 -0
  71. package/dist/client/assets/MissionFocusOverlay-DbAliOSF.js +1 -0
  72. package/dist/client/assets/MissionLeftAgentRow-Bx6Pg8_O.js +1 -0
  73. package/dist/client/assets/MissionLogPane-D06c29Y8.js +1 -0
  74. package/dist/client/assets/{NewAgentModal-D5e0YUAo.js → NewAgentModal-C18Ajovd.js} +1 -1
  75. package/dist/client/assets/NewChatComposer-Bgqes0UQ.js +19 -0
  76. package/dist/client/assets/{NewChatOrigin-BEz6jyqf.js → NewChatOrigin-DpHS2Wmt.js} +1 -1
  77. package/dist/client/assets/ObserveEmbedScreen-Cmhwai4X.js +2 -0
  78. package/dist/client/assets/ObserveTextFlow-C1f5oize.js +2 -0
  79. package/dist/client/assets/ObservedTopologyPanel-D85P6RAk.js +2 -0
  80. package/dist/client/assets/OpenScoutAppShell-IDI4fuUE.js +88 -0
  81. package/dist/client/assets/OpsAgentsView-yt0JavoB.js +1 -0
  82. package/dist/client/assets/OpsScreen-C3yNQqJE.js +1 -0
  83. package/dist/client/assets/OpsSubnav-BijKI3yG.js +1 -0
  84. package/dist/client/assets/ProjectAgentProfile-DnIeC16r.js +1 -0
  85. package/dist/client/assets/{ProjectAgentProfileBar-B1VpwzGD.js → ProjectAgentProfileBar-IDEpKZvI.js} +1 -1
  86. package/dist/client/assets/ProjectAgentProfileHero-Bh_aISs-.js +1 -0
  87. package/dist/client/assets/ProjectsInbox-B8Srlklk.js +2 -0
  88. package/dist/client/assets/ProjectsRail-DqAbdvCf.js +1 -0
  89. package/dist/client/assets/ProjectsScreen-DKHQ2iEv.js +1 -0
  90. package/dist/client/assets/ProjectsThreadAside-DpkjYLL2.js +1 -0
  91. package/dist/client/assets/Provider-Ve8yXaWR.js +1 -0
  92. package/dist/client/assets/RailRow-B0sRaJc6.css +1 -0
  93. package/dist/client/assets/RailRow-C4GNGR80.js +1 -0
  94. package/dist/client/assets/RawSessionsTable-Co3vzwsf.js +1 -0
  95. package/dist/client/assets/RealtimeVoiceScreen-DMd1CBAf.js +9 -0
  96. package/dist/client/assets/{RepoDiffEmbedScreen-VLg4caej.js → RepoDiffEmbedScreen-C97Euf4s.js} +1 -1
  97. package/dist/client/assets/{RepoDiffPageScreen-BelnvgnP.js → RepoDiffPageScreen-DUKLzkrW.js} +1 -1
  98. package/dist/client/assets/RepoDiffViewer-CovKjSgb.js +7 -0
  99. package/dist/client/assets/RepoDiffViewerLazy-zIiEmh-e.js +2 -0
  100. package/dist/client/assets/{ReposScreen-IINK-CFn.js → ReposScreen-BR1LqTf1.js} +6 -6
  101. package/dist/client/assets/ScoutDeckSurface-BGsVicc2.js +1 -0
  102. package/dist/client/assets/{ScoutSurface-x_QbcRyk.js → ScoutSurface-BMKW7hSu.js} +1 -1
  103. package/dist/client/assets/{ScoutbotFxLab-7t9JVvZg.js → ScoutbotFxLab-0O2iDRrF.js} +1 -1
  104. package/dist/client/assets/{SecondaryNav-Dj30epYF.js → SecondaryNav-cYTw2p39.js} +1 -1
  105. package/dist/client/assets/{SessionEmbedScreen-s2mJ5Fg9.js → SessionEmbedScreen-mNjT0R6j.js} +1 -1
  106. package/dist/client/assets/{SessionObserve-DaUrJCMq.js → SessionObserve-zAlFbwFn.js} +1 -1
  107. package/dist/client/assets/{SessionObserveEvidence-ClUW8jpV.js → SessionObserveEvidence-BVawzqoE.js} +1 -1
  108. package/dist/client/assets/SessionRefScreen-BmKhf29o.js +1 -0
  109. package/dist/client/assets/SessionsScreen-CsSqjIY2.js +1 -0
  110. package/dist/client/assets/SettingsDrawer-Dsj-On_x.css +1 -0
  111. package/dist/client/assets/SettingsDrawer-DwYQTGi8.js +3 -0
  112. package/dist/client/assets/SettingsScreen-Btaku7YM.js +1 -0
  113. package/dist/client/assets/{ShikiPane-Dkwyx--r.js → ShikiPane-DyEJdcvb.js} +1 -1
  114. package/dist/client/assets/{SlidePanel-CuTeirnk.js → SlidePanel-Dg8_styW.js} +1 -1
  115. package/dist/client/assets/{SpriteAvatar-DQ3PTb8L.js → SpriteAvatar-DMrSssNZ.js} +1 -1
  116. package/dist/client/assets/{StatusPill-BJ1ierIR.js → StatusPill-NFFnphtx.js} +1 -1
  117. package/dist/client/assets/{TailView-CufWcrvf.js → TailView-BfObcZu3.js} +2 -2
  118. package/dist/client/assets/Terminal-Dr-M9U4u.js +1 -0
  119. package/dist/client/assets/TerminalEmbedScreen-BmyZkonh.js +1 -0
  120. package/dist/client/assets/{TerminalRelay-rvUzI9Ek.js → TerminalRelay-lJ2KdMCW.js} +3 -3
  121. package/dist/client/assets/{TextDocumentSurface-Bc-kHPgG.js → TextDocumentSurface-C7fGlzY8.js} +1 -1
  122. package/dist/client/assets/{TmuxPeek-DLyDkq_D.js → TmuxPeek-BSeKIjnX.js} +1 -1
  123. package/dist/client/assets/{VoicePermissionsPanel-CD903y9K.js → VoicePermissionsPanel-BkIGTzgw.js} +1 -1
  124. package/dist/client/assets/{WorkDetailScreen-D51oI0dH.js → WorkDetailScreen-Cwe-KWK4.js} +3 -3
  125. package/dist/client/assets/WorkFilesViewer-BBtKRBPv.js +1 -0
  126. package/dist/client/assets/{activity-BvGruxWG.js → activity-D4W2XZY2.js} +1 -1
  127. package/dist/client/assets/{addon-fit-Cfq4Ayjd.js → addon-fit-Celjj2yn.js} +1 -1
  128. package/dist/client/assets/{addon-webgl-B8sIf9-s.js → addon-webgl-Cu4tJ21-.js} +1 -1
  129. package/dist/client/assets/{ScoutbotBroadcastChip-CxtYZWPZ.css → agent-autocomplete-C7xwIcwd.css} +1 -1
  130. package/dist/client/assets/agent-autocomplete-Dv-_9dAw.js +2 -0
  131. package/dist/client/assets/{agent-essentials-yb4wIJlX.js → agent-essentials-CngjUhQj.js} +1 -1
  132. package/dist/client/assets/agent-identity-DzHGhLdJ.js +1 -0
  133. package/dist/client/assets/{agent-lane-card-model-q4cwzLX4.js → agent-lane-card-model-CSugZCdy.js} +1 -1
  134. package/dist/client/assets/{agent-lane-detail-BNNm6FNu.js → agent-lane-detail-D5EIlX7_.js} +1 -1
  135. package/dist/client/assets/{agent-lane-preview-C33Dwpn7.js → agent-lane-preview-BhplDYGf.js} +1 -1
  136. package/dist/client/assets/{agent-lanes-BDNktFBZ.css → agent-lanes-DlqcEf0l.css} +1 -1
  137. package/dist/client/assets/{agent-lanes-model-VYQ5a68i.js → agent-lanes-model-BKOs_32K.js} +2 -2
  138. package/dist/client/assets/agent-specialization-CNrsRbKA.js +1 -0
  139. package/dist/client/assets/{api-BkjHJfgJ.js → api-BHHEUSS3.js} +1 -1
  140. package/dist/client/assets/api-DEHEgJ9m.js +1 -0
  141. package/dist/client/assets/{arc.es-BBTfhvLE.js → arc.es-DNT50Y-_.js} +1 -1
  142. package/dist/client/assets/archive-DH49QqFG.js +1 -0
  143. package/dist/client/assets/{arrow-left-BOht-YQu.js → arrow-left-i-h6JAgs.js} +1 -1
  144. package/dist/client/assets/arrow-right-B0Yi01Zr.js +1 -0
  145. package/dist/client/assets/{arrow-up-right-hoR8_oUz.js → arrow-up-right-RBC6k8nn.js} +1 -1
  146. package/dist/client/assets/{bot-BUK7dOPS.js → bot-r2IuAuJd.js} +1 -1
  147. package/dist/client/assets/broker-display-Q75fupqG.js +2 -0
  148. package/dist/client/assets/{cache-Dr0why2k.js → cache-BO2Bd_LV.js} +1 -1
  149. package/dist/client/assets/{check--esHw52j.js → check-Bfs7hMb1.js} +1 -1
  150. package/dist/client/assets/{chevron-down-NAhBUkFd.js → chevron-down-Da5tV19_.js} +1 -1
  151. package/dist/client/assets/{chevron-right-C10o7t_X.js → chevron-right-BMqtBds_.js} +1 -1
  152. package/dist/client/assets/{chunk-HRAB3GC3-DF8R9rPv.js → chunk-HRAB3GC3-BUVYXXAp.js} +1 -1
  153. package/dist/client/assets/{clock-of01sAB6.js → clock-DaKLp6Xd.js} +1 -1
  154. package/dist/client/assets/{code-xml-CLn3TDWF.js → code-xml-ByQsfOI_.js} +1 -1
  155. package/dist/client/assets/collapsed-strip-raJWthAH.css +1 -0
  156. package/dist/client/assets/compass-BepM5iWH.js +1 -0
  157. package/dist/client/assets/{content-Cgj5AWqT.js → content-5hnDC9WE.js} +1 -1
  158. package/dist/client/assets/content-BRFZ-a6m.js +1 -0
  159. package/dist/client/assets/content-BYykncDo.js +1 -0
  160. package/dist/client/assets/content-Be6yyWbJ.js +1 -0
  161. package/dist/client/assets/content-Bgl_X3ao.js +1 -0
  162. package/dist/client/assets/content-BopJW1Zx.js +1 -0
  163. package/dist/client/assets/content-Bv2sfg0w.js +1 -0
  164. package/dist/client/assets/content-CMBiIZTg.js +1 -0
  165. package/dist/client/assets/content-CPVqvf5o.js +1 -0
  166. package/dist/client/assets/content-CbwyFqdI.js +1 -0
  167. package/dist/client/assets/content-ClQjAWYi.js +1 -0
  168. package/dist/client/assets/content-Cv2tSAbv.js +1 -0
  169. package/dist/client/assets/content-DFFe3-Ot.js +1 -0
  170. package/dist/client/assets/content-DY5hwBmm.js +1 -0
  171. package/dist/client/assets/content-_IXoxGno.js +1 -0
  172. package/dist/client/assets/content-j_tewJdE.js +1 -0
  173. package/dist/client/assets/{conversation-icons-ClBJi21l.js → conversation-icons-C4amK8Sa.js} +1 -1
  174. package/dist/client/assets/conversation-model-CigSPlKA.js +1 -0
  175. package/dist/client/assets/conversation-motion-features-_95aZx_1.js +1 -0
  176. package/dist/client/assets/{copy-Dty8ZYsM.js → copy-De4s38o2.js} +1 -1
  177. package/dist/client/assets/cpu-Bc268H9Q.js +1 -0
  178. package/dist/client/assets/{createLucideIcon-Bt67PWH-.js → createLucideIcon-DLlxGjKt.js} +1 -1
  179. package/dist/client/assets/credentials-qwds23lv.js +1 -0
  180. package/dist/client/assets/ctx-panel-D_HJ3nhb.css +1 -0
  181. package/dist/client/assets/discover-DOlk1hG7.js +2 -0
  182. package/dist/client/assets/embed-entry-BqDJfa87.js +2 -0
  183. package/dist/client/assets/{external-link-Dem738OJ.js → external-link-BGHC_naA.js} +1 -1
  184. package/dist/client/assets/{eye-B3lBIwJZ.js → eye-BeCSqJn1.js} +1 -1
  185. package/dist/client/assets/file-code-corner-CX53Cd9y.js +1 -0
  186. package/dist/client/assets/{file-text-iF0hyVyU.js → file-text-BVhkMWyC.js} +1 -1
  187. package/dist/client/assets/gauge-CPcEPmNt.js +1 -0
  188. package/dist/client/assets/gestures-BXIGYk_p.js +1 -0
  189. package/dist/client/assets/git-branch-q8Ayc8py.js +1 -0
  190. package/dist/client/assets/home-moving-signal-DMguaRWR.css +1 -0
  191. package/dist/client/assets/home-moving-signal-Dm2Z2x0p.js +1 -0
  192. package/dist/client/assets/{home-now-card-nano-hZl9klbP.js → home-now-card-nano-Djhy6ax0.js} +1 -1
  193. package/dist/client/assets/home-now-card-xU5LGP7q.js +1 -0
  194. package/dist/client/assets/hooks-CdKx1CxP.js +2 -0
  195. package/dist/client/assets/host-advisor-B2Fqs5Dd.css +1 -0
  196. package/dist/client/assets/index-Bli6bTLU.js +10 -0
  197. package/dist/client/assets/index-D7UEHxaY.js +1 -0
  198. package/dist/client/assets/index-DFdlQs_c.js +1 -0
  199. package/dist/client/assets/index-DhfOMK0D.js +1 -0
  200. package/dist/client/assets/index-DzlEgstl.css +1 -0
  201. package/dist/client/assets/index-wLwc74Pu.css +1 -0
  202. package/dist/client/assets/inspector-panel-B8pigRsg.js +2 -0
  203. package/dist/client/assets/{keyboard-nav-Chf51dns.js → keyboard-nav-7iEtvu9P.js} +1 -1
  204. package/dist/client/assets/{lane-observe-BA3g9aVd.js → lane-observe-vfyACHi0.js} +1 -1
  205. package/dist/client/assets/{lane-roster-store-BiIVlYmG.js → lane-roster-store-pHT3TAVs.js} +1 -1
  206. package/dist/client/assets/layers-BiZA-Clc.js +1 -0
  207. package/dist/client/assets/layout-grid-DMpv9CZM.js +1 -0
  208. package/dist/client/assets/left-BayK4ocL.js +1 -0
  209. package/dist/client/assets/left-BhZhSrS2.js +1 -0
  210. package/dist/client/assets/left-BhgU6NOA.js +1 -0
  211. package/dist/client/assets/left-CY_FGnN7.js +1 -0
  212. package/dist/client/assets/left-Cq8mjamr.js +1 -0
  213. package/dist/client/assets/left-DH44V4I_.css +1 -0
  214. package/dist/client/assets/left-Dnqla0b5.js +2 -0
  215. package/dist/client/assets/left-Dy403II2.js +2 -0
  216. package/dist/client/assets/left-R2OOE7VG.css +1 -0
  217. package/dist/client/assets/left-advisor-oOAtJ9YE.js +1 -0
  218. package/dist/client/assets/left-agents-TIKe8vW8.js +1 -0
  219. package/dist/client/assets/left-default-owH0Lwxo.js +1 -0
  220. package/dist/client/assets/left-lanes-BE_co2lP.js +1 -0
  221. package/dist/client/assets/left-mission-C_nWUtfA.js +1 -0
  222. package/dist/client/assets/library-BSVrjn_m.js +1 -0
  223. package/dist/client/assets/{loader-circle-4LDsy4Ke.js → loader-circle-DoT8gpw6.js} +1 -1
  224. package/dist/client/assets/{local-agents-DIi2EacM.js → local-agents-BMadXuP1.js} +1 -1
  225. package/dist/client/assets/mentions-Cd6XticV.js +1 -0
  226. package/dist/client/assets/{mesh-ops-JZwGuAPn.js → mesh-ops-C0zCLTR8.js} +1 -1
  227. package/dist/client/assets/{mesh-view-store-Du7VqIT_.js → mesh-view-store-Cpqil_2D.js} +1 -1
  228. package/dist/client/assets/{message-circle-BM3XgevU.js → message-circle-44KSmbvQ.js} +1 -1
  229. package/dist/client/assets/{message-markup-BcY1lShv.js → message-markup-DAnnGpWr.js} +1 -1
  230. package/dist/client/assets/{message-square-ER1_q2pe.js → message-square-DlY4EneU.js} +1 -1
  231. package/dist/client/assets/mission-control-CnU7dNt1.css +1 -0
  232. package/dist/client/assets/{mission-control-store-C6w5iVfg.js → mission-control-store-DtjtRs9Z.js} +1 -1
  233. package/dist/client/assets/{observe-3-jn4SXb.js → observe-DL5_8-Zj.js} +1 -1
  234. package/dist/client/assets/{operator-attention-BwSPeheT.js → operator-attention-BqoWAlhp.js} +1 -1
  235. package/dist/client/assets/{page-status-0LPfBC8S.js → page-status-CW8co39E.js} +1 -1
  236. package/dist/client/assets/persistent-state-DYjP8lqN.js +1 -0
  237. package/dist/client/assets/{plus-C-2gTcPK.js → plus-64n9qucr.js} +1 -1
  238. package/dist/client/assets/profile-BkmuseW7.js +1 -0
  239. package/dist/client/assets/projects-inbox-C0umZMSY.js +1 -0
  240. package/dist/client/assets/{provider-BvAxRQfE.js → provider-CX9EWecp.js} +1 -1
  241. package/dist/client/assets/proxy-C35W-YHZ.js +1 -0
  242. package/dist/client/assets/{radio-v7UAMZGh.js → radio-BjpQTKT0.js} +1 -1
  243. package/dist/client/assets/{refresh-cw-B5To7b6B.js → refresh-cw-IgN2fZLM.js} +1 -1
  244. package/dist/client/assets/resolve-panes-CCqRkQdM.js +1 -0
  245. package/dist/client/assets/resolve-sidebar-context-JkxY8qsV.js +1 -0
  246. package/dist/client/assets/right-B3PQUHd5.js +1 -0
  247. package/dist/client/assets/right-B96CBzrV.js +1 -0
  248. package/dist/client/assets/right-BPirlFC8.js +1 -0
  249. package/dist/client/assets/right-BUP2Ro_M.js +1 -0
  250. package/dist/client/assets/right-BVWYPIFX.js +1 -0
  251. package/dist/client/assets/right-BoAJxwA3.js +1 -0
  252. package/dist/client/assets/right-C2aOC2li.js +1 -0
  253. package/dist/client/assets/right-CtPJjgOV.js +1 -0
  254. package/dist/client/assets/{right-BvoGOUKH.js → right-DqiVyo8v.js} +1 -1
  255. package/dist/client/assets/right-SfSu0zHC.js +1 -0
  256. package/dist/client/assets/{rocket-BQQQv2L5.js → rocket-DnmN_YOD.js} +1 -1
  257. package/dist/client/assets/{router-C65cZYPn.js → router-B0YclXYg.js} +1 -1
  258. package/dist/client/assets/{scope-views-BOOmgmwx.js → scope-views-Z8aoAmtU.js} +1 -1
  259. package/dist/client/assets/scout-voice-DvG_3stJ.js +1 -0
  260. package/dist/client/assets/{scoutbot-BTIErYHo.js → scoutbot-D4vuKzOL.js} +2 -2
  261. package/dist/client/assets/scoutbot-markdown-BJJyaPu2.js +6 -0
  262. package/dist/client/assets/{scroll-text-BuneRiAD.js → scroll-text-DRidbcse.js} +1 -1
  263. package/dist/client/assets/{search-7_n7CxWl.js → search-BbgsEMXa.js} +1 -1
  264. package/dist/client/assets/secondaryNavConfig-DyC_P9Wx.js +1 -0
  265. package/dist/client/assets/{selection-bridge-SlGsgHw2.js → selection-bridge-CpzFGx3-.js} +1 -1
  266. package/dist/client/assets/{send-horizontal-DP16OOIW.js → send-horizontal-BXo2uz3Z.js} +1 -1
  267. package/dist/client/assets/{server-pYOMFjrT.js → server-Dt3tpiBj.js} +1 -1
  268. package/dist/client/assets/{session-catalog-_QfQ7fhZ.js → session-catalog-CUQ8LUJY.js} +1 -1
  269. package/dist/client/assets/{session-table-CYN8e4s3.js → session-table-B4JOKevn.js} +1 -1
  270. package/dist/client/assets/settings-BzWCF3NF.js +1 -0
  271. package/dist/client/assets/{sliders-horizontal-D2Z8gz6J.js → sliders-horizontal-7V8B3xsf.js} +1 -1
  272. package/dist/client/assets/{sparkles-Bth2iK7t.js → sparkles-ytTwpCbZ.js} +1 -1
  273. package/dist/client/assets/{sse-CL6gctHY.js → sse-CSozY6mp.js} +1 -1
  274. package/dist/client/assets/system-surfaces-redesign-QVXNeGYw.css +1 -0
  275. package/dist/client/assets/{tail-display-BRcJltQa.js → tail-display-DcliDVkW.js} +1 -1
  276. package/dist/client/assets/{tail-events-NLIWLq27.js → tail-events-CrN-Rmxj.js} +1 -1
  277. package/dist/client/assets/{terminal-By1Lw2i2.js → terminal-BiNIXhna.js} +1 -1
  278. package/dist/client/assets/{terminal-relay-CjkI5aUy.js → terminal-relay-pSm7_An6.js} +1 -1
  279. package/dist/client/assets/{terminal-sessions-AmSgHklm.js → terminal-sessions-D4dHTRkt.js} +1 -1
  280. package/dist/client/assets/{terminal-takeover-7AvNpnkC.js → terminal-takeover-CtA3wcXh.js} +1 -1
  281. package/dist/client/assets/{runtime-picker-eDEvx2Mz.js → text-BR9Bap0E.js} +1 -1
  282. package/dist/client/assets/text-rLpBg4_z.css +1 -0
  283. package/dist/client/assets/{use-conversation-list-BCzY032j.js → use-conversation-list-C0bEXFeH.js} +1 -1
  284. package/dist/client/assets/{use-fleet-active-asks-CJ6-oj5k.js → use-fleet-active-asks-CK4aw-3G.js} +1 -1
  285. package/dist/client/assets/{use-mesh-ops-items-D5L-CKe_.js → use-mesh-ops-items-QixBijmT.js} +1 -1
  286. package/dist/client/assets/use-reduced-motion-BLn59zLn.js +1 -0
  287. package/dist/client/assets/{use-scout-dev-flags-BohC8seq.js → use-scout-dev-flags-JKb1EhFh.js} +1 -1
  288. package/dist/client/assets/{useAgentHoverCard-RsLUYyeh.js → useAgentHoverCard-6N8b7qsU.js} +1 -1
  289. package/dist/client/assets/useContentSecondaryNav-D-hVKzM9.js +1 -0
  290. package/dist/client/assets/{usePersistentState-D3M4m2Ou.js → usePersistentState-DOEahRlt.js} +1 -1
  291. package/dist/client/assets/{usePierreRuntime-B4hbNWTz.js → usePierreRuntime-Bq6mXrgd.js} +1 -1
  292. package/dist/client/assets/{wrench-M4G7WtYB.js → wrench-CQvdf7KT.js} +1 -1
  293. package/dist/client/assets/{x-ynOfVadO.js → x-BJyPzFnn.js} +1 -1
  294. package/dist/client/assets/{xterm-DZHyijPp.js → xterm-D6dE_wMr.js} +1 -1
  295. package/dist/client/assets/zap-rw7uwZht.js +1 -0
  296. package/dist/client/index.html +2 -2
  297. package/dist/main.mjs +629 -167
  298. package/dist/node/main.mjs +454 -270
  299. package/dist/pairing-runtime-controller.mjs +607 -357
  300. package/dist/runtime/base-daemon.mjs +384 -21
  301. package/dist/runtime/broker-daemon.mjs +11024 -10023
  302. package/dist/runtime/broker-process-manager.mjs +9 -3
  303. package/dist/runtime/mesh-discover.mjs +9 -3
  304. package/dist/scout-control-plane-web.mjs +1590 -984
  305. package/dist/scout-web-server.mjs +1590 -984
  306. package/package.json +4 -4
  307. package/dist/client/assets/ActivityScreen-aewI4Ul1.js +0 -1
  308. package/dist/client/assets/AgentAvatar-DMov24_o.js +0 -1
  309. package/dist/client/assets/AgentConfigurationScreen-BjG6ECjl.js +0 -1
  310. package/dist/client/assets/AgentDefinitionsWorkspace-D4MbSMXp.js +0 -1
  311. package/dist/client/assets/AgentFloorView-h9KDJdw0.js +0 -1
  312. package/dist/client/assets/AgentInfoScreen-SjhK_SBh.js +0 -1
  313. package/dist/client/assets/AgentLaneDetailSheet-DnAKe4e3.js +0 -4
  314. package/dist/client/assets/AgentLanesEmbedScreen-BNOYF16R.js +0 -1
  315. package/dist/client/assets/AgentLanesView-Ct-Gz5WD.js +0 -2
  316. package/dist/client/assets/AgentSessions-CDfSfNiE.js +0 -6
  317. package/dist/client/assets/AgentsConsole-BVxhBqRa.js +0 -1
  318. package/dist/client/assets/AgentsSubnav-CiIuzxnZ.js +0 -1
  319. package/dist/client/assets/BriefingDetailScreen-C83o2YfN.js +0 -6
  320. package/dist/client/assets/BrokerScreen-DplF8d_X.js +0 -5
  321. package/dist/client/assets/ChatCollapsedStrip-BRljIymi.js +0 -1
  322. package/dist/client/assets/ContextMenu-CxkmFQcN.js +0 -1
  323. package/dist/client/assets/ConversationComposer-CWohCCmn.js +0 -1
  324. package/dist/client/assets/ConversationFeedRows-IWh0JSIL.js +0 -1
  325. package/dist/client/assets/ConversationHeader-BxTzXl8e.js +0 -1
  326. package/dist/client/assets/ConversationPanels-D9UCwNkS.js +0 -2
  327. package/dist/client/assets/ConversationScreen-oZSitVtX.js +0 -1
  328. package/dist/client/assets/ConversationScreen-yIKEsm-8.css +0 -1
  329. package/dist/client/assets/ConversationStatus-B6pAbo2w.js +0 -1
  330. package/dist/client/assets/DocumentFocusViewer-DRKjNG9s.js +0 -1
  331. package/dist/client/assets/FleetSearch-CYeWn85V.js +0 -1
  332. package/dist/client/assets/FleetSearch-EXOe8ulE.css +0 -1
  333. package/dist/client/assets/FlightObserveScreen-DYJJ3Z2B.js +0 -1
  334. package/dist/client/assets/HomeHero-BPBArHXa.js +0 -1
  335. package/dist/client/assets/HomeHero-DEl-WBsT.css +0 -1
  336. package/dist/client/assets/KnowledgeSearchScreen-BP8tD-Bh.js +0 -1
  337. package/dist/client/assets/LaneTraceDetailSheet-B4i1Ut4R.js +0 -1
  338. package/dist/client/assets/MessageComposerSuggestions-Dfc3PH2y.js +0 -1
  339. package/dist/client/assets/MessagesScreen-TgSL5KMc.js +0 -1
  340. package/dist/client/assets/MissionControlView-D629w2A8.js +0 -1
  341. package/dist/client/assets/MissionFocusOverlay-Bubrr8Gc.js +0 -1
  342. package/dist/client/assets/MissionLeftAgentRow-DokImu4Y.js +0 -1
  343. package/dist/client/assets/MissionLogPane-Cs0LuIkn.js +0 -1
  344. package/dist/client/assets/NewChatComposer-S08F6_La.js +0 -19
  345. package/dist/client/assets/ObserveEmbedScreen-CHx2sEAA.js +0 -2
  346. package/dist/client/assets/ObserveTextFlow-_ApDwRCO.js +0 -2
  347. package/dist/client/assets/ObservedTopologyPanel-ByW7Ar7p.js +0 -2
  348. package/dist/client/assets/OpenScoutAppShell-DTmnbG-h.js +0 -88
  349. package/dist/client/assets/OpsAgentsView-DiFuHcJs.js +0 -1
  350. package/dist/client/assets/OpsScreen-CCR3U_9P.js +0 -1
  351. package/dist/client/assets/OpsSubnav-CZs_OL2N.js +0 -1
  352. package/dist/client/assets/PlanView-C54eAzig.js +0 -1
  353. package/dist/client/assets/ProjectAgentProfile-BEfYOaxc.js +0 -1
  354. package/dist/client/assets/ProjectAgentProfileHero-B4f_AoCr.js +0 -1
  355. package/dist/client/assets/ProjectsInbox-DoPZ17FC.js +0 -2
  356. package/dist/client/assets/ProjectsRail-CWOkZjsY.js +0 -1
  357. package/dist/client/assets/ProjectsScreen-Dse0Q6p6.js +0 -1
  358. package/dist/client/assets/ProjectsThreadAside-DMnfyPLE.js +0 -1
  359. package/dist/client/assets/Provider-DKZWuzSR.js +0 -1
  360. package/dist/client/assets/RailRow-Cf9LOiEj.css +0 -1
  361. package/dist/client/assets/RailRow-DIGd3MMM.js +0 -1
  362. package/dist/client/assets/RawSessionsTable-Zkl4YDvz.js +0 -1
  363. package/dist/client/assets/RealtimeVoiceScreen-B_PMJxY_.js +0 -1
  364. package/dist/client/assets/RepoDiffViewer-VrUJw33u.js +0 -7
  365. package/dist/client/assets/RepoDiffViewerLazy-BPg_JkYW.js +0 -2
  366. package/dist/client/assets/ScoutDeckSurface-MbwGp6Ab.js +0 -1
  367. package/dist/client/assets/ScoutbotBroadcastChip-DAKQKB25.js +0 -2
  368. package/dist/client/assets/ScoutbotRealtimeVoiceCall-Br4bYVAx.js +0 -1
  369. package/dist/client/assets/SessionRefScreen-DLZNFZFK.js +0 -1
  370. package/dist/client/assets/SessionsScreen-D-hN1n4k.js +0 -1
  371. package/dist/client/assets/SettingsDrawer-BFsnww-k.js +0 -3
  372. package/dist/client/assets/SettingsDrawer-UX7pFJU_.css +0 -1
  373. package/dist/client/assets/SettingsScreen-Bc3Xtv5V.js +0 -1
  374. package/dist/client/assets/Terminal-D_OmdFmr.js +0 -1
  375. package/dist/client/assets/TerminalEmbedScreen-D21ytNXW.js +0 -1
  376. package/dist/client/assets/WorkFilesViewer-BDMNbxE4.js +0 -1
  377. package/dist/client/assets/agent-identity-BxCsXnDp.js +0 -1
  378. package/dist/client/assets/api-h5zurxmi.js +0 -1
  379. package/dist/client/assets/broker-display-pp33bLsu.js +0 -2
  380. package/dist/client/assets/collapsed-strip-Dz-of2SM.css +0 -1
  381. package/dist/client/assets/content-B-SUUhXj.js +0 -1
  382. package/dist/client/assets/content-BRY2vo1_.js +0 -1
  383. package/dist/client/assets/content-BTm0mVyD.js +0 -1
  384. package/dist/client/assets/content-BTqvyb5E.js +0 -1
  385. package/dist/client/assets/content-BjDaXmSD.js +0 -1
  386. package/dist/client/assets/content-BrR6deGh.js +0 -1
  387. package/dist/client/assets/content-C5yvBEMy.js +0 -1
  388. package/dist/client/assets/content-CkhG__-v.js +0 -1
  389. package/dist/client/assets/content-CudIBsiP.js +0 -1
  390. package/dist/client/assets/content-DBb7ppd5.js +0 -1
  391. package/dist/client/assets/content-DEw_kGyK.js +0 -1
  392. package/dist/client/assets/content-DIy0DCzK.js +0 -1
  393. package/dist/client/assets/content-THl9hRAo.js +0 -1
  394. package/dist/client/assets/content-vi9FbmV9.js +0 -1
  395. package/dist/client/assets/content-wcgPMGVf.js +0 -1
  396. package/dist/client/assets/conversation-model-CHwHZNw-.js +0 -1
  397. package/dist/client/assets/conversation-motion-features-zU0k3Agz.js +0 -1
  398. package/dist/client/assets/ctx-panel-B4s49N9e.css +0 -1
  399. package/dist/client/assets/discover-NDAqNvKt.js +0 -2
  400. package/dist/client/assets/embed-entry-BVR09F6e.js +0 -2
  401. package/dist/client/assets/home-moving-signal-C8dTXieA.js +0 -1
  402. package/dist/client/assets/home-moving-signal-CAa0V91u.css +0 -1
  403. package/dist/client/assets/home-now-card-BgvVcE83.js +0 -1
  404. package/dist/client/assets/hooks-DBIezYS2.js +0 -2
  405. package/dist/client/assets/index-BMwKgdz_.js +0 -1
  406. package/dist/client/assets/index-Bu-fckyR.css +0 -1
  407. package/dist/client/assets/index-BxoufAPA.js +0 -1
  408. package/dist/client/assets/index-Cj7NnSxI.js +0 -1
  409. package/dist/client/assets/index-CvF09yvf.css +0 -1
  410. package/dist/client/assets/index-o4FKpU7Z.js +0 -10
  411. package/dist/client/assets/inspector-panel-Dy2cVTCi.js +0 -2
  412. package/dist/client/assets/left-BC7p5QbT.js +0 -1
  413. package/dist/client/assets/left-BCSGqccQ.js +0 -1
  414. package/dist/client/assets/left-BSyj8PuJ.js +0 -2
  415. package/dist/client/assets/left-Bk3XnxPD.css +0 -1
  416. package/dist/client/assets/left-CCoobxPS.css +0 -1
  417. package/dist/client/assets/left-DDnxNUxd.js +0 -1
  418. package/dist/client/assets/left-DLoDKxT5.js +0 -2
  419. package/dist/client/assets/left-O-TBH7JB.js +0 -1
  420. package/dist/client/assets/left-agents-Dk9Y89lb.js +0 -1
  421. package/dist/client/assets/left-default-B3JBRQNJ.js +0 -1
  422. package/dist/client/assets/left-lanes-30Oe_3RM.js +0 -1
  423. package/dist/client/assets/left-mission-DEl4-7xu.js +0 -1
  424. package/dist/client/assets/left-plan-B4qdm4Gn.js +0 -2
  425. package/dist/client/assets/left-rvUOB14X.js +0 -1
  426. package/dist/client/assets/library-DDKSLFJ_.js +0 -1
  427. package/dist/client/assets/mentions-CvDaviLJ.js +0 -1
  428. package/dist/client/assets/mission-control-m3BTDQ9l.css +0 -1
  429. package/dist/client/assets/model-Co0zkMIc.js +0 -1
  430. package/dist/client/assets/plan-view-D56fneVF.css +0 -1
  431. package/dist/client/assets/profile-DW80Gn5k.js +0 -1
  432. package/dist/client/assets/projects-inbox-DCeD3FfV.js +0 -1
  433. package/dist/client/assets/resolve-panes-BDi9Qx4R.js +0 -1
  434. package/dist/client/assets/resolve-sidebar-context-HE-5eZYa.js +0 -1
  435. package/dist/client/assets/right-BDf_yTv6.js +0 -1
  436. package/dist/client/assets/right-C-bgjYg-.js +0 -1
  437. package/dist/client/assets/right-C3JdEfYQ.js +0 -1
  438. package/dist/client/assets/right-CYIs2tEe.js +0 -1
  439. package/dist/client/assets/right-CyRCv6Up.js +0 -1
  440. package/dist/client/assets/right-DBYGtoRv.js +0 -1
  441. package/dist/client/assets/right-o3LHMiKa.js +0 -1
  442. package/dist/client/assets/right-oPrcx9MX.js +0 -1
  443. package/dist/client/assets/right-sSvBUK-j.js +0 -1
  444. package/dist/client/assets/runtime-picker-vhm0gtLs.css +0 -1
  445. package/dist/client/assets/scout-voice-B7kXlkcl.js +0 -1
  446. package/dist/client/assets/secondaryNavConfig-CSFDCQAf.js +0 -1
  447. package/dist/client/assets/system-surfaces-redesign-B7GQhfpw.css +0 -1
  448. package/dist/client/assets/text-DsBWV_4k.js +0 -1
  449. package/dist/client/assets/use-reduced-motion-CqXpVXv-.js +0 -1
  450. package/dist/client/assets/useContentSecondaryNav-DOr5yHbT.js +0 -1
  451. /package/dist/client/assets/{document-focus-viewer-BSC_JwVE.css → DocumentFocusViewer-BSC_JwVE.css} +0 -0
@@ -51,12 +51,18 @@ var __require = import.meta.require;
51
51
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
52
52
  import { homedir } from "os";
53
53
  import { join } from "path";
54
+ function isTestRunnerProcess() {
55
+ if (false)
56
+ ;
57
+ const entry = typeof Bun !== "undefined" ? Bun.main : process.argv[1] ?? "";
58
+ return /[._](test|spec)\.[cm]?[jt]sx?$/.test(entry);
59
+ }
54
60
  function assertTestIsolatedUserData(operation, isolationEnvKey) {
55
- if (true)
61
+ if (!isTestRunnerProcess())
56
62
  return;
57
63
  if (process.env[isolationEnvKey]?.trim())
58
64
  return;
59
- throw new Error(`Refusing to ${operation} while NODE_ENV=test without ${isolationEnvKey} set. ` + "Tests must isolate OpenScout user data in a temp directory (see prepareHome in onboarding.test.ts).");
65
+ throw new Error(`Refusing to ${operation} under a test runner without ${isolationEnvKey} set. ` + "Tests must isolate OpenScout user data in a temp directory (see prepareHome in onboarding.test.ts).");
60
66
  }
61
67
  function resolveOpenScoutSupportPaths() {
62
68
  const home = homedir();
@@ -117,28 +123,236 @@ function ensureOpenScoutCleanSlateSync() {
117
123
  var OPENSCOUT_RPC_CUTOVER_MARKER = "rpc-runtime-cutover-v1";
118
124
  var init_support_paths = () => {};
119
125
 
120
- // ../runtime/src/local-config.ts
126
+ // ../runtime/src/node-identity.ts
127
+ import {
128
+ createHash,
129
+ createPrivateKey,
130
+ createPublicKey,
131
+ generateKeyPairSync,
132
+ randomBytes,
133
+ sign,
134
+ verify
135
+ } from "crypto";
121
136
  import {
137
+ chmodSync,
122
138
  existsSync as existsSync2,
123
139
  mkdirSync as mkdirSync2,
124
140
  readFileSync,
125
141
  renameSync,
142
+ rmSync as rmSync2,
126
143
  writeFileSync as writeFileSync2
127
144
  } from "fs";
128
- import { homedir as homedir2, hostname as osHostname } from "os";
129
145
  import { dirname, join as join2 } from "path";
146
+ function stripBonjourCollisionSuffix(value) {
147
+ if (!value || typeof value !== "string")
148
+ return "";
149
+ let trimmed = value.trim();
150
+ const isDotLocal = /\.local\.?$/i.test(trimmed);
151
+ if (isDotLocal) {
152
+ trimmed = trimmed.replace(/\.local\.?$/i, "");
153
+ }
154
+ const isHyphenLocalOpenscout = /-local-openscout$/i.test(trimmed);
155
+ const isHyphenLocal = !isHyphenLocalOpenscout && /-local$/i.test(trimmed);
156
+ if (isHyphenLocalOpenscout) {
157
+ trimmed = trimmed.replace(/-local-openscout$/i, "");
158
+ } else if (isHyphenLocal) {
159
+ trimmed = trimmed.replace(/-local$/i, "");
160
+ }
161
+ if (!isDotLocal && !isHyphenLocalOpenscout && !isHyphenLocal) {
162
+ return trimmed;
163
+ }
164
+ trimmed = trimmed.replace(/(?<=[a-zA-Z].*?)(?:-\d+)+$/, "");
165
+ if (isDotLocal)
166
+ return `${trimmed}.local`;
167
+ if (isHyphenLocalOpenscout)
168
+ return `${trimmed}-local-openscout`;
169
+ if (isHyphenLocal)
170
+ return `${trimmed}-local`;
171
+ return trimmed;
172
+ }
173
+ function nodeIdentityPath(supportDirectory) {
174
+ const dir = supportDirectory ?? resolveOpenScoutSupportPaths().supportDirectory;
175
+ return join2(dir, NODE_IDENTITY_FILE);
176
+ }
177
+ function loadOrCreateNodeIdentity(supportDirectory) {
178
+ const path = nodeIdentityPath(supportDirectory);
179
+ if (existsSync2(path)) {
180
+ return readAndValidateNodeIdentity(path);
181
+ }
182
+ return createNodeIdentity(supportDirectory);
183
+ }
184
+ function readStableNodeQualifier(supportDirectory) {
185
+ const path = nodeIdentityPath(supportDirectory);
186
+ const cached = stableNodeQualifierCache.get(path);
187
+ if (cached) {
188
+ return cached;
189
+ }
190
+ if (!existsSync2(path)) {
191
+ return null;
192
+ }
193
+ const nodeQualifier = normalizeNodeQualifier(readAndValidateNodeIdentity(path).nodeQualifier);
194
+ if (nodeQualifier) {
195
+ stableNodeQualifierCache.set(path, nodeQualifier);
196
+ }
197
+ return nodeQualifier || null;
198
+ }
199
+ function readAndValidateNodeIdentity(path) {
200
+ let parsed;
201
+ try {
202
+ parsed = JSON.parse(readFileSync(path, "utf8"));
203
+ } catch {
204
+ throw new Error(`Corrupt node identity at ${path}; remove it to generate a fresh one.`);
205
+ }
206
+ if (parsed.version !== 1 || !parsed.publicKey || !parsed.privateKey) {
207
+ throw new Error(`Corrupt node identity at ${path}; remove it to generate a fresh one.`);
208
+ }
209
+ if (parsed.nodeQualifier !== undefined && normalizePersistedNodeQualifier(parsed.nodeQualifier) !== parsed.nodeQualifier) {
210
+ throw new Error(`Corrupt node identity at ${path}; remove it to generate a fresh one.`);
211
+ }
212
+ try {
213
+ const derived = createPublicKey(importPrivateKey(parsed.privateKey)).export({ type: "spki", format: "der" }).toString("base64");
214
+ if (derived !== parsed.publicKey) {
215
+ throw new Error("mismatch");
216
+ }
217
+ } catch {
218
+ throw new Error(`Node identity at ${path} has mismatched or invalid keys; remove it to generate a fresh one.`);
219
+ }
220
+ return parsed;
221
+ }
222
+ function normalizePersistedNodeQualifier(value) {
223
+ return typeof value === "string" ? value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "") : "";
224
+ }
225
+ function normalizeNodeQualifier(value) {
226
+ return stripBonjourCollisionSuffix(normalizePersistedNodeQualifier(value));
227
+ }
228
+ function createNodeIdentity(supportDirectory) {
229
+ if (!supportDirectory) {
230
+ assertTestIsolatedUserData("write the node identity", "OPENSCOUT_SUPPORT_DIRECTORY");
231
+ }
232
+ const path = nodeIdentityPath(supportDirectory);
233
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519");
234
+ const identity = {
235
+ version: 1,
236
+ publicKey: publicKey.export({ type: "spki", format: "der" }).toString("base64"),
237
+ privateKey: privateKey.export({ type: "pkcs8", format: "der" }).toString("base64"),
238
+ createdAt: Date.now()
239
+ };
240
+ mkdirSync2(dirname(path), { recursive: true });
241
+ try {
242
+ writeFileSync2(path, `${JSON.stringify(identity, null, 2)}
243
+ `, { encoding: "utf8", mode: 384, flag: "wx" });
244
+ } catch (error) {
245
+ if (error.code === "EEXIST") {
246
+ return readAndValidateNodeIdentity(path);
247
+ }
248
+ throw error;
249
+ }
250
+ try {
251
+ chmodSync(path, 384);
252
+ } catch {}
253
+ return identity;
254
+ }
255
+ function nodeKeyId(publicKeyBase64) {
256
+ return createHash("sha256").update(Buffer.from(publicKeyBase64, "base64")).digest("hex");
257
+ }
258
+ function nodeFingerprint(publicKeyBase64) {
259
+ const digest = createHash("sha256").update(Buffer.from(publicKeyBase64, "base64")).digest();
260
+ const encoded = base32Encode(digest.subarray(0, 10)).toLowerCase();
261
+ return `${NODE_FINGERPRINT_PREFIX}:${encoded.slice(0, 4)}-${encoded.slice(4, 8)}`;
262
+ }
263
+ function signNodePayload(identity, payload) {
264
+ const key = importPrivateKey(identity.privateKey);
265
+ return sign(null, typeof payload === "string" ? Buffer.from(payload, "utf8") : payload, key).toString("base64");
266
+ }
267
+ function verifyNodeSignature(publicKeyBase64, payload, signatureBase64) {
268
+ try {
269
+ const key = importPublicKey(publicKeyBase64);
270
+ return verify(null, typeof payload === "string" ? Buffer.from(payload, "utf8") : payload, key, Buffer.from(signatureBase64, "base64"));
271
+ } catch {
272
+ return false;
273
+ }
274
+ }
275
+ function canonicalJson(value) {
276
+ if (value === null || typeof value !== "object") {
277
+ return JSON.stringify(value);
278
+ }
279
+ if (Array.isArray(value)) {
280
+ return `[${value.map(canonicalJson).join(",")}]`;
281
+ }
282
+ const record = value;
283
+ const keys = Object.keys(record).sort();
284
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
285
+ }
286
+ function verifySignedNodeCard(card, now = Date.now()) {
287
+ if (nodeKeyId(card.publicKey) !== card.keyId) {
288
+ return false;
289
+ }
290
+ if (nodeFingerprint(card.publicKey) !== card.fingerprint) {
291
+ return false;
292
+ }
293
+ if (!Number.isFinite(card.expiresAt) || card.expiresAt <= now) {
294
+ return false;
295
+ }
296
+ if (card.tls !== undefined) {
297
+ if (typeof card.tls !== "object" || card.tls === null || typeof card.tls.spkiFingerprint !== "string" || !/^[0-9a-f]{64}$/.test(card.tls.spkiFingerprint)) {
298
+ return false;
299
+ }
300
+ }
301
+ const { signature, ...unsigned } = card;
302
+ return verifyNodeSignature(card.publicKey, canonicalJson(unsigned), signature);
303
+ }
304
+ function base32Encode(input) {
305
+ let bits = 0;
306
+ let value = 0;
307
+ let output = "";
308
+ for (const byte of input) {
309
+ value = value << 8 | byte;
310
+ bits += 8;
311
+ while (bits >= 5) {
312
+ output += BASE32_ALPHABET[value >>> bits - 5 & 31];
313
+ bits -= 5;
314
+ }
315
+ }
316
+ if (bits > 0) {
317
+ output += BASE32_ALPHABET[value << 5 - bits & 31];
318
+ }
319
+ return output;
320
+ }
321
+ function importPrivateKey(privateKeyBase64) {
322
+ return createPrivateKey({ key: Buffer.from(privateKeyBase64, "base64"), format: "der", type: "pkcs8" });
323
+ }
324
+ function importPublicKey(publicKeyBase64) {
325
+ return createPublicKey({ key: Buffer.from(publicKeyBase64, "base64"), format: "der", type: "spki" });
326
+ }
327
+ var NODE_IDENTITY_FILE = "node-identity.json", NODE_FINGERPRINT_PREFIX = "osc1", NODE_CARD_TTL_MS, stableNodeQualifierCache, BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
328
+ var init_node_identity = __esm(() => {
329
+ init_support_paths();
330
+ NODE_CARD_TTL_MS = 24 * 60 * 60 * 1000;
331
+ stableNodeQualifierCache = new Map;
332
+ });
333
+
334
+ // ../runtime/src/local-config.ts
335
+ import {
336
+ existsSync as existsSync3,
337
+ mkdirSync as mkdirSync3,
338
+ readFileSync as readFileSync2,
339
+ renameSync as renameSync2,
340
+ writeFileSync as writeFileSync3
341
+ } from "fs";
342
+ import { homedir as homedir2, hostname as osHostname } from "os";
343
+ import { dirname as dirname2, join as join3 } from "path";
130
344
  function localConfigHome() {
131
- return process.env.OPENSCOUT_HOME ?? join2(homedir2(), ".openscout");
345
+ return process.env.OPENSCOUT_HOME ?? join3(homedir2(), ".openscout");
132
346
  }
133
347
  function localConfigPath() {
134
- return join2(localConfigHome(), "config.json");
348
+ return join3(localConfigHome(), "config.json");
135
349
  }
136
350
  function loadLocalConfig() {
137
351
  const configPath = localConfigPath();
138
- if (!existsSync2(configPath))
352
+ if (!existsSync3(configPath))
139
353
  return { version: LOCAL_CONFIG_VERSION };
140
354
  try {
141
- return validateLocalConfig(JSON.parse(readFileSync(configPath, "utf8")));
355
+ return validateLocalConfig(JSON.parse(readFileSync2(configPath, "utf8")));
142
356
  } catch {
143
357
  return { version: LOCAL_CONFIG_VERSION };
144
358
  }
@@ -222,6 +436,7 @@ function resolveHost() {
222
436
  var LOCAL_CONFIG_VERSION = 1, DEFAULT_SCOUT_WEB_PORTAL_HOST = "scout.local", DEFAULT_SCOUT_WEB_DEV_HOST, OPENSCOUT_PORTS, DEFAULT_LOCAL_CONFIG;
223
437
  var init_local_config = __esm(() => {
224
438
  init_support_paths();
439
+ init_node_identity();
225
440
  DEFAULT_SCOUT_WEB_DEV_HOST = `dev.${DEFAULT_SCOUT_WEB_PORTAL_HOST}`;
226
441
  OPENSCOUT_PORTS = {
227
442
  broker: 43110,
@@ -246,7 +461,7 @@ var init_local_config = __esm(() => {
246
461
  });
247
462
 
248
463
  // ../runtime/src/open-scout-network.ts
249
- import { readFileSync as readFileSync2 } from "fs";
464
+ import { readFileSync as readFileSync3 } from "fs";
250
465
  function defaultOpenScoutNetworkSettings() {
251
466
  return {
252
467
  discoveryEnabled: false,
@@ -267,7 +482,7 @@ function normalizeOpenScoutNetworkSettings(input) {
267
482
  }
268
483
  function readOpenScoutNetworkSettingsSync() {
269
484
  try {
270
- const raw = readFileSync2(resolveOpenScoutSupportPaths().settingsPath, "utf8");
485
+ const raw = readFileSync3(resolveOpenScoutSupportPaths().settingsPath, "utf8");
271
486
  const parsed = JSON.parse(raw);
272
487
  const network = isRecord(parsed) && isRecord(parsed.network) ? parsed.network : {};
273
488
  return normalizeOpenScoutNetworkSettings(isRecord(network.openScoutNetwork) ? network.openScoutNetwork : {});
@@ -310,7 +525,7 @@ var init_open_scout_network = __esm(() => {
310
525
  // ../agent-sessions/src/codex-executable.ts
311
526
  import { execFileSync } from "child_process";
312
527
  import { accessSync, constants } from "fs";
313
- import { delimiter, join as join3 } from "path";
528
+ import { delimiter, join as join4 } from "path";
314
529
  function isExecutable(filePath) {
315
530
  if (!filePath)
316
531
  return false;
@@ -354,11 +569,11 @@ function codexAppBundleCandidates(env) {
354
569
  const appNames = ["Codex.app", "ChatGPT.app"];
355
570
  const candidates = appNames.flatMap((appName) => [
356
571
  {
357
- path: join3("/Applications", appName, "Contents", "Resources", "codex"),
572
+ path: join4("/Applications", appName, "Contents", "Resources", "codex"),
358
573
  source: "codex_app_bundle"
359
574
  },
360
575
  {
361
- path: join3(env.HOME ?? "", "Applications", appName, "Contents", "Resources", "codex"),
576
+ path: join4(env.HOME ?? "", "Applications", appName, "Contents", "Resources", "codex"),
362
577
  source: "codex_app_bundle"
363
578
  }
364
579
  ]);
@@ -366,7 +581,7 @@ function codexAppBundleCandidates(env) {
366
581
  }
367
582
  function pathCandidates(env) {
368
583
  return (env.PATH ?? "").split(delimiter).filter(Boolean).map((directory) => ({
369
- path: join3(directory, "codex"),
584
+ path: join4(directory, "codex"),
370
585
  source: "path"
371
586
  }));
372
587
  }
@@ -377,7 +592,7 @@ function commonCandidates(env) {
377
592
  "/opt/homebrew/bin",
378
593
  "/usr/local/bin"
379
594
  ].filter(Boolean).map((directory) => ({
380
- path: join3(directory, "codex"),
595
+ path: join4(directory, "codex"),
381
596
  source: "common"
382
597
  }));
383
598
  }
@@ -661,10 +876,10 @@ var init_auth = __esm(() => {
661
876
 
662
877
  // ../runtime/src/harness-catalog.ts
663
878
  import { execFileSync as execFileSync2 } from "child_process";
664
- import { existsSync as existsSync4, statSync } from "fs";
879
+ import { existsSync as existsSync5, statSync } from "fs";
665
880
  import { mkdir, readFile, writeFile } from "fs/promises";
666
881
  import { homedir as homedir4 } from "os";
667
- import { dirname as dirname2, join as join4 } from "path";
882
+ import { dirname as dirname3, join as join5 } from "path";
668
883
  function readinessFromAuthModel(harness) {
669
884
  const model = harnessAuthModel(harness);
670
885
  if (!model)
@@ -697,7 +912,7 @@ function expandHomePath(value) {
697
912
  if (value === "~")
698
913
  return home;
699
914
  if (value.startsWith("~/"))
700
- return join4(home, value.slice(2));
915
+ return join5(home, value.slice(2));
701
916
  return value;
702
917
  }
703
918
  function defaultWhichBinary(binary, platform) {
@@ -731,7 +946,7 @@ function defaultRunCommand(command, platform) {
731
946
  }
732
947
  function defaultRequirementExists(requirement) {
733
948
  const expanded = expandHomePath(requirement.path);
734
- if (!existsSync4(expanded))
949
+ if (!existsSync5(expanded))
735
950
  return false;
736
951
  if (requirement.fileType === "any" || !requirement.fileType)
737
952
  return true;
@@ -813,6 +1028,7 @@ function codexCandidateReport(candidate, selectedPath) {
813
1028
  function createBuiltInHarnessCatalog() {
814
1029
  return BUILT_IN_HARNESS_CATALOG.map((entry) => ({
815
1030
  ...entry,
1031
+ aliases: entry.aliases ? [...entry.aliases] : undefined,
816
1032
  tags: [...entry.tags],
817
1033
  support: { ...entry.support },
818
1034
  install: entry.install ? { ...entry.install, requires: [...entry.install.requires ?? []] } : undefined,
@@ -959,7 +1175,7 @@ async function readHarnessCatalogOverrides(overridePath = resolveOpenScoutSuppor
959
1175
  }
960
1176
  }
961
1177
  async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
962
- await mkdir(dirname2(overridePath), { recursive: true });
1178
+ await mkdir(dirname3(overridePath), { recursive: true });
963
1179
  const payload = {
964
1180
  version: HARNESS_CATALOG_VERSION,
965
1181
  entries: overrides,
@@ -969,7 +1185,7 @@ async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpe
969
1185
  `, "utf8");
970
1186
  }
971
1187
  async function ensureHarnessCatalogOverrideFile(overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
972
- if (existsSync4(overridePath))
1188
+ if (existsSync5(overridePath))
973
1189
  return;
974
1190
  await writeHarnessCatalogOverrides({}, overridePath);
975
1191
  }
@@ -1181,6 +1397,7 @@ var init_harness_catalog = __esm(() => {
1181
1397
  {
1182
1398
  name: "opencode",
1183
1399
  harness: "opencode",
1400
+ aliases: ["oc", "opencode2"],
1184
1401
  label: "OpenCode",
1185
1402
  description: "OpenCode's coding agent over ACP, fronting many model vendors via OpenCode Zen",
1186
1403
  homepage: "https://opencode.ai/docs/",
@@ -1378,7 +1595,8 @@ function canonicalizeIdentity(input) {
1378
1595
  const definitionId = normalizeAgentIdentitySegment(input.definitionId);
1379
1596
  const workspaceQualifier = input.workspaceQualifier ? normalizeAgentIdentitySegment(input.workspaceQualifier) : undefined;
1380
1597
  const profile = input.profile ? normalizeAgentIdentitySegment(input.profile) : undefined;
1381
- const harness = input.harness ? normalizeAgentIdentitySegment(input.harness) : undefined;
1598
+ const rawHarness = input.harness ? normalizeAgentIdentitySegment(input.harness) : undefined;
1599
+ const harness = rawHarness === "oc" ? "opencode" : rawHarness;
1382
1600
  const model = input.model ? normalizeAgentIdentitySegment(input.model) : undefined;
1383
1601
  const nodeQualifier = input.nodeQualifier ? normalizeAgentIdentitySegment(input.nodeQualifier) : undefined;
1384
1602
  if (!definitionId) {
@@ -2341,6 +2559,20 @@ var init_agent_runs = __esm(() => {
2341
2559
  // ../protocol/src/budget.ts
2342
2560
  var init_budget = () => {};
2343
2561
 
2562
+ // ../protocol/src/presence.ts
2563
+ function presenceLifecycle(beat, now, options = {}) {
2564
+ if (now < beat.staleAt)
2565
+ return "fresh";
2566
+ const goneAfterStaleMs = options.goneAfterStaleMs ?? PRESENCE_GONE_AFTER_STALE_MS;
2567
+ if (now < beat.staleAt + goneAfterStaleMs)
2568
+ return "stale";
2569
+ return "gone";
2570
+ }
2571
+ function isPresenceGone(beat, now, options = {}) {
2572
+ return presenceLifecycle(beat, now, options) === "gone";
2573
+ }
2574
+ var PRESENCE_STALE_AFTER_MS = 45000, PRESENCE_GONE_AFTER_STALE_MS = 60000;
2575
+
2344
2576
  // ../protocol/src/host-integrations.ts
2345
2577
  var init_host_integrations = () => {};
2346
2578
 
@@ -2807,7 +3039,9 @@ var init_runtime_profiles = __esm(() => {
2807
3039
  "fable",
2808
3040
  "kimi",
2809
3041
  "grok",
2810
- "opus"
3042
+ "opus",
3043
+ "oc",
3044
+ "opencode"
2811
3045
  ];
2812
3046
  });
2813
3047
 
@@ -3018,6 +3252,14 @@ var init_scout_composer = __esm(() => {
3018
3252
  // ../protocol/src/inbox.ts
3019
3253
  var init_inbox = () => {};
3020
3254
 
3255
+ // ../protocol/src/events.ts
3256
+ var EPHEMERAL_CONTROL_EVENT_KINDS;
3257
+ var init_events = __esm(() => {
3258
+ EPHEMERAL_CONTROL_EVENT_KINDS = new Set([
3259
+ "presence.updated"
3260
+ ]);
3261
+ });
3262
+
3021
3263
  // ../protocol/src/cursor-transport.ts
3022
3264
  var init_cursor_transport = () => {};
3023
3265
 
@@ -3112,6 +3354,7 @@ var init_src = __esm(() => {
3112
3354
  init_reserved_vocabulary();
3113
3355
  init_scout_composer();
3114
3356
  init_inbox();
3357
+ init_events();
3115
3358
  init_permission_policy();
3116
3359
  init_cursor_transport();
3117
3360
  init_terminal_surface_id();
@@ -4697,7 +4940,7 @@ var init_model_window_registry = __esm(() => {
4697
4940
  });
4698
4941
 
4699
4942
  // ../agent-sessions/src/history.ts
4700
- import { basename, dirname as dirname3 } from "path";
4943
+ import { basename, dirname as dirname4 } from "path";
4701
4944
  function decodeClaudeProjectsSlug(name) {
4702
4945
  if (!name || !name.startsWith("-")) {
4703
4946
  return null;
@@ -4709,7 +4952,7 @@ function decodeClaudeProjectsSlug(name) {
4709
4952
  return `/${tail.replace(/-/g, "/")}`;
4710
4953
  }
4711
4954
  function inferClaudeHistoryCwd(path2) {
4712
- const parent = basename(dirname3(path2));
4955
+ const parent = basename(dirname4(path2));
4713
4956
  return decodeClaudeProjectsSlug(parent);
4714
4957
  }
4715
4958
  function deriveHistoryName(path2) {
@@ -4717,7 +4960,7 @@ function deriveHistoryName(path2) {
4717
4960
  if (claudeCwd) {
4718
4961
  return basename(claudeCwd) || claudeCwd;
4719
4962
  }
4720
- const parent = basename(dirname3(path2));
4963
+ const parent = basename(dirname4(path2));
4721
4964
  return parent || basename(path2) || "History Session";
4722
4965
  }
4723
4966
  function normalizeTimestamp(value) {
@@ -6619,9 +6862,9 @@ function createLiveNormalizerContext(sessionId) {
6619
6862
  }
6620
6863
 
6621
6864
  // ../agent-sessions/src/adapters/claude-code/team-topology.ts
6622
- import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
6865
+ import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
6623
6866
  import { homedir as homedir5 } from "os";
6624
- import { basename as basename2, dirname as dirname4, join as join5, relative } from "path";
6867
+ import { basename as basename2, dirname as dirname5, join as join6, relative } from "path";
6625
6868
  function isObject(value) {
6626
6869
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6627
6870
  }
@@ -6644,7 +6887,7 @@ function sourceRefId(kind, value) {
6644
6887
  }
6645
6888
  function readJsonObject(path2) {
6646
6889
  try {
6647
- const parsed = JSON.parse(readFileSync4(path2, "utf8"));
6890
+ const parsed = JSON.parse(readFileSync5(path2, "utf8"));
6648
6891
  return isObject(parsed) ? parsed : null;
6649
6892
  } catch {
6650
6893
  return null;
@@ -6665,17 +6908,17 @@ function statIsFile(path2) {
6665
6908
  }
6666
6909
  }
6667
6910
  function readTeamConfigs(homeDir) {
6668
- const teamsRoot = join5(homeDir, ".claude", "teams");
6669
- if (!existsSync5(teamsRoot) || !statIsDirectory(teamsRoot)) {
6911
+ const teamsRoot = join6(homeDir, ".claude", "teams");
6912
+ if (!existsSync6(teamsRoot) || !statIsDirectory(teamsRoot)) {
6670
6913
  return [];
6671
6914
  }
6672
6915
  const teams = [];
6673
6916
  for (const entry of readdirSync(teamsRoot)) {
6674
- const teamDir = join5(teamsRoot, entry);
6917
+ const teamDir = join6(teamsRoot, entry);
6675
6918
  if (!statIsDirectory(teamDir)) {
6676
6919
  continue;
6677
6920
  }
6678
- const configPath = join5(teamDir, "config.json");
6921
+ const configPath = join6(teamDir, "config.json");
6679
6922
  const config = readJsonObject(configPath);
6680
6923
  if (!config) {
6681
6924
  continue;
@@ -6813,8 +7056,8 @@ function membersFromConfig(team, groupId, configRefId) {
6813
7056
  return { agents, relationships, agentByExternal };
6814
7057
  }
6815
7058
  function readTaskFiles(tasksRoot, teamName) {
6816
- const teamTasksRoot = join5(tasksRoot, teamName);
6817
- if (!existsSync5(teamTasksRoot) || !statIsDirectory(teamTasksRoot)) {
7059
+ const teamTasksRoot = join6(tasksRoot, teamName);
7060
+ if (!existsSync6(teamTasksRoot) || !statIsDirectory(teamTasksRoot)) {
6818
7061
  return [];
6819
7062
  }
6820
7063
  const result = [];
@@ -6824,7 +7067,7 @@ function readTaskFiles(tasksRoot, teamName) {
6824
7067
  if (!current)
6825
7068
  continue;
6826
7069
  for (const entry of readdirSync(current)) {
6827
- const path2 = join5(current, entry);
7070
+ const path2 = join6(current, entry);
6828
7071
  if (statIsDirectory(path2)) {
6829
7072
  stack.push(path2);
6830
7073
  } else if (statIsFile(path2)) {
@@ -6855,14 +7098,14 @@ function firstMarkdownTitle(raw) {
6855
7098
  function parseTaskFile(taskPath, teamName, tasksRoot, sourceRef) {
6856
7099
  let raw;
6857
7100
  try {
6858
- raw = readFileSync4(taskPath, "utf8");
7101
+ raw = readFileSync5(taskPath, "utf8");
6859
7102
  } catch {
6860
7103
  return null;
6861
7104
  }
6862
- const relativePath = relative(join5(tasksRoot, teamName), taskPath);
7105
+ const relativePath = relative(join6(tasksRoot, teamName), taskPath);
6863
7106
  const fallbackId = relativePath.replace(/\.[^.]+$/u, "");
6864
7107
  const fallbackTitle = firstMarkdownTitle(raw) ?? basename2(fallbackId);
6865
- const inferredState = inferTaskStateFromPath(dirname4(relativePath));
7108
+ const inferredState = inferTaskStateFromPath(dirname5(relativePath));
6866
7109
  let parsed = null;
6867
7110
  try {
6868
7111
  const json = JSON.parse(raw);
@@ -6893,7 +7136,7 @@ function parseTaskFile(taskPath, teamName, tasksRoot, sourceRef) {
6893
7136
  };
6894
7137
  }
6895
7138
  function tasksFromFiles(homeDir, teamName, agentByExternal) {
6896
- const tasksRoot = join5(homeDir, ".claude", "tasks");
7139
+ const tasksRoot = join6(homeDir, ".claude", "tasks");
6897
7140
  const taskFiles = readTaskFiles(tasksRoot, teamName);
6898
7141
  const sourceRefs = [];
6899
7142
  const parsedTasks = [];
@@ -8107,9 +8350,9 @@ function flushLine(line, onLine) {
8107
8350
  }
8108
8351
 
8109
8352
  // ../agent-sessions/src/adapters/claude-code/adapter.ts
8110
- import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
8353
+ import { existsSync as existsSync7, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
8111
8354
  import { homedir as homedir6 } from "os";
8112
- import { delimiter as delimiter2, join as join6 } from "path";
8355
+ import { delimiter as delimiter2, join as join7 } from "path";
8113
8356
  function asRecord2(value) {
8114
8357
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
8115
8358
  }
@@ -8122,8 +8365,8 @@ function resolveClaudeResumeContext(config) {
8122
8365
  if (!resumeId) {
8123
8366
  return null;
8124
8367
  }
8125
- const projectsRoot = join6(homedir6(), ".claude", "projects");
8126
- if (!existsSync6(projectsRoot)) {
8368
+ const projectsRoot = join7(homedir6(), ".claude", "projects");
8369
+ if (!existsSync7(projectsRoot)) {
8127
8370
  return null;
8128
8371
  }
8129
8372
  let projectSlugs;
@@ -8133,8 +8376,8 @@ function resolveClaudeResumeContext(config) {
8133
8376
  return null;
8134
8377
  }
8135
8378
  for (const slug of projectSlugs) {
8136
- const sessionPath = join6(projectsRoot, slug, `${resumeId}.jsonl`);
8137
- if (!existsSync6(sessionPath)) {
8379
+ const sessionPath = join7(projectsRoot, slug, `${resumeId}.jsonl`);
8380
+ if (!existsSync7(sessionPath)) {
8138
8381
  continue;
8139
8382
  }
8140
8383
  const cwd = decodeClaudeProjectsSlug2(slug);
@@ -8174,7 +8417,7 @@ function resolveExecutableFromPath(command, env) {
8174
8417
  for (const directory of pathValue.split(delimiter2)) {
8175
8418
  if (!directory)
8176
8419
  continue;
8177
- const candidate = join6(directory, command);
8420
+ const candidate = join7(directory, command);
8178
8421
  try {
8179
8422
  if (statSync3(candidate).isFile()) {
8180
8423
  return candidate;
@@ -8481,9 +8724,9 @@ var init_claude_code = __esm(() => {
8481
8724
  });
8482
8725
 
8483
8726
  // ../agent-sessions/src/codex-launch-config.ts
8484
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync7 } from "fs";
8727
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync8 } from "fs";
8485
8728
  import { homedir as homedir7 } from "os";
8486
- import { basename as basename3, delimiter as delimiter3, dirname as dirname5, join as join7, resolve } from "path";
8729
+ import { basename as basename3, delimiter as delimiter3, dirname as dirname6, join as join8, resolve } from "path";
8487
8730
  import { fileURLToPath } from "url";
8488
8731
  function isExecutable2(filePath) {
8489
8732
  if (!filePath) {
@@ -8504,7 +8747,7 @@ function ancestorChain(start) {
8504
8747
  let current = resolve(start);
8505
8748
  while (true) {
8506
8749
  chain.push(current);
8507
- const parent = dirname5(current);
8750
+ const parent = dirname6(current);
8508
8751
  if (parent === current) {
8509
8752
  return chain;
8510
8753
  }
@@ -8514,14 +8757,14 @@ function ancestorChain(start) {
8514
8757
  function resolveExecutableFromSearchPath(names, env) {
8515
8758
  const pathEntries = (env.PATH ?? "").split(delimiter3).filter(Boolean);
8516
8759
  const commonDirectories = [
8517
- join7(homedir7(), ".local", "bin"),
8518
- join7(homedir7(), ".bun", "bin"),
8760
+ join8(homedir7(), ".local", "bin"),
8761
+ join8(homedir7(), ".bun", "bin"),
8519
8762
  "/opt/homebrew/bin",
8520
8763
  "/usr/local/bin"
8521
8764
  ];
8522
8765
  for (const directory of [...pathEntries, ...commonDirectories]) {
8523
8766
  for (const name of names) {
8524
- const candidate = join7(directory, name);
8767
+ const candidate = join8(directory, name);
8525
8768
  if (isExecutable2(candidate)) {
8526
8769
  return candidate;
8527
8770
  }
@@ -8560,12 +8803,12 @@ function resolveScoutExecutable(env) {
8560
8803
  return resolveExecutableFromSearchPath(["scout"], env);
8561
8804
  }
8562
8805
  function resolveRepoScoutScript(currentDirectory) {
8563
- const moduleDirectory = dirname5(fileURLToPath(import.meta.url));
8806
+ const moduleDirectory = dirname6(fileURLToPath(import.meta.url));
8564
8807
  const starts = uniquePaths([currentDirectory, moduleDirectory]);
8565
8808
  for (const start of starts) {
8566
8809
  for (const candidate of ancestorChain(start)) {
8567
- const scriptPath = join7(candidate, "apps", "desktop", "bin", "scout.ts");
8568
- if (existsSync7(scriptPath)) {
8810
+ const scriptPath = join8(candidate, "apps", "desktop", "bin", "scout.ts");
8811
+ if (existsSync8(scriptPath)) {
8569
8812
  return scriptPath;
8570
8813
  }
8571
8814
  }
@@ -8655,7 +8898,7 @@ var init_secret_redaction = __esm(() => {
8655
8898
  // ../agent-sessions/src/local/transports/codex-app-server.ts
8656
8899
  import { spawn } from "child_process";
8657
8900
  import { appendFile, mkdir as mkdir2, readFile as readFile2, rm, stat, writeFile as writeFile2 } from "fs/promises";
8658
- import { join as join8 } from "path";
8901
+ import { join as join9 } from "path";
8659
8902
  function codexAppServerExitMessage(input) {
8660
8903
  if (input.exitKind === "proactive_shutdown") {
8661
8904
  return `Codex app-server session for ${input.agentName} was stopped by OpenScout` + (input.reason ? `: ${input.reason}` : "") + ".";
@@ -8970,7 +9213,7 @@ function parseCodexMaybeJson(value) {
8970
9213
  }
8971
9214
  }
8972
9215
  async function readCodexSessionCatalog(runtimeDirectory) {
8973
- const raw = await readOptionalFile(join8(runtimeDirectory, SESSION_CATALOG_FILENAME));
9216
+ const raw = await readOptionalFile(join9(runtimeDirectory, SESSION_CATALOG_FILENAME));
8974
9217
  if (!raw) {
8975
9218
  return { activeSessionId: null, sessions: [] };
8976
9219
  }
@@ -8985,7 +9228,7 @@ async function readCodexSessionCatalog(runtimeDirectory) {
8985
9228
  }
8986
9229
  async function writeCodexSessionCatalog(runtimeDirectory, catalog) {
8987
9230
  await mkdir2(runtimeDirectory, { recursive: true });
8988
- await writeFile2(join8(runtimeDirectory, SESSION_CATALOG_FILENAME), JSON.stringify(catalog, null, 2) + `
9231
+ await writeFile2(join9(runtimeDirectory, SESSION_CATALOG_FILENAME), JSON.stringify(catalog, null, 2) + `
8989
9232
  `);
8990
9233
  }
8991
9234
  async function recordCodexSessionCatalog(runtimeDirectory, threadId, input) {
@@ -9013,9 +9256,15 @@ async function recordCodexSessionCatalog(runtimeDirectory, threadId, input) {
9013
9256
  });
9014
9257
  }
9015
9258
  async function closeCodexSessionCatalog(runtimeDirectory, threadId) {
9259
+ if (!threadId) {
9260
+ return;
9261
+ }
9016
9262
  const catalog = await readCodexSessionCatalog(runtimeDirectory);
9263
+ if (catalog.activeSessionId !== threadId) {
9264
+ return;
9265
+ }
9266
+ const activeSessionId = threadId;
9017
9267
  const now = Date.now();
9018
- const activeSessionId = threadId ?? catalog.activeSessionId;
9019
9268
  const sessions = catalog.sessions.map((session) => session.id === activeSessionId && !session.endedAt ? { ...session, endedAt: now } : session);
9020
9269
  await writeCodexSessionCatalog(runtimeDirectory, {
9021
9270
  activeSessionId: null,
@@ -9038,18 +9287,20 @@ class CodexAppServerTransport {
9038
9287
  nextRequestId = 1;
9039
9288
  pendingRequests = new Map;
9040
9289
  starting = null;
9290
+ threadPersistence = Promise.resolve();
9041
9291
  threadId = null;
9042
9292
  threadPath = null;
9293
+ durableThreadId = null;
9043
9294
  proactiveShutdown = null;
9044
9295
  lastConfigSignature;
9045
9296
  notificationListeners = new Set;
9046
9297
  errorListeners = new Set;
9047
9298
  constructor(options) {
9048
9299
  this.options = options;
9049
- this.threadIdPath = join8(options.runtimeDirectory, "codex-thread-id.txt");
9050
- this.statePath = join8(options.runtimeDirectory, "state.json");
9051
- this.stdoutLogPath = join8(options.logsDirectory, "stdout.log");
9052
- this.stderrLogPath = join8(options.logsDirectory, "stderr.log");
9300
+ this.threadIdPath = join9(options.runtimeDirectory, "codex-thread-id.txt");
9301
+ this.statePath = join9(options.runtimeDirectory, "state.json");
9302
+ this.stdoutLogPath = join9(options.logsDirectory, "stdout.log");
9303
+ this.stderrLogPath = join9(options.logsDirectory, "stderr.log");
9053
9304
  this.lastConfigSignature = this.configSignature(options);
9054
9305
  }
9055
9306
  get currentThreadId() {
@@ -9107,7 +9358,7 @@ class CodexAppServerTransport {
9107
9358
  cwd: this.options.cwd,
9108
9359
  input: this.textInput(prompt)
9109
9360
  });
9110
- await this.persistState();
9361
+ await this.persistThreadId();
9111
9362
  return response;
9112
9363
  }
9113
9364
  async steerTurn(prompt, expectedTurnId) {
@@ -9157,10 +9408,12 @@ class CodexAppServerTransport {
9157
9408
  child.kill("SIGKILL");
9158
9409
  }
9159
9410
  }
9411
+ await this.threadPersistence;
9160
9412
  if (options.resetThread) {
9161
- await closeCodexSessionCatalog(this.options.runtimeDirectory, this.threadId);
9413
+ await closeCodexSessionCatalog(this.options.runtimeDirectory, this.durableThreadId);
9162
9414
  this.threadId = null;
9163
9415
  this.threadPath = null;
9416
+ this.durableThreadId = null;
9164
9417
  await rm(this.threadIdPath, { force: true });
9165
9418
  }
9166
9419
  await this.persistState();
@@ -9204,7 +9457,7 @@ class CodexAppServerTransport {
9204
9457
  async startSession() {
9205
9458
  await mkdir2(this.options.runtimeDirectory, { recursive: true });
9206
9459
  await mkdir2(this.options.logsDirectory, { recursive: true });
9207
- await writeFile2(join8(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
9460
+ await writeFile2(join9(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
9208
9461
  this.proactiveShutdown = null;
9209
9462
  try {
9210
9463
  await assertCodexWorkingDirectory(this.options.cwd, this.options.agentName);
@@ -9283,6 +9536,7 @@ class CodexAppServerTransport {
9283
9536
  const requestedThreadId = this.options.threadId?.trim() || null;
9284
9537
  const storedThreadId = requestedThreadId ?? await readOptionalFile(this.threadIdPath);
9285
9538
  if (storedThreadId) {
9539
+ const threadOrigin = requestedThreadId ? "requested" : "stored";
9286
9540
  try {
9287
9541
  const resumed = await this.request("thread/resume", {
9288
9542
  threadId: storedThreadId,
@@ -9294,11 +9548,10 @@ class CodexAppServerTransport {
9294
9548
  });
9295
9549
  this.threadId = resumed.thread.id;
9296
9550
  this.threadPath = resumed.thread.path ?? null;
9297
- await this.persistThreadId();
9298
- await recordCodexSessionCatalog(this.options.runtimeDirectory, this.threadId, this.catalogRuntimeMeta());
9551
+ await this.persistThreadId({ confirmed: true });
9299
9552
  return;
9300
9553
  } catch (error) {
9301
- await appendFile(this.stderrLogPath, `[openscout] failed to resume stored Codex thread ${storedThreadId}: ${errorMessage(error)}
9554
+ await appendFile(this.stderrLogPath, `[openscout] failed to resume ${threadOrigin} Codex thread ${storedThreadId}: ${errorMessage(error)}
9302
9555
  `).catch(() => {
9303
9556
  return;
9304
9557
  });
@@ -9306,9 +9559,11 @@ class CodexAppServerTransport {
9306
9559
  await rm(this.threadIdPath, { force: true }).catch(() => {
9307
9560
  return;
9308
9561
  });
9562
+ await closeCodexSessionCatalog(this.options.runtimeDirectory, storedThreadId);
9563
+ await this.persistState();
9309
9564
  }
9310
9565
  if (requestedThreadId || this.options.requireExistingThread) {
9311
- throw new Error(`Failed to resume requested Codex thread ${storedThreadId}: ${errorMessage(error)}`);
9566
+ throw new Error(`Failed to resume ${threadOrigin} Codex thread ${storedThreadId}: ${errorMessage(error)}`);
9312
9567
  }
9313
9568
  }
9314
9569
  }
@@ -9327,8 +9582,10 @@ class CodexAppServerTransport {
9327
9582
  });
9328
9583
  this.threadId = started.thread.id;
9329
9584
  this.threadPath = started.thread.path ?? null;
9585
+ if (this.durableThreadId !== this.threadId) {
9586
+ this.durableThreadId = null;
9587
+ }
9330
9588
  await this.persistThreadId();
9331
- await recordCodexSessionCatalog(this.options.runtimeDirectory, this.threadId, this.catalogRuntimeMeta());
9332
9589
  }
9333
9590
  catalogRuntimeMeta() {
9334
9591
  return {
@@ -9398,12 +9655,17 @@ class CodexAppServerTransport {
9398
9655
  if (method === "thread/started" || method === "thread/name/updated") {
9399
9656
  const thread = params.thread;
9400
9657
  if (thread?.id) {
9658
+ if (thread.id !== this.threadId) {
9659
+ this.durableThreadId = null;
9660
+ }
9401
9661
  this.threadId = thread.id;
9402
9662
  }
9403
9663
  if ("path" in (thread ?? {})) {
9404
9664
  this.threadPath = thread?.path ?? null;
9405
9665
  }
9406
9666
  this.persistThreadId();
9667
+ } else if (this.threadId && !this.durableThreadId) {
9668
+ this.persistThreadId();
9407
9669
  }
9408
9670
  this.emitNotification(message);
9409
9671
  }
@@ -9455,16 +9717,46 @@ class CodexAppServerTransport {
9455
9717
  });
9456
9718
  this.persistState();
9457
9719
  }
9458
- async persistThreadId() {
9459
- if (!this.threadId) {
9720
+ persistThreadId(options = {}) {
9721
+ const persistence = this.threadPersistence.then(() => this.persistThreadIdNow(options));
9722
+ this.threadPersistence = persistence.catch(() => {
9723
+ return;
9724
+ });
9725
+ return persistence;
9726
+ }
9727
+ async persistThreadIdNow(options) {
9728
+ const threadId = this.threadId;
9729
+ if (!threadId) {
9730
+ this.durableThreadId = null;
9731
+ await rm(this.threadIdPath, { force: true });
9732
+ await this.persistState();
9733
+ return;
9734
+ }
9735
+ let rolloutExists = false;
9736
+ if (this.threadPath) {
9737
+ try {
9738
+ rolloutExists = (await stat(this.threadPath)).isFile();
9739
+ } catch {
9740
+ rolloutExists = false;
9741
+ }
9742
+ }
9743
+ if (!options.confirmed && !rolloutExists && this.durableThreadId !== threadId) {
9744
+ this.durableThreadId = null;
9460
9745
  await rm(this.threadIdPath, { force: true });
9746
+ await this.persistState();
9461
9747
  return;
9462
9748
  }
9463
- await writeFile2(this.threadIdPath, `${this.threadId}
9749
+ const becameDurable = this.durableThreadId !== threadId;
9750
+ await writeFile2(this.threadIdPath, `${threadId}
9464
9751
  `);
9752
+ this.durableThreadId = threadId;
9465
9753
  await this.persistState();
9754
+ if (becameDurable) {
9755
+ await recordCodexSessionCatalog(this.options.runtimeDirectory, threadId, this.catalogRuntimeMeta());
9756
+ }
9466
9757
  }
9467
9758
  async persistState() {
9759
+ const durableThreadPath = this.durableThreadId === this.threadId ? this.threadPath : null;
9468
9760
  await mkdir2(this.options.runtimeDirectory, { recursive: true });
9469
9761
  await writeFile2(this.statePath, JSON.stringify({
9470
9762
  agentId: this.options.agentName,
@@ -9472,8 +9764,8 @@ class CodexAppServerTransport {
9472
9764
  sessionId: this.options.sessionId,
9473
9765
  projectRoot: this.options.cwd,
9474
9766
  cwd: this.options.cwd,
9475
- threadId: this.threadId,
9476
- threadPath: this.threadPath,
9767
+ threadId: this.durableThreadId,
9768
+ threadPath: durableThreadPath,
9477
9769
  requestedThreadId: this.options.threadId ?? null,
9478
9770
  requireExistingThread: this.options.requireExistingThread === true,
9479
9771
  pid: this.process?.pid ?? null,
@@ -9910,9 +10202,9 @@ async function shutdownCodexAppServerLocalAgent(options, shutdownOptions = {}) {
9910
10202
  const session = codexAppServerClients.get(key);
9911
10203
  if (!session) {
9912
10204
  if (shutdownOptions.resetThread) {
9913
- const threadId = await readOptionalFile(join8(options.runtimeDirectory, "codex-thread-id.txt"));
10205
+ const threadId = await readOptionalFile(join9(options.runtimeDirectory, "codex-thread-id.txt"));
9914
10206
  await closeCodexSessionCatalog(options.runtimeDirectory, threadId);
9915
- await rm(join8(options.runtimeDirectory, "codex-thread-id.txt"), { force: true });
10207
+ await rm(join9(options.runtimeDirectory, "codex-thread-id.txt"), { force: true });
9916
10208
  }
9917
10209
  return;
9918
10210
  }
@@ -10787,9 +11079,9 @@ var init_normalizer3 = __esm(() => {
10787
11079
  });
10788
11080
 
10789
11081
  // ../agent-sessions/src/adapters/codex/topology.ts
10790
- import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
11082
+ import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
10791
11083
  import { homedir as homedir8 } from "os";
10792
- import { basename as basename4, join as join9 } from "path";
11084
+ import { basename as basename4, join as join10 } from "path";
10793
11085
  function isObject2(value) {
10794
11086
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
10795
11087
  }
@@ -10906,7 +11198,7 @@ function parseTomlKeyValues(raw) {
10906
11198
  }
10907
11199
  function readTomlKeyValues(path2) {
10908
11200
  try {
10909
- return parseTomlKeyValues(readFileSync5(path2, "utf8"));
11201
+ return parseTomlKeyValues(readFileSync6(path2, "utf8"));
10910
11202
  } catch {
10911
11203
  return null;
10912
11204
  }
@@ -10920,8 +11212,8 @@ function firstString2(record2, keys) {
10920
11212
  return;
10921
11213
  }
10922
11214
  function readAgentDefinitions(root, scope) {
10923
- const agentsDir = join9(root, ".codex", "agents");
10924
- if (!existsSync8(agentsDir) || !statIsDirectory2(agentsDir)) {
11215
+ const agentsDir = join10(root, ".codex", "agents");
11216
+ if (!existsSync9(agentsDir) || !statIsDirectory2(agentsDir)) {
10925
11217
  return { agents: [], sourceRefs: [] };
10926
11218
  }
10927
11219
  const agents = [];
@@ -10929,7 +11221,7 @@ function readAgentDefinitions(root, scope) {
10929
11221
  for (const entry of readdirSync3(agentsDir).sort()) {
10930
11222
  if (!entry.endsWith(".toml"))
10931
11223
  continue;
10932
- const path2 = join9(agentsDir, entry);
11224
+ const path2 = join10(agentsDir, entry);
10933
11225
  if (!statIsFile2(path2))
10934
11226
  continue;
10935
11227
  const parsed = readTomlKeyValues(path2);
@@ -10968,8 +11260,8 @@ function readAgentDefinitions(root, scope) {
10968
11260
  function readProjectAgentsConfig(cwd) {
10969
11261
  if (!cwd)
10970
11262
  return {};
10971
- const configPath = join9(cwd, ".codex", "config.toml");
10972
- if (!existsSync8(configPath) || !statIsFile2(configPath)) {
11263
+ const configPath = join10(cwd, ".codex", "config.toml");
11264
+ if (!existsSync9(configPath) || !statIsFile2(configPath)) {
10973
11265
  return {};
10974
11266
  }
10975
11267
  const parsed = readTomlKeyValues(configPath);
@@ -11232,7 +11524,7 @@ var init_topology = () => {};
11232
11524
 
11233
11525
  // ../agent-sessions/src/adapters/codex/adapter.ts
11234
11526
  import { homedir as homedir9 } from "os";
11235
- import { join as join10 } from "path";
11527
+ import { join as join11 } from "path";
11236
11528
  function errorMessage2(error) {
11237
11529
  if (error instanceof Error) {
11238
11530
  return error.message;
@@ -11259,7 +11551,7 @@ var init_adapter2 = __esm(() => {
11259
11551
  sequence = 0;
11260
11552
  constructor(config) {
11261
11553
  super(config);
11262
- const runtimeRoot = join10(homedir9(), ".scout/pairing", "codex", this.session.id);
11554
+ const runtimeRoot = join11(homedir9(), ".scout/pairing", "codex", this.session.id);
11263
11555
  this.observedTopology = new CodexObservedTopologyTracker({
11264
11556
  cwd: config.cwd ?? process.cwd(),
11265
11557
  homeDir: config.env?.HOME,
@@ -11271,8 +11563,8 @@ var init_adapter2 = __esm(() => {
11271
11563
  model: this.session.model,
11272
11564
  providerMeta: {
11273
11565
  ...this.session.providerMeta ?? {},
11274
- stdoutLogFile: join10(runtimeRoot, "logs/stdout.log"),
11275
- stderrLogFile: join10(runtimeRoot, "logs/stderr.log")
11566
+ stdoutLogFile: join11(runtimeRoot, "logs/stdout.log"),
11567
+ stderrLogFile: join11(runtimeRoot, "logs/stderr.log")
11276
11568
  }
11277
11569
  });
11278
11570
  }
@@ -11331,7 +11623,7 @@ var init_adapter2 = __esm(() => {
11331
11623
  this.setStatus("closed");
11332
11624
  }
11333
11625
  get codexOptions() {
11334
- const runtimeRoot = join10(homedir9(), ".scout/pairing", "codex", this.session.id);
11626
+ const runtimeRoot = join11(homedir9(), ".scout/pairing", "codex", this.session.id);
11335
11627
  const configuredThreadId = this.config.options?.["threadId"];
11336
11628
  const requireExistingThread = this.config.options?.["requireExistingThread"];
11337
11629
  const rawLaunchArgs = this.config.options?.["launchArgs"];
@@ -11343,8 +11635,8 @@ var init_adapter2 = __esm(() => {
11343
11635
  sessionId: this.session.id,
11344
11636
  cwd: this.config.cwd ?? process.cwd(),
11345
11637
  systemPrompt: this.systemPrompt,
11346
- runtimeDirectory: join10(runtimeRoot, "runtime"),
11347
- logsDirectory: join10(runtimeRoot, "logs"),
11638
+ runtimeDirectory: join11(runtimeRoot, "runtime"),
11639
+ logsDirectory: join11(runtimeRoot, "logs"),
11348
11640
  env: this.config.env,
11349
11641
  launchArgs,
11350
11642
  threadId: typeof configuredThreadId === "string" && configuredThreadId.trim().length > 0 ? configuredThreadId.trim() : undefined,
@@ -11363,10 +11655,10 @@ var init_adapter2 = __esm(() => {
11363
11655
  return typeof raw === "string" && raw.trim().length > 0 ? raw : "You are a helpful agent working through Pairing.";
11364
11656
  }
11365
11657
  get stdoutLogPath() {
11366
- return this.transport?.stdoutLogFile ?? join10(this.codexOptions.logsDirectory, "stdout.log");
11658
+ return this.transport?.stdoutLogFile ?? join11(this.codexOptions.logsDirectory, "stdout.log");
11367
11659
  }
11368
11660
  get stderrLogPath() {
11369
- return this.transport?.stderrLogFile ?? join10(this.codexOptions.logsDirectory, "stderr.log");
11661
+ return this.transport?.stderrLogFile ?? join11(this.codexOptions.logsDirectory, "stderr.log");
11370
11662
  }
11371
11663
  enqueue(task) {
11372
11664
  const next = this.serialized.then(task, task);
@@ -11534,9 +11826,9 @@ var init_codex = __esm(() => {
11534
11826
 
11535
11827
  // ../agent-sessions/src/adapters/acp/adapter.ts
11536
11828
  import { spawn as spawn2 } from "child_process";
11537
- import { existsSync as existsSync9 } from "fs";
11829
+ import { existsSync as existsSync10 } from "fs";
11538
11830
  import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
11539
- import { dirname as dirname6, isAbsolute, relative as relative2, resolve as resolve2 } from "path";
11831
+ import { dirname as dirname7, isAbsolute, relative as relative2, resolve as resolve2 } from "path";
11540
11832
  import { pathToFileURL } from "url";
11541
11833
  function isRecord3(value) {
11542
11834
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -11915,7 +12207,7 @@ var init_adapter3 = __esm(() => {
11915
12207
  return;
11916
12208
  }
11917
12209
  const options = this.acpOptions;
11918
- if (!existsSync9(options.cwd)) {
12210
+ if (!existsSync10(options.cwd)) {
11919
12211
  const failure = new Error(`ACP agent working directory does not exist: ${options.cwd}` + ` (harness command: ${options.command})`);
11920
12212
  this.failSession(failure);
11921
12213
  throw failure;
@@ -12575,7 +12867,7 @@ ${plan}`,
12575
12867
  return;
12576
12868
  }
12577
12869
  const filePath = this.resolveAllowedPath(requestedPath);
12578
- await mkdir3(dirname6(filePath), { recursive: true });
12870
+ await mkdir3(dirname7(filePath), { recursive: true });
12579
12871
  await writeFile3(filePath, params.content, "utf8");
12580
12872
  this.writeResult(message.id, {});
12581
12873
  }
@@ -12775,16 +13067,16 @@ var init_acp = __esm(() => {
12775
13067
  });
12776
13068
 
12777
13069
  // ../agent-sessions/src/adapters/grok-acp/adapter.ts
12778
- import { existsSync as existsSync10 } from "fs";
13070
+ import { existsSync as existsSync11 } from "fs";
12779
13071
  import { homedir as homedir10 } from "os";
12780
- import { join as join11 } from "path";
13072
+ import { join as join12 } from "path";
12781
13073
  function defaultGrokCommand(env) {
12782
13074
  const override = firstNonEmptyString(env?.GROK_CLI_BIN, process.env.GROK_CLI_BIN);
12783
13075
  if (override) {
12784
13076
  return override;
12785
13077
  }
12786
- const installed = join11(homedir10(), ".grok", "bin", "grok");
12787
- return existsSync10(installed) ? installed : "grok";
13078
+ const installed = join12(homedir10(), ".grok", "bin", "grok");
13079
+ return existsSync11(installed) ? installed : "grok";
12788
13080
  }
12789
13081
  function isRecord4(value) {
12790
13082
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -12859,9 +13151,9 @@ var init_grok_acp = __esm(() => {
12859
13151
  });
12860
13152
 
12861
13153
  // ../agent-sessions/src/adapters/kimi-acp/adapter.ts
12862
- import { existsSync as existsSync11 } from "fs";
13154
+ import { existsSync as existsSync12 } from "fs";
12863
13155
  import { homedir as homedir11 } from "os";
12864
- import { join as join12 } from "path";
13156
+ import { join as join13 } from "path";
12865
13157
  function isRecord5(value) {
12866
13158
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
12867
13159
  }
@@ -12890,10 +13182,10 @@ function defaultKimiCommand(env) {
12890
13182
  return override;
12891
13183
  }
12892
13184
  const installedCandidates = [
12893
- join12(homedir11(), ".kimi-code", "bin", "kimi"),
12894
- join12(homedir11(), ".local", "bin", "kimi")
13185
+ join13(homedir11(), ".kimi-code", "bin", "kimi"),
13186
+ join13(homedir11(), ".local", "bin", "kimi")
12895
13187
  ];
12896
- return installedCandidates.find((candidate) => existsSync11(candidate)) ?? "kimi";
13188
+ return installedCandidates.find((candidate) => existsSync12(candidate)) ?? "kimi";
12897
13189
  }
12898
13190
  var DEFAULT_KIMI_ARGS, DEFAULT_KIMI_STARTUP_TIMEOUT_MS = 60000, KIMI_ACP_ADAPTER_TYPE = "kimi-acp", createAdapter5 = (config) => {
12899
13191
  const rawOptions = isRecord5(config.options) ? config.options : {};
@@ -15064,7 +15356,7 @@ var init_service = () => {};
15064
15356
  import { readFile as readFile4 } from "fs/promises";
15065
15357
  import { spawn as spawn3 } from "child_process";
15066
15358
  import { homedir as homedir12 } from "os";
15067
- import { join as join13 } from "path";
15359
+ import { join as join14 } from "path";
15068
15360
  async function discover(options = {}) {
15069
15361
  return (await discoverLocal(options))?.endpoint;
15070
15362
  }
@@ -15176,7 +15468,7 @@ async function stop(options = {}) {
15176
15468
  await kill(existing, options);
15177
15469
  }
15178
15470
  function fallback() {
15179
- return join13(process.env["XDG_STATE_HOME"] ?? join13(homedir12(), ".local", "state"), "opencode", "service.json");
15471
+ return join14(process.env["XDG_STATE_HOME"] ?? join14(homedir12(), ".local", "state"), "opencode", "service.json");
15180
15472
  }
15181
15473
  function headers(endpoint) {
15182
15474
  if (endpoint.auth === undefined)
@@ -16025,9 +16317,9 @@ var init_normalizer4 = __esm(() => {
16025
16317
  });
16026
16318
 
16027
16319
  // ../agent-sessions/src/adapters/opencode-v2/adapter.ts
16028
- import { existsSync as existsSync12 } from "fs";
16320
+ import { existsSync as existsSync13 } from "fs";
16029
16321
  import { homedir as homedir13 } from "os";
16030
- import { basename as basename5, isAbsolute as isAbsolute2, join as join14, resolve as resolve3 } from "path";
16322
+ import { basename as basename5, isAbsolute as isAbsolute2, join as join15, resolve as resolve3 } from "path";
16031
16323
  import { pathToFileURL as pathToFileURL2 } from "url";
16032
16324
  function deferred() {
16033
16325
  let resolvePromise;
@@ -16061,10 +16353,10 @@ function defaultOpenCodeV2Binary(env) {
16061
16353
  const candidates = [
16062
16354
  "/opt/homebrew/bin/opencode2",
16063
16355
  "/usr/local/bin/opencode2",
16064
- join14(home, ".opencode", "bin", "opencode2"),
16065
- join14(home, ".local", "bin", "opencode2")
16356
+ join15(home, ".opencode", "bin", "opencode2"),
16357
+ join15(home, ".local", "bin", "opencode2")
16066
16358
  ];
16067
- return candidates.find((candidate) => existsSync12(candidate)) ?? "opencode2";
16359
+ return candidates.find((candidate) => existsSync13(candidate)) ?? "opencode2";
16068
16360
  }
16069
16361
  function modelRef(value, variantValue) {
16070
16362
  const raw = stringValue8(value);
@@ -17094,9 +17386,9 @@ var init_opencode_v2 = __esm(() => {
17094
17386
 
17095
17387
  // ../agent-sessions/src/adapters/opencode-acp/adapter.ts
17096
17388
  import { spawnSync as spawnSync2 } from "child_process";
17097
- import { existsSync as existsSync13 } from "fs";
17389
+ import { existsSync as existsSync14 } from "fs";
17098
17390
  import { homedir as homedir14 } from "os";
17099
- import { join as join15 } from "path";
17391
+ import { join as join16 } from "path";
17100
17392
  function isRecord8(value) {
17101
17393
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
17102
17394
  }
@@ -17127,10 +17419,10 @@ function defaultOpenCodeCommand(env) {
17127
17419
  const installedCandidates = [
17128
17420
  "/opt/homebrew/bin/opencode",
17129
17421
  "/usr/local/bin/opencode",
17130
- join15(homedir14(), ".opencode", "bin", "opencode"),
17131
- join15(homedir14(), ".local", "bin", "opencode")
17422
+ join16(homedir14(), ".opencode", "bin", "opencode"),
17423
+ join16(homedir14(), ".local", "bin", "opencode")
17132
17424
  ];
17133
- return installedCandidates.find((candidate) => existsSync13(candidate)) ?? "opencode";
17425
+ return installedCandidates.find((candidate) => existsSync14(candidate)) ?? "opencode";
17134
17426
  }
17135
17427
  function configContentEnv(rawOptions, env) {
17136
17428
  const model = stringValue9(rawOptions.model);
@@ -17147,7 +17439,7 @@ function configContentEnv(rawOptions, env) {
17147
17439
  return { [OPENCODE_CONFIG_CONTENT_ENV]: JSON.stringify(overlay) };
17148
17440
  }
17149
17441
  function keychainSecret(name, commandOverride) {
17150
- const candidates = commandOverride ? [commandOverride] : ["secret", join15(homedir14(), ".local", "bin", "secret")];
17442
+ const candidates = commandOverride ? [commandOverride] : ["secret", join16(homedir14(), ".local", "bin", "secret")];
17151
17443
  for (const command of candidates) {
17152
17444
  try {
17153
17445
  const result = spawnSync2(command, ["get", name], { encoding: "utf8", timeout: 5000 });
@@ -18213,184 +18505,6 @@ var init_src2 = __esm(() => {
18213
18505
  init_cost();
18214
18506
  });
18215
18507
 
18216
- // ../runtime/src/node-identity.ts
18217
- import {
18218
- createHash,
18219
- createPrivateKey,
18220
- createPublicKey,
18221
- generateKeyPairSync,
18222
- randomBytes,
18223
- sign,
18224
- verify
18225
- } from "crypto";
18226
- import {
18227
- chmodSync,
18228
- existsSync as existsSync14,
18229
- mkdirSync as mkdirSync4,
18230
- readFileSync as readFileSync6,
18231
- renameSync as renameSync2,
18232
- rmSync as rmSync2,
18233
- writeFileSync as writeFileSync4
18234
- } from "fs";
18235
- import { dirname as dirname7, join as join16 } from "path";
18236
- function nodeIdentityPath(supportDirectory) {
18237
- const dir = supportDirectory ?? resolveOpenScoutSupportPaths().supportDirectory;
18238
- return join16(dir, NODE_IDENTITY_FILE);
18239
- }
18240
- function loadOrCreateNodeIdentity(supportDirectory) {
18241
- const path2 = nodeIdentityPath(supportDirectory);
18242
- if (existsSync14(path2)) {
18243
- return readAndValidateNodeIdentity(path2);
18244
- }
18245
- return createNodeIdentity(supportDirectory);
18246
- }
18247
- function readStableNodeQualifier(supportDirectory) {
18248
- const path2 = nodeIdentityPath(supportDirectory);
18249
- const cached = stableNodeQualifierCache.get(path2);
18250
- if (cached) {
18251
- return cached;
18252
- }
18253
- if (!existsSync14(path2)) {
18254
- return null;
18255
- }
18256
- const nodeQualifier = normalizeNodeQualifier(readAndValidateNodeIdentity(path2).nodeQualifier);
18257
- if (nodeQualifier) {
18258
- stableNodeQualifierCache.set(path2, nodeQualifier);
18259
- }
18260
- return nodeQualifier || null;
18261
- }
18262
- function readAndValidateNodeIdentity(path2) {
18263
- let parsed;
18264
- try {
18265
- parsed = JSON.parse(readFileSync6(path2, "utf8"));
18266
- } catch {
18267
- throw new Error(`Corrupt node identity at ${path2}; remove it to generate a fresh one.`);
18268
- }
18269
- if (parsed.version !== 1 || !parsed.publicKey || !parsed.privateKey) {
18270
- throw new Error(`Corrupt node identity at ${path2}; remove it to generate a fresh one.`);
18271
- }
18272
- if (parsed.nodeQualifier !== undefined && normalizeNodeQualifier(parsed.nodeQualifier) !== parsed.nodeQualifier) {
18273
- throw new Error(`Corrupt node identity at ${path2}; remove it to generate a fresh one.`);
18274
- }
18275
- try {
18276
- const derived = createPublicKey(importPrivateKey(parsed.privateKey)).export({ type: "spki", format: "der" }).toString("base64");
18277
- if (derived !== parsed.publicKey) {
18278
- throw new Error("mismatch");
18279
- }
18280
- } catch {
18281
- throw new Error(`Node identity at ${path2} has mismatched or invalid keys; remove it to generate a fresh one.`);
18282
- }
18283
- return parsed;
18284
- }
18285
- function normalizeNodeQualifier(value) {
18286
- return typeof value === "string" ? value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "") : "";
18287
- }
18288
- function createNodeIdentity(supportDirectory) {
18289
- if (!supportDirectory) {
18290
- assertTestIsolatedUserData("write the node identity", "OPENSCOUT_SUPPORT_DIRECTORY");
18291
- }
18292
- const path2 = nodeIdentityPath(supportDirectory);
18293
- const { publicKey, privateKey } = generateKeyPairSync("ed25519");
18294
- const identity = {
18295
- version: 1,
18296
- publicKey: publicKey.export({ type: "spki", format: "der" }).toString("base64"),
18297
- privateKey: privateKey.export({ type: "pkcs8", format: "der" }).toString("base64"),
18298
- createdAt: Date.now()
18299
- };
18300
- mkdirSync4(dirname7(path2), { recursive: true });
18301
- try {
18302
- writeFileSync4(path2, `${JSON.stringify(identity, null, 2)}
18303
- `, { encoding: "utf8", mode: 384, flag: "wx" });
18304
- } catch (error) {
18305
- if (error.code === "EEXIST") {
18306
- return readAndValidateNodeIdentity(path2);
18307
- }
18308
- throw error;
18309
- }
18310
- try {
18311
- chmodSync(path2, 384);
18312
- } catch {}
18313
- return identity;
18314
- }
18315
- function nodeKeyId(publicKeyBase64) {
18316
- return createHash("sha256").update(Buffer.from(publicKeyBase64, "base64")).digest("hex");
18317
- }
18318
- function nodeFingerprint(publicKeyBase64) {
18319
- const digest = createHash("sha256").update(Buffer.from(publicKeyBase64, "base64")).digest();
18320
- const encoded = base32Encode(digest.subarray(0, 10)).toLowerCase();
18321
- return `${NODE_FINGERPRINT_PREFIX}:${encoded.slice(0, 4)}-${encoded.slice(4, 8)}`;
18322
- }
18323
- function signNodePayload(identity, payload) {
18324
- const key = importPrivateKey(identity.privateKey);
18325
- return sign(null, typeof payload === "string" ? Buffer.from(payload, "utf8") : payload, key).toString("base64");
18326
- }
18327
- function verifyNodeSignature(publicKeyBase64, payload, signatureBase64) {
18328
- try {
18329
- const key = importPublicKey(publicKeyBase64);
18330
- return verify(null, typeof payload === "string" ? Buffer.from(payload, "utf8") : payload, key, Buffer.from(signatureBase64, "base64"));
18331
- } catch {
18332
- return false;
18333
- }
18334
- }
18335
- function canonicalJson(value) {
18336
- if (value === null || typeof value !== "object") {
18337
- return JSON.stringify(value);
18338
- }
18339
- if (Array.isArray(value)) {
18340
- return `[${value.map(canonicalJson).join(",")}]`;
18341
- }
18342
- const record2 = value;
18343
- const keys = Object.keys(record2).sort();
18344
- return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record2[key])}`).join(",")}}`;
18345
- }
18346
- function verifySignedNodeCard(card, now = Date.now()) {
18347
- if (nodeKeyId(card.publicKey) !== card.keyId) {
18348
- return false;
18349
- }
18350
- if (nodeFingerprint(card.publicKey) !== card.fingerprint) {
18351
- return false;
18352
- }
18353
- if (!Number.isFinite(card.expiresAt) || card.expiresAt <= now) {
18354
- return false;
18355
- }
18356
- if (card.tls !== undefined) {
18357
- if (typeof card.tls !== "object" || card.tls === null || typeof card.tls.spkiFingerprint !== "string" || !/^[0-9a-f]{64}$/.test(card.tls.spkiFingerprint)) {
18358
- return false;
18359
- }
18360
- }
18361
- const { signature, ...unsigned } = card;
18362
- return verifyNodeSignature(card.publicKey, canonicalJson(unsigned), signature);
18363
- }
18364
- function base32Encode(input) {
18365
- let bits = 0;
18366
- let value = 0;
18367
- let output = "";
18368
- for (const byte of input) {
18369
- value = value << 8 | byte;
18370
- bits += 8;
18371
- while (bits >= 5) {
18372
- output += BASE32_ALPHABET[value >>> bits - 5 & 31];
18373
- bits -= 5;
18374
- }
18375
- }
18376
- if (bits > 0) {
18377
- output += BASE32_ALPHABET[value << 5 - bits & 31];
18378
- }
18379
- return output;
18380
- }
18381
- function importPrivateKey(privateKeyBase64) {
18382
- return createPrivateKey({ key: Buffer.from(privateKeyBase64, "base64"), format: "der", type: "pkcs8" });
18383
- }
18384
- function importPublicKey(publicKeyBase64) {
18385
- return createPublicKey({ key: Buffer.from(publicKeyBase64, "base64"), format: "der", type: "spki" });
18386
- }
18387
- var NODE_IDENTITY_FILE = "node-identity.json", NODE_FINGERPRINT_PREFIX = "osc1", NODE_CARD_TTL_MS, stableNodeQualifierCache, BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
18388
- var init_node_identity = __esm(() => {
18389
- init_support_paths();
18390
- NODE_CARD_TTL_MS = 24 * 60 * 60 * 1000;
18391
- stableNodeQualifierCache = new Map;
18392
- });
18393
-
18394
18508
  // ../../node_modules/.bun/reflect-metadata@0.2.2/node_modules/reflect-metadata/Reflect.js
18395
18509
  var require_Reflect = __commonJS(() => {
18396
18510
  /*! *****************************************************************************
@@ -22452,13 +22566,13 @@ function resolveBrokerUrl(host, port, scope, env = process.env, lanHost = findLa
22452
22566
  return explicit;
22453
22567
  }
22454
22568
  if (scope === "mesh") {
22569
+ if (lanHost) {
22570
+ return buildDefaultBrokerHttpsUrl(lanHost, port);
22571
+ }
22455
22572
  const tailnetHost = readTailscaleSelfWebHostsSync(env)[0];
22456
22573
  if (tailnetHost) {
22457
22574
  return buildDefaultBrokerHttpsUrl(tailnetHost, port);
22458
22575
  }
22459
- if (lanHost) {
22460
- return buildDefaultBrokerHttpsUrl(lanHost, port);
22461
- }
22462
22576
  }
22463
22577
  return buildDefaultBrokerUrl(host, port);
22464
22578
  }
@@ -28357,6 +28471,9 @@ function normalizeManagedHarness(value, fallback2) {
28357
28471
  if (value === "pi") {
28358
28472
  return "pi";
28359
28473
  }
28474
+ if (value === "opencode") {
28475
+ return "opencode";
28476
+ }
28360
28477
  return fallback2;
28361
28478
  }
28362
28479
  function titleCase(value) {
@@ -29096,7 +29213,8 @@ async function detectHarnessMarkers(projectRoot) {
29096
29213
  grok: [],
29097
29214
  "grok-acp": [],
29098
29215
  kimi: [],
29099
- pi: []
29216
+ pi: [],
29217
+ opencode: []
29100
29218
  };
29101
29219
  for (const harness of MANAGED_AGENT_HARNESSES) {
29102
29220
  for (const marker of PROJECT_HARNESS_MARKERS[harness]) {
@@ -29313,6 +29431,8 @@ async function readRelayAgentOverrides() {
29313
29431
  }));
29314
29432
  }
29315
29433
  async function writeRelayAgentOverrides(overrides) {
29434
+ assertTestIsolatedUserData("write the relay-agents registry", "OPENSCOUT_SUPPORT_DIRECTORY");
29435
+ const registryPath = resolveOpenScoutSupportPaths().relayAgentsRegistryPath;
29316
29436
  const normalizedAgents = Object.fromEntries(Object.entries(overrides).map(([agentId, record2]) => {
29317
29437
  const definitionId = normalizeAgentId(record2.definitionId || record2.agentId || agentId);
29318
29438
  const projectRoot = normalizePath(record2.projectRoot);
@@ -29346,7 +29466,11 @@ async function writeRelayAgentOverrides(overrides) {
29346
29466
  }
29347
29467
  ];
29348
29468
  }));
29349
- await writeJsonFile(resolveOpenScoutSupportPaths().relayAgentsRegistryPath, {
29469
+ const registryPathNow = resolveOpenScoutSupportPaths().relayAgentsRegistryPath;
29470
+ if (registryPathNow !== registryPath) {
29471
+ throw new Error(`Refusing to write the relay-agents registry: target moved from ${registryPath} to ${registryPathNow} mid-write (test teardown?).`);
29472
+ }
29473
+ await writeJsonFile(registryPath, {
29350
29474
  version: 1,
29351
29475
  agents: normalizedAgents
29352
29476
  });
@@ -30074,7 +30198,7 @@ var init_setup = __esm(() => {
30074
30198
  init_open_scout_network();
30075
30199
  init_support_paths();
30076
30200
  init_user_project_hints();
30077
- MANAGED_AGENT_HARNESSES = ["claude", "codex", "cursor", "grok", "grok-acp", "kimi", "pi"];
30201
+ MANAGED_AGENT_HARNESSES = ["claude", "codex", "cursor", "grok", "grok-acp", "kimi", "pi", "opencode"];
30078
30202
  DEFAULT_OPERATOR_NAME = guessedOperatorName();
30079
30203
  DEFAULT_CAPABILITIES = ["chat", "invoke", "deliver"];
30080
30204
  PROJECT_SCAN_SKIP_DIRECTORIES = new Set([
@@ -30177,6 +30301,10 @@ var init_setup = __esm(() => {
30177
30301
  pi: [
30178
30302
  "PI.md",
30179
30303
  ".pi"
30304
+ ],
30305
+ opencode: [
30306
+ "OPENCODE.md",
30307
+ ".opencode"
30180
30308
  ]
30181
30309
  };
30182
30310
  PROJECT_STRONG_MARKERS_FLAT_NESTED = partitionFlatAndNestedMarkers(PROJECT_STRONG_MARKERS);
@@ -32993,7 +33121,7 @@ var init_local_agents = __esm(() => {
32993
33121
  // ../web/server/core/pairing/runtime/config.ts
32994
33122
  init_local_config();
32995
33123
  init_open_scout_network();
32996
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
33124
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
32997
33125
  import { homedir as homedir3 } from "os";
32998
33126
  import path from "path";
32999
33127
  var PAIRING_QR_TTL_MS = 5 * 60 * 1000;
@@ -33011,11 +33139,11 @@ function pairingPaths() {
33011
33139
  }
33012
33140
  function loadPairingConfig() {
33013
33141
  const { configPath } = pairingPaths();
33014
- if (!existsSync3(configPath)) {
33142
+ if (!existsSync4(configPath)) {
33015
33143
  return {};
33016
33144
  }
33017
33145
  try {
33018
- const payload = JSON.parse(readFileSync3(configPath, "utf8"));
33146
+ const payload = JSON.parse(readFileSync4(configPath, "utf8"));
33019
33147
  return typeof payload === "object" && payload ? payload : {};
33020
33148
  } catch {
33021
33149
  return {};
@@ -34379,7 +34507,7 @@ function sql(strings, ...params) {
34379
34507
  return new SQL([new StringChunk(str)]);
34380
34508
  }
34381
34509
  sql2.raw = raw;
34382
- function join5(chunks, separator) {
34510
+ function join6(chunks, separator) {
34383
34511
  const result = [];
34384
34512
  for (const [i, chunk] of chunks.entries()) {
34385
34513
  if (i > 0 && separator !== undefined) {
@@ -34389,7 +34517,7 @@ function sql(strings, ...params) {
34389
34517
  }
34390
34518
  return new SQL(result);
34391
34519
  }
34392
- sql2.join = join5;
34520
+ sql2.join = join6;
34393
34521
  function identifier(value) {
34394
34522
  return new Name(value);
34395
34523
  }
@@ -37331,10 +37459,12 @@ class InMemoryControlRuntime {
37331
37459
  }
37332
37460
  }
37333
37461
  // ../runtime/src/sqlite-store.ts
37462
+ init_node_identity();
37334
37463
  init_sqlite_adapter();
37335
37464
 
37336
37465
  // ../runtime/src/control-plane-migrations.ts
37337
37466
  init_support_paths();
37467
+ init_node_identity();
37338
37468
 
37339
37469
  // ../runtime/src/budget-observations.ts
37340
37470
  var QUOTA_HISTORY_BUCKET_MS = 60 * 60 * 1000;
@@ -50102,8 +50232,8 @@ function buildMeshRendezvousPresence(node, options = {}) {
50102
50232
  });
50103
50233
  }
50104
50234
  async function publishMeshRendezvousPresence(node, options) {
50105
- const presence = buildMeshRendezvousPresence(node, { ttlMs: options.config.ttlMs });
50106
- if (!presence) {
50235
+ const presence2 = buildMeshRendezvousPresence(node, { ttlMs: options.config.ttlMs });
50236
+ if (!presence2) {
50107
50237
  options.logger?.warn("[openscout-runtime] mesh rendezvous skipped: no reachable entrypoints to publish");
50108
50238
  return false;
50109
50239
  }
@@ -50115,7 +50245,7 @@ async function publishMeshRendezvousPresence(node, options) {
50115
50245
  accept: "application/json",
50116
50246
  ...rendezvousAuthHeaders(options.config)
50117
50247
  },
50118
- body: JSON.stringify(presence)
50248
+ body: JSON.stringify(presence2)
50119
50249
  });
50120
50250
  if (!response.ok) {
50121
50251
  const detail = await response.text().catch(() => "");
@@ -51827,14 +51957,14 @@ class BrokerRendezvousService {
51827
51957
  }
51828
51958
  return consumedResponse(activeMatch, input.participantId);
51829
51959
  }
51830
- const presence = this.presences.get(key);
51831
- if (presence && presence.participantId !== input.participantId) {
51960
+ const presence2 = this.presences.get(key);
51961
+ if (presence2 && presence2.participantId !== input.participantId) {
51832
51962
  const match = {
51833
51963
  id: this.createMatchId(),
51834
- projectRoot: presence.projectRoot,
51835
- codename: presence.codename,
51836
- normalizedCodename: presence.normalizedCodename,
51837
- participantIds: [presence.participantId, input.participantId],
51964
+ projectRoot: presence2.projectRoot,
51965
+ codename: presence2.codename,
51966
+ normalizedCodename: presence2.normalizedCodename,
51967
+ participantIds: [presence2.participantId, input.participantId],
51838
51968
  createdAt: now,
51839
51969
  expiresAt: now + this.matchTtlMs
51840
51970
  };
@@ -51843,7 +51973,7 @@ class BrokerRendezvousService {
51843
51973
  this.resolveMatchedWaiters(key, match);
51844
51974
  return matchedResponse(match, input.participantId);
51845
51975
  }
51846
- if (!presence) {
51976
+ if (!presence2) {
51847
51977
  const expiredInvite = this.expiredInvites.get(key);
51848
51978
  if (expiredInvite) {
51849
51979
  return expiredResponse(expiredInvite, input.participantId);
@@ -51860,9 +51990,9 @@ class BrokerRendezvousService {
51860
51990
  };
51861
51991
  }
51862
51992
  if (input.waitMs === 0) {
51863
- return waitingResponse(presence);
51993
+ return waitingResponse(presence2);
51864
51994
  }
51865
- return await this.waitForMatch(key, presence, input.waitMs);
51995
+ return await this.waitForMatch(key, presence2, input.waitMs);
51866
51996
  }
51867
51997
  create(projectRoot, participantId, requestedCodename) {
51868
51998
  const now = this.now();
@@ -51884,15 +52014,15 @@ class BrokerRendezvousService {
51884
52014
  suggestion: "choose_another_codename"
51885
52015
  };
51886
52016
  }
51887
- const presence = this.presences.get(key);
51888
- if (presence) {
52017
+ const presence2 = this.presences.get(key);
52018
+ if (presence2) {
51889
52019
  return {
51890
52020
  status: "codename_busy",
51891
- codename: presence.codename,
52021
+ codename: presence2.codename,
51892
52022
  projectRoot,
51893
52023
  participantId,
51894
52024
  participantCount: 1,
51895
- expiresAt: presence.expiresAt,
52025
+ expiresAt: presence2.expiresAt,
51896
52026
  suggestion: "choose_another_codename"
51897
52027
  };
51898
52028
  }
@@ -51910,7 +52040,7 @@ class BrokerRendezvousService {
51910
52040
  throw new Error("could not allocate a unique match codename");
51911
52041
  }
51912
52042
  createPresence(projectRoot, participantId, codename, normalizedCodename, now) {
51913
- const presence = {
52043
+ const presence2 = {
51914
52044
  participantId,
51915
52045
  projectRoot,
51916
52046
  codename,
@@ -51918,14 +52048,14 @@ class BrokerRendezvousService {
51918
52048
  joinedAt: now,
51919
52049
  expiresAt: now + this.presenceTtlMs
51920
52050
  };
51921
- this.presences.set(rendezvousKey(projectRoot, normalizedCodename), presence);
52051
+ this.presences.set(rendezvousKey(projectRoot, normalizedCodename), presence2);
51922
52052
  return {
51923
52053
  status: "created",
51924
52054
  codename,
51925
52055
  projectRoot,
51926
52056
  participantId,
51927
52057
  createdAt: now,
51928
- expiresAt: presence.expiresAt
52058
+ expiresAt: presence2.expiresAt
51929
52059
  };
51930
52060
  }
51931
52061
  hasCodenameInAnotherProject(projectRoot, normalizedCodename) {
@@ -51937,11 +52067,11 @@ class BrokerRendezvousService {
51937
52067
  }
51938
52068
  cleanupExpired() {
51939
52069
  const now = this.now();
51940
- for (const [key, presence] of this.presences) {
51941
- if (presence.expiresAt > now)
52070
+ for (const [key, presence2] of this.presences) {
52071
+ if (presence2.expiresAt > now)
51942
52072
  continue;
51943
52073
  this.presences.delete(key);
51944
- const expiredInvite = this.recordExpiredInvite(presence);
52074
+ const expiredInvite = this.recordExpiredInvite(presence2);
51945
52075
  this.resolveExpiredWaiters(key, expiredInvite);
51946
52076
  }
51947
52077
  for (const [key, match] of this.matches) {
@@ -51959,18 +52089,18 @@ class BrokerRendezvousService {
51959
52089
  if (this.cleanupTimer) {
51960
52090
  clearInterval(this.cleanupTimer);
51961
52091
  }
51962
- for (const [key, presence] of this.presences) {
51963
- this.resolveExpiredWaiters(key, this.recordExpiredInvite(presence));
52092
+ for (const [key, presence2] of this.presences) {
52093
+ this.resolveExpiredWaiters(key, this.recordExpiredInvite(presence2));
51964
52094
  }
51965
52095
  this.presences.clear();
51966
52096
  this.matches.clear();
51967
52097
  this.expiredInvites.clear();
51968
52098
  }
51969
- waitForMatch(key, presence, waitMs) {
52099
+ waitForMatch(key, presence2, waitMs) {
51970
52100
  return new Promise((resolveWait) => {
51971
- const waitDuration = Math.min(waitMs, Math.max(0, presence.expiresAt - this.now()));
52101
+ const waitDuration = Math.min(waitMs, Math.max(0, presence2.expiresAt - this.now()));
51972
52102
  const waiter = {
51973
- participantId: presence.participantId,
52103
+ participantId: presence2.participantId,
51974
52104
  resolve: resolveWait,
51975
52105
  timer: setTimeout(() => {
51976
52106
  this.removeWaiter(key, waiter);
@@ -51991,7 +52121,7 @@ class BrokerRendezvousService {
51991
52121
  resolveWait(expiredResponse(expiredInvite, waiter.participantId));
51992
52122
  return;
51993
52123
  }
51994
- resolveWait(notFoundResponse(presence, waiter.participantId));
52124
+ resolveWait(notFoundResponse(presence2, waiter.participantId));
51995
52125
  }, waitDuration)
51996
52126
  };
51997
52127
  waiter.timer.unref?.();
@@ -52020,15 +52150,15 @@ class BrokerRendezvousService {
52020
52150
  waiter.resolve(expiredResponse(expiredInvite, waiter.participantId));
52021
52151
  }
52022
52152
  }
52023
- recordExpiredInvite(presence) {
52153
+ recordExpiredInvite(presence2) {
52024
52154
  const expiredInvite = {
52025
- projectRoot: presence.projectRoot,
52026
- codename: presence.codename,
52027
- normalizedCodename: presence.normalizedCodename,
52028
- inviteExpiresAt: presence.expiresAt,
52155
+ projectRoot: presence2.projectRoot,
52156
+ codename: presence2.codename,
52157
+ normalizedCodename: presence2.normalizedCodename,
52158
+ inviteExpiresAt: presence2.expiresAt,
52029
52159
  retainUntil: this.now() + this.matchTtlMs
52030
52160
  };
52031
- this.expiredInvites.set(rendezvousKey(presence.projectRoot, presence.normalizedCodename), expiredInvite);
52161
+ this.expiredInvites.set(rendezvousKey(presence2.projectRoot, presence2.normalizedCodename), expiredInvite);
52032
52162
  return expiredInvite;
52033
52163
  }
52034
52164
  removeWaiter(key, waiter) {
@@ -52107,14 +52237,14 @@ function createRandomInviteCodename() {
52107
52237
  function rendezvousKey(projectRoot, normalizedCodename) {
52108
52238
  return `${projectRoot}\x00${normalizedCodename}`;
52109
52239
  }
52110
- function waitingResponse(presence) {
52240
+ function waitingResponse(presence2) {
52111
52241
  return {
52112
52242
  status: "waiting",
52113
- codename: presence.codename,
52114
- projectRoot: presence.projectRoot,
52115
- participantId: presence.participantId,
52116
- joinedAt: presence.joinedAt,
52117
- expiresAt: presence.expiresAt
52243
+ codename: presence2.codename,
52244
+ projectRoot: presence2.projectRoot,
52245
+ participantId: presence2.participantId,
52246
+ joinedAt: presence2.joinedAt,
52247
+ expiresAt: presence2.expiresAt
52118
52248
  };
52119
52249
  }
52120
52250
  function matchedResponse(match, participantId) {
@@ -52159,11 +52289,11 @@ function projectMismatchResponse(input) {
52159
52289
  suggestion: "run_in_invitation_project"
52160
52290
  };
52161
52291
  }
52162
- function notFoundResponse(presence, participantId) {
52292
+ function notFoundResponse(presence2, participantId) {
52163
52293
  return {
52164
52294
  status: "not_found",
52165
- codename: presence.codename,
52166
- projectRoot: presence.projectRoot,
52295
+ codename: presence2.codename,
52296
+ projectRoot: presence2.projectRoot,
52167
52297
  participantId,
52168
52298
  suggestion: "check_codename_or_create"
52169
52299
  };
@@ -53765,6 +53895,126 @@ async function broadcastApnsAlertToActiveMobileDevices(alert) {
53765
53895
  // ../runtime/src/index.ts
53766
53896
  init_permission_policy2();
53767
53897
 
53898
+ // ../runtime/src/activity-transitions.ts
53899
+ class ActivityTransitionTracker {
53900
+ transitions = new Map;
53901
+ record(agentId, activity2, observedAt, now) {
53902
+ const previous = this.transitions.get(agentId);
53903
+ if (previous && previous.activity === activity2) {
53904
+ return previous.transitionAt;
53905
+ }
53906
+ const transitionAt = Number.isFinite(observedAt) ? Math.min(observedAt, now) : now;
53907
+ this.transitions.set(agentId, { activity: activity2, transitionAt });
53908
+ return transitionAt;
53909
+ }
53910
+ peek(agentId) {
53911
+ const transition = this.transitions.get(agentId);
53912
+ return transition ? { ...transition } : undefined;
53913
+ }
53914
+ forget(agentId) {
53915
+ this.transitions.delete(agentId);
53916
+ }
53917
+ clear() {
53918
+ this.transitions.clear();
53919
+ }
53920
+ size() {
53921
+ return this.transitions.size;
53922
+ }
53923
+ }
53924
+ // ../runtime/src/presence-map.ts
53925
+ init_src();
53926
+ var DEFAULT_DETAIL_DEBOUNCE_MS = 5000;
53927
+
53928
+ class BrokerPresenceMap {
53929
+ beats = new Map;
53930
+ lastDetailChangeAt = new Map;
53931
+ staleAfterMs;
53932
+ goneAfterStaleMs;
53933
+ detailDebounceMs;
53934
+ transitions;
53935
+ constructor(options = {}) {
53936
+ this.staleAfterMs = options.staleAfterMs ?? PRESENCE_STALE_AFTER_MS;
53937
+ this.goneAfterStaleMs = options.goneAfterStaleMs ?? PRESENCE_GONE_AFTER_STALE_MS;
53938
+ this.detailDebounceMs = options.detailDebounceMs ?? DEFAULT_DETAIL_DEBOUNCE_MS;
53939
+ this.transitions = options.transitions ?? new ActivityTransitionTracker;
53940
+ }
53941
+ observe(observation, now) {
53942
+ const agentId = observation.agentId ?? observation.status.agentId ?? observation.status.subjectId;
53943
+ if (!agentId)
53944
+ return;
53945
+ const status = observation.status;
53946
+ if (isTransportInferredStall(status))
53947
+ return;
53948
+ const updatedAt = Math.min(status.updatedAt, now);
53949
+ const staleAt = Math.max(status.staleAt ?? 0, updatedAt + this.staleAfterMs);
53950
+ if (isPresenceGone({ staleAt }, now, { goneAfterStaleMs: this.goneAfterStaleMs })) {
53951
+ this.forget(agentId);
53952
+ return;
53953
+ }
53954
+ const previous = this.beats.get(agentId);
53955
+ const detail = status.detail?.title ?? undefined;
53956
+ const transitionAt = this.transitions.record(agentId, status.activity, status.transitionAt ?? status.updatedAt, now);
53957
+ const activityChanged = previous?.activity !== status.activity;
53958
+ const detailChanged = previous !== undefined && previous.detail !== detail;
53959
+ const debounceElapsed = now - (this.lastDetailChangeAt.get(agentId) ?? 0) >= this.detailDebounceMs;
53960
+ const transitioned = previous === undefined || activityChanged || detailChanged && debounceElapsed;
53961
+ if (activityChanged || detailChanged && debounceElapsed) {
53962
+ this.lastDetailChangeAt.set(agentId, now);
53963
+ }
53964
+ const beat = {
53965
+ agentId,
53966
+ displayName: observation.displayName ?? previous?.displayName,
53967
+ activity: status.activity,
53968
+ phase: status.phase,
53969
+ detail,
53970
+ transitionAt,
53971
+ updatedAt,
53972
+ staleAt,
53973
+ confidence: status.confidence,
53974
+ needRef: observation.needRef,
53975
+ boundConversationId: observation.boundConversationId
53976
+ };
53977
+ this.beats.set(agentId, beat);
53978
+ return { beat, transitioned, previousActivity: previous?.activity };
53979
+ }
53980
+ snapshot(now) {
53981
+ this.prune(now);
53982
+ return { at: now, beats: [...this.beats.values()] };
53983
+ }
53984
+ get(agentId) {
53985
+ return this.beats.get(agentId);
53986
+ }
53987
+ prune(now) {
53988
+ const dropped = [];
53989
+ for (const [agentId, beat] of this.beats) {
53990
+ if (!isPresenceGone(beat, now, { goneAfterStaleMs: this.goneAfterStaleMs }))
53991
+ continue;
53992
+ this.beats.delete(agentId);
53993
+ this.lastDetailChangeAt.delete(agentId);
53994
+ this.transitions.forget(agentId);
53995
+ dropped.push(agentId);
53996
+ }
53997
+ return dropped;
53998
+ }
53999
+ forget(agentId) {
54000
+ this.beats.delete(agentId);
54001
+ this.lastDetailChangeAt.delete(agentId);
54002
+ this.transitions.forget(agentId);
54003
+ }
54004
+ clear() {
54005
+ this.beats.clear();
54006
+ this.lastDetailChangeAt.clear();
54007
+ this.transitions.clear();
54008
+ }
54009
+ size() {
54010
+ return this.beats.size;
54011
+ }
54012
+ }
54013
+ function isTransportInferredStall(status) {
54014
+ if (status.activity !== "stalled")
54015
+ return false;
54016
+ return status.provenance.some((entry) => entry.source === "staleness_inference");
54017
+ }
53768
54018
  // ../runtime/src/session-attention.ts
53769
54019
  init_src2();
53770
54020
  var BLOCKED_STATUS_PATTERN = /\b(blocked|needs[-_\s]?input|awaiting[-_\s]?(input|answer|approval)|waiting[-_\s]?for[-_\s]?(input|approval)|requires[-_\s]?action)\b/i;
@@ -62960,7 +63210,7 @@ function readScoutPairingRuntimePid() {
62960
63210
  return null;
62961
63211
  }
62962
63212
  }
62963
- function isScoutPairingProcessRunning(pid) {
63213
+ function isScoutPairingProcessRunning2(pid) {
62964
63214
  if (!pid || !Number.isInteger(pid) || pid <= 0) {
62965
63215
  return false;
62966
63216
  }
@@ -62973,11 +63223,11 @@ function isScoutPairingProcessRunning(pid) {
62973
63223
  }
62974
63224
  function isScoutPairingRuntimeRunning() {
62975
63225
  const pid = readScoutPairingRuntimePid();
62976
- if (isScoutPairingProcessRunning(pid)) {
63226
+ if (isScoutPairingProcessRunning2(pid)) {
62977
63227
  return true;
62978
63228
  }
62979
63229
  const snapshot = readScoutPairingRuntimeSnapshot();
62980
- return Boolean(snapshot && isScoutPairingProcessRunning(snapshot.childPid ?? snapshot.pid));
63230
+ return Boolean(snapshot && isScoutPairingProcessRunning2(snapshot.childPid ?? snapshot.pid));
62981
63231
  }
62982
63232
  var pairingMutationChain = Promise.resolve();
62983
63233
  async function getScoutWebPairingSessionSnapshots() {